/* ── Base element rules ────────────────────────────────────────────────────
   Moved here from tokens.css so that file is custom properties only and the
   Creator console can link it without inheriting the app's base styles.
   First in app.css, so they cascade exactly where tokens.css put them. */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html, body { height: 100%; }

/* The base element rules take their SIZES from the type ramp, as every px
   text size in app.css and the views does (icons excepted: MD3 sizes them apart).
   They deliberately keep relative line-heights: the ramp's line-heights are
   lengths, and a length on an inheriting root is taken literally by every
   descendant — a 24px h2 would inherit a 20px line box. */
body {
  font-family: var(--md-sys-typescale-font);
  font-size: var(--md-sys-typescale-body-medium-size);
  line-height: 1.5;
  color: var(--md-sys-color-on-surface);
  background: var(--md-sys-color-surface);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* Smooth theme transitions but skip on initial paint */
  transition: background-color .2s ease, color .2s ease;
}

/* When lang=ar, use Cairo for body, falling back to Inter for Latin glyphs. */
:root[lang="ar"] body,
:root[dir="rtl"] body {
  font-family: 'Cairo', var(--md-sys-typescale-font);
}

h1, h2, h3, h4 {
  font-family: var(--md-sys-typescale-font);
  letter-spacing: -0.01em;
}
/* h1 = headline-large, h2 = headline-small, h3 = title-medium (its old 18px
   is not a step on MD3's ramp). Weights stay heavier than MD3's for scanning
   dense CRM pages. */
h1 { font-size: var(--md-sys-typescale-headline-large-size); font-weight: 700; line-height: 1.2; }
h2 { font-size: var(--md-sys-typescale-headline-small-size); font-weight: 700; }
h3 { font-size: var(--md-sys-typescale-title-medium-size); font-weight: 600; }

.caption { font-size: var(--md-sys-typescale-body-dense-size); color: var(--md-sys-color-on-surface-variant); }

/* `hidden` always hides. The UA's `[hidden] { display: none }` loses to any
   author `display`, so without `!important` every component that sets one
   would have to restate it. Show an element by clearing `hidden`, never by
   giving it a display; a rule that must display a [hidden] element needs
   `!important` and a higher specificity (index.html's <noscript> un-hider). */
[hidden] { display: none !important; }

/* Layout */
/* `position: relative` is load-bearing, not decoration. `.sr-only` is
   `position: absolute`, and every ancestor between it and <html> was static —
   so its containing block was the initial one, which means NO ancestor's
   `overflow` could clip it (clipping only reaches descendants whose containing
   block is inside the clipper). Each hidden label therefore sat at its *static
   position* — the document Y it would have had in flow — and rows scrolled deep
   inside `.settings-pane` put that hundreds of pixels below the fold, where it
   still counted toward the ROOT element's scrollable overflow.
   Settings > Members with 16 people gave <html> a scrollHeight of 1506 against
   a 1042 viewport: 464px of page scroll that slid this whole `100dvh` shell —
   top bar included — out of view and left the page background behind it.
   Making the shell a containing block puts those labels back inside the
   `overflow: hidden` above, so they can never extend the document again.
   No stacking context is created (z-index stays auto) and `position: fixed`
   descendants are unaffected, so the mobile sidebar and bottom nav are too. */
#app { display: flex; flex-direction: column; height: 100vh; height: 100dvh; overflow: hidden; position: relative; }

.demo-banner {
  display: none;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  min-height: 42px;
  padding: var(--space-2) var(--space-4);
  background: var(--color-tertiary-container);
  color: var(--color-on-tertiary-container);
  border-bottom: 1px solid var(--color-outline-variant);
  font-size: var(--md-sys-typescale-body-dense-size);
  font-weight: 600;
  flex-shrink: 0;
}
html.crm-demo .demo-banner { display: flex; }
@media (max-width: 520px) { .demo-banner { justify-content: space-between; gap: var(--space-2); padding-inline: var(--space-2); } }

/* Asks people named by a login handle, or without a photo, to fix their
   profile. Dismissible; app.js decides when it shows. */
.profile-nudge {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 42px;
  padding-block: var(--space-1);
  padding-inline: var(--space-3) var(--space-1);
  background: var(--color-primary-container);
  color: var(--color-on-primary-container);
  border-bottom: 1px solid var(--color-outline-variant);
  font-size: var(--md-sys-typescale-body-dense-size);
  font-weight: 600;
  flex-shrink: 0;
}
.profile-nudge > .material-symbols-outlined { font-size: 20px; flex-shrink: 0; }
.profile-nudge__text { flex: 1; min-width: 0; }
.profile-nudge .btn { flex-shrink: 0; }
.profile-nudge__close { min-width: 40px; min-height: 40px; }
@media (max-width: 520px) {
  .profile-nudge { flex-wrap: wrap; padding-inline: var(--space-2) 0; }
  .profile-nudge > .material-symbols-outlined { display: none; }
  /* Text and × share the first row; the button takes the second. */
  .profile-nudge__text { flex-basis: calc(100% - 56px); }
  .profile-nudge__close { order: 1; }
  .profile-nudge .btn { order: 2; }
}

/* ── Top Bar ─────────────────────────────────────────────────────────── */
/* MD3 small top app bar: surface colour, no divider. */
.top-bar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  height: var(--md-top-app-bar-h);
  padding: 0 var(--space-4);
  padding-inline-start: max(var(--space-4), env(safe-area-inset-left, 0));
  padding-inline-end:   max(var(--space-4), env(safe-area-inset-right, 0));
  background: var(--md-sys-color-surface);
  color: var(--color-on-surface);
  z-index: 100;
  flex-shrink: 0;
}
.top-bar__brand { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.top-bar__logo-img { height: 22px; width: auto; }
.top-bar__logo-sep { font-size: var(--md-sys-typescale-title-large-size); font-weight: 300; color: var(--color-on-surface-var); opacity: .4; line-height: 1; }
.top-bar__logo-text { font-family: var(--font-display); font-weight: 600; font-size: var(--md-sys-typescale-body-large-size); letter-spacing: 0.04em; color: var(--color-on-surface-var); }
.top-bar__center { flex: 1; display: flex; justify-content: center; min-width: 0; padding: 0 var(--space-3); }
.top-bar__actions { display: flex; align-items: center; gap: var(--space-2); }

/* ── Search pill (top bar center) ────────────────────────────────────── */
.search-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  max-width: 480px;
  padding: 7px 14px;
  background: var(--color-surface-container);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-pill);
  color: var(--color-on-surface-var);
  font-family: var(--font-body);
  font-size: var(--md-sys-typescale-body-dense-size);
  cursor: pointer;
  transition: background .15s, border-color .15s;
}
.search-pill:hover {
  background: var(--color-surface-container-high);
  border-color: var(--color-outline);
}
.search-pill .material-symbols-outlined { font-size: 18px; opacity: .7; }
.search-pill__text {
  flex: 1; text-align: left;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.search-pill__kbd {
  font-family: var(--font-body); font-size: var(--md-sys-typescale-label-small-size); font-weight: 600;
  padding: 2px 6px; border-radius: var(--md-sys-shape-corner-extra-small);
  border: 1px solid var(--color-outline-variant);
  color: var(--color-on-surface-var); opacity: .6;
  line-height: 1.3; flex-shrink: 0;
}

/* ── Pipeline selector pill ──────────────────────────────────────────── */
.pipeline-select-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
}
/* The pipeline picker: an MD3 tonal control (secondary-container), which
   reads in both themes — the old primary fill carried hardcoded white text,
   unreadable on the light dark-theme primary. */
.pipeline-select-wrap select {
  appearance: none;
  -webkit-appearance: none;
  background: var(--md-sys-color-secondary-container);
  border: none;
  border-radius: var(--md-sys-shape-corner-full);
  color: var(--md-sys-color-on-secondary-container);
  font-family: var(--font-display);
  font-size: var(--md-sys-typescale-label-large-size);
  font-weight: var(--md-sys-typescale-label-large-weight);
  min-height: 40px;
  padding-block: 6px;
  padding-inline: 16px 40px;
  cursor: pointer;
  min-width: 150px;
}
.pipeline-select-wrap select:hover {
  background: color-mix(in srgb, var(--md-sys-color-on-secondary-container) 8%, var(--md-sys-color-secondary-container));
}
.pipeline-select-wrap select option {
  background: var(--md-sys-color-surface-container);
  color: var(--md-sys-color-on-surface);
  font-weight: 500;
}
.pipeline-select-wrap .select-icon {
  position: absolute;
  inset-inline-end: 12px;
  pointer-events: none;
  color: var(--md-sys-color-on-secondary-container);
  font-size: 18px;
  line-height: 1;
}

.layout { display: flex; flex: 1; overflow: hidden; }

/* ── Sidebar ─────────────────────────────────────────────────────────── */
/* `.layout` is overflow:hidden, so anything taller than the sidebar's own box
   is not merely cut off — it is unreachable. Grouping the nav pushed it past a
   768px laptop viewport (13 items + 4 headings), which put Workflows and
   Settings below the fold with no way to scroll to them. The scroll is the
   safety net; the density below is what stops it being needed at all. */
.sidebar {
  width: 256px;
  background: var(--color-surface-container-low);
  display: flex;
  flex-direction: column;
  padding: var(--space-3) var(--space-2);
  flex-shrink: 0;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-gutter: stable;
}

/* MD3 navigation drawer item: a full-corner active indicator in
   secondary-container behind label-large text and a filled icon. 40px rather
   than the spec's 56: thirteen destinations and four headings must fit a
   768px laptop without scrolling (the density note above). */
.nav-item {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 40px;
  padding: 0 var(--space-3);
  color: var(--md-sys-color-on-surface-variant);
  text-decoration: none;
  font-size: var(--md-sys-typescale-label-large-size);
  line-height: var(--md-sys-typescale-label-large-line);
  font-weight: var(--md-sys-typescale-label-large-weight);
  letter-spacing: var(--md-sys-typescale-label-large-tracking);
  border-radius: var(--md-sys-shape-corner-full);
  position: relative;
}
.nav-item.active {
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
  font-weight: 600;
}
.nav-icon {
  font-size: 20px;
  line-height: 1;
  width: 24px;
  text-align: center;
  flex-shrink: 0;
}
.sidebar__spacer { flex: 1; }

/* Group heading. Twelve flat destinations became four labelled groups — the
   same twelve, but you scan one group of 2-5 instead of a wall of ten. */
.nav-group-label {
  margin: 10px 0 4px;
  padding-inline: var(--space-3);
  font-size: var(--md-sys-typescale-title-small-size);
  font-weight: var(--md-sys-typescale-title-small-weight);
  line-height: var(--md-sys-typescale-title-small-line);
  letter-spacing: var(--md-sys-typescale-title-small-tracking);
  color: var(--md-sys-color-on-surface-variant);
}
.sidebar__section:first-child .nav-group-label { margin-top: 2px; }

/* ── Navigation rail (desktop, collapsed) ───────────────────────────────────
   Icons only, as narrow as a 24px icon allows — the point of collapsing is the
   table width it gives back. The name is not gone: the label stays in the DOM,
   visually hidden, so screen readers still announce it, and each link carries
   a data-i18n-title so a hover shows it as a tooltip in the current language.

   app.js auto-collapses below the large breakpoint and remembers an explicit
   hamburger choice. Group headings do not fit, so the groups become the
   hairline rules between sections. */
@media (min-width: 768px) {
  .sidebar { transition: width .2s ease; }
  /* No bar: a classic (Windows) scrollbar would take 15 of the 64px and push
     every icon off-centre. The rail still scrolls by wheel, touch and focus. */
  /* MD3 navigation rail: 80px wide; each destination's indicator is a
     56×32 pill around the icon. */
  .sidebar--collapsed {
    width: 80px;
    padding-inline: var(--space-3);
    scrollbar-width: none;
  }
  .sidebar--collapsed .nav-item {
    justify-content: center;
    width: 56px;
    min-height: 32px;
    padding: 0;
    margin-block: 4px;
  }
  /* .sr-only, scoped to the rail (it cannot join that rule: a saved collapse
     applies on phones too, where the drawer must keep its labels). .nav-item is
     position: relative, so the label cannot escape to the document. */
  .sidebar--collapsed .nav-label {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0);
    white-space: nowrap;
  }
  .sidebar--collapsed .nav-group-label { display: none; }
  .sidebar--collapsed .nav-badge {
    position: absolute;
    top: -4px;
    inset-inline-end: 4px;
  }
  /* :not(:first-child), not the adjacent-sibling form — .sidebar__spacer sits
     between the third section and the fourth and would break the adjacency. */
  .sidebar--collapsed .sidebar__section:not(:first-child) {
    margin-top: var(--space-2);
    padding-top: var(--space-2);
    border-top: 1px solid var(--color-outline-variant);
  }
}

/* ── Organization chips (Add Contact) ───────────────────────────────────────
   One chip per company the contact carries. The first is the main one and says
   so; the rest offer a one-click promotion, because the main company decides
   who may see work logged with this person and that is not something to settle
   by which name was typed first.

   This replaces a `.org-chip` block written for a top-bar element that has
   carried `account-btn__org` for some time. Nothing used the class, and its
   phone rule was `display: none` — a trap for the next component to take the
   name, on the screen size that matters most. */
.cf-org-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.cf-org-chips:empty { display: none; }
.cf-org-chips:not(:empty) { margin-bottom: 8px; }

.cf-org-chip {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 8px 6px 12px;
  max-width: 100%;
  background: var(--color-surface-container);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-pill);
}
.cf-org-chip__logo {
  width: 24px; height: 24px; font-size: var(--md-sys-typescale-body-small-size); flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
}
.cf-org-chip__name {
  font-size: var(--md-sys-typescale-body-dense-size); max-width: 200px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cf-org-chip__main {
  font-size: var(--md-sys-typescale-label-small-size); flex-shrink: 0;
  padding: 1px 6px;
  border-radius: var(--radius-pill);
  background: var(--color-surface-container-highest);
  color: var(--color-on-surface-var);
}
.cf-org-chip__btn {
  padding: 2px; line-height: 0; flex-shrink: 0;
  background: none; border: none; cursor: pointer;
  color: var(--color-on-surface-var);
}
.cf-org-chip__btn .material-symbols-outlined { font-size: 18px; }

/* ── Login Screen ───────────────────────────────────────────────────────── */
#login-screen, #org-picker-screen {
  position: fixed; inset: 0;
  background: var(--md-sys-color-surface-container);
  display: flex; align-items: center; justify-content: center;
  z-index: 9999;
}
.login-wrap { width: 100%; max-width: 440px; padding: 24px; }
.login-card {
  background: var(--md-sys-color-surface-container-lowest);
  border-radius: var(--md-sys-shape-corner-extra-large);
  padding: 52px 44px 40px;
  box-shadow: var(--md-sys-elevation-1);
  text-align: center;
}
.login-logo { margin-bottom: 28px; }
.login-logo__img { height: 52px; }
.login-title {
  font-family: var(--font-display);
  font-size: var(--md-sys-typescale-title-large-size); font-weight: 700;
  margin: 0 0 10px; color: var(--md-sys-color-on-surface);
  display: flex; align-items: center; justify-content: center; gap: 10px;
}
.login-title__sep { font-weight: 300; color: var(--md-sys-color-outline-variant); }
.login-sub {
  color: var(--md-sys-color-on-surface-variant); margin: 0 0 32px;
  font-size: var(--md-sys-typescale-body-large-size); line-height: 1.5;
}
.login-btn {
  display: flex; align-items: center; justify-content: center;
  gap: 10px; width: 100%;
  padding: 12px 24px;
  background: var(--md-sys-color-primary); color: var(--md-sys-color-on-primary);
  border: none; border-radius: var(--radius-pill);
  font-size: var(--md-sys-typescale-label-large-size);
  font-weight: var(--md-sys-typescale-label-large-weight);
  letter-spacing: var(--md-sys-typescale-label-large-tracking);
  font-family: inherit; cursor: pointer;
  transition: box-shadow var(--md-sys-motion-duration-short2) var(--md-sys-motion-easing-standard);
}
/* MD3 filled button: level 1 on hover, an 8% on-primary layer over the fill. */
.login-btn:hover {
  background: color-mix(in srgb, var(--md-sys-color-on-primary) 8%, var(--md-sys-color-primary));
  box-shadow: var(--md-sys-elevation-1);
}
.login-btn:disabled { opacity: .7; cursor: wait; }
/* ── Login page (Pipedrive-style page layout) ───────────────────────────── */
#login-screen.login-page-mode {
  align-items: stretch; justify-content: stretch;
  background: var(--md-sys-color-surface);
}
.login-page {
  flex: 1; align-self: stretch;
  display: flex; flex-direction: column;
  width: 100%; min-width: 0;
}
.login-page__header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 20px 32px; gap: 16px;
}
.login-page__brand { display: inline-flex; align-items: center; }
.login-page__brand-img { height: 32px; }
.login-page__top-cta {
  font-size: var(--md-sys-typescale-body-medium-size); color: var(--md-sys-color-on-surface-variant); text-decoration: none; font-weight: 500;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 16px; border-radius: var(--md-sys-shape-corner-full);
  border: 1px solid var(--md-sys-color-outline-variant); background: var(--md-sys-color-surface-container-lowest);
  transition: background .15s, border-color .15s;
}
.login-page__top-cta:hover { background: var(--md-sys-color-surface-container); border-color: var(--md-sys-color-outline); }

.login-page__main {
  flex: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 56px; padding: 40px 24px;
}

.login-card--compact {
  padding: 40px 36px;
  border-radius: var(--md-sys-shape-corner-large);
  width: 100%; max-width: 380px;
  border: 1px solid var(--md-sys-color-outline-variant);
}
.login-card__title {
  margin: 0 0 8px; font-family: var(--font-display);
  font-size: var(--md-sys-typescale-headline-small-size); font-weight: 700; color: var(--md-sys-color-on-surface);
}
.login-card__subtitle {
  margin: 0 0 28px; font-size: var(--md-sys-typescale-body-medium-size); color: var(--md-sys-color-on-surface-variant);
}

.login-brand { text-align: center; max-width: 720px; width: 100%; }
.login-brand__name {
  margin: 0 0 6px; font-family: var(--font-display);
  font-size: var(--md-sys-typescale-body-large-size); font-weight: 700; color: var(--md-sys-color-on-surface);
}
.login-brand__tagline {
  margin: 0 0 28px; font-size: var(--md-sys-typescale-body-medium-size); color: var(--md-sys-color-on-surface-variant);
}
.login-brand__features {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 24px; font-size: var(--md-sys-typescale-body-dense-size); color: var(--md-sys-color-on-surface-variant);
}
.login-brand__features li {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  text-align: center; line-height: 1.5; padding: 0 4px;
}
.login-brand__icon {
  font-size: 26px !important; color: var(--color-primary);
}

.login-page__footer {
  display: flex; align-items: center; justify-content: space-between;
  padding: 20px 32px; gap: 24px; flex-wrap: wrap;
  border-top: 1px solid var(--md-sys-color-outline-variant);
  font-size: var(--md-sys-typescale-body-small-size); color: var(--md-sys-color-on-surface-variant);
}
.login-page__footer-legal {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.login-page__footer-legal a { color: var(--md-sys-color-on-surface-variant); text-decoration: none; }
.login-page__footer-legal a:hover { color: var(--md-sys-color-on-surface); text-decoration: underline; }
.login-page__footer-sep { color: var(--md-sys-color-outline-variant); }
.login-page__footer-social {
  display: flex; align-items: center; gap: 16px;
}
.login-page__footer-social a {
  color: var(--md-sys-color-on-surface-variant); transition: color .15s;
  display: inline-flex; align-items: center;
}
.login-page__footer-social a:hover { color: var(--md-sys-color-on-surface); }
.login-page__footer-social svg {
  width: 16px; height: 16px; fill: currentColor;
}

@media (max-width: 600px) {
  .login-page__header { padding: 14px 18px; }
  .login-page__top-cta { font-size: var(--md-sys-typescale-body-dense-size); padding: 6px 12px; }
  .login-page__main { gap: 36px; padding: 24px 16px; }
  .login-card--compact { padding: 32px 24px; }
  .login-brand__features {
    grid-template-columns: 1fr; gap: 14px;
  }
  .login-brand__features li {
    flex-direction: row; text-align: start; padding: 0;
  }
  .login-page__footer {
    flex-direction: column-reverse; gap: 14px; padding: 16px 18px;
    text-align: center;
  }
  .login-page__footer-legal { justify-content: center; }
}

/* ── Org picker ──────────────────────────────────────────────────────────── */
.login-wrap--wide { max-width: 480px; }
.org-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 4px; }
.org-card {
  display: flex; align-items: center; gap: 12px;
  width: 100%; padding: 14px 16px;
  background: var(--md-sys-color-surface-container-low);
  border: 1px solid transparent;
  border-radius: var(--md-sys-shape-corner-medium);
  font-size: var(--md-sys-typescale-body-large-size); font-weight: 500;
  font-family: inherit; cursor: pointer;
  color: var(--md-sys-color-on-surface); text-align: start;
  transition: border-color .15s, background .15s, box-shadow .15s;
}
.org-card:hover {
  background: color-mix(in srgb, var(--md-sys-color-primary) 8%, var(--md-sys-color-surface-container-lowest));
  border-color: var(--md-sys-color-primary);
  box-shadow: var(--md-sys-elevation-1);
}
.org-card__icon { font-size: 22px; color: var(--md-sys-color-primary); }
.org-card__name { flex: 1; }
.org-card__arrow { font-size: 18px; color: var(--md-sys-color-outline-variant); transition: color .15s; }
.org-card:hover .org-card__arrow { color: var(--md-sys-color-primary); }
.org-picker__signout {
  margin-top: 16px;
  background: none;
  border: none;
  color: var(--md-sys-color-on-surface-variant);
  font-size: var(--md-sys-typescale-body-dense-size);
  font-family: inherit;
  cursor: pointer;
  padding: 8px;
}
.org-picker__signout:hover {
  color: var(--md-sys-color-primary);
  text-decoration: underline;
}

/* ── Main View ───────────────────────────────────────────────────────── */
/* Its padding as two properties, all that each breakpoint below sets: what
   pins to its top (a report's editing header) takes them back from them. */
.view {
  --view-pad-block: var(--space-4);
  --view-pad-inline: var(--space-4);
  flex: 1; overflow-y: auto; padding: var(--view-pad-block) var(--view-pad-inline);
}

/* Ledger pages: sticky toolbar + pagination, scroll only the table body.
   The leads list sits in a wrapper beside its side panel (leads.js); the
   wrapper takes no box of its own, so the list lays out as any other. */
.leads-list { display: contents; }
.view:has(> .ledger-card, > .leads-list > .ledger-card) {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-height: 0;
}

/* Deals board: the view shell is the settings one (see "Settings: full-height
   desktop shell"); the board takes whatever height is left under the header,
   toolbar and KPI row, and each column scrolls inside itself. Phones keep the
   page scroller and a calc() cap on the column (mobile block). */
@media (min-width: 768px) {
  .view:has(> .kanban) > .kanban { flex: 1 1 0; min-height: 0; }
  .view:has(> .kanban) .skeleton-kanban { min-height: 0; }
  /* Keyed on the deals toolbar, not the board, so switching to list or
     timeline does not move the header. */
  .page-header:has(+ .pipeline-kpi) { margin-bottom: var(--space-3); }
}
.ledger-card {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.ledger-card > .table-toolbar { flex-shrink: 0; }
/* A toolbar menu over a short list is not cut off by the card. */
.ledger-card:has(.sort-dropdown__menu.open) { overflow: visible !important; }
.table-toolbar--tabs > .tag-filter-wrap { flex: none; }
.ledger-card > .ledger-body {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.ledger-scroll {
  flex: 1;
  min-height: 0;
  overflow: auto;
}
.ledger-card .pagination-row {
  flex-shrink: 0;
  border-top: 1px solid var(--color-outline-variant);
  background: var(--color-surface-container-lowest);
}

/* ── Cards ───────────────────────────────────────────────────────────── */
/* MD3 elevated card: medium (12px) corners, level 1 at rest. Only a card that
   is itself a link or button lifts on hover — a lift on a static panel
   promises an interaction that isn't there. */
.card {
  background: var(--crm-card-surface);
  border-radius: var(--md-sys-shape-corner-medium);
  box-shadow: var(--md-sys-elevation-1);
  padding: var(--space-4);
}
:is(a, button).card:hover { box-shadow: var(--md-sys-elevation-2); }

/* ── Buttons ─────────────────────────────────────────────────────────── */
/* MD3 common button: 40px container, full corners, label-large, 24px side
   padding (16px on the icon side). The 48px touch target is the ::before
   band — invisible, outside the container — so the button itself can sit at
   the spec's 40px beside fields and chips. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 10px 24px;
  min-height: 40px;
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-size: var(--md-sys-typescale-label-large-size);
  line-height: var(--md-sys-typescale-label-large-line);
  font-weight: var(--md-sys-typescale-label-large-weight);
  letter-spacing: var(--md-sys-typescale-label-large-tracking);
  cursor: pointer;
  border: none;
  transition: box-shadow var(--md-sys-motion-duration-short2) var(--md-sys-motion-easing-standard);
}
a.btn, a.btn:hover { text-decoration: none; }
.btn::before {
  content: "";
  position: absolute;
  inset-block: -4px;
  inset-inline: 0;
}
/* A label's leading icon takes less room than text (MD3: 16dp before the icon,
   24dp after the label). Not on a button that is only an icon: there the
   padding is even, so the icon sits in the middle (.btn--icon, .icon-only).
   :where() keeps the specificity these rules always had. */
.btn:where(:not(.btn--icon, .icon-only)):has(> .material-symbols-outlined:first-child) { padding-inline-start: 16px; }
.btn > .material-symbols-outlined { font-size: 18px; }

/* A leading icon in a button or label — MD3 button icons are 18px. */
.icon-lead { font-size: 18px; vertical-align: middle; margin-inline-end: 4px; }
.btn > .icon-lead { margin-inline-end: 0; }
/* Hover/press feedback comes from the state layer (see “MD3 state layer” below),
   not from fading the whole button — opacity dimmed the label along with the
   fill, which reads as “disabled” rather than “pressed”. */
/* MD3 filled button: no elevation at rest, level 1 on hover. */
.btn--primary {
  background: var(--color-primary);
  color: var(--color-on-primary);
}
.btn--primary:hover { box-shadow: var(--md-sys-elevation-1); }
/* MD3 disabled: the label at on-surface 38%; a container (where the variant
   has one) at on-surface 12%; no elevation. The :hover half outranks the
   variant hover rules above — equal specificity, later in source order. */
.btn:disabled,
.btn:disabled:hover {
  color: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent);
  cursor: not-allowed;
  box-shadow: none;
  filter: none;
}
:is(.btn--primary, .btn--tonal, .btn--success, .btn--danger):disabled {
  background: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent);
}
:is(.btn--outline, .btn--icon):disabled {
  border-color: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent);
}
.btn--outline {
  background: transparent;
  border: 1px solid var(--md-sys-color-outline);
  color: var(--md-sys-color-primary);
}
.btn--sm { min-height: 32px; padding: 6px 16px; font-size: var(--md-sys-typescale-body-dense-size); }
.btn--sm:where(:not(.btn--icon, .icon-only)):has(> .material-symbols-outlined:first-child) { padding-inline-start: 12px; }
/* MD3 outlined icon button: a 40px circle, 1px outline, 24px icon. */
.btn--icon {
  min-width: 40px;
  padding: 7px;
  background: transparent;
  border: 1px solid var(--md-sys-color-outline);
  color: var(--md-sys-color-on-surface-variant);
  border-radius: var(--md-sys-shape-corner-full);
}
.btn--icon .material-symbols-outlined { font-size: 24px; }
/* MD3 text button — lowest emphasis, primary label, no container. `ghost`
   is the CRM's older name for it; both classes are the same variant. */
.btn--ghost,
.btn--text {
  background: transparent; border: none;
  color: var(--md-sys-color-primary); padding: 10px 12px;
}
:is(.btn--ghost, .btn--text):where(:not(.btn--icon, .icon-only)):has(> .material-symbols-outlined:first-child) { padding-inline: 12px 16px; }
/* MD3 tonal button — medium emphasis, secondary-container. */
.btn--tonal {
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
}

/* ── Modal ───────────────────────────────────────────────────────────── */
/* MD3 modal — same DOM, MD3 surfaces, scrim, and shape. */
.modal-overlay {
  position: fixed; inset: 0; z-index: 300;
  background: color-mix(in srgb, var(--md-sys-color-scrim) 32%, transparent);
  display: none; align-items: center; justify-content: center;
  padding: var(--space-4);
}
.modal-overlay.open { display: flex; }
/* MD3 dialog: surface-container-high, extra-large corners, level 3. */
.modal {
  background: var(--md-sys-color-surface-container-high);
  border-radius: var(--md-sys-shape-corner-extra-large);
  box-shadow: var(--md-sys-elevation-3);
  width: 520px; max-width: 100%; max-height: 90vh;
  display: flex; flex-direction: column;
  animation: modal-in var(--md-sys-motion-duration-medium2) var(--md-sys-motion-easing-standard-decelerate);
}
.modal--wide { width: 720px; }
/* Reduced-motion guard for .modal lives at the END of the file — it must
   follow the mobile modal-slide-up rule in source order to win the cascade. */
@keyframes modal-in {
  from { opacity:0; transform: translateY(16px); }
  to   { opacity:1; transform: translateY(0); }
}
/* No dividers: MD3 dialogs separate header, body and actions by spacing. */
.modal__header {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--space-4) var(--space-3) var(--space-2) var(--space-4);
  flex-shrink: 0;
}
.modal__title {
  font-family: var(--font-display);
  font-size: var(--md-sys-typescale-headline-small-size);
  line-height: var(--md-sys-typescale-headline-small-line);
  font-weight: var(--md-sys-typescale-headline-small-weight);
  letter-spacing: var(--md-sys-typescale-headline-small-tracking);
  color: var(--md-sys-color-on-surface);
}
.modal__close {
  /* MD3 IconButton spec: 48×48 dp target. */
  width: 48px; height: 48px; border: none; background: none; cursor: pointer;
  border-radius: 50%; font-size: var(--md-sys-typescale-title-large-size); color: var(--color-on-surface-var);
  display: flex; align-items: center; justify-content: center;
  position: relative;
}
.modal__body {
  padding: var(--space-2) var(--space-4) var(--space-4); overflow-y: auto; flex: 1;
}
.modal__actions {
  display: flex; align-items: center; justify-content: flex-end; gap: var(--space-2);
  padding: var(--space-2) var(--space-4) var(--space-4);
  flex-shrink: 0;
}
/* Controls a form wants beside Cancel/Save — "Mark as done" — so they are
   reachable without scrolling a long body. Empty for every other modal. */
.modal__actions-start { margin-inline-end: auto; display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.modal__actions-start:empty { display: none; }
.modal__actions-start label { margin: 0; font-size: var(--md-sys-typescale-body-medium-size); font-weight: 400; letter-spacing: 0; cursor: pointer; }
.modal__actions-start input[type="checkbox"] { width: auto; margin: 0; }

/* ── Call sheet — aggregated "Call <name>" number picker ─────────────────── */
.modal.call-sheet .modal__body { padding: var(--space-2) var(--space-3) var(--space-3); }
.call-sheet__list { display: flex; flex-direction: column; gap: var(--space-2); }
.call-sheet__row {
  display: flex; align-items: center; gap: var(--space-3);
  min-height: 56px;
  padding: 10px var(--space-3);
  border-radius: var(--radius-m);
  border: 1px solid var(--color-outline-variant);
  background: var(--color-surface-container-lowest);
  color: var(--color-on-surface);
  text-decoration: none;
  transition: background .15s, border-color .15s;
}
.call-sheet__row:hover,
.call-sheet__row:active {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--color-on-primary);
}
.call-sheet__icon { font-size: 22px; color: var(--color-primary); flex-shrink: 0; }
.call-sheet__row:hover .call-sheet__icon,
.call-sheet__row:active .call-sheet__icon { color: var(--color-on-primary); }
.call-sheet__text { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.call-sheet__label {
  font-size: var(--md-sys-typescale-label-small-size); font-weight: 700; letter-spacing: .5px;
  color: var(--color-on-surface-var);
}
.call-sheet__row:hover .call-sheet__label,
.call-sheet__row:active .call-sheet__label { color: var(--color-on-primary); }
.call-sheet__num { font-size: var(--md-sys-typescale-body-large-size); font-weight: 600; }
.call-sheet__chev { font-size: 18px; opacity: .6; flex-shrink: 0; }

/* ── Log sheet — the call being logged (views/_callButton.js) ────────────── */
.modal.log-call-sheet .modal__body { padding: var(--space-3); }
/* The swapped-in footer control plus Close and Save can outgrow a 375px sheet. */
.modal.log-call-sheet .modal__actions { flex-wrap: wrap; }
.modal.log-call-sheet #lcCallAgain { text-decoration: none; }
.lc-status {
  margin: 0 0 var(--space-3);
  padding: 10px var(--space-3);
  border-radius: var(--radius-m);
  background: var(--color-surface-container);
  color: var(--color-on-surface);
  font-size: var(--md-sys-typescale-body-medium-size); font-weight: 600;
}
.lc-status--ok   { background: var(--color-success-bg); color: var(--color-success-text); }
.lc-status--warn { background: var(--color-warning-bg); color: var(--color-warning-text); }
.lc-outcomes {
  display: flex; flex-wrap: wrap; gap: var(--space-2);
  margin: 0 0 var(--space-3); padding: 0; border: 0; min-width: 0;
}
.lc-outcomes legend {
  padding: 0; margin-bottom: 6px;
  font-size: var(--md-sys-typescale-label-medium-size);
  font-weight: var(--md-sys-typescale-label-medium-weight);
  letter-spacing: var(--md-sys-typescale-label-medium-tracking);
  color: var(--color-on-surface-var);
}
/* The chip is the span; the radio sits over it, invisible but focusable and
   arrow-key operable, so the group behaves as one native radio group. An MD3
   filter chip: 32px, small corners, selected = secondary-container. */
.lc-outcomes label { position: relative; display: inline-flex; margin: 0; }
.lc-outcomes input[type="radio"] {
  appearance: none; -webkit-appearance: none;
  position: absolute; inset: 0; width: 100%; height: 100%;
  margin: 0; opacity: 0; cursor: pointer;
}
.lc-outcomes span {
  display: inline-flex; align-items: center;
  min-height: 32px; padding: 0 16px;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-small);
  background: transparent;
  color: var(--md-sys-color-on-surface-variant);
  font-size: var(--md-sys-typescale-label-large-size);
  font-weight: var(--md-sys-typescale-label-large-weight);
  transition: background .15s, border-color .15s, color .15s;
}
.lc-outcomes input:checked + span {
  background: var(--md-sys-color-secondary-container);
  border-color: transparent;
  color: var(--md-sys-color-on-secondary-container);
}
.lc-outcomes input:focus-visible + span { outline: 2px solid var(--color-primary); outline-offset: 2px; }
#lc-duration { max-width: 10em; }
/* Call | Missed call at the top of the sheet: the MD3 segmented button
   (.view-switcher) with text segments over native radios, equal in width as
   M3 sizes them. The sheet only opens on a phone, so each segment is a 48px
   touch target. These selectors outrank .view-switcher__btn. */
.lc-type { margin: 0 0 var(--space-3); }
.lc-type .view-switcher__btn {
  flex: 1 1 0; width: auto; min-width: 0; min-height: var(--space-6);
  gap: var(--space-2); padding-inline: var(--space-3);
  font-size: var(--md-sys-typescale-label-large-size);
  font-weight: var(--md-sys-typescale-label-large-weight);
}
/* The radio covers its segment: invisible, but focusable and arrow-key
   operable, so the segments are one native radio group. */
.lc-type input[type="radio"] {
  appearance: none; -webkit-appearance: none;
  position: absolute; inset: 0; width: 100%; height: 100%;
  margin: 0; opacity: 0; cursor: pointer;
}
.lc-type .view-switcher__btn:has(input:focus-visible) { outline: 2px solid var(--color-primary); outline-offset: -2px; }
.lc-type .view-switcher__btn:has(input:focus-visible)::after { opacity: var(--md-sys-state-focus); }
.lc-type__name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── Forms ───────────────────────────────────────────────────────────── */
.form-group { display: flex; flex-direction: column; gap: 6px; margin-bottom: var(--space-3); }
.form-group:last-child { margin-bottom: 0; }
/* MD3 outlined text field at density -4 (40px): 4px corners, a 1px outline
   that darkens on hover and becomes 2px primary on focus, transparent on
   whatever surface holds it. The label sits above the field rather than
   floating in its outline — a deliberate CRM deviation: forms are built as
   label + control pairs across ~100 views, and the above-label reads the same. */
.form-group label {
  font-size: var(--md-sys-typescale-label-medium-size);
  line-height: var(--md-sys-typescale-label-medium-line);
  font-weight: var(--md-sys-typescale-label-medium-weight);
  letter-spacing: var(--md-sys-typescale-label-medium-tracking);
  color: var(--md-sys-color-on-surface-variant);
}
.form-group:focus-within > label { color: var(--md-sys-color-primary); }
.form-group:has([aria-invalid="true"]) > label { color: var(--md-sys-color-error); }
.form-group input,
.form-group select,
.form-group textarea {
  width: 100%; padding: 9px 12px; min-height: 40px;
  border: 1px solid var(--md-sys-color-outline);
  border-radius: var(--md-sys-shape-corner-extra-small);
  font-family: var(--font-body);
  font-size: var(--md-sys-typescale-body-medium-size);
  color: var(--color-on-surface);
  background: transparent;
  outline: none; transition: border-color .15s, box-shadow .15s;
}
.form-group :is(input, select, textarea):hover:not(:focus):not(:disabled) {
  border-color: var(--md-sys-color-on-surface);
}
.form-group :is(input, select, textarea):disabled {
  border-color: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent);
  color: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent);
}
.form-group select option { background: var(--md-sys-color-surface-container); color: var(--md-sys-color-on-surface); }
/* Native check and radio marks in the primary role. */
input[type="checkbox"]:not([role="switch"]),
input[type="radio"] { accent-color: var(--md-sys-color-primary); }
.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
  /* MD3 outlined field: the outline thickens to 2px primary. The inset ring
     adds the second pixel without shifting the layout. */
  border-color: var(--md-sys-color-primary);
  box-shadow: inset 0 0 0 1px var(--md-sys-color-primary);
}
.form-group textarea { resize: vertical; min-height: 80px; }
/* A row is one field in the form's flow: the space under it is a lone
   field's, and the row's gap spaces its own fields, side by side or stacked
   on a phone. Its fields used to keep their own margin, but the last of them
   lost it to .form-group:last-child: stacked, the field under the row sat
   tight against it (Yahia, 2026-10-20). */
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); margin-bottom: var(--space-3); }
.form-row:last-child { margin-bottom: 0; }
.form-row > .form-group { margin-bottom: 0; }
/* Date beside a start–end pair: the pair needs the wider share. */
.form-row--when { grid-template-columns: minmax(0, 1fr) minmax(0, 1.7fr); }

/* Inline validation message — WCAG 3.3.1 (paired with aria-invalid + aria-describedby) */
.field-error { color: var(--color-error); font-size: var(--md-sys-typescale-body-small-size); margin-top: 4px; }
[aria-invalid="true"] { border-color: var(--color-error) !important; }

/* ── Invite-modal Edara user picker ─────────────────────────────────── */
.invite-picker { position: relative; }
.invite-picker__results {
  margin-top: 4px;
  max-height: 240px; overflow-y: auto;
  background: var(--color-surface-container-lowest);
  border: 1.5px solid var(--color-surface-container-high);
  border-radius: var(--radius-m);
  box-shadow: var(--shadow-2);
}
.invite-picker__row {
  padding: 8px 12px; cursor: pointer;
  border-bottom: 1px solid var(--color-surface-container-high);
}
.invite-picker__row:last-child { border-bottom: none; }
.invite-picker__row:hover { background: var(--color-surface-container); }
.invite-picker__empty {
  padding: 12px; text-align: center;
  color: var(--color-on-surface-var); font-size: var(--md-sys-typescale-body-dense-size);
}
.invite-picker__hint {
  padding: 8px 12px; font-size: var(--md-sys-typescale-body-small-size);
  color: var(--color-on-surface-var);
  background: var(--color-surface-container);
  border-top: 1px solid var(--color-surface-container-high);
}
.invite-picker__selected {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-2);
  padding: 9px 12px;
  background: var(--color-surface-container);
  border: 1.5px solid var(--color-primary-container);
  border-radius: var(--radius-m);
}
.invite-picker__selected-info { min-width: 0; flex: 1; }
.invite-picker__selected-info .caption { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ── Filter chips (contacts / orgs) ─────────────────────────────────── */
/* Wrapping is what stops a long filter set from pushing the search box and the
   trailing actions off the end of the toolbar — Organizations has six chips
   plus Views and used to overlap its own Tags button. */
.filter-chips { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; min-width: 0; }
/* inline-flex + gap is what lets a chip carry a leading icon, which is how the
   Organizations, Activities and owner filters used to justify their own
   component. They are all this one now. Material 3's chip: 32dp tall, "slightly
   rounded with an 8dp corner", 8dp apart. */
.filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  min-height: 32px;
  padding: 5px 14px;
  border-radius: var(--md-sys-shape-corner-small);
  font-size: var(--md-sys-typescale-label-large-size);
  font-weight: var(--md-sys-typescale-label-large-weight);
  cursor: pointer;
  background: transparent;
  color: var(--color-on-surface-var);
  border: 1px solid var(--md-sys-color-outline-variant);
  transition: background var(--md-sys-motion-duration-short2) var(--md-sys-motion-easing-standard),
              color var(--md-sys-motion-duration-short2) var(--md-sys-motion-easing-standard),
              border-color var(--md-sys-motion-duration-short2) var(--md-sys-motion-easing-standard);
}
:is(.filter-chip, .toolbar-btn) .material-symbols-outlined { font-size: 16px; }
/* Selected filter chips carry secondary-container per MD3, not a filled primary —
   a filter is a refinement, not the page's primary action. Both themes resolve
   the same two roles, so this needs no [data-theme="dark"] block. */
.filter-chip.active,
.filter-chip[aria-pressed="true"] {
  background: var(--color-secondary-container);
  color: var(--color-on-secondary-container);
  border-color: transparent;
}

/* ── Table toolbar (search + chips row above table) ─────────────────── */
/* One shape for every list page: search, then filters, then trailing actions
   (Views, Tags, …) pushed to the end. Sizing the search box here rather than
   inline per view is what keeps the six of them from drifting apart. */
.table-toolbar {
  display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap;
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-surface-container-high);
}
.table-toolbar > .search-bar { flex: 1 1 240px; max-width: 380px; }
.table-toolbar__actions {
  display: flex; align-items: center; gap: var(--space-2);
  margin-inline-start: auto;
}
.search-bar {
  display: flex; align-items: center; gap: 8px; min-width: 0;
  background: var(--color-surface-container-low);
  border: 1.5px solid transparent;
  border-radius: var(--radius-pill); padding: 7px 14px;
  font-size: var(--md-sys-typescale-body-medium-size); transition: border-color .15s, box-shadow .15s;
}
.search-bar:focus-within {
  border-color: var(--color-primary-container);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--md-sys-color-primary) 10%, transparent);
}
.search-bar .material-symbols-outlined { font-size: 18px; color: var(--color-on-surface-var); }
.search-bar input {
  border: none; outline: none; flex: 1; background: transparent;
  font-family: var(--font-body); font-size: var(--md-sys-typescale-body-medium-size); color: var(--color-on-surface);
  /* An input's default intrinsic width refuses to shrink below ~170px, which is
     what pushed the toolbar past its container instead of letting it wrap. */
  min-width: 0;
}

/* ── Small avatar (table rows, deal cards) ───────────────────────────── */
.avatar-sm {
  width: 30px; height: 30px; border-radius: 50%; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: var(--md-sys-typescale-label-small-size); font-weight: 700; color: #fff; letter-spacing: 0;
}
/* Org logo — the organization's initial on the same palette as a person's
   avatar (AVATAR_COLORS in _userPicker.js keys both). */
.org-logo {
  width:40px; height:40px; border-radius:var(--radius-m); flex-shrink:0;
  display:flex; align-items:center; justify-content:center;
  font-family:var(--font-display); font-size:var(--md-sys-typescale-body-large-size); font-weight:700; color:#fff;
}
/* The shared palette. After both base rules, which set white ink: the light
   swatches (amber, gold) take dark ink instead. */
.avatar-sm--blue,   .org-logo--blue    { background: #004a79; }
.avatar-sm--indigo, .org-logo--indigo  { background: #3949ab; }
.avatar-sm--violet, .org-logo--violet  { background: #7b1fa2; }
.avatar-sm--teal,   .org-logo--teal    { background: #00796b; }
.avatar-sm--green,  .org-logo--green   { background: #2e7d32; }
.avatar-sm--amber,  .org-logo--amber   { background: #f57f17; color: #1a1a1a; }
.avatar-sm--orange, .org-logo--orange  { background: #e65100; }
.avatar-sm--red,    .org-logo--red     { background: #c62828; }
.avatar-sm--navy,   .org-logo--navy    { background: #0f2740; }
.avatar-sm--gold,   .org-logo--gold    { background: #f7be00; color: #1a1a1a; }
/* A profile photo in the same slot as the initials. */
.avatar-sm--img { object-fit: cover; background: var(--color-surface-container-high); }

/* ── Profile editor (My profile modal) ───────────────────────────────── */
.profile-editor__photo {
  display: flex; align-items: center; gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.profile-avatar {
  width: 88px; height: 88px; border-radius: 50%; flex-shrink: 0;
  object-fit: cover;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: var(--md-sys-typescale-headline-medium-size); font-weight: 700; color: #fff;
  border: 1px solid var(--color-outline-variant);
}
.profile-editor__photo-actions { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.profile-editor__buttons { display: flex; flex-wrap: wrap; gap: var(--space-2); }

/* ── Status & role badges (team table) ───────────────────────────────── */
.status-badge {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--md-sys-typescale-body-small-size); font-weight: 600; white-space: nowrap;
}
.status-dot {
  width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0;
}
.status-badge--active              { color: var(--md-sys-color-success); }
.status-badge--active .status-dot  { background: var(--md-sys-color-success); }
.status-badge--invited             { color: var(--md-sys-color-warning); }
.status-badge--invited .status-dot { background: var(--md-sys-color-warning); }
.status-badge--inactive                { color: var(--color-on-surface-var); }
.status-badge--inactive .status-dot    { background: var(--color-on-surface-var); }

.role-badge {
  display: inline-block; padding: 2px 10px; border-radius: var(--radius-pill);
  font-size: var(--md-sys-typescale-label-small-size); font-weight: 600; letter-spacing: 0.03em;
}
.role-badge--admin  { background: var(--color-primary); color: var(--color-on-primary); }
.role-badge--member { background: var(--color-surface-container-high); color: var(--color-on-surface-var); }
.role-badge--warn   { background: var(--color-warning-bg); color: var(--color-warning-text); }
.role-badge--owner  { background: var(--color-gold); color: #1a1400; border: 1px solid rgba(0,0,0,0.12); }

/* ── Plan block (402 upgrade gate) ─────────────────────────────────── */
.plan-block {
  position: fixed; inset: 0; display: flex; align-items: center; justify-content: center;
  background: var(--color-surface); padding: var(--space-4); z-index: 10000;
}
.plan-block__card {
  max-width: 480px; width: 100%; padding: var(--space-6);
  background: var(--color-surface-container); border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-l); text-align: center;
}
.plan-block__icon {
  width: 64px; height: 64px; border-radius: 50%;
  background: var(--color-gold); color: #1a1400;
  display: flex; align-items: center; justify-content: center;
  margin: 0 auto var(--space-4);
}
.plan-block__icon .material-symbols-outlined { font-size: 36px; }
.plan-block__title { margin: 0 0 var(--space-2); font-size: var(--md-sys-typescale-title-large-size); }
.plan-block__msg   { margin: 0 0 var(--space-3); font-size: var(--md-sys-typescale-body-large-size); font-weight: 600; }
.plan-block__hint  { margin: 0 0 var(--space-5); color: var(--color-on-surface-var); font-size: var(--md-sys-typescale-body-medium-size); }
/* Left-align a form field inside the otherwise-centered block card (e.g. the
   currency setup picker), with spacing before the action button below it. */
.plan-block__form  { text-align: start; margin-bottom: var(--space-4); }
/* Which account was turned away — the fact an admin needs to issue the right
   invitation. Sits between the backend message and the hint. */
.plan-block__identity {
  margin: 0 0 var(--space-3); font-size: var(--md-sys-typescale-body-medium-size);
  color: var(--color-on-surface-var); overflow-wrap: anywhere;
}
/* Stack the actions on narrow screens so neither button is clipped at 375px. */
.plan-block__actions {
  display: flex; gap: var(--space-2);
  align-items: center; justify-content: center; flex-wrap: wrap;
}

/* ── Upgrade-required panel (in-card, not full-page) ────────────────── */
.upgrade-panel {
  display: flex; gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  background: var(--color-surface-container);
  border: 1px solid var(--color-outline-variant);
  border-inline-start: 4px solid var(--color-gold);
  border-radius: var(--radius-s);
}
.upgrade-panel__icon {
  flex-shrink: 0; width: 32px; height: 32px; border-radius: 50%;
  background: var(--color-gold); color: #1a1400;
  display: flex; align-items: center; justify-content: center;
}
.upgrade-panel__icon .material-symbols-outlined { font-size: 18px; }
/* Neutral variant: same layout, no gold. Used when the panel reports that
   setup didn't finish — copy that explicitly does NOT claim the tenant's plan
   is limited, so it must not wear the upsell medal. Tokens only, so it
   inherits both themes. */
.upgrade-panel--notice { border-inline-start-color: var(--color-outline); }
.upgrade-panel--notice .upgrade-panel__icon {
  background: var(--color-surface-variant); color: var(--color-on-surface-var);
}
.upgrade-panel__title {
  margin: 0 0 4px; font-size: var(--md-sys-typescale-body-dense-size); font-weight: 600;
}
.upgrade-panel__body  {
  margin: 0; font-size: var(--md-sys-typescale-body-small-size); line-height: 1.5;
  color: var(--color-on-surface-var);
}

/* ── Pagination row ──────────────────────────────────────────────────── */
.pagination-row {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--space-2) var(--space-4);
  font-size: var(--md-sys-typescale-body-dense-size); color: var(--color-on-surface-var);
  border-top: 1px solid var(--color-surface-container-high);
}
.pagination-row__controls { display: flex; gap: 4px; }
.pagination-btn {
  width: 32px; height: 32px; border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--radius-s); background: var(--color-surface-container-lowest);
  cursor: pointer; font-size: var(--md-sys-typescale-body-dense-size); color: var(--color-on-surface-var);
  display: inline-flex; align-items: center; justify-content: center;
}
.pagination-btn.active { background: var(--color-primary); color: var(--color-on-primary); border-color: var(--color-primary); }
.pagination-btn .material-symbols-outlined { font-size: 16px; }
.pagination-btn:disabled { opacity: .35; cursor: default; pointer-events: none; }
.pagination-ellipsis {
  width: 32px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: var(--md-sys-typescale-body-dense-size); color: var(--color-on-surface-var); user-select: none;
}
.pagination-row__per-page {
  display: flex; align-items: center; gap: 6px;
  font-size: var(--md-sys-typescale-body-dense-size); color: var(--color-on-surface-var); margin-inline-end: 12px;
}
.pagination-row__per-page label { white-space: nowrap; }
.pagination-row__per-page select {
  border: 1.5px solid var(--color-surface-container-high);
  border-radius: var(--radius-s);
  background: var(--color-surface-container-lowest);
  padding: 4px 8px; font-size: var(--md-sys-typescale-body-dense-size);
  color: var(--color-on-surface-var); cursor: pointer;
}
@media (max-width: 767px) {
  .pagination-row { flex-wrap: wrap; gap: 8px; }
  .pagination-row__per-page { order: 2; }
}

@keyframes slide-up-in {
  from { opacity:0; transform: translateY(8px); }
  to   { opacity:1; transform: translateY(0); }
}

/* ── Bulk-select toolbar + row checkboxes ─────────────────────────────── */
.bulk-actions-bar {
  position: sticky; top: 0; z-index: 5;
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  padding: 10px 14px; margin-bottom: 12px;
  background: var(--color-primary);
  color: var(--color-on-primary);
  border-radius: var(--md-sys-shape-corner-medium);
  box-shadow: var(--shadow-1);
  animation: slide-up-in .15s ease;
}
.bulk-actions-bar__count { font-weight: 600; margin-inline-end: 6px; color: inherit; }
.bulk-actions-bar__spacer { flex: 1; }
.bulk-actions-bar .btn--tonal {
  background: rgba(255,255,255,.18);
  color: #fff;
  border: 1px solid rgba(255,255,255,.3);
}
.bulk-actions-bar .btn--tonal:hover { background: rgba(255,255,255,.28); }
.bulk-actions-bar .btn--danger {
  background: var(--color-error);
  color: var(--color-on-error);
  border: 1px solid transparent;
}
.bulk-actions-bar .btn--danger:hover { filter: brightness(.94); }

.bulk-select-all-banner {
  padding: 8px 12px; margin-bottom: 10px; font-size: var(--md-sys-typescale-body-dense-size);
  background: var(--color-surface-variant);
  border: 1px dashed var(--color-outline-variant);
  border-radius: var(--md-sys-shape-corner-medium);
}
.bulk-select-all-banner button {
  background: transparent; border: none; padding: 0;
  color: var(--color-primary-text); font-weight: 600; cursor: pointer;
  text-decoration: underline;
}

.row-check { cursor: pointer; width: 16px; height: 16px; }
.checkbox-cell { width: 36px; text-align: center; }
.checkbox-cell--card {
  position: absolute; top: 10px; inset-inline-start: 10px;
  display: inline-block; width: auto;
}
.bulk-actions-bar .btn .material-symbols-outlined {
  font-size: 18px; vertical-align: -4px;
}

/* Trash view */
.trash-row { background: var(--color-surface-variant); }
.filter-chip__count { opacity: .7; font-weight: 500; margin-inline-start: 2px; }
.trash-footnote {
  margin-top: 14px; padding: 10px 12px;
  font-size: var(--md-sys-typescale-body-small-size); color: var(--color-on-surface-var);
  background: var(--color-surface-variant);
  border-radius: var(--md-sys-shape-corner-medium);
}
@media (max-width: 640px) {
  .bulk-actions-bar { padding: 8px 10px; }
  .bulk-actions-bar .btn { flex: 1 1 auto; }
  .bulk-actions-bar__spacer { display: none; }
}

/* ── Stage chips ─────────────────────────────────────────────────────── */
.chip {
  display: inline-flex;
  align-items: center;
  padding: 2px 10px;
  border-radius: var(--radius-pill);
  font-size: var(--md-sys-typescale-body-small-size);
  font-weight: 600;
}

/* ── Central tags ────────────────────────────────────────────────────────
   Chip colours are admin-chosen and applied inline (background + readable
   text colour computed in _tagPicker.js), so the base class is shape only. */
.tag-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  font-size: var(--md-sys-typescale-body-small-size);
  font-weight: 600;
  line-height: 1.6;
  max-width: 100%;
}
.tag-chip__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tag-chip__x {
  background: transparent;
  border: none;
  color: inherit;
  cursor: pointer;
  font-size: var(--md-sys-typescale-body-large-size);
  line-height: 1;
  padding: 0;
  margin-inline-start: 2px;
  opacity: .7;
  min-width: 24px;
  min-height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.tag-chip__x:hover { opacity: 1; }

.tag-row { display: flex; align-items: flex-start; gap: 8px; }
.tag-row__label {
  font-size: var(--md-sys-typescale-body-small-size);
  color: var(--color-on-surface-var);
  padding-top: 4px;
  white-space: nowrap;
}
.tag-row__chips {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  flex: 1 1 auto;
}
.tag-empty { color: var(--color-on-surface-var); }

.tag-add-btn {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 2px 10px 2px 6px;
  border: 1px dashed var(--color-outline-variant);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--color-on-surface-var);
  font-size: var(--md-sys-typescale-body-small-size);
  font-weight: 600;
  cursor: pointer;
  transition: background .12s, color .12s, border-color .12s;
}
.tag-add-btn:hover {
  background: var(--color-surface-container);
  color: var(--color-on-surface);
  border-color: var(--color-outline);
}
.tag-add-btn .material-symbols-outlined { font-size: 16px; }

/* Fixed-position popover anchored to the chip row by _tagPicker.js. Fixed (not
   absolute) so it escapes the section card (overflow:hidden) and the sidebar
   scroll column (overflow:auto), which would otherwise clip the option list.
   Geometry (left/top/width/max-height + above/below flip) is set inline by JS. */
.tag-dropdown {
  position: fixed;
  z-index: 1000;
  min-width: 248px;
  max-width: 92vw;
  max-height: 340px;
  overflow-y: auto;
  padding: 8px;
}
.tag-dropdown__search {
  width: 100%;
  box-sizing: border-box;
  margin-bottom: 8px;
  padding: 10px 12px;
  font: inherit;
  font-size: var(--md-sys-typescale-body-dense-size);
  color: var(--color-on-surface);
  background: var(--color-surface);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-s);
  outline: none;
  transition: border-color .12s, box-shadow .12s;
}
.tag-dropdown__search:focus {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 22%, transparent);
}
.tag-dropdown__list { display: flex; flex-direction: column; gap: 2px; }
.tag-dropdown__optname { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tag-dropdown__count { margin-inline-start: auto; padding-inline-start: 8px; font-size: var(--md-sys-typescale-body-small-size); color: var(--color-on-surface-var); font-variant-numeric: tabular-nums; }
.tag-filter-btn[aria-busy="true"] { cursor: progress; opacity: .7; }
.tag-dropdown__opt {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 10px;
  border: none;
  border-radius: var(--radius-s);
  background: transparent;
  color: var(--color-on-surface);
  font-size: var(--md-sys-typescale-body-dense-size);
  text-align: start;
  cursor: pointer;
}
.tag-dropdown__opt:hover,
.tag-dropdown__opt.is-active { background: var(--color-surface-container); }
.tag-dropdown__create { color: var(--color-primary-text); font-weight: 600; }
.tag-dropdown__create .material-symbols-outlined { font-size: 18px; }
.tag-dropdown__empty { padding: 10px 12px; }
.tag-swatch {
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 1px solid rgba(0, 0, 0, .15);
}

/* Settings → Tags (admin vocabulary management) */
.tags-admin__intro { margin-bottom: var(--space-3); }

/* Create-tag card */
.tag-create {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-3);
  margin-bottom: var(--space-4);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-m);
  background: var(--color-surface-container-low);
}
.tag-create__top { display: flex; gap: var(--space-4); align-items: flex-end; flex-wrap: wrap; }
.tag-create__name { flex: 1 1 240px; display: flex; flex-direction: column; gap: 4px; }
.tag-create__preview { display: flex; flex-direction: column; gap: 6px; min-width: 120px; }
.tag-create__chip { display: inline-flex; }
.tag-create__label {
  font-size: var(--md-sys-typescale-body-small-size);
  font-weight: 600;
  color: var(--color-on-surface-var);
}
.tag-create__name input {
  width: 100%;
  box-sizing: border-box;
  padding: 9px 12px;
  font: inherit;
  font-size: var(--md-sys-typescale-body-medium-size);
  color: var(--color-on-surface);
  background: var(--color-surface-container-high);
  border: none;
  border-bottom: 2px solid transparent;
  border-radius: var(--radius-s) var(--radius-s) 0 0;
  outline: none;
}
.tag-create__name input:focus { border-bottom-color: var(--color-primary); }
.tag-create__actions { display: flex; justify-content: flex-end; }

/* Colour palette (create card + recolour popover) */
.tag-palette { display: flex; flex-wrap: wrap; gap: 8px; }
.tag-swatch-btn {
  position: relative;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 2px solid transparent;
  border-radius: 50%;
  background: var(--sw, #78909C);
  cursor: pointer;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .12);
  transition: transform .1s ease;
}
.tag-swatch-btn:hover { transform: scale(1.1); }
.tag-swatch-btn.is-selected {
  border-color: var(--color-surface-container-low);
  box-shadow: 0 0 0 2px var(--color-primary);
}
.tag-swatch-btn--custom {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  color: #fff;
}
.tag-swatch-btn--custom .material-symbols-outlined { font-size: 16px; pointer-events: none; }
.tag-palette__custom {
  position: absolute;
  inset: 0;
  padding: 0;
  border: none;
  opacity: 0;
  cursor: pointer;
}

/* List header */
.tag-list-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: var(--space-2);
  flex-wrap: wrap;
}
.tag-list-head__title {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--md-sys-typescale-body-dense-size);
  font-weight: 700;
  color: var(--color-on-surface);
}
.tag-list-head__count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: var(--md-sys-shape-corner-medium);
  background: var(--color-surface-container-high);
  color: var(--color-on-surface-var);
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: 700;
}
.tag-list-search {
  flex: 0 1 220px;
  box-sizing: border-box;
  padding: 7px 11px;
  font: inherit;
  font-size: var(--md-sys-typescale-body-dense-size);
  color: var(--color-on-surface);
  background: var(--color-surface-container-high);
  border: none;
  border-bottom: 2px solid transparent;
  border-radius: var(--radius-s) var(--radius-s) 0 0;
  outline: none;
}
.tag-list-search:focus { border-bottom-color: var(--color-primary); }

/* List rows */
.tag-admin-list { display: flex; flex-direction: column; gap: 6px; }
/* ── Custom fields (Pipedrive migration Part 2) ─────────────────────────── */
.cf-section {
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--color-outline-variant);
}
.cf-section__head {
  font-weight: 600;
  font-size: var(--md-sys-typescale-body-medium-size);
  color: var(--color-on-surface-var);
  margin-bottom: var(--space-2);
}
.cf-req { color: var(--color-error); }
.cf-multi { display: flex; flex-wrap: wrap; gap: 10px; }
.cf-check { display: inline-flex; align-items: center; gap: 4px; }
/* Monetary: a currency badge glued to the number input (Part 2a). */
.cf-money { display: flex; align-items: stretch; gap: 0; }
.cf-money input { flex: 1; }
.cf-currency {
  display: inline-flex; align-items: center; padding: 0 10px;
  font-size: var(--md-sys-typescale-body-dense-size); font-weight: 600;
  color: var(--color-on-surface-var);
  background: var(--color-surface-container-high);
  border: 1px solid var(--color-outline-variant);
  border-inline-end: none;
  border-start-start-radius: var(--radius-s); border-end-start-radius: var(--radius-s);
}
/* Date/time range: paired inputs with a separator (Part 2a). */
.cf-range { display: flex; align-items: center; gap: 8px; }
.cf-range input { flex: 1; min-width: 0; }
.cf-range__sep { color: var(--color-on-surface-var); flex-shrink: 0; }
/* Read-only custom-fields card on detail pages (Part 2b). */
.cf-ro-card {
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-s);
  padding: var(--space-2) var(--space-3);
  margin-top: var(--space-2);
}
.cf-ro-head {
  display: flex; align-items: center; justify-content: space-between;
  font-size: var(--md-sys-typescale-body-small-size); font-weight: 700;
  letter-spacing: .04em; color: var(--color-on-surface-var);
  margin-bottom: 6px;
}
.cf-ro-row {
  display: flex; gap: 10px; align-items: baseline;
  padding: 5px 0;
}
.cf-ro-label { flex: 0 0 40%; color: var(--color-on-surface-var); font-size: var(--md-sys-typescale-body-medium-size); }
.cf-ro-value { flex: 1; min-width: 0; word-break: break-word; }
.cf-ro-empty { color: var(--color-on-surface-var); opacity: .6; }
.cf-id { display: inline-flex; align-items: center; gap: 2px; font-size: var(--md-sys-typescale-body-dense-size); color: var(--color-on-surface-var); }
.cf-id code { font-size: var(--md-sys-typescale-body-dense-size); }

/* Inline click-to-edit rows on the detail-page custom-fields card. Mirrors the
   read-only row layout; .ie-field/.field-label/.field-value supply the editing
   affordance + hover/focus styles shared with native fields. */
.cf-ie-row {
  position: relative;       /* anchor for the composite-type popover */
  display: flex; gap: 10px; align-items: baseline; padding: 5px 0;
}
.cf-ie-row .field-label { flex: 0 0 40%; color: var(--color-on-surface-var); font-size: var(--md-sys-typescale-body-medium-size); }
.cf-ie-row .field-value { flex: 1; min-width: 0; word-break: break-word; }

/* Popover editor for multi_option / date_range / time_range. */
.cf-inline-pop {
  position: absolute; z-index: 50; top: calc(100% + 4px); inset-inline-start: 0;
  min-width: 220px; max-width: 320px;
  background: var(--color-surface-container-lowest);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-m); box-shadow: var(--shadow-2);
  padding: var(--space-3);
  display: flex; flex-direction: column; gap: var(--space-2);
}
.cf-inline-pop__body { display: flex; flex-direction: column; gap: 6px; max-height: 240px; overflow: auto; }
.cf-inline-pop__actions { display: flex; justify-content: flex-end; gap: 8px; }
.cf-entity-tabs { margin-bottom: var(--space-3); }
.cf-def__opts { border-top: 1px dashed var(--color-outline-variant); }

.tag-admin-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 10px;
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-s);
  background: var(--color-surface);
  transition: border-color .12s;
}
.tag-admin-row:hover { border-color: var(--color-outline); }
.tag-admin-swatch {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  padding: 0;
  border: 1px solid rgba(0, 0, 0, .18);
  border-radius: var(--md-sys-shape-corner-small);
  background: var(--sw, #9E9E9E);
  cursor: pointer;
  transition: box-shadow .12s;
}
.tag-admin-swatch:hover { box-shadow: 0 0 0 3px var(--color-surface-container-high); }
.tag-admin-name { flex: 1 1 auto; min-width: 0; cursor: text; }
.tag-admin-name .tag-admin-name__text { font-weight: 600; }
.tag-admin-usage {
  flex: 0 0 auto;
  font-size: var(--md-sys-typescale-body-small-size);
  color: var(--color-on-surface-var);
  white-space: nowrap;
}
.tag-admin-usage.is-zero { font-style: italic; opacity: .7; }
.tag-admin-del { flex: 0 0 auto; }

/* Recolour popover (anchored under a list row's swatch) */
.tag-recolor-pop {
  position: absolute;
  top: calc(100% - 2px);
  inset-inline-start: 8px;
  z-index: 40;
  width: max-content;
  max-width: 240px;
  padding: 10px;
  background: var(--color-surface-container-high);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-s);
  box-shadow: var(--md-sys-elevation-3);
}

/* ── Activity-types Settings tab (Part 1b) ─────────────────────────────────
   Builds on the shared .tag-admin / .tag-swatch styles above; adds the icon
   grid, the swatch-with-icon, the visibility toggle, and the built-in badge. */
.at-icon-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(34px, 1fr));
  gap: 4px;
  margin: 6px 0 10px;
  max-height: 168px;
  overflow-y: auto;
}
.at-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-s);
  background: var(--color-surface);
  color: var(--color-on-surface-var);
  cursor: pointer;
  transition: background .12s, border-color .12s, color .12s;
}
.at-icon-btn .material-symbols-outlined { font-size: 19px; pointer-events: none; }
.at-icon-btn:hover { background: var(--color-surface-container-high); }
.at-icon-btn.is-selected {
  border-color: var(--color-primary);
  background: var(--color-primary-container);
  color: var(--color-on-primary-container);
}
/* Swatch button in the list row carries the type's icon over its colour. */
.tag-admin-swatch.at-row-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.tag-admin-swatch.at-row-icon .material-symbols-outlined {
  font-size: 16px;
  color: #fff;
  pointer-events: none;
}
.at-recolor-pop { max-width: 280px; }
/* Per-row visibility toggle; the Google Meet and Products switches' labels read the same. */
.at-visToggle, .at-meetToggle, .at-productsToggle {
  font-size: var(--md-sys-typescale-body-small-size);
  color: var(--color-on-surface-var);
  white-space: nowrap;
}
.at-visToggle {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  cursor: pointer;
}
.at-visToggle input { cursor: pointer; }
.tag-admin-row.is-hidden-type { opacity: .6; }
/* The row's controls: the Google Meet (Yahia, 2026-10-21) and Products switches,
   Visible, the arrows and delete. In line after the usage count on a computer; on a
   phone, their own line under the type's name, so the name keeps the width. */
.at-row-tools { display: flex; align-items: center; gap: 12px; flex: 0 0 auto; }
.at-meet-note { margin-bottom: var(--space-2); }
@media (max-width: 767px) {
  .tag-admin-row.at-row { flex-wrap: wrap; row-gap: 8px; }
  .at-row-tools { flex: 1 1 100%; flex-wrap: wrap; gap: 8px; }
  .at-row-tools [data-act="up"] { margin-inline-start: auto; }
}

/* ── Settings ▸ Quote templates ────────────────────────────────────────────
   Two-line rows (name, then kind) with the ⋮ menu at the end; the default is
   an in-line label beside the name. */
.qt-actions { display: flex; flex-wrap: wrap; gap: 8px; justify-content: flex-end; margin-bottom: var(--space-4); }
.qt-actions .btn { display: inline-flex; align-items: center; gap: 6px; }
.qt-actions .material-symbols-outlined { font-size: 18px; }
.qt-row { align-items: center; }
.qt-row__icon { color: var(--color-on-surface-var); }
.qt-row__text { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.qt-row__name { font-weight: 600; overflow-wrap: anywhere; }
.qt-row__meta { color: var(--color-on-surface-var); }
.qt-row__default {
  display: inline-block; margin-inline-start: 6px; padding: 0 8px; border-radius: var(--md-sys-shape-corner-full);
  font-size: var(--md-sys-typescale-body-small-size); font-weight: 600; line-height: 20px; vertical-align: middle;
  background: var(--color-secondary-container); color: var(--color-on-secondary-container);
}
.qt-row__more { flex: 0 0 auto; }
.qt-problems { margin: var(--space-2) 0; padding-inline-start: 18px; display: grid; gap: 6px; max-height: 50vh; overflow: auto; }
.qt-problem__line { font-weight: 600; margin-inline-end: 6px; white-space: nowrap; }
/* List-detail, one pane at a time: the list, or one template's settings. */
.qt-row__open { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; align-self: stretch;
  padding: 0; border: 0; background: none; color: inherit; font: inherit; text-align: start; cursor: pointer; }
.qt-row__chevron { color: var(--color-on-surface-var); flex: 0 0 auto; }
.qt-row:has(.qt-row__open:hover) { border-color: var(--color-outline); background: var(--color-surface-container-low); }
.qt-detail__back { display: inline-flex; align-items: center; gap: 6px; margin: 0 0 var(--space-2); padding-inline: 8px; }
.qt-detail__title { margin: 0; font-size: var(--md-sys-typescale-title-large-size); overflow-wrap: anywhere; }
.qt-detail__title:focus { outline: none; }
.qt-card { border: 1px solid var(--color-outline-variant); border-radius: var(--md-sys-shape-corner-medium);
  background: var(--color-surface); margin-top: var(--space-3); padding: var(--space-3) var(--space-4); }
.qt-card h4 { margin: 0 0 4px; font-size: var(--md-sys-typescale-body-large-size); }
.qt-detail__switches { display: grid; gap: 4px; margin-top: var(--space-2); }
.qt-detail__switch { min-height: 40px; }
.qt-search { position: relative; margin: var(--space-3) 0 var(--space-2); max-width: 520px; }
.qt-search__label { display: block; font-size: var(--md-sys-typescale-body-small-size); font-weight: 600; color: var(--color-on-surface-var); margin-bottom: 4px; }
.qt-search__field { position: relative; display: block; }
.qt-search__field .material-symbols-outlined { position: absolute; inset-inline-start: 12px; top: 50%;
  transform: translateY(-50%); font-size: 20px; color: var(--color-on-surface-var); pointer-events: none; }
.qt-search__field input { width: 100%; min-height: 44px; padding-inline-start: 40px; border-radius: var(--md-sys-shape-corner-extra-small); }
.qt-search__results { position: absolute; inset-inline: 0; top: 100%; z-index: 30; display: block; margin-top: 4px; max-height: 280px; overflow: auto; }
.qt-search__none { padding: 10px 14px; margin: 0; }
.qt-names { display: grid; gap: 8px; }
.qt-name { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr) auto; align-items: center; gap: 8px; }
.qt-name__product { display: flex; flex-direction: column; min-width: 0; overflow-wrap: anywhere; }
.qt-name__input { min-height: 40px; }
@media (max-width: 600px) {
  .qt-name { grid-template-columns: minmax(0, 1fr) auto; }
  .qt-name__input { grid-column: 1 / -1; grid-row: 2; }
}
@media (pointer: coarse) { .qt-detail__switch, .qt-name__input, .qt-search__field input { min-height: 48px; } }
.qt-preview-modal.modal--wide { width: min(1100px, 96vw); }
.qt-preview__note { margin: 0 0 var(--space-2); }
.qt-preview__stage { background: var(--color-surface-container); border-radius: var(--md-sys-shape-corner-small); padding: 8px; display: flex; justify-content: center; }
.qt-preview__frame { width: 100%; height: 65vh; border: 0; background: #fff; border-radius: var(--md-sys-shape-corner-extra-small); }

/* ── Settings ▸ Teams ──────────────────────────────────────────────────────
   The reporting tree. Rows are indented by depth (inline-start, so the nesting
   reads correctly in Arabic too) and every surface and border colour comes from MD3
   tokens rather than a literal, so light and dark both follow automatically. */
.teams-admin__intro { margin-bottom: var(--space-3); max-width: 70ch; }

.team-list { display: flex; flex-direction: column; gap: 6px; }

.team-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-s);
  background: var(--color-surface);
  transition: border-color .12s, background .12s;
}
.team-row:hover { border-color: var(--color-outline); }

.team-row__toggle { flex: 0 0 auto; }
.team-row__name { font-weight: 600; color: var(--color-on-surface); }
/* The click-to-edit wrapper must not stretch and push the actions off-screen. */
.team-row__edit { flex: 0 1 auto; min-width: 0; }
.team-row__count { margin-inline-start: auto; white-space: nowrap; }
.team-row__parent { flex: 0 0 auto; max-width: 190px; }

.team-members {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 8px 12px;
  border: 1px dashed var(--color-outline-variant);
  border-radius: var(--radius-s);
  background: var(--color-surface-container-lowest);
}
.team-member { display: flex; align-items: center; gap: 8px; }
.team-member__name { font-size: var(--md-sys-typescale-body-dense-size); color: var(--color-on-surface); }

@media (max-width: 720px) {
  /* Keep the tree legible on a phone: drop the indent step and let the row wrap
     rather than scrolling the settings panel sideways. */
  .team-row { flex-wrap: wrap; margin-inline-start: 0 !important; }
  .team-members { margin-inline-start: 0 !important; }
  .team-row__count { margin-inline-start: 0; }
  .team-row__parent { max-width: 100%; flex: 1 1 100%; }
}
.at-system-badge {
  margin-inline-start: 6px;
  padding: 1px 6px;
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: 600;
  border-radius: var(--md-sys-shape-corner-medium);
  background: var(--color-surface-container-high);
  color: var(--color-on-surface-var);
  vertical-align: middle;
  white-space: nowrap;
}
/* Trailing toolbar controls — Views, Tags, Save view. One size for the cluster,
   because a full-height .btn next to a 28px tag button read as three rows:
   the filter chips' (32px, an 8px corner), as they sit in the same row. */
.tag-filter-wrap { position: relative; display: inline-flex; }
.toolbar-btn,
.tag-filter-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: 32px;
  padding: 5px 12px;
  border-radius: var(--md-sys-shape-corner-small);
  border: 1px solid var(--color-outline-variant);
  background: transparent;
  color: var(--color-on-surface-var);
  font-size: var(--md-sys-typescale-body-dense-size);
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  transition: background .12s, color .12s, border-color .12s;
}
.tag-filter-btn.active {
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
  border-color: transparent;
}
.tag-filter-count {
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: var(--md-sys-shape-corner-small);
  background: var(--color-primary);
  color: var(--color-on-primary);
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: 700;
  line-height: 16px;
  text-align: center;
}
/* Anchor the filter dropdown to the button's trailing edge (toolbars sit right). */
.tag-filter-dropdown { inset-inline-start: auto; inset-inline-end: 0; }
.tag-filter-clear {
  width: 100%;
  margin-top: 6px;
  padding: 6px;
  border: none;
  border-top: 1px solid var(--color-outline-variant);
  background: transparent;
  color: var(--color-primary-text);
  font-size: var(--md-sys-typescale-body-small-size);
  font-weight: 600;
  cursor: pointer;
}
.tag-filter-clear:hover { background: var(--color-surface-container); }

/* ── Icon button ─────────────────────────────────────────────────────── */
.icon-btn {
  background: transparent;
  border: none;
  color: inherit;
  cursor: pointer;
  padding: 6px;
  /* MD3 IconButton spec: 48×48 dp target — top bar bell/theme/lang/logout
     were ~32px previously and failed WCAG 2.5.5. */
  min-width: 48px;
  min-height: 48px;
  border-radius: var(--md-sys-shape-corner-full);
  font-size: 20px;
  /* The text font: each glyph is a .material-symbols-outlined span with its
     own, so a count or a label inside (the bell's badge, EN / ع) reads as text. */
  font-family: var(--font-body);
  line-height: 1;
  display: flex; align-items: center; justify-content: center;
}

/* ── UCM click-to-call button ─────────────────────────────────────────────── */
.ucm-call-btn {
  background: transparent;
  border: 1px solid var(--color-outline-variant);
  color: var(--color-primary-text);
  cursor: pointer;
  padding: 2px 6px;
  border-radius: var(--radius-s);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  vertical-align: middle;
  margin-inline-start: 4px;
  line-height: 1;
}
.ucm-call-btn:hover { background: var(--color-primary-container); color: var(--color-on-primary-container); }
/* Device-dialer (tel:) variant — an <a>, so suppress the link underline.
   Inherits sizing/hover from .ucm-call-btn. */
.tel-call-btn, .tel-call-btn:hover { text-decoration: none; }
/* WhatsApp chat (_callButton.js, Yahia, 2026-10-19): the mark keeps its green. */
.wa-chat-btn, .wa-chat-btn:hover { text-decoration: none; color: var(--color-whatsapp); }
.wa-mark { width: var(--space-3); height: var(--space-3); display: block; }
/* A WhatsApp username and its button stay together (whatsappUsernameHtml,
   Yahia, 2026-10-20). When the row is too narrow for label and name, the
   name moves under the label, whole; only a name wider than the row is cut. */
.wa-username { display: inline-flex; align-items: center; max-width: 100%; vertical-align: middle; }
.wa-username > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wa-username > .wa-chat-btn { flex-shrink: 0; }
.ie-field:has(.wa-username) { flex-wrap: wrap; }
.ie-display:has(> .wa-username) { margin-inline-start: auto; min-width: 0; max-width: 100%; }

/* Language toggle keeps the icon-btn footprint but shows EN / ع glyphs */
.lang-toggle__label {
  font-size: var(--md-sys-typescale-body-dense-size);
  font-weight: 600;
  line-height: 1;
  min-width: 24px;
}

/* ── Loading / empty ─────────────────────────────────────────────────── */
.loading-state, .empty-state {
  display: flex; align-items: center; justify-content: center;
  flex-direction: column; text-align: center; gap: 4px;
  height: 200px; color: var(--color-on-surface-var);
  font-size: var(--md-sys-typescale-body-large-size);
}
/* A zero-state built by _empty.js sizes to its own content instead of the flat
   200px the bare class assumes — that fixed height is what every call site was
   overriding inline. The three variants differ on purpose: "nothing yet",
   "you're done" and "this broke" are not the same news. */
.empty-state--empty, .empty-state--success, .empty-state--error {
  height: auto; min-height: 140px; gap: var(--space-2);
  padding: var(--space-4) var(--space-3);
}
.empty-state__icon { font-size: 40px; opacity: .35; }
.empty-state--success .empty-state__icon { color: var(--color-success); opacity: .6; }
.empty-state--error   .empty-state__icon { color: var(--color-error);   opacity: .7; }
.empty-state__title {
  margin: 0;
  font-size: var(--md-sys-typescale-title-small-size);
  font-weight: var(--md-sys-typescale-title-small-weight);
  color: var(--color-on-surface);
}
.empty-state__body {
  margin: 0; max-width: 42ch;
  font-size: var(--md-sys-typescale-body-medium-size);
  color: var(--color-on-surface-var);
}
.empty-state__action { margin-top: var(--space-2); }

/* ── Data table — "Ghost Table" (no lines) ───────────────────────────── */
/* Wrapper for any .data-table too wide for its container: the table scrolls
   sideways inside the wrapper instead of pushing the page sideways.
   NOTE: this alone is not enough. The wrapper still reports the table's
   min-content width to its parent, so an ancestor that is a grid/flex item
   must also carry min-width:0 or it grows to fit the table and the overflow
   just moves up the tree (see .rac-analytics-card). */
.table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.data-table { width: 100%; border-collapse: collapse; }
/* Virtualization-lite: skip rendering off-screen rows. Gives 60-80% of
   true virtual-scroll benefit with zero JS. Estimated row height 48px keeps
   scrollbar thumb sized correctly for pages up to 500 rows. */
.data-table tbody tr {
  content-visibility: auto;
  contain-intrinsic-size: 0 48px;
}
/* Sentence-case label-medium, not 11px ALL-CAPS 700 at .08em tracking. Caps at
   small sizes strip word-shape and read slower; a column header is a label, not
   a heading. `start` rather than `left` is what lets rtl.css drop its override. */
.data-table th {
  text-align: start;
  padding: 8px 16px;
  font-size: var(--md-sys-typescale-label-medium-size);
  font-weight: var(--md-sys-typescale-label-medium-weight);
  color: var(--color-on-surface-var);
  border-bottom: 1px solid var(--color-surface-container-high);
  background: var(--color-surface-container-lowest);
  position: sticky; top: 0; z-index: 1;
}
.data-table td {
  padding: 12px 16px;
  font-size: var(--md-sys-typescale-body-medium-size);
  /* No border — separation by vertical padding only */
  border: none;
}
.data-table tr:hover td {
  background: var(--color-surface-container-highest);
}

/* Sort + filter + drag-to-reorder controls in <thead> */
.data-table th .col-sort {
  display: inline-flex; align-items: center; gap: 4px;
  background: transparent; border: 0; padding: 0; margin: 0;
  font: inherit; color: inherit; letter-spacing: inherit; text-transform: inherit;
  cursor: pointer;
}
.data-table th .col-sort:hover { color: var(--color-primary-text); }
.data-table th .col-sort__arrow {
  font-size: 16px;
  line-height: 1;
  color: var(--color-primary-text);
}
.data-table th[draggable="true"] { cursor: grab; }
.data-table th.col-drag-src { opacity: .5; }
.data-table th.col-drop-target {
  box-shadow: inset 2px 0 0 var(--color-primary);
}

/* ── Pill Toolbar (legacy, contacts / orgs filter bar) ──────────────── */

/* ── KPI metric card ─────────────────────────────────────────────────── */
.kpi-card {
  background: var(--crm-card-surface);
  border-radius: var(--md-sys-shape-corner-medium);
  padding: var(--space-4);
  box-shadow: var(--md-sys-elevation-1);
  transition: box-shadow var(--md-sys-motion-duration-short2) var(--md-sys-motion-easing-standard);
}
/* The Won tile keeps the brand gold as its value colour — the accent the
   left bar used to carry, now on the number it is about. */
.kpi-card--gold .kpi-card__value { color: var(--md-sys-color-tertiary); }
.kpi-card__label {
  font-size: var(--md-sys-typescale-label-medium-size);
  line-height: var(--md-sys-typescale-label-medium-line);
  font-weight: var(--md-sys-typescale-label-medium-weight);
  letter-spacing: var(--md-sys-typescale-label-medium-tracking);
  color: var(--color-on-surface-var);
}
.kpi-card__value {
  font-family: var(--font-display);
  font-size: var(--md-sys-typescale-headline-medium-size);
  line-height: var(--md-sys-typescale-headline-medium-line);
  font-weight: 500;
  color: var(--color-on-surface);
  margin: 4px 0;
}
.kpi-card__sub {
  font-size: var(--md-sys-typescale-body-small-size);
  line-height: var(--md-sys-typescale-body-small-line);
  letter-spacing: var(--md-sys-typescale-body-small-tracking);
  color: var(--color-on-surface-var);
  margin-top: 4px;
}

/* ── KPI grid ────────────────────────────────────────────────────────────── */
.kpi-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--sp-3);
  margin-bottom: var(--space-3);
}
/* A card's widest line must not widen its track past the row (1fr's floor is
   the content's width): the cards share the row, and their lines wrap. */
.kpi-grid > .kpi-card { min-width: 0; }
/* The 30-day cards' trend (_kpiTrend.js) wraps rather than cutting off
   "vs previous 30 days" on a narrow card, as a report's one-line change does. */
.rb-kpi-delta.kpi-trend { white-space: normal; }

/* The list's KPI row: the native-currency breakdown under its total. */
.pipeline-kpi__split {
  font-size: var(--md-sys-typescale-label-small-size);
  color: var(--color-on-surface-var);
  line-height: 1.4;
  word-break: break-word;
}
/* A list row's link (_rowLink.js): empty and stretched over its cell, so the
   cell's own links (website, LinkedIn) sit above it instead of inside it. The
   cell is already the containing block — the sticky first column below. */
a.row-link { position: absolute; inset: 0; }
td:has(> a.row-link) a:not(.row-link) { position: relative; z-index: 1; }
/* Stage action icon buttons */
.btn--icon.btn--xs {
  width: 28px; height: 28px; min-width: 28px; min-height: 28px; padding: 0;
  border-radius: var(--md-sys-shape-corner-full); border: none;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; cursor: pointer;
  color: var(--color-on-surface-var);
}
.btn--icon.btn--xs .material-symbols-outlined { font-size: 18px; }

/* Pipeline KPI bar */
/* One slim row of "LABEL value" figures. The three numbers are context, not
   the work — the board underneath is — so they get a line, not a card. */
.pipeline-kpi {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-4);
  background: var(--color-surface-container-lowest);
  border-radius: var(--radius-m);
  padding: 4px var(--space-3);
  min-height: 28px;
  margin-bottom: var(--space-2);
  box-shadow: var(--shadow-1);
}
.pipeline-kpi__item { display: flex; align-items: baseline; gap: 6px; }
.pipeline-kpi__item-label {
  font-size: var(--md-sys-typescale-label-small-size); font-weight: 700;
  letter-spacing: .5px; color: var(--color-on-surface-var);
}
.pipeline-kpi__item-value {
  font-family: var(--font-display);
  font-size: var(--md-sys-typescale-body-dense-size); font-weight: 700;
  color: var(--color-primary);
}
.pipeline-kpi__divider {
  width: 1px; height: 14px;
  background: var(--color-surface-container-high);
}

/* ── Deals board (2026 redesign) ─────────────────────────────────────────
   deals.js + _dealBoard.js / _dealCard.js / _dealPeek.js. The board is a
   column of chrome (health strip, tabs + toolbar) over #kanban, which holds
   .bcols (the horizontal column scroller) — or, on a phone, the stage tabs
   plus .bcols, or the agenda. MD3 tokens only; logical properties throughout,
   so RTL mirrors without rules of its own. */

/* Title row: the pipeline picker sits beside "Deals", not in the toolbar. */
.deals-title { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.deals-title h1 { margin: 0; }
.deals-title .pipeline-select-wrap select { font-weight: 600; }

/* Health strip */
.board-health {
  display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--space-2);
  margin-bottom: var(--space-2); flex-shrink: 0;
}
.bh-tile {
  display: flex; flex-direction: column; align-items: flex-start; min-width: 0;
  padding: 8px 12px 9px; text-align: start; cursor: pointer;
  background: var(--color-surface-container-lowest); color: var(--color-on-surface);
  border: 1px solid var(--color-outline-variant); border-radius: var(--radius-l);
  font: inherit; transition: border-color .15s, box-shadow .15s;
}
.bh-tile:hover { border-color: var(--color-outline); }
.bh-tile.is-on { border-color: var(--color-primary); box-shadow: inset 0 0 0 1px var(--color-primary); }
.bh-tile__label {
  display: flex; align-items: center; gap: 4px; max-width: 100%;
  font-size: var(--md-sys-typescale-label-small-size); font-weight: 600; color: var(--color-on-surface-var); white-space: nowrap;
}
.bh-tile__label .material-symbols-outlined { font-size: 15px; }
.bh-tile__value {
  font-family: var(--font-display); font-size: var(--md-sys-typescale-body-large-size); font-weight: 700; line-height: 1.3;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.bh-tile__sub {
  max-width: 100%; font-size: var(--md-sys-typescale-label-small-size); color: var(--color-on-surface-var);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bh-tile__sub b { color: var(--color-on-surface); font-weight: 600; }
.bh-tile.is-warn .bh-tile__value, .bh-tile.is-warn .bh-tile__label .material-symbols-outlined { color: var(--color-error); }
.bh-tile.is-good .bh-tile__value, .bh-tile.is-good .bh-tile__label .material-symbols-outlined { color: var(--color-success); }

/* Tabs: the first thing in the toolbar row on the board. */
:is(#pipelineToolbar, .table-toolbar--tabs) .btabs { display: flex; flex-wrap: wrap; gap: 2px; min-width: 0; flex: 1 1 auto; }
.btab {
  display: inline-flex; align-items: center; gap: 4px; flex: none;
  padding: 6px 9px; border: 0; border-radius: var(--radius-pill); cursor: pointer;
  background: none; color: var(--color-on-surface-var); font: inherit; font-size: var(--md-sys-typescale-body-dense-size); font-weight: 600; white-space: nowrap;
}
.btab:hover { background: var(--color-surface-container-high); }
/* Across rows the pill cannot slide: it fades over instead. */
@media (prefers-reduced-motion: no-preference) { .btab { transition: background-color 200ms, color 200ms; } }
.btab .material-symbols-outlined { font-size: 16px; color: var(--btab-icon, inherit); }
.btab.is-on .material-symbols-outlined { color: inherit; }
/* Tabs that would need a third row get the room from the buttons, which keep
   their names for a screen reader and a tooltip. */
.toolbar-compact :is(.tag-filter-btn, .sort-dropdown__trigger, #followedChip, #listFollowed) { font-size: 0; gap: 0; }
.toolbar-compact :is(.tag-filter-btn, .sort-dropdown__trigger, #followedChip, #listFollowed) .material-symbols-outlined:not(:first-child) { display: none; }
.toolbar-compact .tag-filter-count { font-size: var(--md-sys-typescale-label-small-size); margin-inline-start: 4px; }
.btab__n {
  font-size: var(--md-sys-typescale-label-small-size); font-variant-numeric: tabular-nums; line-height: 17px; padding: 0 5px;
  border-radius: var(--radius-pill); background: var(--color-surface-container-high); color: var(--color-on-surface);
}
.btab.is-on { background: var(--color-primary); color: var(--color-on-primary); }
.btab.is-on .btab__n { background: var(--color-on-primary); color: var(--color-primary); }
.btab--warn .btab__n { background: var(--color-error-container); color: var(--color-on-error-container); }
.btab--add { color: var(--color-primary); }
.btab-saved { display: inline-flex; align-items: center; flex: none; border-radius: var(--radius-pill); }
.btab-saved.is-on { background: var(--color-primary); }
.btab-saved.is-on .btab { background: none; color: var(--color-on-primary); }
.btab-saved__x { display: none; border: 0; background: none; cursor: pointer; color: inherit; padding: 0; padding-inline-end: 6px; }
.btab-saved:hover .btab-saved__x, .btab-saved.is-on .btab-saved__x { display: inline-flex; }
.btab-saved.is-on .btab-saved__x { color: var(--color-on-primary); }
.btab-saved__x .material-symbols-outlined { font-size: 15px; }

/* #kanban: a column holding the scroller, so phone stage tabs can sit above it. */
.kanban { display: flex; flex-direction: column; min-height: 0; }
.bcols {
  flex: 1 1 auto; min-height: 0; display: flex; gap: var(--space-2);
  overflow-x: auto; overflow-y: hidden; padding-bottom: 4px; scrollbar-width: thin;
}
.bcols::-webkit-scrollbar { height: 6px; }
.bcols::-webkit-scrollbar-thumb { background: var(--color-surface-container-high); border-radius: var(--md-sys-shape-corner-medium); }
/* Room past the last column while the deal panel covers the right side. */
.kanban.is-peeking .bcols::after { content: ""; flex: 0 0 var(--bpeek-w); }

/* 232px: five columns fit beside the open sidebar at 1536px wide — a
   1920×1080 screen at Windows' default 125% scaling. */
.bcol {
  flex: 1 0 232px; min-width: 0; display: flex; flex-direction: column; min-height: 0;
  background: var(--color-surface-container-low); border: 1.5px solid transparent;
  border-radius: var(--radius-l); transition: border-color .12s, background .12s;
}
.bcol.is-over { border-color: var(--color-primary); background: var(--color-primary-container); }
.bcol__head { padding: 10px 12px 8px; flex-shrink: 0; }
.bcol__row { display: flex; align-items: center; gap: 7px; min-width: 0; }
.bcol__dot { width: 9px; height: 9px; border-radius: var(--md-sys-shape-corner-extra-small); background: var(--stc); flex: none; }
.bcol__name { margin: 0; font-size: var(--md-sys-typescale-body-medium-size); font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bcol__count { font-size: var(--md-sys-typescale-body-small-size); font-weight: 600; color: var(--color-on-surface-var); font-variant-numeric: tabular-nums; }
.bcol__att {
  display: inline-flex; align-items: center; gap: 2px; padding: 0 7px 0 5px; line-height: 18px;
  border-radius: var(--radius-pill); font-size: var(--md-sys-typescale-label-small-size); font-weight: 700; cursor: help;
  background: var(--color-error-container); color: var(--color-on-error-container);
}
.bcol__att .material-symbols-outlined { font-size: 13px; }
.bcol__add {
  margin-inline-start: auto; width: 28px; height: 28px; border: 0; border-radius: var(--radius-pill);
  background: none; color: var(--color-on-surface-var); cursor: pointer; display: grid; place-items: center;
}
.bcol__add:hover { background: var(--color-surface-container-high); }
.bcol__add .material-symbols-outlined { font-size: 18px; }
.bcol__money { margin-top: 2px; align-items: baseline; }
.bcol__total { font-family: var(--font-display); font-size: var(--md-sys-typescale-body-large-size); font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.bcol__split { font-size: var(--md-sys-typescale-label-small-size); color: var(--color-on-surface-var); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bcol__share { height: 4px; margin-top: 8px; border-radius: 2px; background: var(--color-surface-container-highest); overflow: hidden; }
.bcol__share i { display: block; height: 100%; background: var(--stc); border-radius: 2px; transition: width .3s; }
.bcol__list {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 2px 8px 8px;
  display: flex; flex-direction: column; gap: 8px; scrollbar-width: thin;
}
.bcol__list::-webkit-scrollbar { width: 4px; }
.bcol__list::-webkit-scrollbar-thumb { background: var(--color-surface-container-high); border-radius: var(--md-sys-shape-corner-medium); }
.bcol__empty, .bcol__more {
  padding: 18px 8px; text-align: center; font-size: var(--md-sys-typescale-body-small-size); color: var(--color-on-surface-var);
  border: 1px dashed var(--color-outline-variant); border-radius: var(--radius-l);
}
.bcol__more { padding: 10px; border-style: solid; background: var(--color-surface-container-lowest); }
.bcol__addrow {
  margin: 0 8px 8px; height: 32px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; gap: 4px;
  border: 1px dashed var(--color-outline-variant); border-radius: var(--radius-m);
  background: none; color: var(--color-on-surface-var); font: inherit; font-size: var(--md-sys-typescale-body-dense-size); cursor: pointer;
}
.bcol__addrow:hover { border-color: var(--color-primary); color: var(--color-primary); }
.bcol__addrow .material-symbols-outlined { font-size: 18px; }

/* The card. A <div> under a stretched link: the link takes the click (and
   ⌘-click → new tab); buttons and the checkbox sit above it. */
.bcard {
  position: relative; flex: none; padding: 10px 12px;
  background: var(--color-surface-container-lowest); color: var(--color-on-surface);
  border: 1px solid var(--color-outline-variant); border-radius: var(--radius-l);
  box-shadow: var(--shadow-1); transition: box-shadow .15s, border-color .15s;
}
.bcard:hover { box-shadow: var(--shadow-2); }
.bcard__link { position: absolute; inset: 0; z-index: 1; border-radius: inherit; }
.bcard__link:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.bcard button, .bcard a:not(.bcard__link) { position: relative; z-index: 2; }
/* Above the stretched link so their tooltips show (the "+N" chip's is the only
   place the hidden tags are named); a click on them still opens the deal. */
.bcard .bchip, .bcard__idle, .bcard .avatar-sm { position: relative; z-index: 2; }
.bcard::before {
  content: ""; position: absolute; top: 10px; bottom: 10px; inset-inline-start: -1px; width: 3px;
  border-start-end-radius: 3px; border-end-end-radius: 3px; background: transparent;
}
.bcard.is-rot::before { background: var(--color-warning); }
.bcard.is-overdue::before { background: var(--color-error); }
.bcard.is-peeked { border-color: var(--color-primary); }
.bcard.is-dragging { opacity: .4; }
.bcard__head { display: flex; align-items: flex-start; gap: 8px; }
/* Aligned with the UI, not the script: the <bdi> keeps Arabic reading
   right-to-left inside the line, while every title starts at the same edge. */
.bcard__title {
  flex: 1; min-width: 0; text-align: start;
  font-weight: 600; font-size: var(--md-sys-typescale-body-medium-size); line-height: 1.35; overflow-wrap: anywhere;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.bcard .avatar-sm { width: 24px; height: 24px; flex: none; }
.bcard__who { margin-top: 1px; font-size: var(--md-sys-typescale-body-small-size); color: var(--color-on-surface-var); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bcard__dot { margin: 0 4px; opacity: .6; }
/* The board card's due date at the far end of the names' line (or the value
   line), so it adds no height. A long name ellipsizes before it. */
.bcard__whorow { display: flex; align-items: center; gap: 8px; margin-top: 1px; }
.bcard__whorow .bcard__who { flex: 1; min-width: 0; margin-top: 0; }
:is(.bcard__whorow, .bcard__money) > .bcard__date { margin: 0; margin-inline-start: auto; flex: none; white-space: nowrap; }
.bcard__money > .bcard__date + .bcard__idle { margin-inline-start: 0; }
.bchips { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; min-width: 0; }
/* Same solid tag colour + readable text as the deal page's .tag-chip. */
.bchip {
  display: inline-flex; align-items: center; max-width: 100%; padding: 0 7px; line-height: 18px;
  border-radius: var(--radius-pill); font-size: var(--md-sys-typescale-label-small-size); font-weight: 600; white-space: nowrap; overflow: hidden;
  background: var(--tc); color: var(--tc-fg);
}
.bchip span { overflow: hidden; text-overflow: ellipsis; }
.bchip i { display: none; }
.bchip--more { background: var(--color-surface-container-high); color: var(--color-on-surface-var); }
.bcard__money { position: relative; display: flex; align-items: center; gap: 6px; margin-top: 8px; min-height: 20px; flex-wrap: wrap; }
.bcard__val { font-family: var(--font-display); font-weight: 700; font-size: var(--md-sys-typescale-body-medium-size); font-variant-numeric: tabular-nums; white-space: nowrap; }
.bcard__val--zero { color: var(--color-on-surface-var); font-weight: 500; }
.bcard__eqv { font-size: var(--md-sys-typescale-body-small-size); color: var(--color-on-surface-var); white-space: nowrap; font-variant-numeric: tabular-nums; }
.bcard__addval {
  display: inline-flex; align-items: center; gap: 2px; padding: 0; border: 0; background: none; cursor: pointer;
  font: inherit; font-size: var(--md-sys-typescale-body-small-size); font-weight: 500; color: var(--color-on-surface-var);
}
.bcard__addval:hover { color: var(--color-primary); }
.bcard__addval .material-symbols-outlined { font-size: 16px; }
.bcard__idle { display: inline-flex; align-items: center; gap: 2px; margin-inline-start: auto; font-size: var(--md-sys-typescale-label-small-size); color: var(--color-on-surface-var); white-space: nowrap; }
.bcard__idle .material-symbols-outlined { font-size: 14px; }
.bcard__idle.is-bad { color: var(--color-warning); font-weight: 600; }
.bnext {
  display: flex; align-items: center; gap: 6px; width: 100%; min-height: 28px; margin-top: 8px; padding: 5px 8px;
  border: 0; border-radius: var(--radius-m); cursor: pointer; text-align: start;
  background: var(--color-surface-container-low); color: var(--color-on-surface); font: inherit;
  /* Dense, not body: a step up from 12px with the same 18px line, so the card
     doesn't grow. */
  font-size: var(--md-sys-typescale-body-dense-size);
  line-height: var(--md-sys-typescale-body-dense-line);
}
.bnext .material-symbols-outlined { font-size: 16px; color: var(--color-on-surface-var); }
.bnext__what { flex: 1; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.bnext__when { font-weight: 600; color: var(--color-on-surface-var); white-space: nowrap; font-variant-numeric: tabular-nums; }
.bnext.is-today { background: var(--color-warning-bg); }
.bnext.is-today .material-symbols-outlined, .bnext.is-today .bnext__when { color: var(--md-sys-color-on-warning-container); }
.bnext.is-overdue { background: var(--color-error-container); }
.bnext.is-overdue .material-symbols-outlined, .bnext.is-overdue .bnext__when { color: var(--color-on-error-container); }
.bnext.is-none { background: none; border: 1px dashed var(--color-warning); color: var(--color-warning); font-weight: 600; }
.bnext.is-none .material-symbols-outlined { color: var(--color-warning); }
.bnext:hover { filter: brightness(.97); }
.bcard__date { display: flex; align-items: center; gap: 4px; margin-top: 8px; font-size: var(--md-sys-typescale-label-small-size); color: var(--color-on-surface-var); }
.bcard__date .material-symbols-outlined { font-size: 13px; }
.bcard__date.is-past { color: var(--color-error); font-weight: 600; }
.bstatus { padding: 0 7px; line-height: 18px; border-radius: var(--radius-pill); font-size: var(--md-sys-typescale-label-small-size); font-weight: 700; margin-inline-end: 4px; box-shadow: inset 0 0 0 1px currentColor; }
/* A closed deal in a timeline week is tinted whole by its outcome (deals.js
   sorts it below the open ones); the pill is an outline on that tint. Children
   inherit the card's colour; the avatar and tag hues cannot, so they get a ring. */
.bcard--timeline.is-won  { --out: var(--color-success); --out-bg: var(--chip-won-bg);  --out-fg: var(--chip-won-text); }
.bcard--timeline.is-lost { --out: var(--color-error);   --out-bg: var(--chip-lost-bg); --out-fg: var(--chip-lost-text); }
.bcard--timeline:is(.is-won, .is-lost) {
  background: var(--out-bg); color: var(--out-fg);
  border-color: color-mix(in srgb, var(--out) 35%, transparent);
}
.bcard--timeline:is(.is-won, .is-lost)::before { background: var(--out); }
.bcard--timeline:is(.is-won, .is-lost) :is(.bcard__val, .bcard__who, .bcard__eqv, .bcard__idle, .bcard__date) { color: inherit; }
.bcard--timeline:is(.is-won, .is-lost) :is(.bcard__who, .bcard__eqv, .bcard__idle, .bcard__date) { opacity: .8; }
.bcard--timeline:is(.is-won, .is-lost) :is(.avatar-sm, .bchip) { box-shadow: 0 0 0 1.5px var(--color-surface-container-lowest); }

/* Hover actions: over the value row, never over the title. */
.bqa {
  position: absolute; inset-inline-end: -4px; top: 50%; margin-top: -17px; z-index: 3;
  display: flex; gap: 1px; padding: 2px; border: 1px solid var(--color-outline-variant); border-radius: var(--radius-pill);
  background: var(--color-surface-container-lowest); box-shadow: var(--shadow-2);
  opacity: 0; pointer-events: none; transform: translateY(3px); transition: opacity .12s, transform .12s;
}
.bcard:hover .bqa, .bcard:focus-within .bqa { opacity: 1; pointer-events: auto; transform: none; }
body.board-dragging .bqa { display: none; }
.bqa button, .bqa a {
  width: 28px; height: 28px; border: 0; border-radius: var(--radius-pill); cursor: pointer;
  display: grid; place-items: center; background: none; color: var(--color-on-surface-var);
}
.bqa button:hover, .bqa a:hover { background: var(--color-surface-container-high); color: var(--color-on-surface); }
.bqa .material-symbols-outlined { font-size: 18px; }
.bcard__kebab { display: none; }

/* Compact density: one line when it fits, tag chips only when the deal has tags. */
.bcard--compact { padding: 7px 10px; }
.bcard--compact::before { top: 6px; bottom: 6px; }
/* A full value can outgrow a narrow column: the title keeps 40% and
   .bcard__end (value, icon, avatar) wraps under it as one unit. */
.bcard__row { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; min-width: 0; }
.bcard--compact .bcard__title { -webkit-line-clamp: 1; font-size: var(--md-sys-typescale-body-dense-size); min-width: 40%; }
.bcard__end { display: flex; align-items: center; gap: 8px; flex: none; margin-inline-start: auto; }
.bcard__vals { display: flex; flex-direction: column; align-items: flex-end; line-height: 1.2; }
.bcard--compact .bcard__val { font-size: var(--md-sys-typescale-body-small-size); }
.bcard--compact .bcard__eqv { font-size: var(--md-sys-typescale-label-small-size); }
.bcard--compact .bchips { margin-top: 4px; }
.bcard--compact .bchip { line-height: 17px; }
.bcard--compact .avatar-sm { width: 20px; height: 20px; }
.bcard--compact .bqa { top: 50%; inset-inline-end: 4px; }
.bnext-ico {
  width: 24px; height: 24px; flex: none; display: grid; place-items: center; cursor: pointer;
  border: 0; border-radius: var(--md-sys-shape-corner-small); background: var(--color-surface-container-low); color: var(--color-on-surface-var);
}
.bnext-ico .material-symbols-outlined { font-size: 15px; }
.bnext-ico.is-today { background: var(--color-warning-bg); color: var(--md-sys-color-on-warning-container); }
.bnext-ico.is-overdue { background: var(--color-error-container); color: var(--color-on-error-container); }
.bnext-ico.is-none { background: none; border: 1px dashed var(--color-warning); color: var(--color-warning); }

/* The sidebar's width, so the fixed drop bar below spans the content pane
   rather than the viewport. On a phone the sidebar is off-canvas and takes none. */
@media (min-width: 768px) {
  .layout { --sidebar-w: 256px; }
  .layout:has(> .sidebar--collapsed) { --sidebar-w: 80px; }
}

/* Drop bar: slides up from the bottom while a card is dragged. */
.bdrop {
  position: fixed; inset-inline: calc(var(--sidebar-w, 0px) + 24px) 24px; bottom: 20px; z-index: 95;
  display: flex; gap: var(--space-2); pointer-events: none;
  /* Hidden as well as moved off: while the page arrives, its transform makes
     "fixed" mean the page, and a short loading page left the bar on screen. */
  visibility: hidden;
  transform: translateY(160%); transition: transform .2s ease, visibility 0s linear .2s;
}
body.board-dragging .bdrop { visibility: visible; transform: none; pointer-events: auto; transition: transform .2s ease, visibility 0s; }
.bdrop__zone {
  flex: 1; height: 60px; display: flex; align-items: center; justify-content: center; gap: 8px;
  border: 2px dashed; border-radius: var(--radius-l); font-weight: 700; font-size: var(--md-sys-typescale-body-medium-size);
  background: var(--color-surface-container-lowest); box-shadow: var(--shadow-3);
}
.bdrop__zone * { pointer-events: none; }
.bdrop__zone.is-won { border-color: var(--color-success); color: var(--color-success); }
.bdrop__zone.is-lost { border-color: var(--color-error); color: var(--color-error); }
.bdrop__zone.is-pipe { border-color: var(--color-outline); color: var(--color-on-surface-var); flex: .7; }
.bdrop__zone.is-won.is-over { background: var(--color-success); color: var(--color-on-success); }
.bdrop__zone.is-lost.is-over { background: var(--color-error); color: var(--color-on-error); }
.bdrop__zone.is-pipe.is-over { background: var(--color-surface-container-highest); color: var(--color-on-surface); }

/* The deal panel: the whole deal page (deal.js) over the board's right two
   thirds, with a small floating card at its leading edge as in Pipedrive:
   close, open in full, previous / next. Phones open the #deal/ID page
   instead (_dealPeek.js). */
/* Room left on the board side for the panel's tab (.bpeek__rail), which sits
   outside it: a 768px tablet would otherwise push it off the screen. */
:root { --bpeek-w: min(calc(100vw - 64px), clamp(760px, 67vw, 1400px)); }
.bpeek {
  position: fixed; top: var(--md-top-app-bar-h); bottom: 0; inset-inline-end: 0; z-index: 95; width: var(--bpeek-w);
  display: flex;
  background: var(--color-surface); color: var(--color-on-surface);
  border-inline-start: 1px solid var(--color-outline-variant); box-shadow: var(--shadow-3);
  transform: translateX(106%); transition: transform .24s ease;
}
[dir="rtl"] .bpeek { transform: translateX(-106%); }
.bpeek.is-open { transform: none; }
/* A tab of the panel: its surface and its edge line, reaching out over the
   board, as tall as its four buttons. It covers the panel's own edge where
   they meet, so the two read as one sheet, and casts the panel's shadow on
   the board side only. */
.bpeek__rail {
  position: absolute; top: 16px; inset-inline-end: calc(100% - 1px);
  display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 4px;
  background: var(--color-surface);
  border: 1px solid var(--color-outline-variant); border-inline-end: none;
  border-start-start-radius: var(--md-sys-shape-corner-large);
  border-end-start-radius: var(--md-sys-shape-corner-large);
  box-shadow: var(--shadow-2);
  clip-path: inset(-16px 0 -16px -16px);
}
[dir="rtl"] .bpeek__rail { clip-path: inset(-16px -16px -16px 0); }
/* Material 3 standard icon buttons: no container, a state layer on hover and
   focus, 40px; 48px on touch. */
.bpeek__btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; padding: 0; border: none; border-radius: 50%;
  background: transparent; color: var(--color-on-surface-var); cursor: pointer; text-decoration: none;
}
.bpeek__btn:hover { background: var(--color-surface-container-high); color: var(--color-on-surface); }
.bpeek__btn:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.bpeek__btn:disabled { opacity: .38; cursor: default; background: transparent; }
@media (any-pointer: coarse) { .bpeek__btn { width: 48px; height: 48px; } }
.bpeek__body { flex: 1; min-width: 0; min-height: 0; overflow: hidden; }

/* The leads list opens a lead in the same panel (leads.js, Yahia 2026-10-21):
   the row whose lead is open stays marked beside it. */
.list-table.list-table:is(.leads-table, .products-table) tbody tr.is-peeked td { background: var(--color-secondary-container); color: var(--color-on-secondary-container); }
/* The leads list's Owner cell: the avatar, then the name. */
.owner-cell { display: inline-flex; align-items: center; gap: 8px; }
/* The lead page (lead.js): its status button opens the status menu; once
   converted, the records it became sit where Convert was. */
.lead-status { display: inline-flex; align-items: center; gap: 2px; }
.lead-status-badge.chip { border: 1px solid var(--color-outline-variant); }
.lead-became { display: flex; flex-wrap: wrap; gap: 6px; }
.lead-dups__intro { margin: 0 0 var(--space-2); }
.lead-dups__group { margin-bottom: var(--space-2); }
.lead-dup { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 4px 0; }
.lead-dup__what { min-width: 0; overflow-wrap: anywhere; font-size: var(--md-sys-typescale-body-small-size); }
/* The owner pill of a record nobody owns: a person icon where the avatar goes. */
.rh-owner__none { background: var(--color-surface-container-high); color: var(--color-on-surface); }

/* Pickers inside the shared modal (pipeline, tag, save view) */
.board-pick { display: flex; flex-direction: column; gap: 2px; }
.board-pick__row { display: flex; align-items: center; gap: 10px; padding: 8px 4px; font-size: var(--md-sys-typescale-body-medium-size); cursor: pointer; }
.board-pick__sw { width: 10px; height: 10px; border-radius: 50%; flex: none; }
/* A choice that doesn't apply: Material 3's disabled content, at 38%. */
.board-pick__row.is-disabled { opacity: .38; cursor: default; }
/* The phone's action sheet (showModal is already a bottom sheet there). */
.bsheet__row {
  display: flex; align-items: center; gap: 14px; width: 100%; padding: 11px 4px; border: 0; background: none;
  font: inherit; font-size: var(--md-sys-typescale-body-medium-size); color: var(--color-on-surface); text-align: start; cursor: pointer;
}
.bsheet__row:hover { background: var(--color-surface-container-low); }
.bsheet__row .material-symbols-outlined { color: var(--color-on-surface-var); }
.bsheet__row .material-symbols-outlined:last-child:not(:first-child) { margin-inline-start: auto; color: var(--color-primary); }
.bsheet__row.is-good .material-symbols-outlined { color: var(--color-success); }
.bsheet__row.is-bad, .bsheet__row.is-bad .material-symbols-outlined { color: var(--color-error); }
.bsheet__sw { width: 10px; height: 10px; border-radius: var(--md-sys-shape-corner-extra-small); flex: none; }
.bsheet__sec { padding: 4px 4px 6px; font-size: var(--md-sys-typescale-label-small-size); font-weight: 700; letter-spacing: .5px; color: var(--color-on-surface-var); }
/* Arabic is joined script: tracking pulls its letters apart. */
[dir="rtl"] .bsheet__sec, [dir="rtl"] .bag__head { letter-spacing: 0; }
.bsheet__sep { height: 1px; margin: 6px 0; background: var(--color-outline-variant); }
.bkeys { margin: 0; display: grid; gap: 8px; }
.bkeys > div { display: flex; justify-content: space-between; align-items: center; gap: 16px; }
.bkeys dt { margin: 0; }
.bkeys dd { margin: 0; color: var(--color-on-surface-var); font-size: var(--md-sys-typescale-body-medium-size); }
.bkeys kbd {
  font: 600 var(--md-sys-typescale-label-small-size)/1 ui-monospace, SFMono-Regular, Menlo, monospace; padding: 3px 6px; border-radius: var(--md-sys-shape-corner-extra-small);
  border: 1px solid var(--color-outline-variant); border-bottom-width: 2px; background: var(--color-surface-container-lowest);
}

/* One row on a computer: tabs take what the tools leave and scroll. */
@media (min-width: 768px) {
  :is(#pipelineToolbar, .table-toolbar--tabs):has(> .btabs:not([hidden])) { flex-wrap: nowrap; gap: var(--space-2); padding: 8px var(--space-3); }
  #pipelineToolbar:has(> .btabs:not([hidden])) > .search-bar { flex: 0 100 220px; min-width: 140px; }
  .table-toolbar--tabs:has(> .btabs) > .search-bar { flex: 0 0 240px; }
  :is(#pipelineToolbar, .table-toolbar--tabs):has(> .btabs:not([hidden])) .table-toolbar__actions { flex: none; }
}
/* The toolbar's icon buttons (health strip, density) take the toolbar's size,
   not the 48px .btn floor that made the bar a row taller than its controls. */
#pipelineToolbar .btn--icon { min-height: 0; padding: 6px; }
#healthBtn[aria-pressed="true"] { color: var(--color-primary); border-color: var(--color-primary); }

/* Short screens: a 1920×1080 display at 125% scaling leaves the browser about
   730px, and the header, health strip and toolbar left the columns ~200px —
   under two cards. Trim the chrome, not the cards; tall screens are untouched. */
@media (min-width: 768px) and (max-height: 900px) {
  .deals-page { padding: var(--space-3); }
  .deals-page .page-header { margin-bottom: var(--space-2); }
  .deals-page .page-header-info { gap: 0; }
  .deals-page .deals-title h1 { font-size: var(--md-sys-typescale-headline-small-size); }
  /* One row a tile: the label, and the figure at the end. The sub-line goes. */
  .deals-page .bh-tile { flex-direction: row; align-items: center; gap: var(--space-2); padding: 6px 12px; }
  .deals-page .bh-tile__label { display: block; flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
  .deals-page .bh-tile__label .material-symbols-outlined { vertical-align: -3px; margin-inline-end: 4px; }
  .deals-page .bh-tile__value { flex: none; margin-inline-start: auto; }
  .deals-page .bh-tile__sub { display: none; }
  /* The + in the column header adds a deal too. */
  .deals-page .bcol__addrow { display: none; }
}

/* Phone-only pieces, hidden on a computer. */
.board-mbar, .bfab, .bstabs, .bagenda { display: none; }

@media (max-width: 767px) {
  .board-health, #pipelineToolbar .btabs, #densityBtn { display: none !important; }
  /* Activity first: no KPIs on a phone — the total goes with the strip — and
     the FAB replaces Add Deal; import / export stay on the computer. */
  .deals-page.is-m-board .page-subtitle,
  .deals-page.is-m-board #addDealBtn,
  .deals-page.is-m-board #importDealsBtn,
  .deals-page.is-m-board #exportDealsBtn { display: none; }
  .deals-page.is-m-board .page-header { flex-direction: row; flex-wrap: nowrap; align-items: center; justify-content: space-between; margin-bottom: 8px; }
  .deals-page.is-m-board .page-header-info { min-width: 0; }
  .deals-page.is-m-board .page-actions { width: auto; flex: none; }
  .deals-page.is-m-board .deals-title h1 { font-size: var(--md-sys-typescale-title-large-size); }
  .deals-page.is-m-board #pipelineToolbar {
    padding: 0; margin-bottom: 8px; background: none; box-shadow: none; flex-wrap: nowrap; gap: 6px;
  }
  .deals-page.is-m-board #pipelineToolbar > .search-bar { flex: 1 1 auto; max-width: none; }
  .deals-page.is-m-board #pipelineToolbar .table-toolbar__actions { gap: 6px; flex: none; }
  /* Owner, tags and sort as icons: the words don't fit beside the search. */
  .deals-page.is-m-board #pipelineToolbar .tag-filter-btn > span:not(.material-symbols-outlined):not(.tag-filter-count) { display: none; }
  .deals-page.is-m-board #pipelineToolbar .sort-dropdown__trigger { font-size: 0; gap: 0; }
  .deals-page.is-m-board #pipelineToolbar .sort-dropdown__trigger .material-symbols-outlined { font-size: 18px; }
  .board-mbar:not([hidden]) { display: flex; flex-direction: column; gap: 8px; margin-bottom: 8px; }
  .bseg { display: inline-flex; align-self: flex-start; border: 1px solid var(--color-outline-variant); border-radius: var(--radius-pill); padding: 2px; background: var(--color-surface-container-lowest); }
  .bseg button {
    display: inline-flex; align-items: center; gap: 6px; padding: 5px 12px; border: 0; border-radius: var(--radius-pill);
    background: none; color: var(--color-on-surface-var); font: inherit; font-size: var(--md-sys-typescale-body-dense-size); font-weight: 600; cursor: pointer;
  }
  .bseg button .material-symbols-outlined { font-size: 18px; }
  .bseg button.is-on { background: var(--color-primary-container); color: var(--color-on-primary-container); }
  .bmchips { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; }
  .bmchips::-webkit-scrollbar { display: none; }
  .bmchip {
    display: inline-flex; align-items: center; gap: 6px; flex: none; height: 32px; padding: 0 10px;
    border: 1px solid var(--color-outline-variant); border-radius: var(--radius-pill);
    background: var(--color-surface-container-lowest); color: var(--color-on-surface); font: inherit; font-size: var(--md-sys-typescale-body-dense-size); font-weight: 600; cursor: pointer;
  }
  .bmchip__n { font-size: var(--md-sys-typescale-label-small-size); line-height: 17px; padding: 0 6px; border-radius: var(--radius-pill); background: var(--color-surface-container-high); font-variant-numeric: tabular-nums; }
  .bmchip.is-warn .bmchip__n { background: var(--color-error-container); color: var(--color-on-error-container); }
  .bmchip.is-on { background: var(--color-primary-container); color: var(--color-on-primary-container); border-color: transparent; }
  /* The toolbar keeps search, owner and tags; the rest moved into the chips. */
  #pipelineToolbar #followedChip { display: none; }
  /* The agenda is ordered by due date; sorting belongs to the stage tabs. */
  .deals-page.is-m-agenda #pipelineToolbar .sort-dropdown { display: none; }

  .kanban { overflow: visible; }
  .bstabs { display: flex; gap: 6px; overflow-x: auto; padding: 0 0 8px; scrollbar-width: none; flex-shrink: 0; }
  .bstabs::-webkit-scrollbar { display: none; }
  .bstab {
    display: inline-flex; align-items: center; gap: 6px; flex: none; padding: 5px 12px;
    border: 1px solid var(--color-outline-variant); border-radius: var(--radius-pill);
    background: var(--color-surface-container-lowest); color: var(--color-on-surface); font: inherit; font-size: var(--md-sys-typescale-body-small-size); font-weight: 600; cursor: pointer; white-space: nowrap;
  }
  .bstab i { width: 8px; height: 8px; border-radius: var(--md-sys-shape-corner-extra-small); background: var(--stc); }
  .bstab__n { color: var(--color-on-surface-var); }
  .bstab.is-on { background: var(--color-on-surface); color: var(--color-surface); border-color: transparent; }
  .bstab.is-on .bstab__n { color: inherit; opacity: .75; }
  .bcols { gap: 0; scroll-snap-type: x mandatory; scrollbar-width: none; overflow-y: visible; }
  .bcols::-webkit-scrollbar { display: none; }
  .bcol { flex: 0 0 100%; scroll-snap-align: start; background: none; border: 0; border-radius: 0; }
  .bcol__head { padding: 0 0 8px; }
  .bcol__head > .bcol__row:first-child { display: none; }
  .bcol__list { padding: 2px 0 96px; max-height: calc(100vh - 290px); max-height: calc(100dvh - 290px); }
  .bcol__addrow { display: none; }

  /* The activity-first phone card. */
  .bcard--m { padding: 0; overflow: hidden; }
  .bcard--m::before { top: 0; bottom: 0; border-radius: 0; }
  .bm-act {
    display: flex; align-items: center; gap: 8px; padding: 9px 12px; font-size: var(--md-sys-typescale-body-dense-size); font-weight: 600;
    background: var(--color-surface-container-low); border-bottom: 1px solid var(--color-outline-variant);
  }
  .bm-act .material-symbols-outlined { font-size: 18px; color: var(--color-on-surface-var); }
  .bm-act__what { flex: 1; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
  .bm-act__when { font-weight: 700; white-space: nowrap; font-variant-numeric: tabular-nums; color: var(--color-on-surface-var); }
  .bm-act.is-today { background: var(--color-warning-bg); }
  .bm-act.is-today .material-symbols-outlined, .bm-act.is-today .bm-act__when { color: var(--md-sys-color-on-warning-container); }
  .bm-act.is-overdue { background: var(--color-error-container); }
  .bm-act.is-overdue .material-symbols-outlined, .bm-act.is-overdue .bm-act__when { color: var(--color-on-error-container); }
  .bm-act.is-none { background: none; color: var(--color-warning); border-bottom-style: dashed; }
  .bm-act.is-none .material-symbols-outlined, .bm-act.is-none .bm-act__when { color: var(--color-warning); }
  .bm-body { padding: 10px 12px 0; }
  .bm-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
  .bm-meta .bchips { display: contents; }
  .bm-meta .bcard__date { margin-top: 0; }
  .bm-stage {
    display: inline-flex; align-items: center; gap: 5px; padding-block: 1px; padding-inline: 8px 2px; line-height: 18px; cursor: pointer;
    border: 1px solid var(--color-outline-variant); border-radius: var(--radius-pill);
    background: var(--color-surface-container-lowest); color: var(--color-on-surface); font: inherit; font-size: var(--md-sys-typescale-label-small-size); font-weight: 600;
  }
  .bm-stage i { width: 7px; height: 7px; border-radius: 2px; background: var(--stc); }
  .bm-stage .material-symbols-outlined { font-size: 16px; color: var(--color-on-surface-var); }
  .bm-btns { display: flex; gap: 6px; padding: 10px 12px 12px; }
  .bm-btns .btn { flex: 1; justify-content: center; }
  .bm-btns__wide { flex: 2 !important; }
  .bcard--m .bcard__kebab {
    display: grid; place-items: center; width: 28px; height: 28px; margin-inline-start: -4px;
    border: 0; border-radius: var(--radius-pill); background: none; color: var(--color-on-surface-var); cursor: pointer;
  }
  .bcard--m .bcard__kebab .material-symbols-outlined { font-size: 20px; }
  .bcard--m .bqa { display: none; }

  /* Agenda */
  .bagenda { display: block; }
  .bday { padding: 0 0 10px; }
  .bday__row { display: flex; justify-content: space-between; gap: 8px; font-size: var(--md-sys-typescale-body-small-size); font-weight: 600; }
  .bday__od { color: var(--color-error); }
  .bday__bar { height: 6px; margin-top: 6px; border-radius: var(--md-sys-shape-corner-extra-small); background: var(--color-surface-container-highest); overflow: hidden; }
  .bday__bar i { display: block; height: 100%; border-radius: var(--md-sys-shape-corner-extra-small); background: var(--color-success); transition: width .3s; }
  .bagenda__list { padding-bottom: 96px; }
  .bag__head {
    position: sticky; top: 0; z-index: 4; display: flex; align-items: center; gap: 8px; padding: 12px 2px 8px;
    background: var(--color-surface); font-size: var(--md-sys-typescale-body-small-size); font-weight: 700; letter-spacing: .5px; color: var(--color-on-surface-var);
  }
  .bag__head.is-overdue { color: var(--color-error); }
  .bag__head.is-today { color: var(--color-warning); }
  .bag__n { padding: 0 7px; border-radius: var(--radius-pill); background: var(--color-surface-container-high); color: var(--color-on-surface); font-size: var(--md-sys-typescale-label-small-size); letter-spacing: 0; }
  .bag__v { margin-inline-start: auto; letter-spacing: 0; font-weight: 600; }
  .bag .bcard { margin-bottom: 10px; }
  .bag__more { width: 100%; justify-content: center; margin-bottom: 10px; }

  .bfab:not([hidden]) {
    display: grid; place-items: center; position: fixed; inset-inline-end: 18px; bottom: calc(var(--md-nav-bar-h) + 88px + env(safe-area-inset-bottom, 0px));
    z-index: 210; width: 56px; height: 56px; border: 0; border-radius: var(--md-sys-shape-corner-large); cursor: pointer;
    background: var(--color-primary-container); color: var(--color-on-primary-container); box-shadow: var(--shadow-3);
  }
  .bfab .material-symbols-outlined { font-size: 26px; }
  .bdrop { display: none; }

}

@media (prefers-reduced-motion: reduce) {
  .bdrop, .bpeek, .bqa, .bcol__share i, .bday__bar i { transition: none; }
}

/* ── Add Deal Dialog ─────────────────────────────────────────────────── */
.dialog {
  background: var(--color-surface-container-lowest);
  border-radius: var(--radius-l);
  box-shadow: var(--shadow-signature);
  padding: var(--space-4);
  width: 480px;
  max-width: 95vw;
  max-height: 90vh;
  overflow-y: auto;
}

/* Form fields (fill-style, no outlines) */
.field { margin-bottom: var(--space-3); }
.field label {
  display: block;
  font-size: var(--md-sys-typescale-label-medium-size);
  line-height: var(--md-sys-typescale-label-medium-line);
  font-weight: var(--md-sys-typescale-label-medium-weight);
  letter-spacing: var(--md-sys-typescale-label-medium-tracking);
  color: var(--md-sys-color-on-surface-variant);
  margin-bottom: 6px;
}
.field:focus-within > label { color: var(--md-sys-color-primary); }
/* MD3 filled text field: surface-container-highest, top corners 4px, a 1px
   on-surface-variant active indicator that becomes 2px primary on focus. */
.field input, .field select {
  width: 100%;
  background: var(--md-sys-color-surface-container-highest);
  border: none;
  border-bottom: 1px solid var(--md-sys-color-on-surface-variant);
  border-radius: var(--md-sys-shape-corner-extra-small) var(--md-sys-shape-corner-extra-small) 0 0;
  padding: 10px 12px 9px;
  font-family: var(--font-body); font-size: var(--md-sys-typescale-body-medium-size);
  color: var(--color-on-surface);
  outline: none;
  transition: border-color .15s, box-shadow .15s;
}
.field input:focus, .field select:focus {
  border-bottom-color: var(--md-sys-color-primary);
  box-shadow: inset 0 -1px 0 var(--md-sys-color-primary);
}

/* ── Analytics charts ────────────────────────────────────────────────── */
.chart-card {
  background: var(--color-surface-container-lowest);
  border-radius: var(--radius-m);
  padding: var(--space-4);
  box-shadow: var(--shadow-1);
}
.chart-card__header {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: var(--space-3);
}

/* Bar chart */
.bar-chart {
  display: flex; align-items: flex-end; gap: 6px;
  height: 120px;
}
.bar-chart__bar {
  flex: 1; border-radius: 4px 4px 0 0;
  /* Solid roles, not a translucent mix of primary. The .rb-chart__bar rules
     use color-mix(primary 18%), which measures 1.32:1 on a white card — under
     the 3:1 WCAG 1.4.11 floor for meaningful graphics — so copying that idiom
     would have reproduced the invisible-bar bug in a new form. secondary is
     6.5:1 light / 11.4:1 dark and does not depend on what is behind it. */
  background: var(--color-secondary);
  transition: background .15s;
  cursor: pointer;
  position: relative;
}
.bar-chart__bar:hover { background: var(--color-on-surface); }
.bar-chart__bar--active { background: var(--color-primary); }
.bar-chart__labels {
  display: flex; gap: 6px; margin-top: 6px;
}
.bar-chart__label {
  flex: 1; text-align: center;
  font-size: var(--md-sys-typescale-label-small-size); font-weight: 700;
  letter-spacing: .5px;
  color: var(--color-on-surface-var);
}

/* Horizontal bar (pipeline stages / velocity) */
.h-bar-row { margin-bottom: 12px; }
.h-bar-row:last-child { margin-bottom: 0; }
.h-bar-meta {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 4px;
}
.h-bar-meta span:first-child {
  font-size: var(--md-sys-typescale-body-dense-size); font-weight: 500; color: var(--color-on-surface);
}
.h-bar-meta span:last-child {
  font-size: var(--md-sys-typescale-body-small-size); color: var(--color-on-surface-var);
}
.h-bar-track {
  height: 8px; border-radius: var(--radius-pill);
  background: rgba(0,51,85,.1);
  overflow: hidden;
}
.h-bar-fill {
  height: 100%; border-radius: var(--radius-pill);
  background: var(--color-primary);
}

/* A ring opening as its tile arrives (views/_motion.js). A browser without
   @property has no value here, so no mask, and shows the ring whole. */
@property --motion-sweep { syntax: "<angle>"; inherits: false; initial-value: 360deg; }
.motion-sweep { mask-image: conic-gradient(black var(--motion-sweep, 360deg), transparent 0); }
/* The figure in a donut's hole stays whole while the ring opens around it. */
.donut.motion-sweep {
  mask-image: radial-gradient(closest-side, black 68%, transparent 0),
    conic-gradient(black var(--motion-sweep, 360deg), transparent 0);
}

/* Donut chart */
.donut-wrap { display: flex; align-items: center; gap: var(--space-4); }
.donut {
  width: 140px; height: 140px; border-radius: 50%;
  flex-shrink: 0; position: relative;
  display: flex; align-items: center; justify-content: center;
}
/* The hole. Without it the centre figure sat on the fill itself — primary
   text on a primary ring, which read as a smudge. The card's own surface. */
.donut::before {
  content: ""; position: absolute; inset: 22px; border-radius: 50%;
  background: var(--color-surface-container-lowest);
}
.donut__center {
  position: absolute; z-index: 1; text-align: center;
}
.donut__pct {
  font-family: var(--font-display);
  font-size: var(--md-sys-typescale-headline-small-size); font-weight: 700;
  color: var(--color-on-surface);
  line-height: 1.1;
}
.donut__sub { font-size: var(--md-sys-typescale-label-small-size); font-weight: 700; letter-spacing: .5px; color: var(--color-on-surface-var); }
.donut-legend { display: flex; flex-direction: column; gap: 12px; }
.donut-legend-share { font-weight: 500; color: var(--color-on-surface-var); }
.donut-legend-item { display: flex; align-items: center; gap: 8px; }
.donut-legend-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
.donut-legend-label { font-size: var(--md-sys-typescale-body-small-size); color: var(--color-on-surface-var); }
/* The share sits beside the value by a flex gap, not a margin: in RTL the two
   numbers join into one LTR run and a logical margin lands on the far side. */
.donut-legend-value { display: flex; gap: 6px; font-size: var(--md-sys-typescale-body-dense-size); font-weight: 600; color: var(--color-on-surface); }

/* RFM segment pills + churn dots */
.segment-pill {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px; border-radius: var(--radius-pill);
  font-size: var(--md-sys-typescale-label-small-size); font-weight: 600;
  letter-spacing: 0.02em; white-space: nowrap;
  border: 1px solid transparent;
}
/* MD3 container / on-container pairs: they hold AA in both themes, so the
   pills need no dark patches. */
.segment-pill--gold   { background: var(--md-sys-color-tertiary-container); color: var(--md-sys-color-on-tertiary-container); }
.segment-pill--green  { background: var(--md-sys-color-success-container);  color: var(--md-sys-color-on-success-container); }
.segment-pill--yellow { background: var(--md-sys-color-warning-container);  color: var(--md-sys-color-on-warning-container); }
.segment-pill--red    { background: var(--md-sys-color-error-container);    color: var(--md-sys-color-on-error-container); }
.segment-pill--gray   { background: var(--color-surface-container-low); color: var(--color-on-surface-var); border-color: var(--color-outline-variant); }

.churn-dot {
  display: inline-block; width: 10px; height: 10px; border-radius: 50%;
  vertical-align: middle; flex-shrink: 0;
}
.churn-dot--green  { background: var(--color-success); box-shadow: 0 0 0 2px color-mix(in srgb, var(--md-sys-color-success) 15%, transparent); }
.churn-dot--yellow { background: var(--color-warning); box-shadow: 0 0 0 2px color-mix(in srgb, var(--md-sys-color-warning) 15%, transparent); }
.churn-dot--red    { background: var(--color-error);   box-shadow: 0 0 0 2px color-mix(in srgb, var(--md-sys-color-error) 15%, transparent); }

/* KPI card variant for the segment badge on the detail page */
.kpi-card--segment-gold   { border-inline-start: 3px solid var(--color-gold); }
.kpi-card--segment-green  { border-inline-start: 3px solid var(--color-success); }
.kpi-card--segment-yellow { border-inline-start: 3px solid var(--color-warning); }
.kpi-card--segment-red    { border-inline-start: 3px solid var(--color-error); }
.kpi-card--segment-gray   { border-inline-start: 3px solid var(--color-on-surface-var); }

/* RFM insights panel layout — wraps the existing chart classes */
.rfm-insights { display: flex; flex-direction: column; gap: var(--space-3); margin-bottom: var(--space-3); }
.rfm-insights .chart-card { padding: var(--space-3); }
/* Says the KPIs above skip cancelled/pending orders — the list below still
   shows them, so without this the numbers look like they don't add up.
   Colour comes from `.caption`, which this is always paired with. */
.rfm-insights__note { margin-top: var(--space-2); }

/* An order that doesn't count toward revenue: still listed and still
   expandable, but visibly out of the totals. The sibling `.tag--*` modifiers
   carry no styling of their own, so this stays plain text too — a border or
   fill here would make the excluded row the most decorated one in the table.
   The dimmed row and its "Not counted" caption carry the signal. */
.order-row--excluded td { opacity: 0.6; }
.tag--muted { color: var(--color-on-surface-var); font-style: italic; }
.rfm-insights__row {
  display: grid; gap: var(--space-3);
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
/* Cards of one width, each at least as wide as the widest figure a card
   shows (Material 3: text size does not change with the container). A
   compact amount cannot wrap (Intl joins its parts with no-break spaces),
   and a 160px floor left 171px-wide cards at 1280px that "102.9 مليون ج.م."
   ran 89px out of. --rfm-figure is the widest such figure in the currencies
   the currency setup lists first (EGP, USD, EUR, SAR, AED, GBP) at the
   card's figure size, "AED 999.9M" in English and "102.9 مليون ر.س." in
   Arabic, as Chromium on Linux draws it. The floor adds the card's padding,
   its 4px border and 4px for the few pixels font renderers disagree by. A
   row takes as many cards as fit, one on a phone. The padding is narrow so
   two Arabic cards share a row at 1280px with a Windows scrollbar (Yahia,
   2026-10-06): a 513px strip, two cards of 252.5px. */
.rfm-kpi-grid {
  --rfm-figure: 172px;
  --rfm-card-pad: 12px;
  --rfm-card-min: calc(var(--rfm-figure) + 2 * var(--rfm-card-pad) + 8px);
  display: grid; gap: var(--space-2);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--rfm-card-min)), 1fr));
}
.rfm-kpi-grid > .kpi-card { padding-inline: var(--rfm-card-pad); }
[dir="rtl"] .rfm-kpi-grid { --rfm-figure: 220px; }
@media (max-width: 767px) {
  .rfm-kpi-grid { --rfm-figure: 135px; }
  [dir="rtl"] .rfm-kpi-grid { --rfm-figure: 170px; }
}
.rfm-overdue { color: var(--color-error); font-weight: 600; }
.rfm-on-track { color: var(--color-success-text); font-weight: 600; }

/* Mobile: stack the 3-chip cluster under the name */

/* Source master-list dot — inline-end margin (not margin-right) so it flips in RTL. */
.source-dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; margin-inline-end: 6px; }

/* ── Glass panel (Stitch signature effect) ─────────────────────────────── */

/* ── Architectural grid (dark bg texture) ──────────────────────────────── */

/* #pipelineKpi is a SIBLING of #kanban (deals.js render), never inside it —
   the earlier `.kanban .pipeline-kpi` form of these rules matched nothing. */
[data-theme="dark"] .pipeline-kpi { box-shadow: none; }
[data-theme="dark"] .pipeline-kpi__divider    { background: rgba(255,255,255,.08); }

/* ── Analytics glass cards ──────────────────────────────────────────────── */

/* ── Contacts ghost table refinements ───────────────────────────────────── */
.data-table tr { border-bottom: none; }

/* ── Outline utility ─────────────────────────────────────────────────────── */

/* ── Page header utilities (used in all views) ──────────────────────────── */
.page-header        { display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:var(--space-3); margin-bottom:var(--space-4); }
.page-header-info   { display:flex; flex-direction:column; gap:4px; }
.page-header-info > h1 { margin: 0; }
/* A page's back arrow beside its heading (the duplicates review). */
.page-heading-row { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.page-heading-row > h1 { margin: 0; }
.page-subtitle      { font-size:var(--md-sys-typescale-body-dense-size); color:var(--color-on-surface-var); }
.page-actions       { display:flex; align-items:center; gap:8px; flex-wrap:wrap; }

/* ── View switcher (Kanban / List / Timeline tabs) ──────────────────────── */
/* MD3 segmented button: a 40px pill of outlined segments; the selected one
   fills with secondary-container. */
.view-switcher {
  display: flex;
  min-height: 40px;
  border: 1px solid var(--md-sys-color-outline);
  border-radius: var(--md-sys-shape-corner-full);
  overflow: hidden;
}
.view-switcher__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  border: none;
  background: transparent;
  cursor: pointer;
  color: var(--md-sys-color-on-surface);
}
.view-switcher__btn + .view-switcher__btn { border-inline-start: 1px solid var(--md-sys-color-outline); }
.view-switcher__btn .material-symbols-outlined { font-size: 18px; }
.view-switcher__btn.active {
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
}

/* ── Products editor modal (full-deal table) ───────────────────────────── */
.modal--editor {
  max-width: min(1100px, 96vw) !important;
  width: 1100px;
}
/* A dense spreadsheet-style workspace — every pixel the default 90vh leaves on
   the table goes to the table. The calc() term is the overlay's own padding, so
   the sheet never overflows the scrim. Scoped to ≥768px so the mobile
   bottom-sheet height isn't outranked by this more-specific selector. */
@media (min-width: 768px) {
  .modal--editor { max-height: min(94vh, calc(100vh - 2 * var(--space-4))); }
}
.modal--editor .modal__body {
  display: flex;
  min-height: 0;
  overflow: hidden;
  padding: 0;
}
.pe-root {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: var(--space-3);
  /* Inline padding matches .modal__header / .modal__actions (--space-4) so the
     tabs, table and totals line up with the title and the Cancel/Save row. */
  padding: var(--space-3) var(--space-4) var(--space-4);
  min-height: 0;
  /* Safety valve: on very short viewports the table's min-height floor plus the
     toolbar and totals can exceed the modal, so the editor scrolls as a whole
     instead of clipping the totals. Tall viewports never reach this. */
  overflow: auto;
}
.pe-tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--color-outline-variant);
}
/* One tab is just a 51px label — and the count is already in the header row.
   Self-maintaining: adding a second tab brings the bar back. Browsers without
   :has() keep the bar, which is harmless. */
.pe-tabs:has(> .pe-tab:only-child) { display: none; }
.pe-tab {
  padding: 8px 14px;
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  color: var(--color-on-surface-var);
  cursor: pointer;
  font-size: var(--md-sys-typescale-body-medium-size);
  font-weight: 600;
}
.pe-tab.is-active {
  color: var(--color-primary);
  border-bottom-color: var(--color-primary-container);
}
/* Single control row: currency + tax settings on the left, row actions and
   counts on the right. Labels sit beside their selects rather than above, and
   the "+ Product" toolbar folds in here — together that's ~80px the table gets
   back on a short window. Wraps to two lines when narrow instead of crushing. */
.pe-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3) 24px;
  flex-wrap: wrap;
}
.pe-header__inline { display: flex; gap: 8px; align-items: center; }
.pe-header__group {
  display: flex; flex-direction: row; align-items: center;
  gap: 8px; min-width: 0;
}
.pe-header__controls { display: flex; align-items: center; gap: 24px; flex-wrap: wrap; }
.pe-header__actions  { display: flex; align-items: center; gap: var(--space-3); }
.pe-label {
  font-size: var(--md-sys-typescale-body-small-size);
  font-weight: 600;
  color: var(--color-on-surface-var);
}
.pe-input {
  padding: 6px 10px;
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-s);
  background: var(--color-surface-container-lowest);
  color: var(--color-on-surface);
  font-size: var(--md-sys-typescale-body-dense-size);
  font-family: inherit;
}
.pe-input:focus { outline: 2px solid var(--color-primary-container); outline-offset: -1px; }
.pe-link {
  background: none; border: none; padding: 0;
  color: var(--color-primary);
  cursor: pointer;
  font-size: var(--md-sys-typescale-body-dense-size);
  text-decoration: underline;
}
/* Scroll chain: the panel fills the modal body, the table wrap scrolls.
   The toolbar and totals refuse to shrink and the table is the only flexible
   child, so every pixel of overflow used to come out of the table — on a short
   viewport it collapsed to just its sticky header. The wrap now keeps a floor of
   ~2 rows; anything past that overflows the panel into .pe-root, which scrolls. */
.pe-tab-panel {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: var(--space-2);
  min-height: 0;
}
.pe-table-wrap {
  flex: 1 1 auto;
  min-height: clamp(130px, 18vh, 300px);
  overflow: auto;
  scrollbar-gutter: stable;
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-s);
}
/* Fixed columns total 774px (drag 20 + toggle 38 + price 190 + qty 120 +
   discount 158 + tax 90 + amount 110 + actions 28), plus 206px more whenever
   showTermColumns() adds billing 120 + term 86; the rest keeps the product name
   readable. Past that .pe-table-wrap scrolls sideways rather than squashing the
   name to nothing — no breakpoint needed, the floor applies exactly when the
   modal is too narrow for it. Discount is the one column whose share is
   font-relative, so it is 158px here and ~176px under the ≤767px zoom guard.
   The min-width below still earns its keep on the trimmed set — measured, the
   cells' own intrinsic minimum is 863px with tax off and no term columns, and
   1151px with all eleven. Re-derive this when a column is added or resized. */
.pe-table { width: 100%; min-width: 920px; border-collapse: collapse; font-size: var(--md-sys-typescale-body-dense-size); }
.pe-table thead th {
  position: sticky; top: 0; z-index: 1;
  background: var(--color-surface-container-low);
  color: var(--color-on-surface-var);
  text-align: start;
  padding: 8px 12px;
  font-size: var(--md-sys-typescale-label-small-size);
  letter-spacing: 0.04em;
  border-bottom: 1px solid var(--color-outline-variant);
}
.pe-table tbody td {
  padding: 8px 12px;
  border-bottom: 1px solid var(--color-outline-variant);
  vertical-align: middle;
}
.pe-row {
  cursor: default;
  transition: background 0.12s;
}
.pe-row:hover { background: var(--color-surface-container-lowest); }
.pe-row--off { opacity: 0.55; }
.pe-row--off .pe-col-product input { text-decoration: line-through; }
.pe-row--dragging { opacity: 0.4; }
.pe-row--drop-target { box-shadow: inset 0 2px 0 0 var(--color-primary-container); }
.pe-drag-handle {
  display: inline-flex;
  padding: 0 4px;
  color: var(--color-on-surface-var);
  cursor: grab;
  user-select: none;
  letter-spacing: -2px;
  font-size: var(--md-sys-typescale-body-medium-size);
}
.pe-col-drag    { width: 20px;  text-align: center; padding-inline: 2px; }
/* THE HOUSE RULE for every .pe-col-* below: the table is auto-layout, so a
   width here is only a suggestion — the browser collapses a column to the
   intrinsic size of its contents and the width loses. The min-width on the
   CONTROL is what actually reserves space; min-width on the cell would be
   ignored. Each floor below is therefore the real column width, and the
   width: beside it only distributes slack once the table is above its
   intrinsic minimum. Verified: table-layout: fixed is not the shortcut out —
   it makes min-width inert on cells, and the percentage-width product column
   then absorbs the whole deficit and collapses to 0. */
/* The product name is the one cell you cannot afford to be unreadable; without
   its floor it collapsed to ~65px against eleven columns. */
.pe-col-product { width: 32%; min-width: 190px; }
.pe-product-input { width: 100%; min-width: 150px; }
.pe-col-num     { width: 120px; text-align: end; }
.pe-col-price   { width: 190px; }
/* A composite cell (unit select + value), sized for an amount discount like
   "1,500.00" rather than a bare percentage — unfloored, the value input was
   about one digit wide. The floor is font-relative, alone among these columns,
   because it is the only one whose content is wide enough for the ≤767px
   iOS-zoom guard (.pe-input → 16px) to matter: 6em tracks that guard to 96px
   instead of needing a second px floor in the media query. */
.pe-col-discount{ width: 160px; }
.pe-col-discount .pe-input--num { min-width: 6em; }
/* Two-digit rates like "14" clipped without this. */
.pe-col-tax     { width: 90px; }
.pe-col-tax .pe-input--num { min-width: 54px; }
/* Tax mode "None" zeroes every line rate in the totals, so the whole column is
   dead weight — dropped from head and body together. Toggled by class rather
   than by rebuilding the markup: <thead> is written once when the editor opens
   while render() only rewrites <tbody>. */
.pe-root--no-tax .pe-col-tax { display: none; }
/* Billing + Term. Without its floor the billing select clips to "Mon…". */
.pe-col-billing { width: 120px; }
.pe-col-billing .pe-input { width: 100%; min-width: 96px; padding: 6px 4px; font-size: var(--md-sys-typescale-body-small-size); }
.pe-col-term    { width: 86px; }
.pe-col-term .pe-input--num { min-width: 46px; }
.pe-term-cell   { display: flex; align-items: center; gap: 4px; justify-content: flex-end; }
.pe-term-x      { color: var(--md-sys-color-on-surface-variant); font-size: var(--md-sys-typescale-label-small-size); }
/* The per-period suffix on a rate — "61 /mo". Without it a monthly rate reads
   as the whole contract, which is the single likeliest misreading here. */
.pe-suffix      { font-size: var(--md-sys-typescale-label-small-size); color: var(--md-sys-color-on-surface-variant); white-space: nowrap; }
.pe-col-amount  { width: 110px; font-weight: 600; }
.pe-col-actions { width: 28px; text-align: center; padding-inline: 2px; }
/* The one genuinely new control on Settings -> Subscriptions: a count beside a
   period, which no existing settings screen needed. Everything else on that
   page reuses .card / .form-group / .revenue-settings__*. */
.sub-settings__inline { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.sub-settings__inline input { width: 96px; }
.sub-settings__inline select { min-width: 140px; }

.dd-recurring {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 18px;
  margin-top: 8px; padding: 8px 10px;
  border-radius: var(--md-sys-shape-corner-small);
  background: var(--md-sys-color-tertiary-container);
  color: var(--md-sys-color-on-tertiary-container);
}
.dd-recurring__item { display: flex; align-items: baseline; gap: 6px; }
.dd-recurring__item span { font-size: var(--md-sys-typescale-label-small-size); letter-spacing: .5px; opacity: .85; }
.dd-recurring__item b { font-variant-numeric: tabular-nums; font-size: var(--md-sys-typescale-body-dense-size); }
.dd-recurring__note { font-size: var(--md-sys-typescale-label-small-size); opacity: .85; flex-basis: 100%; }
/* "/mo" beside a rate on the deal card, same job as .pe-suffix in the editor. */
.dd-product__period { font-size: var(--md-sys-typescale-label-small-size); color: var(--md-sys-color-on-surface-variant); }
.dd-product__term   { font-size: var(--md-sys-typescale-label-small-size); color: var(--md-sys-color-on-surface-variant); }

.pe-recurring {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 8px 24px; margin-top: 10px; padding: 10px 12px;
  border-radius: var(--md-sys-shape-corner-small);
  background: var(--md-sys-color-tertiary-container);
  color: var(--md-sys-color-on-tertiary-container);
}
.pe-recurring__item  { display: flex; align-items: baseline; gap: 6px; }
.pe-recurring__label { font-size: var(--md-sys-typescale-label-small-size); letter-spacing: .5px; opacity: .85; }
.pe-recurring__item b { font-variant-numeric: tabular-nums; font-size: var(--md-sys-typescale-body-large-size); }
.pe-recurring__note  { font-size: var(--md-sys-typescale-label-small-size); opacity: .85; margin-inline-start: auto; max-width: 42ch; }
@media (max-width: 767px) {
  .pe-recurring__note { margin-inline-start: 0; }
}
.pe-input--num  { text-align: end; width: 100%; }
.pe-input--unit { width: 52px; padding: 6px 4px; }
/* Source dropdown beside the price, not stacked above it — that stacking was
   what made every row 76px tall, so only one row ever fit on a short window.
   The amount input is pinned so the remaining width goes to the source label,
   which otherwise truncates to "Sales…". */
.pe-price-cell { display: flex; flex-direction: row; align-items: center; gap: 4px; }
.pe-price-source { flex: 1 1 auto; min-width: 0; max-width: 92px; padding: 4px 6px; font-size: var(--md-sys-typescale-label-small-size); }
.pe-price-cell .pe-input--num { flex: 0 0 74px; width: 74px; }

/* ── Sticky first-column for list tables ────────────────────────────────
   Tables tagged with .list-table keep their identity column (and bulk-
   select checkbox) visible during horizontal scroll. The existing ≤767px
   mobile rule hides non-essential columns, so sticky has no visible effect
   on phones (no overflow → no scroll). :has() degrades to non-sticky on
   browsers that don't support it. */
.list-table th[data-col-key="name"],
.list-table td[data-col-key="name"],
.list-table th[data-col-key="title"],
.list-table td[data-col-key="title"],
.list-table th.checkbox-cell,
.list-table td.checkbox-cell {
  position: sticky;
  inset-inline-start: 0;
  z-index: 2;
}
.list-table tbody td[data-col-key="name"],
.list-table tbody td[data-col-key="title"],
.list-table tbody td.checkbox-cell {
  background: var(--color-surface-container-lowest);
}
.list-table tbody tr:hover td[data-col-key="name"],
.list-table tbody tr:hover td[data-col-key="title"],
.list-table tbody tr:hover td.checkbox-cell {
  background: var(--color-surface-container-low);
}
.list-table thead th[data-col-key="name"],
.list-table thead th[data-col-key="title"],
.list-table thead th.checkbox-cell {
  z-index: 3;
  background: var(--color-surface-container-low);
}
.list-table:has(.checkbox-cell) th[data-col-key="name"],
.list-table:has(.checkbox-cell) td[data-col-key="name"],
.list-table:has(.checkbox-cell) th[data-col-key="title"],
.list-table:has(.checkbox-cell) td[data-col-key="title"] {
  inset-inline-start: 40px;
}

/* Let long unbroken text (URLs, emails, addresses) wrap as a last resort
   so a single wide value doesn't force its column to consume the row. */
.list-table td { overflow-wrap: break-word; }

/* Headers stay on one line so columns can't shrink below their natural
   width. When that pushes the table past the wrapper, .pe-table-wrap
   scrolls horizontally and the sticky first column keeps context. */
.list-table th { white-space: nowrap; }

.pe-product-cell { position: relative; }
.pe-product-menu {
  position: fixed;
  min-width: 260px; max-height: 240px; overflow-y: auto;
  z-index: 9999;
}
.pe-product-opt { padding: 8px 10px; cursor: pointer; }
.pe-product-opt:hover { background: var(--color-surface-container-low); }
.pe-product-opt__name { font-weight: 600; font-size: var(--md-sys-typescale-body-dense-size); }
.pe-product-opt__meta { margin-top: 2px; }

.pe-discount-cell { display: flex; gap: 4px; align-items: center; }

.pe-icon-btn {
  background: none; border: none;
  padding: 4px 6px; cursor: pointer;
  border-radius: var(--md-sys-shape-corner-full);
  color: var(--color-on-surface-var);
  font-size: 14px;
  display: inline-flex; align-items: center;
}
.pe-icon-btn .material-symbols-outlined { font-size: 20px; }
.pe-icon-btn:hover { background: var(--color-surface-container-low); color: var(--color-error); }

.pe-footer__sep { opacity: .45; }

/* Totals as one strip, not a stacked table. The stacked version cost ~150px of
   height and left the whole left half of the modal empty; this spends that empty
   width instead and hands the height to the table. */
/* nowrap keeps TOTAL parked on the right of the first line; only the left-hand
   items reflow among themselves when cramped. Letting the whole row wrap put
   TOTAL on a line of its own and cost 37px for the sake of 19px of overflow. */
.pe-footer {
  display: flex; align-items: baseline; justify-content: space-between;
  flex-wrap: nowrap;
  gap: var(--space-2);
  flex-shrink: 0;
  padding-top: var(--space-2);
  border-top: 1px solid var(--color-outline-variant);
}
.pe-footer__items {
  display: flex; align-items: center; flex-wrap: wrap;
  flex: 1 1 auto; min-width: 0;
  gap: var(--space-2) 12px;
}
/* Sentence case, no letter-spacing: the old uppercase treatment cost ~10% width
   per label, which is what forced the strip onto extra lines.
   inline-flex is what `style.display = ""` falls back to when recomputeTotals()
   un-hides the tax item, so don't change this to block. */
.pe-footer__item {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--md-sys-typescale-body-small-size); color: var(--color-on-surface-var);
  white-space: nowrap;
}
.pe-footer__item b {
  font-size: var(--md-sys-typescale-body-dense-size); font-weight: 600; color: var(--color-on-surface);
}
.pe-footer__total {
  display: inline-flex; align-items: baseline; gap: var(--space-2);
  font-size: var(--md-sys-typescale-body-small-size); font-weight: 600; color: var(--color-on-surface-var);
  letter-spacing: .5px; white-space: nowrap;
  margin-inline-start: auto;
}
.pe-footer__total strong {
  font-size: var(--md-sys-typescale-title-large-size); font-weight: 700; color: var(--color-primary);
  letter-spacing: 0;
}
.pe-input--disc { width: 56px; }

/* ── Pipeline toolbar (search + chips above kanban/list/timeline) ─────────── */
/* The same row every list page carries, but this one is not inside the card of
   a table — the board below it is three columns, not one surface — so it wears
   the card itself and keeps the gap that would otherwise be the card's edge. */
.pipeline-toolbar {
  background: var(--color-surface-container-lowest);
  border-bottom: none;
  border-radius: var(--radius-m);
  box-shadow: var(--shadow-1);
  margin-bottom: var(--space-2);
  /* Inline padding matches the KPI bar above, so the two line up at the edge. */
  padding: var(--space-3);
}

/* ── Sort dropdown ──────────────────────────────────────────────────── */
.sort-dropdown { position: relative; }
.sort-dropdown__trigger {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 6px 12px;
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-pill);
  background: var(--color-surface-container-lowest);
  color: var(--color-on-surface-var);
  font-size: var(--md-sys-typescale-body-small-size); font-weight: 600; font-family: inherit;
  cursor: pointer; white-space: nowrap;
  transition: background .15s, border-color .15s;
}
.sort-dropdown__trigger .material-symbols-outlined { font-size: 15px; }
.sort-dropdown__trigger:hover {
  background: var(--color-surface-container);
  color: var(--color-on-surface);
}
.sort-dropdown__menu {
  display: none; position: absolute;
  top: calc(100% + 6px); inset-inline-end: 0;
  min-width: 180px;
  z-index: 50; padding: 4px 0;
}
.sort-dropdown__menu.open { display: block; }
.sort-dropdown__item {
  display: flex; align-items: center; gap: 8px;
  width: 100%; padding: 8px 14px;
  border: none; background: transparent;
  color: var(--color-on-surface-var);
  font-size: var(--md-sys-typescale-body-dense-size); font-family: inherit;
  cursor: pointer; text-align: left;
  transition: background .1s;
}
.sort-dropdown__item:hover {
  background: var(--color-surface-container-low);
  color: var(--color-on-surface);
}
.sort-dropdown__check { font-size: var(--md-sys-typescale-body-large-size); visibility: hidden; }
.sort-dropdown__item.active { color: var(--color-primary); font-weight: 600; }
.sort-dropdown__item.active .sort-dropdown__check { visibility: visible; color: var(--color-primary); }

/* ── Pipeline LIST view ──────────────────────────────────────────────────── */
/* The board's container, renamed in list mode (deals.js drops `.kanban`). The
   full-height desktop shell keyed only on `.kanban`, so switching to the list
   switched the shell off: the container grew to the length of the table and
   the page scrolled as a whole, taking the count and the page controls down
   below the last row. It now fills the space under the toolbar the way the
   board does, and the ledger card inside scrolls the table while its footer
   stays put — the Organizations shape. Phones keep the page scroller. */
.pipeline-list-wrap { display: block; height: auto; }
@media (min-width: 768px) {
  .view:has(> .pipeline-list-wrap) > .pipeline-list-wrap {
    flex: 1 1 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
  }
}
.deals-table tbody tr:hover { background: var(--color-surface-container-low); }
.deals-table .tag { white-space: nowrap; }

/* ── Pipeline TIMELINE view (Pipedrive-style week columns) ────────────────── */
.pipeline-timeline {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  overflow: visible;
}
.pl-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  background: var(--color-surface-container-lowest);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-m);
  flex-wrap: wrap;
}
.pl-nav {
  display: flex;
  align-items: center;
  gap: 4px;
}
.pl-summary {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--md-sys-typescale-body-dense-size);
}
.pl-summary strong {
  font-family: var(--font-display);
  font-size: var(--md-sys-typescale-body-large-size);
  color: var(--color-primary);
}
.pl-weeks-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  padding-bottom: var(--space-2);
}
.pl-weeks {
  display: flex;
  gap: var(--space-3);
  min-width: max-content;
}
.pl-week-col {
  width: 280px;
  flex-shrink: 0;
  background: var(--color-surface-container-low);
  border-radius: var(--radius-m);
  padding: var(--space-2);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-height: 200px;
}
.pl-week-header {
  padding: 4px 8px 8px;
  border-bottom: 1px solid var(--color-outline-variant);
}
.pl-week-dates {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--md-sys-typescale-body-dense-size);
  color: var(--color-on-surface);
}
.pl-week-stats {
  font-size: var(--md-sys-typescale-label-small-size);
  color: var(--color-on-surface-var);
  margin-top: 2px;
}
.pl-week-cards {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 80px;
}
.pl-week-empty {
  font-size: var(--md-sys-typescale-body-small-size);
  color: var(--color-on-surface-var);
  text-align: center;
  padding: 24px 8px;
  font-style: italic;
}

/* ═══════════════════════════════════════════════════════════════════════════
   RECORD-PAGE PIECES OUTSIDE THE .dd-* LAYOUT
   The record pages themselves use the .dd-* layout below (_recordLayout.js).
   These remain for the rows that borrow them: the related-row cards.
   ═══════════════════════════════════════════════════════════════════════════ */

.deal-meta-row {
  display:flex; align-items:center; justify-content:space-between;
  padding:5px 0; font-size:var(--md-sys-typescale-body-dense-size);
  border-bottom:1px solid var(--color-surface-container);
}
.deal-meta-row:last-child { border-bottom:none; }
/* A related-deal row is an <a> (_relatedRows.js) so it opens in a new tab. */
a.deal-sidebar-row { align-items:flex-start; gap:6px; color:inherit; text-decoration:none; }
.deal-link { color:var(--color-primary); text-decoration:none; font-size:var(--md-sys-typescale-body-dense-size); }
.deal-link:hover { text-decoration:underline; }

/* Field labels / values */
.field-label { font-size:var(--md-sys-typescale-label-small-size); font-weight:700; letter-spacing:.5px; color:var(--color-on-surface-var); }
.field-value { font-size:var(--md-sys-typescale-body-dense-size); color:var(--color-on-surface); }

/* Inline edit */
.ie-field   { cursor:pointer; border-radius:var(--radius-s); padding:2px; transition:background .15s; }
.ie-field:hover { background:var(--color-surface-container); }
.owner-select {
  appearance: none; -webkit-appearance: none;
  padding: 5px 28px 5px 10px;
  border: 1.5px solid var(--color-surface-container-high);
  border-radius: var(--radius-s);
  font-family: var(--font-body); font-size: var(--md-sys-typescale-body-dense-size); font-weight: 500;
  color: var(--color-on-surface);
  background-color: var(--color-surface-container-lowest);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23666' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 8px center;
  cursor: pointer;
  outline: none;
  transition: border-color .15s, box-shadow .15s;
}
.owner-select:hover  { border-color: var(--color-primary-container); }
.owner-select:focus  { border-color: var(--color-primary-container); box-shadow: 0 0 0 3px color-mix(in srgb, var(--md-sys-color-primary) 12%, transparent); }

.org-search-row:hover,
/* Keyboard focus looks the same as hover: the arrow keys are moving the same
   highlight the mouse does, and two visual languages for one selection reads
   as two selections. */
.org-search-row.is-active { background: var(--color-surface-container); }

/* ── Saved Views Dropdown ─────────────────────────────────────────────── */
.saved-views-wrap { display: flex; align-items: center; }
.saved-views-dropdown {
  position: absolute; top: 100%; right: 0; z-index: 50;
  min-width: 240px; max-height: 320px; overflow-y: auto;
  margin-top: 4px;
}
.saved-view-item {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 14px; cursor: pointer; font-size: var(--md-sys-typescale-body-dense-size);
  color: var(--color-on-surface); transition: background .15s;
}
.saved-view-item:hover { background: var(--color-surface-container-high); }
.saved-view-del {
  background: none; border: none; cursor: pointer; padding: 2px;
  color: var(--color-on-surface-var); border-radius: var(--radius-s);
}
.saved-view-del:hover { color: var(--color-error); background: var(--color-surface-container-high); }

/* ── Settings tabs ───────────────────────────────────────────────────────── */
/* Wrap to multiple rows on narrow viewports instead of horizontal scroll —
   scroll hides the rightmost tabs (e.g. "API Keys") with no visible cue.
   The row-gap keeps wrapped rows visually separated; the bottom border on
   each tab replaces the strip-level border so wrapping doesn't double up. */
.settings-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  row-gap: 0;
  margin-bottom: var(--space-4);
  border-bottom: 1px solid var(--color-outline-variant);
}
.settings-tab__btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 48px;
  padding: 0 16px;
  border: none;
  background: transparent;
  color: var(--color-on-surface-var);
  font-size: var(--md-sys-typescale-title-small-size);
  font-weight: var(--md-sys-typescale-title-small-weight);
  letter-spacing: var(--md-sys-typescale-title-small-tracking);
  font-family: inherit;
  cursor: pointer;
  border-bottom: 3px solid transparent;
  white-space: nowrap;
  transition: color 0.15s, border-color 0.15s;
}
.settings-tab__btn .material-symbols-outlined { font-size: 18px; }
.settings-tab__btn:hover { color: var(--color-on-surface); }
.settings-tab__btn.active {
  color: var(--color-primary);
  /* MD3 primary tab indicator: 3px in primary. primary-container (#cde5ff)
     was all but invisible against a white surface. */
  border-bottom-color: var(--md-sys-color-primary);
}

/* ── Settings — grouped section nav ───────────────────────────────────────
   Distinct from `.settings-tabs` above, which despite its name is the shared
   horizontal strip used by emails.js and the report modal. The
   Settings *page* stopped using it: seventeen tabs wrapped to three rows on a
   desktop and six to nine on a phone, where they cost 200–310px before any
   content. Nothing below may reach back into those classes. */
.settings-layout {
  display: grid;
  grid-template-columns: 264px minmax(0, 1fr);
  gap: var(--space-3);
  align-items: start;
}
/* Five of the nine roles can see exactly one section, and a sidebar listing
   the page you are already on is noise. Same reasoning as `.pe-tabs` collapsing
   at `:only-child`, but counted in JS because `:has()` cannot count across the
   interleaved group headings. */
.settings-layout--solo { grid-template-columns: minmax(0, 1fr); }

.settings-nav {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: var(--space-2);
  background: var(--color-surface-container-low);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-l);
  /* All 22 rows are ~831px, taller than the scrollport on anything under a
     ~887px-high window, which put the Data group out of reach on a 1280x720.
     The desktop block below stretches this column to the full height of the
     view, so it scrolls itself instead of pinning and spilling past the fold —
     no `max-height` guess that has to re-derive the top bar, the view padding
     and the demo banner. On a phone the drill-in resets it to visible. */
  overflow-y: auto;
}

.settings-nav__group {
  margin: 0;                       /* <h2> UA default */
  padding: 12px 12px 4px;
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--color-on-surface-var);
}
.settings-nav__group:first-child { padding-top: 4px; }

.settings-nav__item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 9px 12px;
  border-radius: var(--radius-pill);
  font-size: var(--md-sys-typescale-body-dense-size);
  font-weight: 500;
  text-align: start;
  text-decoration: none;
  color: var(--color-on-surface-var);
  cursor: pointer;
}
.settings-nav__item .material-symbols-outlined { font-size: 18px; flex-shrink: 0; }
.settings-nav__label { flex: 1; min-width: 0; }
/* Drill-in affordance — mobile only, where tapping a row replaces the screen. */
.settings-nav__chevron { display: none; }
.settings-nav__item[aria-current="page"] {
  background: var(--color-secondary-container);
  color: var(--color-on-secondary-container);
  font-weight: 600;
}
.settings-pane { min-width: 0; }
/* The back row belongs to the phone's drill-in; on a desktop both panes are
   on screen at once and the nav already says where you are. */
.settings-pane__head { display: none; }

/* ── Settings: full-height desktop shell ──────────────────────────────────
   Same contract as `.view:has(> .ledger-card)` at the top of this file: the
   view stops being the scroller, `.page-header` stays put as a flex sibling,
   and the two settings columns scroll inside themselves. The deals board
   shares it; its columns scroll the same way. Without it the grid
   was sized by its own content (`align-items: start`), so every section
   shorter than the window — API keys, currency, tags — left a dead band
   between the last card and the bottom of the screen.

   Desktop only, on purpose. Below 768px the page itself is the scroller: the
   mobile block gives `.view` bottom-nav padding, and the drill-in hides one
   of the two columns outright. An inner scroller there would trap the page
   scroll. */
@media (min-width: 768px) {
  .view:has(> .settings-layout),
  .view:has(> .kanban),
  .view:has(> .pipeline-list-wrap) {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    min-height: 0;
  }
  /* Same shape as `.dd-body` on the deal page: one row capped at the parent's
     height, so a 22-row nav scrolls inside its column instead of growing the
     track past a `.view` that no longer scrolls. `align-items` overrides the
     `start` above. */
  .settings-layout {
    flex: 1;
    min-height: 0;
    grid-template-rows: minmax(0, 1fr);
    align-items: stretch;
  }
  /* Each column owns its own scrollbar. */
  .settings-nav { min-height: 0; }
  .settings-pane {
    min-height: 0;
    overflow-y: auto;
    /* Reserve the gutter so the card width does not jump when a short section
       (Currency) is swapped for a long one (Edara). No-op under overlay
       scrollbars. Same device as `.sidebar`. */
    scrollbar-gutter: stable;
    /* `overflow-y` forces `overflow-x` to compute to `auto`, so the pane — not
       `.view` — is now the clip box on both axes. `.card` has no border; its
       shadow is the only thing defining its edge, and a full-width card would
       have that shadow cut off flush against both inline edges. */
    padding-inline: var(--space-1);
  }
  /* The view's 24px bottom padding used to sit under the last card; the pane's
     scrollport now ends at the window edge, so the content supplies it. Tab
     modules space cards with `margin-bottom` and put nothing after the last
     one. On the *content*, not the scroll container: end-side padding of a
     scroll container is dropped from the scrollable overflow area in some
     engines, a child's padding never is. */
  #settingsTabContent {
    padding-bottom: var(--space-4);
    /* A column so one card can absorb the slack the pane no longer leaves as
       bare background. `min-height` rather than `height`: a tall section still
       grows past the pane and scrolls. */
    display: flex;
    flex-direction: column;
    min-height: 100%;
  }
  /* Tabs mark the ONE card that should fill — the list or table, which is not
     always the last one (API keys puts "How to use" after it). `:has(> …)`
     promotes whatever bare wrapper the tab happens to put in between, so a
     module opts in by adding a class, not by restructuring its markup.
     `1 0 auto`, never `1`: flex-basis must stay at the content height so a
     card taller than the pane is not shrunk into its own scrollbar. */
  #settingsTabContent :has(> .card--fill) {
    display: flex;
    flex-direction: column;
    flex: 1 0 auto;
    min-height: 0;
  }
  .card--fill { flex: 1 0 auto; min-height: 0; }
}

/* ── Paginated lists outside the ledger pages: pin the footer ─────────────
   Organizations, Contacts, Leads, Activities and Products fill the window and
   scroll the table inside, so "Showing 1–50 of 3038" and the page controls
   never leave the screen. Two more lists printed that footer under their last
   row, so reading the count or turning a page meant scrolling to the bottom
   first. Same shape here, desktop only — phones keep the page scroller the
   ledger pages keep, where an inner box would leave too little room to read.
   Still one scrollbar: the outer box stops scrolling as the inner one starts.

   Tasks, with one bucket open (the five-bucket overview has no pagination). */
@media (min-width: 768px) {
  .view:has(> .tasks-wrap--single) {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    min-height: 0;
  }
  .tasks-wrap--single { flex: 1 1 0; min-height: 0; display: flex; flex-direction: column; }
  .tasks-wrap--single > * { flex-shrink: 0; }
  .tasks-wrap--single > .tasks-bucket {
    flex: 1 1 0; min-height: 0; display: flex; flex-direction: column;
  }
  .tasks-wrap--single > .tasks-bucket > .tasks-list { flex: 1 1 0; min-height: 0; overflow-y: auto; }

  /* Settings → Trash. Settings lets a card grow and scrolls the whole pane
     (`.card--fill`, deliberately never shrunk into its own scrollbar) — right
     for a form, wrong for a list whose footer is the point. Trash only. */
  /* The card and its scroller are the ledger's own; only the chain from the
     pane down to them is Trash's, since Trash is not a direct child of .view. */
  .settings-pane:has(> #settingsTabContent > .trash-shell) {
    overflow: hidden; display: flex; flex-direction: column;
  }
  .settings-pane:has(> #settingsTabContent > .trash-shell) > #settingsTabContent {
    flex: 1 1 0; min-height: 0;
  }
  .trash-shell { flex: 1 1 0; min-height: 0; display: flex; flex-direction: column; }
  .trash-shell > #trashList { flex: 1 1 0; min-height: 0; display: flex; flex-direction: column; }
}

/* ── Edara settings tab — hero + entities + advanced ──────────────────────── */
.edara-entities .data-table th,
.edara-entities .data-table td { vertical-align: middle; padding: 8px 10px; }

/* Chevron rotation is applied inline by the settings.js toggle listener — no
   reliable :open styling across our supported browsers without that hook. */
.edara-advanced > summary { user-select: none; }
.edara-advanced > summary::-webkit-details-marker { display: none; }
.edara-advanced > summary::marker { content: ""; }

@media (max-width: 480px) {
  /* On phones the target ("→ Organizations") and last-sync columns crowd
     the count column. Hide them — the per-entity tap can still reach detail
     pages elsewhere, and a relative timestamp lives in the hero card. */
  .edara-entities__target,
  .edara-entities__lastsync { display: none; }
  .edara-entities .data-table th,
  .edara-entities .data-table td { padding: 8px 6px; }
}

/* ── Industry tags ────────────────────────────────────────────────────────── */
.ind-tag {
  display: inline-block;
  padding: 2px 10px;
  border-radius: var(--radius-pill);
  font-size: var(--md-sys-typescale-body-small-size);
  font-weight: 600;
  background: var(--color-surface-container);
  color: var(--color-on-surface-var);
}
/* Industry tags on MD3 container / on-container pairs, so each reads in both
   themes (the old hex pairs had no dark values, and four fell below AA). */
.ind-tag--tech,
.ind-tag--saas       { background: var(--md-sys-color-primary-container);   color: var(--md-sys-color-on-primary-container); }
.ind-tag--finance,
.ind-tag--fintech    { background: var(--md-sys-color-success-container);   color: var(--md-sys-color-on-success-container); }
.ind-tag--health,
.ind-tag--ecommerce  { background: var(--md-sys-color-error-container);     color: var(--md-sys-color-on-error-container); }
.ind-tag--mfg        { background: var(--md-sys-color-warning-container);   color: var(--md-sys-color-on-warning-container); }
.ind-tag--retail     { background: var(--chip-negotiation-bg);      color: var(--chip-negotiation-text); }
.ind-tag--realestate,
.ind-tag--edu        { background: var(--md-sys-color-tertiary-container);  color: var(--md-sys-color-on-tertiary-container); }
.ind-tag--media      { background: var(--md-sys-color-secondary-container); color: var(--md-sys-color-on-secondary-container); }
.ind-tag--logistics,
.ind-tag--aerospace,
.ind-tag--other      { background: var(--md-sys-color-surface-container-highest); color: var(--md-sys-color-on-surface-variant); }

/* ── Open deals cell ──────────────────────────────────────────────────────── */
.open-deals-cell {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--color-on-surface-var);
}
.open-deals-cell .material-symbols-outlined { font-size: 16px; color: var(--color-gold); }
.open-deals-cell span[style] { color: var(--color-on-surface); }

/* ═══════════════════════════════════════════════════════════════════════════
   MOBILE  —  full responsive layout for screens < 768px
   ═══════════════════════════════════════════════════════════════════════════ */

/* The hamburger is an MD3 standard icon button at every width: on a phone it
   opens the drawer, on desktop it toggles the rail. */
.hamburger-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  color: var(--color-on-surface);
  cursor: pointer;
  padding: 8px;
  border-radius: var(--md-sys-shape-corner-full);
  margin-inline-end: 4px;
  flex-shrink: 0;
}
.hamburger-btn .material-symbols-outlined { font-size: 24px; }

/* Desktop: no bottom nav and no drawer backdrop. */
@media (min-width: 768px) {
  .bottom-nav     { display: none !important; }
  .sidebar-backdrop { display: none !important; }
}

@media (max-width: 767px) {

  /* ── Top bar ──────────────────────────────────────────────────────────── */
  .top-bar { padding: 0 var(--space-2); gap: var(--space-1); }
  .top-bar__logo-text { display: none; }
  .top-bar__logo-sep { display: none; }
  .top-bar__logo-img { height: 18px; }
  .top-bar__center { flex: 1; min-width: 0; padding: 0 var(--space-1); }
  /* Search pill collapses to icon-only on mobile */
  .search-pill { width: auto; max-width: none; padding: 6px; }
  .search-pill__text { display: none; }
  .search-pill__kbd  { display: none; }
  .pipeline-select-wrap select { font-size: var(--md-sys-typescale-body-small-size); padding-block: 5px; padding-inline: 10px 30px; min-width: 100px; }
  /* The bell stays; What's New moves into the account menu, so the bar keeps
     Material 3's two trailing icons beside the avatar (Yahia, 2026-10-25). */
  .top-bar__actions .header-wn-slot { display: none; }

  /* ── Sidebar: slide-in drawer ─────────────────────────────────────────── */
  .sidebar {
    position: fixed;
    top: var(--md-top-app-bar-h);
    left: 0;
    bottom: 0;
    z-index: 250;
    width: 280px;
    transform: translateX(-100%);
    transition: transform var(--md-sys-motion-duration-medium2) var(--md-sys-motion-easing-emphasized);
    /* MD3 modal navigation drawer: large corners on the trailing edge. */
    border-start-end-radius: var(--md-sys-shape-corner-large);
    border-end-end-radius: var(--md-sys-shape-corner-large);
    box-shadow: var(--md-sys-elevation-1);
  }
  .sidebar--open { transform: translateX(0); }

  /* ── Backdrop ─────────────────────────────────────────────────────────── */
  .sidebar-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 240;
    background: color-mix(in srgb, var(--md-sys-color-scrim) 32%, transparent);
  }
  .sidebar-backdrop--visible { display: block; }

  /* ── Layout ───────────────────────────────────────────────────────────── */
  /* overflow: hidden on .layout is critical: it clamps .view to the height
     left under the top bar and any banner, so .view's overflow-y: auto can
     actually create a scroll container. With overflow: visible the flex item
     stretches to its content height and scroll silently breaks. */
  .layout { position: relative; }
  .view {
    --view-pad-block: var(--space-3);
    --view-pad-inline: var(--space-2);
    /* Extra bottom padding so content isn't hidden behind bottom nav + iOS home indicator */
    padding-bottom: calc(var(--md-nav-bar-h) + 4px + var(--view-pad-block) + env(safe-area-inset-bottom, 0px));
    /* No min-height: the flex stretch already fills what .layout gets, so a
       short page still reaches the bottom of the screen. A `100dvh - 56px`
       floor counted the top bar only; with a banner above it, .view grew
       past .layout and its end was clipped under the bottom nav. */
  }

  /* ── Bottom tab bar ───────────────────────────────────────────────────── */
  /* MD3 navigation bar: 80px on surface-container; the active destination's
     icon sits in a 64×32 secondary-container pill above a label-medium label. */
  .bottom-nav {
    display: flex;
    position: fixed;
    bottom: 0; left: 0; right: 0;
    z-index: 200;
    background: var(--md-sys-color-surface-container);
    height: calc(var(--md-nav-bar-h) + env(safe-area-inset-bottom, 0px));
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  .bottom-nav__item {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    min-width: 0;
    text-decoration: none;
    color: var(--md-sys-color-on-surface-variant);
    font-size: var(--md-sys-typescale-label-medium-size);
    line-height: var(--md-sys-typescale-label-medium-line);
    font-weight: var(--md-sys-typescale-label-medium-weight);
    letter-spacing: var(--md-sys-typescale-label-medium-tracking);
    padding: 12px 0 16px;
    -webkit-tap-highlight-color: transparent;
  }
  .bottom-nav__item .material-symbols-outlined {
    display: grid;
    place-items: center;
    width: 64px;
    height: 32px;
    font-size: 24px;
    border-radius: var(--md-sys-shape-corner-full);
    transition: background var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard);
  }
  .bottom-nav__item.active { color: var(--md-sys-color-on-surface); font-weight: 600; }
  .bottom-nav__item.active .material-symbols-outlined {
    background: var(--md-sys-color-secondary-container);
    color: var(--md-sys-color-on-secondary-container);
  }
  /* The item is also a .nav-item; the indicator is the icon pill, not it. */
  .bottom-nav__item { background: transparent !important; border-radius: 0 !important; min-height: 0; }

  /* ── Page header: stack on mobile ─────────────────────────────────────── */
  .page-header {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-2);
    margin-bottom: var(--space-3);
  }
  .page-header-info > h1 { font-size: var(--md-sys-typescale-title-large-size); line-height: 1.2; }
  .page-actions { width: 100%; justify-content: flex-end; }
  /* Not .btn--icon: it has no label to pad around, and keeps its own 7px. */
  .page-actions .btn:not(.btn--icon) { font-size: 13px; padding: 7px 12px; }

  /* ── Ledger pages: let the whole view scroll on mobile ────────────────── */
  /* Desktop traps scroll inside .ledger-scroll so the toolbar stays sticky.
     On a phone the page-header + toolbar consume so much vertical space the
     inner area is unusable, AND .view's overflow:hidden then blocks the user
     from scrolling the page itself. Undo the trap on mobile. */
  .view:has(> .ledger-card, > .leads-list > .ledger-card) {
    overflow-y: auto;
    overflow-x: hidden;
  }
  .ledger-card { flex: 0 0 auto; }
  .ledger-card > .ledger-body { overflow: visible; }
  .ledger-scroll { overflow-x: auto; }

  /* ── Tables: hide non-essential columns on mobile ─────────────────────────
     Use [data-col-key="X"] for column-picker tables (orgs/contacts/deals) so
     the rule survives bulk-select checkbox prepending AND user column reorder.
     Static-HTML tables (products) still use nth-child but adjusted for the
     prepended checkbox column. */

  /* Organizations — keep "name" + "open_deals"; hide all other data columns */
  .orgs-table th[data-col-key]:not([data-col-key="name"]):not([data-col-key="open_deals"]),
  .orgs-table td[data-col-key]:not([data-col-key="name"]):not([data-col-key="open_deals"]) { display: none; }

  /* Contacts — keep "name" + "company"; hide all other data columns */
  .contacts-table th[data-col-key]:not([data-col-key="name"]):not([data-col-key="company"]),
  .contacts-table td[data-col-key]:not([data-col-key="name"]):not([data-col-key="company"]) { display: none; }

  /* Products (static <th>/<td>, no column picker; bulk-select prepends a
     checkbox at nth-child(1) so all data-column indices are +1):
     Keep Name(2) + Unit Price(6). Hide SKU(3), Type(4), Category(5),
     Source(7), Status(8). */
  .products-table th:nth-child(3),
  .products-table td:nth-child(3),
  .products-table th:nth-child(4),
  .products-table td:nth-child(4),
  .products-table th:nth-child(5),
  .products-table td:nth-child(5),
  .products-table th:nth-child(n+7),
  .products-table td:nth-child(n+7) { display: none; }

  /* Team table — no bulk-select, keep User(1) + Status(3) + Actions(5). Hide Role(2), Joined(4) */
  .team-table th:nth-child(2),
  .team-table td:nth-child(2),
  .team-table th:nth-child(4),
  .team-table td:nth-child(4) { display: none; }

  /* Deals table — keep "title" + "value" + "status"; hide all other data
     columns. Status earns its place on a phone now that the list can be asked
     for won and lost: without it a closed deal reads exactly like a live one,
     and the column's header filter is where that narrowing is changed. */
  .deals-table th[data-col-key]:not([data-col-key="title"]):not([data-col-key="value"]):not([data-col-key="status"]),
  .deals-table td[data-col-key]:not([data-col-key="title"]):not([data-col-key="value"]):not([data-col-key="status"]) { display: none; }

  /* Timeline — narrower columns + smaller font */
  .pl-week-col { width: 240px; }
  .pl-toolbar { padding: var(--space-2); }
  .pl-summary { font-size: var(--md-sys-typescale-body-small-size); }
  .pl-summary strong { font-size: var(--md-sys-typescale-body-medium-size); }

  /* Team table — icon-only action buttons on mobile, so padded alike on both
     sides (the label padding is for a label). */
  .team-table .action-label { display: none; }
  .team-table .btn:has(.action-label) { padding-inline: 8px; }

  /* Shared tab strip (organization / contact / emails detail pages): the strip
     wraps rather than scrolls, so this only tightens the pills. */
  .settings-tab__btn { font-size: var(--md-sys-typescale-body-dense-size); padding: 8px 12px; }

  /* ── Settings: drill-in — the index list and a section, never both ─────── */
  .settings-layout { grid-template-columns: 1fr; gap: 0; }
  .settings-nav {
    padding: 0;
    background: transparent;
    border: 0;
    border-radius: 0;
    /* The index list is the whole screen here — it scrolls with the page, not
       inside its own box. */
    overflow-y: visible;
  }
  .settings-nav__item {
    padding: 12px;
    min-height: 48px;              /* the wrapped tabs were ~34px */
    border-radius: var(--radius-m);
  }
  .settings-nav__chevron {
    display: inline;
    margin-inline-start: auto;
    font-size: 20px;
    opacity: 0.45;
  }
  /* `data-view` tracks the URL: `#settings` is the index, `#settings/<key>` is
     a section — so the browser's own Back walks out of a pane. */
  .settings-layout[data-view="detail"] .settings-nav  { display: none; }
  .settings-layout[data-view="index"]  .settings-pane { display: none; }

  .settings-pane__head {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-bottom: var(--space-3);
  }
  .settings-pane__title { margin: 0; font-size: var(--md-sys-typescale-body-large-size); font-weight: 600; }

  /* ── Search bar in toolbar ────────────────────────────────────────────── */
  .table-toolbar { flex-wrap: wrap; gap: var(--space-2); padding: var(--space-2); }
  .table-toolbar > .search-bar { width: 100%; max-width: none; }
  .table-toolbar .filter-chips { width: 100%; }

  /* ── Analytics: KPI grid 4→2 cols ────────────────────────────────────── */
  .kpi-grid { grid-template-columns: 1fr 1fr; gap: var(--space-2); }
  .kpi-card__value { font-size: var(--md-sys-typescale-title-large-size); }

  /* Bar chart: shorter on mobile */
  .bar-chart { height: 80px; }
  .bar-chart__label { font-size: var(--md-sys-typescale-label-small-size); }

  /* Donut: stack the donut above the legend */
  .donut-wrap { flex-direction: column; align-items: flex-start; gap: var(--space-3); }

  /* ── Settings: 2-col → 1-col ──────────────────────────────────────────── */

  /* ── Modal: bottom sheet ──────────────────────────────────────────────── */
  .modal-overlay { align-items: flex-end; padding: 0; }
  .modal, .modal--wide {
    width: 100%;
    max-width: 100%;
    max-height: 92vh;
    /* MD3 bottom sheet: extra-large top corners on surface-container-low. */
    background: var(--md-sys-color-surface-container-low);
    border-radius: var(--md-sys-shape-corner-extra-large) var(--md-sys-shape-corner-extra-large) 0 0;
    animation: modal-slide-up var(--md-sys-motion-duration-medium2) var(--md-sys-motion-easing-emphasized-decelerate);
  }
  @keyframes modal-slide-up {
    from { transform: translateY(40px); opacity: 0; }
    to   { transform: translateY(0);    opacity: 1; }
  }
  /* A form dialog fills the screen: Material 3's full-screen dialog, for
     compact screens, "when changes aren't saved instantly". Its top bar is
     close, then the title, then Save as a text button; the header's and the
     footer's own boxes step aside (display: contents) so their buttons share
     that bar, and the footer keeps only what a form put at its start. */
  .modal.modal--form {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-rows: auto minmax(0, 1fr) auto;
    width: 100%; height: 100%; max-height: none; border-radius: 0;
    background: var(--md-sys-color-surface);
    /* Clear of an installed iPhone's status bar and home indicator. */
    padding-block: env(safe-area-inset-top, 0) env(safe-area-inset-bottom, 0);
  }
  .modal.modal--form :is(.modal__header, .modal__actions) { display: contents; }
  .modal.modal--form .modal__header::before { content: none; }
  .modal.modal--form .modal__close { grid-area: 1 / 1; margin-inline-start: var(--space-1); align-self: center; }
  .modal.modal--form .modal__title { grid-area: 1 / 2; align-self: center; padding-block: var(--space-3);
                                     padding-inline: var(--space-1); overflow-wrap: anywhere; }
  .modal.modal--form #modal-primary-btn { grid-area: 1 / 3; align-self: center; margin-inline-end: var(--space-2);
                                          background: none; box-shadow: none; color: var(--color-primary); }
  .modal.modal--form #modal-cancel-btn { display: none; }
  .modal.modal--form .modal__body { grid-area: 2 / 1 / 3 / -1; border-top: 1px solid var(--md-sys-color-outline-variant); }
  .modal.modal--form .modal__actions-start { grid-area: 3 / 1 / 4 / -1; margin: 0; padding: var(--space-3) var(--space-4);
                                             border-top: 1px solid var(--md-sys-color-outline-variant); }
  /* Drag handle affordance */
  .modal__header { position: relative; padding-top: 24px; }
  .modal__header::before {
    content: "";
    position: absolute;
    top: 8px; left: 50%;
    transform: translateX(-50%);
    width: 32px; height: 4px;
    border-radius: 2px;
    background: color-mix(in srgb, var(--md-sys-color-on-surface-variant) 40%, transparent);
  }

  /* ── Stage bar: horizontal scroll ────────────────────────────────────── */

  /* ── Form rows: 2-col → 1-col ─────────────────────────────────────────── */
  .form-row { grid-template-columns: 1fr !important; }

  /* ── Pagination ───────────────────────────────────────────────────────── */
  .pagination-row {
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
  }
  /* Page-number buttons total ~410px on a 390px viewport — let them wrap so
     prev/next + first/last + … reflow into multiple rows instead of clipping. */
  .pagination-row__controls { flex-wrap: wrap; justify-content: center; }
  .pagination-row__per-page { justify-content: space-between; }

  /* ── Prevent iOS zoom on focus: inputs need ≥16px font-size ─────────── */
  .form-group input,
  .form-group select,
  .form-group textarea,
  .field input,
  .field select,
  .drawer-field input,
  .drawer-field select,
  .drawer-field textarea,
  .search-bar input,
  .dd-filter input,
  .ec-input,
  .ec-rte,
  .inline-input,
  .pe-input,
  .col-filter,
  .search-overlay__input-row input { font-size: var(--md-sys-typescale-body-large-size); }

  /* ── Touch targets: ≥44×44 on key controls ────────────────────────── */
  .icon-btn,
  .modal__close,
  .pagination-btn,
  .drawer-close,
  .pe-icon-btn,
  .pe-tab,
  .loc-btn,
  .task-done-btn { min-width: 44px; min-height: 44px; }

  /* ── Modal editor: drop fixed pixel width on mobile ─────────────── */
  /* .modal--editor's desktop min(1100px, 96vw) outranks the bottom-sheet rule
     above, which left the sheet 2vw short on each side. */
  .modal--editor { width: 100% !important; max-width: 100% !important; }
  .pe-root { padding: var(--space-2) var(--space-3) var(--space-3); }
  /* On a phone the control row is the one place stacking is worth the height —
     inline label+select pairs don't fit side by side at 375px. */
  .pe-header { gap: var(--space-2) 12px; }
  .pe-header__group { flex-direction: column; align-items: flex-start; gap: 4px; }
  .pe-header__controls { gap: 12px; }
  .pe-header__actions { width: 100%; justify-content: space-between; }

  /* Right-edge fade so it reads as "columns continue past here", matching
     .kanban. */
  .pe-table-wrap {
    -webkit-mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 24px), transparent);
            mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 24px), transparent);
  }
  [dir="rtl"] .pe-table-wrap {
    -webkit-mask-image: linear-gradient(to left, #000 0, #000 calc(100% - 24px), transparent);
            mask-image: linear-gradient(to left, #000 0, #000 calc(100% - 24px), transparent);
  }
  /* The strip's nowrap items are wider than a phone, which would push a
     horizontal scrollbar onto .pe-root — let them wrap and drop TOTAL onto its
     own full-width line. */
  .pe-footer { flex-wrap: wrap; }
  .pe-footer__item { white-space: normal; }
  .pe-footer__total { width: 100%; justify-content: space-between; margin-inline-start: 0; }
  /* The iOS-zoom guard above pushes .pe-input to 16px, which overflows the
     desktop 56px discount box. */
  .pe-input--disc { width: 64px; }

  /* ── Login card: shrink padding so it doesn't blow out at 320–375px ── */
  .login-wrap { padding: 16px; }
  .login-card { padding: 36px 24px 28px; border-radius: var(--md-sys-shape-corner-large); }
  .login-sub { font-size: var(--md-sys-typescale-body-medium-size); margin-bottom: 24px; }

  /* ── Popovers / dropdowns: cap to viewport ────────────────────── */
  .rh-popover,
  .notification-dropdown,
  .mention-suggest,
  .saved-views-dropdown,
  .pe-product-menu,
  .sort-dropdown__menu { max-width: calc(100vw - 16px); }

  /* ── KPI grid: single column on the smallest screens, two below ───── */
  .pipeline-kpi { gap: var(--space-1) var(--space-3); padding: 4px var(--space-2); }
  .pipeline-kpi__divider { display: none; }

  /* ── Inline-edit hint: always visible on touch (no hover) ──────── */
  .ie-hint { opacity: .7; }

  /* ── Touch tap highlight: remove blue flash globally on mobile ───── */
  a, button, .btn, .nav-item, .filter-chip,
  .view-switcher__btn, .icon-btn,
  .saved-view-item, .pagination-btn { -webkit-tap-highlight-color: transparent; }
}

/* ── Very small screens (≤375px): tighten further ─────────────────────── */
@media (max-width: 375px) {
  .top-bar { padding: 0 var(--space-1); }
  .top-bar__actions { gap: 0; }
  .pipeline-select-wrap select { font-size: var(--md-sys-typescale-label-small-size); min-width: 80px; padding: 5px 22px 5px 8px; }
  .kpi-grid { grid-template-columns: 1fr; }
  .view {
    --view-pad-block: var(--space-2);
    --view-pad-inline: var(--space-2);
  }
  .pe-table { font-size: var(--md-sys-typescale-body-small-size); }
  /* Drop the text label on .page-actions primary buttons; keep the icon. */
  .page-actions .btn--primary { padding: 7px 10px; }
  .page-actions .btn--primary > :not(.material-symbols-outlined) { display: none; }
  .page-actions .btn--primary .material-symbols-outlined { font-size: 18px; }
}

/* ── Mid-breakpoint reflow (≤900px): single-column for inline 2-col grids ──
   Targets pages whose grid-template-columns is set inline (Analytics charts)
   so the sidebar isn't crushed at landscape-phone widths.
   Existing 768px overrides keep these as the canonical mobile rules — this
   block kicks in earlier so a 600–767px viewport doesn't show a 60px sidebar.
   minmax(0, 1fr) prevents grid items with wide content from blowing the track
   past the viewport (1fr alone allows min-content to widen the column). */

/* ═══════════════════════════════════════════════════════════════════════════
   DEAL DETAIL — Pipedrive-style two-column layout (light + dark)
   Uses .dd-* prefix for the new components.
   ═══════════════════════════════════════════════════════════════════════════ */

.dd-page {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--color-surface);
  color: var(--color-on-surface);
  overflow: hidden;
}

/* ── Top bar ─────────────────────────────────────────────────────────────── */
.dd-topbar {
  /* The back arrow's size, which the headline's line and the context line's
     indent follow. */
  --dd-lead: 40px;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4) var(--space-2);
  flex-shrink: 0;
  /* Actions that don't fit beside the title move to their own row rather than
     squeezing it (a quote's seven, an org's pills + Brief at mid widths). */
  flex-wrap: wrap;
}
/* Material 3 app bar: the back arrow is its leading button, on the
   headline's line ("The leading button should be used for navigating… a
   back arrow, which returns to the previous screen"). A context line (a job
   title, a deal's pipeline and stage) sits above, in line with the headline. */
.dd-topbar__left { display: flex; flex-direction: column; gap: 4px; flex: 1 1 320px; min-width: 0; }
.dd-topbar__heading { display: flex; align-items: flex-start; gap: var(--space-2); }
.dd-topbar__titles { flex: 1 1 auto; min-width: 0; }
.dd-breadcrumb--inset { padding-inline-start: calc(var(--dd-lead) + var(--space-2)); }
.dd-topbar__actions {
  display: flex; align-items: center; justify-content: flex-end; flex-wrap: wrap;
  gap: var(--space-2); margin-inline-start: auto;
}

/* As tall as the headline's line (.dd-title-row), so the two centre on each
   other; 48px to touch (M3 icon button target). Also the duplicates review's,
   the lead-form builder's and a phone's settings section's back arrow. */
.dd-back {
  position: relative;
  width: var(--dd-lead, 40px); height: var(--dd-lead, 40px);
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  color: var(--color-on-surface-var);
  background: var(--color-surface-container);
  text-decoration: none;
  flex-shrink: 0;
  transition: background .15s, color .15s;
}
/* A 48px target round a smaller button (M3: "at least 48x48"). */
:is(.dd-back, .dd-title-edit)::before { content: ""; position: absolute; inset: calc((100% - 48px) / 2); }
.dd-back:hover { background: var(--color-surface-container-high); color: var(--color-on-surface); }

.dd-breadcrumb {
  display: flex; align-items: center; gap: 4px;
  font-size: var(--md-sys-typescale-body-small-size); color: var(--color-on-surface-var);
}
/* A context line with nothing to say (no job title yet) takes no room. */
.dd-breadcrumb:has(> .dd-breadcrumb__stage:empty) { display: none; }
/* The <button> the deal's context line starts with (it opens a pipeline
   switcher). `start`-relative layout comes free from flex, so this needs no
   rtl.css override — but the chevron between crumbs does point the wrong way
   without .icon-mirrorable on it. */
.dd-breadcrumb__parent {
  background: none; border: none; padding: 0; margin: 0; cursor: pointer;
  font: inherit; color: var(--color-primary); text-decoration: underline;
  text-underline-offset: 2px;
}
.dd-breadcrumb__stage { color: var(--color-primary); font-weight: 600; }

.dd-title-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; min-height: var(--dd-lead, 40px); }
.dd-title {
  font-family: var(--font-display);
  font-size: var(--md-sys-typescale-headline-small-size);
  font-weight: 700;
  color: var(--color-on-surface);
  margin: 0;
  line-height: 1.2;
}
/* Click-to-edit titles (deal, contact, organization); product, owner and
   quote titles are read-only. */
#dealTitleEl, .ie-field > .dd-title { cursor: pointer; }
#dealTitleEl:hover, .ie-field > .dd-title:hover { color: var(--color-primary); }
.dd-subtitle { font-size: var(--md-sys-typescale-body-dense-size); color: var(--color-on-surface-var); margin-top: 2px; }
/* Contact / organization: the avatar or logo leads the title row, and a
   person's first and last names are two click-to-edit titles side by side. */
.dd-title-row .dd-title-avatar { width: 40px; height: 40px; font-size: var(--md-sys-typescale-body-large-size); flex-shrink: 0; }
.dd-title-row .ie-name-row { display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; min-width: 0; }
.dd-title-input {
  font-family: var(--font-display);
  font-size: var(--md-sys-typescale-headline-small-size);
  font-weight: 700;
  background: var(--color-surface-container);
  color: var(--color-on-surface);
  border: 1.5px solid var(--color-primary-container);
  border-radius: var(--radius-s);
  padding: 4px 10px;
  outline: none;
  width: 100%; max-width: 600px;
}

.dd-status {
  display: inline-flex;
  padding: 3px 10px;
  border-radius: var(--radius-pill);
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: 700;
  letter-spacing: 0.04em;
}
.dd-status--open { background: var(--chip-lead-bg);     color: var(--chip-lead-text); }
.dd-status--won  { background: var(--chip-won-bg);      color: var(--chip-won-text); }
.dd-status--lost { background: var(--chip-lost-bg);     color: var(--chip-lost-text); }

/* ── Stage chevron bar ───────────────────────────────────────────────────── */
.dd-stage-bar-wrap {
  padding: 0 var(--space-4) var(--space-3);
  flex-shrink: 0;
}
.dd-stage-bar {
  display: flex;
  height: 44px;
  border-radius: var(--radius-s);
  overflow: hidden;
  gap: 2px;
}
.dd-stage {
  flex: 1;
  position: relative;
  display: flex; align-items: center; justify-content: center;
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: 700;
  letter-spacing: 0.03em;
  cursor: default;
  transition: filter .15s, transform .15s;
  /* Chevron arrow shape via clip-path */
  clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 50%, calc(100% - 12px) 100%, 0 100%, 12px 50%);
  padding: 0 8px 0 18px;
  min-width: 0;
}
.dd-stage:first-child {
  clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 50%, calc(100% - 12px) 100%, 0 100%);
  padding-left: 14px;
}
.dd-stage:last-child {
  clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%, 12px 50%);
}
.dd-stage[data-move-stage] { cursor: pointer; }
.dd-stage[data-move-stage]:hover { filter: brightness(1.08); transform: translateX(1px); }
.dd-stage__inner {
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  white-space: nowrap; overflow: hidden;
  max-width: 100%;
}
.dd-stage__name {
  text-overflow: ellipsis; overflow: hidden; max-width: 100%;
}
.dd-stage__days {
  font-size: var(--md-sys-typescale-label-small-size); font-weight: 600; opacity: .9; letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}

.dd-stage.past   { background: var(--stage-bar-past);   color: var(--stage-bar-text-past); }
.dd-stage.active { background: var(--stage-bar-active); color: var(--stage-bar-text-active); }
.dd-stage.future { background: var(--stage-bar-future); color: var(--stage-bar-text-future); }
.dd-stage.won    { background: var(--stage-bar-won);    color: #fff; }
.dd-stage.lost   { background: var(--stage-bar-lost);   color: #fff; }

/* ── Body grid ───────────────────────────────────────────────────────────── */
.dd-body {
  display: grid;
  grid-template-columns: 320px minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr);
  gap: var(--space-3);
  padding: 0 var(--space-4) var(--space-4);
  flex: 1;
  min-height: 0;
  overflow: visible;
  align-items: start;
}

/* ── Left sidebar ────────────────────────────────────────────────────────── */
.dd-sidebar {
  display: flex; flex-direction: column;
  gap: var(--space-2);
  background: var(--color-surface-container-low);
  border-radius: var(--radius-l);
  padding: var(--space-3);
  overflow-y: auto;
  /* The row starts its items at the top and lets them grow, so without a cap a
     long column runs off the page with nothing to scroll. */
  max-height: 100%;
  min-width: 0;
}

.dd-filter {
  display: flex; align-items: center; gap: 8px;
  background: var(--color-surface-container-lowest);
  border-radius: var(--radius-m);
  padding: 8px 12px;
  margin-bottom: var(--space-2);
  position: sticky; top: 0;
  z-index: 2;
  flex-shrink: 0;
}
/* Inner input suppresses its outline — show keyboard focus on the wrapper (WCAG 2.4.7). */
.dd-filter:focus-within { box-shadow: 0 0 0 2px var(--color-primary-container); }
.dd-filter .material-symbols-outlined { font-size: 18px; color: var(--color-on-surface-var); }
.dd-filter input {
  flex: 1; background: none; border: none; outline: none;
  font-family: var(--font-body); font-size: var(--md-sys-typescale-body-dense-size);
  color: var(--color-on-surface);
  min-width: 0;
}
.dd-filter input::placeholder { color: var(--color-on-surface-var); }
.dd-filter__clear {
  background: none; border: none; cursor: pointer;
  color: var(--color-on-surface-var);
  font-size: var(--md-sys-typescale-body-large-size); line-height: 1;
  padding: 0 4px;
}
.dd-filter__clear:hover { color: var(--color-on-surface); }

.dd-section {
  background: var(--color-surface-container-lowest);
  border-radius: var(--radius-m);
  overflow: hidden;
  flex-shrink: 0;
}
.dd-section__header {
  display: flex; align-items: center; justify-content: space-between;
  gap: 6px;
  padding: 10px 12px;
}
.dd-section__toggle {
  display: flex; align-items: center; gap: 8px;
  background: none; border: none; cursor: pointer;
  font-family: var(--font-body); font-size: var(--md-sys-typescale-body-dense-size); font-weight: 700;
  color: var(--color-on-surface);
  padding: 0;
  flex: 1;
  text-align: left;
}
.dd-section__chev {
  font-size: 18px;
  color: var(--color-on-surface-var);
  transition: transform .2s;
}
.dd-section:not(.collapsed) .dd-section__chev { transform: rotate(90deg); }
.dd-section__toggle .material-symbols-outlined:not(.dd-section__chev) {
  font-size: 16px; color: var(--color-primary);
}
.dd-section__title { letter-spacing: 0.02em; }
.dd-section__action {
  background: none; border: none; cursor: pointer;
  font-size: var(--md-sys-typescale-body-small-size); font-weight: 600;
  color: var(--color-primary);
  padding: 4px 8px;
  border-radius: var(--radius-s);
}
.dd-section__action:hover { background: var(--color-surface-container); }
/* How many rows a list section holds (a contact's deals, an org's contacts). */
.dd-section__count {
  font-size: var(--md-sys-typescale-body-small-size); font-weight: 600;
  color: var(--color-on-surface-var);
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  background: var(--color-surface-container);
}
/* The org Summary: a rule before the Edara figures, whose order rows are
   buttons that open the Orders tab. */
.dd-summary-divider { border-top: 1px solid var(--color-outline-variant); margin: 2px 0; }
button.dd-row {
  width: 100%;
  background: none; border: 0; border-radius: var(--radius-s);
  font: inherit; color: inherit; text-align: start;
  cursor: pointer;
}
button.dd-row .dd-row__value { color: var(--color-primary); }
button.dd-row:hover .dd-row__value { text-decoration: underline; }

.dd-section__body {
  padding: 4px 12px 14px;
  display: flex; flex-direction: column;
  gap: 8px;
}
.dd-section.collapsed .dd-section__body { display: none; }

.dd-value-card {
  background: var(--color-surface-container);
  border-radius: var(--radius-s);
  padding: 12px;
  margin-bottom: 6px;
}
.dd-value-amount {
  font-family: var(--font-display);
  font-size: var(--md-sys-typescale-headline-medium-size);
  font-weight: 700;
  color: var(--color-primary);
  line-height: 1;
}
.dd-value-label {
  font-size: var(--md-sys-typescale-label-small-size);
  letter-spacing: 0.04em;
  color: var(--color-on-surface-var);
  margin-top: 4px;
}
.dd-value-card--locked { cursor: help; }
.dd-value-card--locked .dd-value-amount { color: var(--color-on-surface-var); }
.dd-value-lock-icon { font-size: 14px; vertical-align: middle; opacity: 0.7; }
.dd-value-discount {
  font-size: var(--md-sys-typescale-label-small-size);
  color: var(--color-on-surface-var);
  margin-top: 6px;
}

.dd-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px;
  padding: 6px 0;
  font-size: var(--md-sys-typescale-body-dense-size);
  border-bottom: none;
  min-width: 0;
}
.dd-row__label {
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: 700;
  letter-spacing: 0.03em;
  color: var(--color-on-surface-var);
  flex-shrink: 0;
}
.dd-row__value {
  display: flex; align-items: center; gap: 6px;
  color: var(--color-on-surface);
  font-weight: 500;
  text-align: right;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.dd-prob-bar {
  display: inline-block;
  width: 60px;
  height: 4px;
  background: var(--color-surface-container-high);
  border-radius: var(--radius-pill);
  overflow: hidden;
}
.dd-prob-bar__fill {
  display: block;
  height: 100%;
  background: var(--color-primary);
  border-radius: var(--radius-pill);
  transition: width .25s;
}
.dd-prob-pct {
  font-size: var(--md-sys-typescale-body-small-size); font-weight: 700;
  color: var(--color-primary);
  min-width: 32px; text-align: right;
}

.dd-link {
  color: var(--color-primary);
  text-decoration: none;
  font-weight: 500;
  overflow: hidden; text-overflow: ellipsis;
}
.dd-link:hover { text-decoration: underline; }

.dd-empty {
  font-size: var(--md-sys-typescale-body-small-size);
  color: var(--color-on-surface-var);
  padding: 8px 0;
  text-align: center;
  font-style: italic;
}

.dd-person {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 14px 16px;
  background: var(--color-surface-container);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-m);
  transition: background .12s, border-color .12s;
}
.dd-person:hover { background: var(--color-surface-container-high); border-color: var(--color-primary-container); }

/* The contact card (contactCardHtml in _relatedRows.js): a header line —
   avatar, editable name, icons — then the field rows below at the card's full
   width, label over value. The fields used to sit beside the icons, which
   left the value column ~70px in the 320px sidebar: less than intl-tel-input's
   flag + dial-code prefix, so the phone editor had nowhere to type. */
.dd-contact {
  display: flex; flex-direction: column; gap: 4px;
  padding: 12px 14px 8px;
  background: var(--color-surface-container);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-m);
  transition: background .12s, border-color .12s;
}
.dd-contact:hover { background: var(--color-surface-container-high); border-color: var(--color-primary-container); }
.dd-contact__head { display: flex; align-items: center; gap: 6px; }
.dd-contact__head .avatar-sm { flex-shrink: 0; }
/* Inline flow, not flex: first and last name wrap at the space between them,
   and a hyphenated surname stays whole. break-word only splits a token that
   cannot fit on a line of its own. */
.dd-contact__name {
  flex: 1; min-width: 0;
  font-size: var(--md-sys-typescale-body-dense-size); font-weight: 600; line-height: 1.35;
  color: var(--color-on-surface);
  overflow-wrap: break-word;
  /* Physical, not `start`: dir="auto" makes an Arabic name resolve RTL, and
     `start` would then push it against the icons instead of the avatar.
     text-align never reorders bidi text, so the name still reads right.
     rtl.css flips this for the Arabic UI. */
  text-align: left;
}
/* Label above value, each on its own line and as wide as the card. */
.dd-contact__info .deal-meta-row {
  flex-direction: column; align-items: stretch; gap: 2px;
  padding: 6px 0;
}
.dd-contact__info .field-value { min-width: 0; overflow-wrap: anywhere; }
/* The three trailing icon buttons on a contact card — the link that opens the
   contact's own record, the star that picks the deal's primary contact, and
   remove (×). Shared base so they stay the same size and sit on the same
   baseline; only the hover colour differs. */
.dd-open-btn,
.dd-remove-btn,
.dd-primary-btn {
  background: none; border: none; cursor: pointer;
  color: var(--color-on-surface-var);
  font-size: var(--md-sys-typescale-body-large-size); line-height: 1;
  padding: 2px 6px;
  border-radius: 50%;
  opacity: .4;
  transition: opacity .15s, color .15s, background .15s;
}
.dd-remove-btn:hover { opacity: 1; color: var(--color-error); background: var(--color-error-container); }

.dd-open-btn,
.dd-primary-btn { display: inline-flex; align-items: center; justify-content: center; }
.dd-open-btn .material-symbols-outlined,
.dd-primary-btn .material-symbols-outlined { font-size: 20px; }
/* Filled `star` when this row is primary, outline `star_outline` otherwise.
   Tertiary, not --color-gold: the brand gold is a FILL, and as a foreground it
   lands at 1.32:1 on a light container. `tertiary` is its tone-40 text variant
   (#785a00 light) and stays brand gold in dark, where that reads. Hover takes
   the matching container pair, the same move .dd-remove-btn makes with
   error/error-bg. */
.dd-primary-btn:hover {
  opacity: 1;
  color: var(--color-on-tertiary-container);
  background: var(--color-tertiary-container);
}
.dd-primary-btn.is-primary { opacity: 1; color: var(--md-sys-color-tertiary); }

/* Opens #contact/{id} on the contact card (.dd-contact, both pages). An anchor rather than a button so the hash router, the
   keyboard and open-in-new-tab all work without JS — and so wireInlineEdit's
   "ignore clicks inside a, button" guard keeps it off the editable fields
   beside it. It shares the star's box above, which puts all three icons on the
   same 24px target. Primary container on hover, the pairing .dd-remove-btn
   takes with error and .dd-primary-btn with tertiary. */
.dd-open-btn { text-decoration: none; }
.dd-open-btn:hover {
  opacity: 1;
  color: var(--color-on-primary-container);
  background: var(--color-primary-container);
}

.dd-org-card__header { align-items: center; margin-bottom: 8px; }
.dd-org-card__name {
  flex: 1; min-width: 0;
  font-size: var(--md-sys-typescale-body-dense-size); font-weight: 600;
  color: var(--color-on-surface);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Merge two leads or deals (_recordMerge.js): both side by side, a radio
   where they differ, the merged result last; on a phone one card per field. */
.rec-merge__info {
  margin: 0 0 var(--space-3); padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-outline-variant); border-radius: var(--radius-m);
  background: var(--color-surface-container-low); color: var(--color-on-surface);
  font-size: var(--md-sys-typescale-body-medium-size);
}
.rec-merge__search { width: 100%; margin-bottom: var(--space-2); }
/* What leaves the reports when a won or lost deal goes to the trash (Yahia,
   2026-10-19): a plain sentence, no alarm (M3 dialogs). */
.rec-merge__left-out { margin: 0 0 var(--space-2); font-size: var(--md-sys-typescale-body-medium-size); }
.rec-merge__results { display: flex; flex-direction: column; gap: 2px; }
.rec-merge__hit {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px; text-align: start;
  padding: var(--space-2); border: none; border-radius: var(--radius-s); background: none; cursor: pointer;
  color: var(--color-on-surface);
}
.rec-merge__hit:hover, .rec-merge__hit.is-active { background: var(--color-surface-container-high); }
.rec-merge__scroll { overflow-x: auto; }
.rec-merge__table { width: 100%; border-collapse: collapse; font-size: var(--md-sys-typescale-body-medium-size); }
.rec-merge__table th, .rec-merge__table td {
  padding: var(--space-2); border-bottom: 1px solid var(--color-outline-variant);
  text-align: start; vertical-align: top;
}
.rec-merge__table tbody th { font-weight: 600; color: var(--color-on-surface-var); white-space: nowrap; }
.rec-merge__table thead th { font-weight: 600; }
.rec-merge__result { background: var(--color-primary-container); color: var(--color-on-primary-container); }
.rec-merge__result hr { border: none; border-top: 1px solid currentColor; opacity: .3; margin: 4px 0; }
.rec-merge__pick { display: flex; align-items: flex-start; gap: 6px; cursor: pointer; }
.rec-merge__pick input { margin-top: 3px; flex: none; }
.rec-merge-modal.modal--wide { width: min(1040px, 96vw); }
/* On a computer the info line, In case of conflict and the column headings
   stay put and only the field rows scroll, so every value keeps the column
   it belongs to in view (Yahia, 2026-10-15). A phone scrolls it all: its
   cards label each value, and pinned headings would leave room for one field. */
@media (min-width: 601px) {
  .rec-merge-modal .modal__body { display: flex; flex-direction: column; overflow: hidden; min-height: 0; }
  .rec-merge-modal #mergeBody { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow-y: auto; }
  .rec-merge__scroll { flex: 1; min-height: 0; overflow: auto; }
  .rec-merge__table thead th {
    position: sticky; top: 0; z-index: 1;
    background: var(--md-sys-color-surface-container-high);
    box-shadow: inset 0 -1px 0 var(--color-outline-variant);   /* a sticky cell drops its collapsed border */
  }
  .rec-merge__table thead th.rec-merge__result { background: var(--color-primary-container); }
}
.rec-merge__note { display: block; margin-top: 2px; }
.rec-merge__keep {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-3);
  margin: 0 0 var(--space-3); padding: var(--space-2) var(--space-3);
  border: none; border-radius: var(--radius-m);
  background: var(--color-warning-bg); color: var(--md-sys-color-on-warning-container);
}
.rec-merge__keep legend { float: inline-start; font-weight: 600; margin-inline-end: var(--space-2); }
.rec-merge__keep label { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
@media (any-pointer: coarse) { .rec-merge__pick, .rec-merge__keep label { min-height: 48px; align-items: center; } }
@media (max-width: 600px) {
  .rec-merge__table thead { display: none; }
  .rec-merge__table tr { display: grid; grid-template-columns: 1fr; border-bottom: 1px solid var(--color-outline-variant); padding: var(--space-2) 0; }
  .rec-merge__table th, .rec-merge__table td { border: none; padding: 2px var(--space-2); }
  .rec-merge__table td[data-label]::before {
    content: attr(data-label); display: block;
    font-size: var(--md-sys-typescale-label-small-size); color: var(--color-on-surface-var);
  }
  .rec-merge__table td.rec-merge__result[data-label]::before { color: inherit; opacity: .8; }
  .rec-merge__keep { flex-direction: column; align-items: flex-start; gap: 0; }
}

/* Choose fields (_cardFields.js): the tune button in a card section's header,
   and a product line's Show all, are .btn--icon.btn--xs; a 48px target on
   touch (Material 3). In a header it keeps the header's height. */
.dd-section__header .card-btn { margin-block: -4px; }
@media (any-pointer: coarse) { .btn--icon.btn--xs.card-btn { width: 48px; height: 48px; } }
/* A step's, a condition's and a rule row's buttons are the same small,
   borderless kind — M3's standard style is "for low-emphasis buttons", and an
   outlined 40px circle outweighed the 14px text beside it (Yahia, 2026-10-27).
   48px to touch, as above. */
@media (any-pointer: coarse) {
  :is(.wf-panel, .wf-rules-table) .btn--icon.btn--xs {
    width: 48px; height: 48px;
  }
}
/* A card's Show all fields (.cf-more) at its foot, close under its last row. */
.dd-contact .cf-more, [data-entity-type="organization"] > .cf-more { margin: 4px 0 0; }
/* A product line's remove, with its Show all under it: the line keeps the
   width it had before it could be opened. */
.dd-product__actions { display: flex; flex-direction: column; align-items: center; gap: 2px; flex-shrink: 0; }
/* A product line's chosen rows under its quantity and price. */
.dd-product__extra {
  display: flex; gap: 6px; align-items: baseline; flex-wrap: wrap;
  font-size: var(--md-sys-typescale-label-small-size); color: var(--color-on-surface-var);
  margin-top: 2px;
}
.dd-product__extra .field-label { font-weight: 600; }
/* The picker: a checkbox row whose label is the whole row's target. */
.cf-pick { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; cursor: pointer; }
.cp-row--hidden .cf-pick:has(input:disabled) { cursor: default; }
.cf-pick__search { width: 100%; margin-bottom: 8px; }
.cf-pick__status { display: flex; justify-content: space-between; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0 0 4px; }
@media (any-pointer: coarse) { .cf-pick { min-height: 48px; } }

.dd-products { display: flex; flex-direction: column; gap: 8px; }
.dd-product {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px;
  background: var(--color-surface-container);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-m);
  transition: background .12s, border-color .12s;
}
.dd-product:hover { background: var(--color-surface-container-high); border-color: var(--color-primary-container); }
.dd-product__main { flex: 1; min-width: 0; }
.dd-product__name {
  font-size: var(--md-sys-typescale-body-small-size); font-weight: 600;
  color: var(--color-on-surface);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* The name opens the product's page; it keeps the look of the text it was. */
a.dd-product__name { display: block; text-decoration: none; }
a.dd-product__name:hover { text-decoration: underline; }
.dd-product__meta {
  font-size: var(--md-sys-typescale-label-small-size); color: var(--color-on-surface-var);
}
.dd-product__totals { text-align: right; flex-shrink: 0; }
.dd-product__tcv {
  font-size: var(--md-sys-typescale-body-small-size); font-weight: 700;
  color: var(--color-primary);
}
.dd-products__total {
  display: flex; justify-content: space-between;
  padding: 6px 8px; font-size: var(--md-sys-typescale-body-small-size);
  color: var(--color-on-surface);
}

/* ── Right area: tabs + quick actions + feed ─────────────────────────────── */
.dd-main {
  display: flex; flex-direction: column;
  background: var(--color-surface-container-lowest);
  border-radius: var(--radius-l);
  height: 100%;
  /* The whole right column scrolls as one unit (not just the feed) — so an
     expanded email composer can't squeeze the activity feed out of reach.
     Mirrors the mobile @media pattern below. The tab bar stays pinned via
     position:sticky so tab-switching works while scrolled. */
  overflow-y: auto;
  overflow-x: hidden;
  min-width: 0;
}

/* Product / owner: the main column holds figure tiles, not a feed. */
.dd-main--plain { padding: var(--space-3); height: auto; max-height: 100%; }
/* A long value (a description) under its label rather than beside it. */
.dd-row--block { flex-direction: column; align-items: stretch; gap: 4px; }
.dd-row--block .dd-row__value { text-align: start; white-space: pre-wrap; overflow: visible; font-weight: 400; }

/* The tab bar: the three view tabs, and the activity-type filter at the end.
   The filter sits beside the tablist, not inside it — a tablist holds tabs. */
.dd-tabbar {
  /* Sized by its own width, not the viewport's: the timeline column is narrow
     at 1024px too, beside the details sidebar. */
  container: dd-tabbar / inline-size;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 8px var(--space-3) 0;
  border-bottom: 1px solid var(--color-surface-container-high);
  flex-shrink: 0;
  /* Pin the tab bar to the top of the scrolling .dd-main column. */
  position: sticky;
  top: 0;
  z-index: 4;
  background: var(--color-surface-container-lowest);
}
.dd-tabs {
  display: flex;
  gap: 4px;
  flex: 1 1 auto;
  min-width: 0;
  align-self: stretch;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.dd-tabs::-webkit-scrollbar { display: none; }

.dd-type-filter { display: flex; align-items: center; gap: 4px; flex-shrink: 0; padding-bottom: 6px; }
.dd-type-filter:empty { display: none; }
.dd-type-filter__btn,
.dd-type-filter__clear {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-height: 32px;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-small);
  background: transparent;
  color: var(--color-on-surface-var);
  font-family: var(--font-body);
  font-size: var(--md-sys-typescale-label-large-size);
  font-weight: var(--md-sys-typescale-label-large-weight);
  white-space: nowrap;
  cursor: pointer;
}
.dd-type-filter__btn { padding: 6px 8px 6px 12px; }
.dd-type-filter__clear { width: 34px; padding: 0; }
.dd-type-filter__btn .material-symbols-outlined,
.dd-type-filter__clear .material-symbols-outlined { font-size: 16px; }
/* A filter is on: an MD3 selected filter chip. */
.dd-type-filter__btn.is-active {
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
  border-color: transparent;
}
/* A narrow bar gives its room to the three tabs. First the filter shrinks to
   one icon button — the picked type's icon, filled, while one is on; its name
   stays in aria-label/title and "All types" in its menu clears it — then,
   phone-narrow, the tabs drop their icons and pack tighter. The Arabic labels
   run longest, so the breakpoints are set by them. */
@container dd-tabbar (max-width: 560px) {
  .dd-type-filter__label,
  .dd-type-filter__caret,
  .dd-type-filter__clear { display: none; }
  .dd-type-filter__btn { width: 40px; min-height: 40px; padding: 0; }
}
@container dd-tabbar (max-width: 400px) {
  .dd-tabs { gap: 0; }
  /* .dd-tabs-qualified to outrank the 768px block's later .dd-tab padding. */
  .dd-tabs .dd-tab { padding-inline: 6px; font-size: var(--md-sys-typescale-body-dense-size); letter-spacing: 0; }
  .dd-tab .material-symbols-outlined { display: none; }
}
/* MD3 primary tabs: 48px, title-small, a 3px primary indicator. */
.dd-tab {
  display: flex; align-items: center; gap: 6px;
  min-height: 48px;
  padding: 0 14px;
  background: none; border: none;
  border-bottom: 3px solid transparent;
  cursor: pointer;
  font-family: var(--font-body);
  font-size: var(--md-sys-typescale-title-small-size);
  font-weight: var(--md-sys-typescale-title-small-weight);
  letter-spacing: var(--md-sys-typescale-title-small-tracking);
  color: var(--color-on-surface-var);
  white-space: nowrap;
  flex-shrink: 0;
  margin-bottom: -1px;
  transition: color .15s, border-color .15s;
}
.dd-tab .material-symbols-outlined { font-size: 18px; }
.dd-tab:hover { color: var(--color-primary); }
.dd-tab.active {
  color: var(--color-primary);
  font-weight: 600;
  border-bottom-color: var(--md-sys-color-primary);
}

/* One line, never scrolled: fitQuickActions() folds what doesn't fit into the
   trailing More button (a sideways scroller with no scrollbar hid them). */
.dd-quick-actions {
  display: flex;
  gap: 8px;
  padding: var(--space-3);
  flex-shrink: 0;
  overflow: hidden;
}
.dd-quick-btn {
  display: flex; align-items: center; gap: 6px;
  padding: 8px 14px;
  background: var(--color-surface-container);
  border: none;
  border-radius: var(--radius-pill);
  cursor: pointer;
  font-family: var(--font-body);
  font-size: var(--md-sys-typescale-body-small-size);
  font-weight: 600;
  color: var(--color-on-surface);
  white-space: nowrap;
  flex-shrink: 0;
  transition: background .15s, color .15s;
}
.dd-quick-btn .material-symbols-outlined { font-size: 16px; color: var(--color-primary); }
.dd-quick-btn:hover {
  background: var(--color-primary);
  color: var(--color-on-primary);
}
.dd-quick-btn:hover .material-symbols-outlined { color: var(--color-on-primary); }
/* Built as `${cssClass}--more` (_activityTypes.js quickActivityButtonsHtml). */
.dd-quick-btn--more {
  background: var(--color-surface-container-lowest);
  box-shadow: inset 0 0 0 1px var(--color-outline-variant);
}

/* Mobile floating action button (add / call / mail). Hidden on desktop —
   the .dd-quick-actions pill row serves there; shown in the mobile @media. */
.dd-fab { display: none; }

.dd-feed {
  /* grow to fill a short column (keeps the empty-state centered) but never
     shrink below content — the whole .dd-main column owns the scroll now. */
  flex: 1 0 auto;
  overflow: visible;
  padding: 0 var(--space-3) var(--space-3);
}

.dd-empty-feed {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 12px;
  padding: 60px 20px;
  color: var(--color-on-surface-var);
  text-align: center;
}
.dd-empty-feed .material-symbols-outlined {
  font-size: 48px;
  opacity: 0.25;
}
.dd-empty-feed p { font-size: var(--md-sys-typescale-body-medium-size); max-width: 300px; }

/* Mobile-only Timeline/Details switch — shown in the ≤768px media block
   below, hidden on desktop. */
.dd-switch { display: none; }

/* ── Unified timeline ────────────────────────────────────────────────────── */
.dd-tl-item {
  position: relative;
  display: flex; align-items: flex-start; gap: 12px;
  padding: 14px 0 14px 0;
}
.dd-tl-stem {
  position: absolute;
  inset-inline-start: 15px; top: 32px; bottom: -14px;
  width: 2px;
  background: var(--color-surface-container-high);
  z-index: 0;
}
.dd-tl-item:last-child .dd-tl-stem { display: none; }
/* Quote rows are links (deal.js renderQuotesTab). */
a.dd-tl-item { color: inherit; text-decoration: none; }
.dd-tl-node {
  width: 32px; height: 32px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  position: relative;
  z-index: 1;
}
.dd-tl-node .material-symbols-outlined { font-size: 16px; }
.dd-tl-node--email   { background: var(--chip-won-bg);         color: var(--chip-won-text); }
.dd-tl-node--history { background: var(--color-surface-container); color: var(--color-on-surface-var); }
.dd-tl-node--note    { background: var(--color-warning-bg); color: var(--md-sys-color-on-warning-container); }

/* ── Notes on a record ───────────────────────────────────────────────────── */
/* The box sits above the timeline: writing a note is the first thing someone
   wants on a record with nothing on it yet. */
.note-composer {
  display: flex; flex-direction: column; gap: var(--space-2);
  padding: var(--space-3); margin-bottom: var(--space-3);
  background: var(--color-surface-container-low);
  border: 1px solid var(--color-outline-variant); border-radius: var(--radius-m);
}
.note-composer textarea, .note-edit-box {
  width: 100%; resize: vertical; min-height: 44px;
  padding: var(--space-2); font: inherit; color: var(--color-on-surface);
  background: var(--color-surface); border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-s);
}
.note-composer__actions { display: flex; gap: var(--space-2); justify-content: flex-end; }
/* A note is prose, so it keeps the line breaks whoever wrote it typed. */
.dd-tl-note-body { white-space: pre-wrap; word-break: break-word; }
.dd-tl-note-actions { display: flex; gap: var(--space-1); margin-top: var(--space-1); }

/* ── Record timeline: Focus above History (_notes.js timelineSectionsHtml) ── */
/* The same cards in two parts: Focus is what is left to do, History what has
   happened. Focus gets its own bordered surface so the two read apart at a
   glance — both sit on the same page background, and the cards inside keep
   theirs (.dd-tl-content). */
.tl-section + .tl-section { margin-top: var(--space-4); }
.tl-section__head {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2);
  padding-block: var(--space-1);
}
.tl-section__title {
  margin: 0;
  font-size: var(--md-sys-typescale-body-dense-size); font-weight: 700; letter-spacing: .3px;
  color: var(--color-on-surface-var);
}
.tl-section__count { font-size: var(--md-sys-typescale-body-dense-size); color: var(--color-on-surface-var); }
/* Same pair as .tasks-due-pill--overdue, so overdue reads alike everywhere. */
.tl-overdue-chip {
  font-size: var(--md-sys-typescale-body-small-size); font-weight: 600;
  padding: 2px 8px; border-radius: var(--radius-pill);
  background: var(--color-error-container); color: var(--color-error);
}
.tl-section--focus {
  padding: var(--space-2) var(--space-3);
  background: var(--color-surface-container-lowest);
  border: 1px solid var(--color-outline-variant);
  border-inline-start: 3px solid var(--color-primary);
  border-radius: var(--radius-m);
}
/* A phone has no width to spare for the frame: keep the border, drop most of
   the inset so the cards inside stay as wide as History's. */
@media (max-width: 768px) {
  .tl-section--focus { padding: var(--space-1) var(--space-2); }
}
/* Lines up under the cards' text: 32px node + 12px gap, less its own padding. */
.tl-focus-more {
  display: inline-flex; align-items: center; gap: 4px;
  min-height: 40px; padding: 0 var(--space-2); margin-inline-start: 36px;
  background: none; border: none; border-radius: var(--radius-pill); cursor: pointer;
  font-family: var(--font-body); font-size: var(--md-sys-typescale-body-dense-size); font-weight: 600;
  color: var(--color-primary);
}
.tl-focus-more:hover { background: var(--color-surface-container); }
.tl-focus-more .material-symbols-outlined { font-size: 18px; }
.tl-focus-empty {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap;
  gap: var(--space-2) var(--space-3);
  padding-block: var(--space-2);
  font-size: var(--md-sys-typescale-body-medium-size); color: var(--color-on-surface-var);
}
.tl-focus-empty p { margin: 0; }
.tl-history-empty {
  margin: 0; padding-block: var(--space-3);
  font-size: var(--md-sys-typescale-body-medium-size); color: var(--color-on-surface-var);
}

.dd-tl-node--create { background: var(--color-success-bg); color: var(--md-sys-color-on-success-container); }
.dd-tl-node--delete,
.dd-tl-node--remove_participant,
.dd-tl-node--remove_product { background: var(--color-error-container); color: var(--color-error); }
.dd-tl-node--add_participant,
.dd-tl-node--add_product { background: var(--color-primary-container); color: var(--color-on-primary-container); }

.dd-tl-content {
  flex: 1; min-width: 0;
  background: var(--color-surface-container-low);
  border-radius: var(--radius-m);
  padding: 10px 12px;
}
/* Email activity card — rich layout inside timeline */
.dd-tl-email-card { padding: 12px 14px; }
.dd-tl-node--email-sent {
  background: var(--color-primary-container);
  color: var(--color-on-primary-container);
}
.dd-tl-email-header {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 8px; margin-bottom: 8px; flex-wrap: wrap;
}
.dd-tl-email-meta { display: flex; align-items: center; gap: 8px; min-width: 0; flex: 1; }
.dd-tl-email-addr {
  font-size: var(--md-sys-typescale-body-dense-size); color: var(--color-on-surface);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dd-tl-email-addr strong { font-weight: 600; }
.dd-tl-email-addr-secondary { font-weight: 400; color: var(--color-on-surface-var); font-size: var(--md-sys-typescale-body-small-size); }
.dd-tl-email-subject { font-size: var(--md-sys-typescale-body-medium-size); font-weight: 600; margin-bottom: 6px; color: var(--color-on-surface); }
.dd-tl-email-snippet {
  font-size: var(--md-sys-typescale-body-dense-size); color: var(--color-on-surface-var); line-height: 1.5;
  overflow: hidden; text-overflow: ellipsis;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.dd-tl-email-expand {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: var(--md-sys-typescale-body-small-size); color: var(--color-primary-text); cursor: pointer;
  padding: 6px 0; margin-top: 2px;
}
.dd-tl-email-expand:hover { text-decoration: underline; }
.dd-tl-email-body-wrap { margin-top: 8px; }
.dd-tl-email-body {
  font-size: var(--md-sys-typescale-body-medium-size); line-height: 1.6; padding: 12px 14px;
  background: var(--color-surface); border-radius: var(--radius-s);
  border: 1px solid var(--color-outline-variant);
  max-height: 400px; overflow-y: auto;
}
.dd-tl-email-body img { max-width: 100%; height: auto; }
.dd-tl-email-loading { font-size: var(--md-sys-typescale-body-dense-size); color: var(--color-on-surface-var); padding: 8px 0; }
.dd-tl-email-actions {
  display: flex; gap: 6px; margin-top: 10px; padding-top: 10px; flex-wrap: wrap;
  border-top: 1px solid var(--color-outline-variant);
}
.dd-tl-email-actions .btn {
  font-size: var(--md-sys-typescale-body-small-size); padding: 4px 12px; gap: 4px;
}
.dd-tl-email-actions .btn .material-symbols-outlined { font-size: 14px; }
.dd-tl-email-attachments {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  margin-top: 8px; padding: 6px 0;
}
.dd-tl-email-attachments > .material-symbols-outlined {
  color: var(--color-on-surface-var); flex-shrink: 0;
}
.dd-tl-attach-chip {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: var(--md-sys-typescale-body-small-size); padding: 4px 10px;
  background: var(--color-surface-container-high);
  color: var(--color-on-surface);
  border-radius: var(--radius-s);
  text-decoration: none;
  border: 1px solid var(--color-outline-variant);
  transition: background .15s;
  max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dd-tl-attach-chip:hover {
  background: var(--color-primary-container);
  color: var(--color-on-primary-container);
}
.dd-tl-attach-size { color: var(--color-on-surface-var); font-size: var(--md-sys-typescale-body-small-size); }
/* The chip is a <button> for CRM attachments (the payload is fetched on click)
   and an <a> for Gmail ones, so neutralise the button chrome. */
button.dd-tl-attach-chip { cursor: pointer; font-family: inherit; }

/* A voice note on an activity: a list item with its play control leading and
   its Download trailing, and the browser's player on a line of its own once it
   opens: beside those buttons, a phone left its track too short to use. */
.att-audio {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0 4px;
  flex: 1 1 100%; min-width: 0; margin-top: 8px; padding-inline: 4px;
  background: var(--color-surface-container-high);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-s);
}
.att-audio__main { flex: 1 1 0; min-width: 0; padding-block: 6px; padding-inline-start: 8px; }
.att-audio__label {
  display: flex; align-items: baseline; gap: 4px; min-width: 0;
  font-size: var(--md-sys-typescale-body-small-size); color: var(--color-on-surface);
}
.att-audio__name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.att-audio__label .dd-tl-attach-size { flex-shrink: 0; }
.att-audio__player { flex: 0 0 100%; min-width: 0; padding-block-end: 6px; }
.att-audio__player:empty { display: none; }
.att-audio__player audio { display: block; width: 100%; height: 40px; }
.att-audio__cant-play { padding-inline: 8px; }
.att-audio > .icon-btn { flex-shrink: 0; color: var(--color-on-surface-var); }
.att-audio > .att-audio__play { color: var(--color-primary); }

/* A URL typed into free text (activity body, note, text custom field). It sits
   inside click-to-edit rows, so it must read as a link and not as the row. */
.text-link {
  color: var(--color-primary);
  text-decoration: underline;
  text-underline-offset: 2px;
  overflow-wrap: anywhere;
}
.text-link:hover { text-decoration-thickness: 2px; }

/* Notes in the activity drawer: the links in the textarea, as chips. */
.dr-body-links { margin-top: 6px; }
.dr-body-links .material-symbols-outlined { font-size: 14px; }

/* Who made the contact, on the activity card. margin-inline-start so it stays
   pinned to the trailing edge in both directions. */
.dd-tl-owner {
  display: inline-flex; align-items: center; gap: 5px;
  margin-inline-start: auto;
}
.dd-tl-owner-name {
  font-size: var(--md-sys-typescale-body-dense-size); color: var(--color-on-surface-var);
  max-width: 120px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dd-tl-contact-link,
.dd-tl-contact-name { font-size: var(--md-sys-typescale-body-dense-size); color: var(--color-primary); }
.dd-tl-contact-link { text-decoration: none; }
.dd-tl-contact-link:hover { text-decoration: underline; }
/* Click-to-edit contact: wireInlineEdit nests the name in an .ie-display span
   and swaps it for a combobox while editing. The name carries the link's look
   -- it names the same record -- and the trailing icon is what navigates. */
.dd-tl-contact .ie-display { display: inline-flex; align-items: center; gap: 5px; }
/* Resolved from the parent deal rather than set on this activity. Dimmed and
   italic so "inherited" is visible before the tooltip explains it. */
.dd-tl-contact-name--inherited { color: var(--color-on-surface-var); font-style: italic; }
.dd-tl-contact-open {
  color: var(--color-on-surface-var); text-decoration: none;
  opacity: .5; margin-inline-start: 3px; vertical-align: middle;
}
.dd-tl-contact-open:hover { opacity: 1; color: var(--color-primary); }
.dd-tl-contact-open .material-symbols-outlined { font-size: 14px; vertical-align: middle; }
/* The combobox an "entity" inline edit swaps in. It owns its own input, so this
   only has to give it somewhere to sit and stop it stretching the row. */
.inline-entity { display: inline-flex; min-width: 200px; max-width: 260px; vertical-align: middle; }
.inline-entity input { font-size: var(--md-sys-typescale-body-small-size); }

/* Staged files in the log-activity modal, before the activity exists. */
.act-attach-row {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-top: 6px;
}
.attach-drop--over {
  outline: 2px dashed var(--color-primary);
  outline-offset: -4px;
}
.act-attach-staged {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: var(--md-sys-typescale-body-dense-size); padding: 3px 8px;
  background: var(--color-surface-container-high);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-s);
}
.act-attach-staged button {
  background: none; border: none; cursor: pointer; padding: 0;
  color: var(--color-on-surface-var); font-size: var(--md-sys-typescale-body-medium-size); line-height: 1;
}

.dd-tl-header {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
}
.dd-tl-meta {
  display: flex; align-items: center; gap: 8px;
  flex-wrap: wrap;
  /* A 220px basis, not 0: on a narrow card the date / ⋯ side drops to its own
     row instead of squeezing the title into a one-word-per-line column. */
  flex: 1 1 220px; min-width: 0;
}
.dd-tl-done {
  position: relative;
  background: none; border: none; cursor: pointer;
  color: var(--color-on-surface-var);
  padding: 0;
  display: flex; align-items: center;
}
.dd-tl-done .material-symbols-outlined { font-size: 18px; }
.dd-tl-done.done { color: var(--color-success-text); }
/* The done circle holds both glyphs and CSS shows one, so the state is a class
   flip and hover can preview the next one. */
.dd-tl-done__on,
.dd-tl-done.done .dd-tl-done__off { display: none; }
.dd-tl-done.done .dd-tl-done__on  { display: inline-block; }
/* A 40px target round an 18px glyph, without moving the row. Lopsided on
   purpose: the type pill is 8px to the inline-end and the notes line 6px
   below, so the extra reach goes into the card's own padding instead. */
.dd-tl-done::before {
  content: "";
  position: absolute;
  inset-block: -15px -7px;
  inset-inline: -15px -7px;
}
@media (hover: hover) {
  .dd-tl-done:not(.done):hover { color: var(--color-success-text); }
  .dd-tl-done:not(.done):hover .dd-tl-done__off { display: none; }
  .dd-tl-done:not(.done):hover .dd-tl-done__on  { display: inline-block; opacity: .6; }
}
/* The shipped icon font is a static FILL-0 subset (no fvar), so
   font-variation-settings:'FILL' 1 does nothing. The filled look is a tonal
   disc painted inside check_circle's ring instead — on the timeline circle,
   the activities list's tick and the Tasks inbox toggle alike. */
.dd-tl-done.done .dd-tl-done__on,
.act-done-check,
.task-done-btn--done .material-symbols-outlined {
  border-radius: 50%;
  background: radial-gradient(circle closest-side, var(--color-success-bg) 84%, transparent 85%);
}
.dd-tl-type {
  font-size: var(--md-sys-typescale-body-small-size);
  font-weight: 700;
  letter-spacing: .3px;
  padding: 2px 8px;
  border-radius: var(--radius-s);
  background: var(--color-surface-container-high);
  color: var(--color-on-surface-var);
}
.dd-tl-type--history { background: var(--color-primary-container); color: var(--color-primary); }
.dd-tl-title {
  font-size: var(--md-sys-typescale-body-large-size); font-weight: 600;
  color: var(--color-on-surface);
  display: inline-flex; align-items: center; gap: 6px;
  flex-wrap: wrap;
}
.dd-tl-old { color: var(--color-on-surface-var); }
.dd-tl-new { color: var(--color-primary); font-weight: 700; }
.dd-tl-title .material-symbols-outlined { font-size: 16px; color: var(--color-on-surface-var); }
/* A card's subject opens the activity drawer, the timeline's one editor: a
   button, dressed as the title it replaces. */
.dd-tl-title--open {
  background: none; border: 0; padding: 0; margin: 0;
  font-family: inherit; text-align: start; cursor: pointer;
}
.dd-tl-title--open:hover { color: var(--color-primary); text-decoration: underline; }
.dd-tl-title--open:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; border-radius: var(--radius-s); }
.dd-tl-right {
  display: flex; align-items: center; gap: 8px;
  /* May shrink, so on a phone a done card's "edited · completed …" line wraps
     inside the card instead of running past its edge. */
  flex-shrink: 1; min-width: 0;
}
.dd-tl-date { font-size: var(--md-sys-typescale-body-dense-size); color: var(--color-on-surface-var); }
.dd-tl-edited { font-size: var(--md-sys-typescale-body-small-size); color: var(--color-on-surface-var); cursor: help; }
.dd-tl-completed {
  font-size: var(--md-sys-typescale-body-small-size);
  margin-inline-start: 6px;
  color: var(--color-success);
  cursor: help;
}
.dd-tl-menu-wrap { position: relative; }
.dd-tl-menu-btn {
  background: none; border: none; cursor: pointer;
  color: var(--color-on-surface-var);
  font-size: var(--md-sys-typescale-body-large-size);
  padding: 0 4px;
  display: inline-flex; align-items: center;
}
.dd-tl-menu-btn .material-symbols-outlined { font-size: 20px; }
.dd-tl-menu-btn:hover { color: var(--color-on-surface); }
.dd-tl-dropdown {
  position: absolute;
  inset-inline-end: 0; top: 100%;
  min-width: 140px;
  overflow: hidden;
  z-index: 50;
}
/* A choice not picked keeps its checkmark's place, unseen. */
.dd-tl-dropdown-item[aria-checked="false"] > .material-symbols-outlined { visibility: hidden; }
.dd-tl-dropdown-item {
  display: flex; align-items: center; gap: 8px;
  width: 100%;
  background: none; border: none; cursor: pointer;
  padding: 10px 12px;
  font-family: var(--font-body);
  /* The type scale's line, not the font's. A button's line height is
     "normal", the font's own: Cairo's is 24px at 13px to Inter's 16px, so
     in Arabic a dimmed item's reason sat a line below its name. */
  font-size: var(--md-sys-typescale-body-dense-size);
  line-height: var(--md-sys-typescale-body-dense-line);
  color: var(--color-on-surface);
  text-align: start;
}
.dd-tl-dropdown-item .material-symbols-outlined { font-size: 16px; color: var(--color-on-surface-var); }
.dd-tl-dropdown-item:hover { background: var(--color-surface-container); }
.dd-tl-dropdown-item--danger { color: var(--color-error); }
.dd-tl-dropdown-item--danger .material-symbols-outlined { color: var(--color-error); }
.dd-tl-dropdown-item--danger:hover { background: var(--color-error-container); }
/* An item that works only under some conditions: dimmed as Material 3 dims a
   disabled item, the reason under its label left readable. */
.dd-tl-dropdown-item[aria-disabled="true"] { cursor: default; }
.dd-tl-dropdown-item:has(.dd-tl-dropdown-item__hint) { align-items: flex-start; }
.dd-tl-dropdown-item[aria-disabled="true"]:hover { background: none; }
.dd-tl-dropdown-item[aria-disabled="true"] > .material-symbols-outlined,
.dd-tl-dropdown-item[aria-disabled="true"] .dd-tl-dropdown-item__label { opacity: .38; }
.dd-tl-dropdown-item__text { display: flex; flex-direction: column; gap: 2px; }
.dd-tl-dropdown-item__hint { font-size: var(--md-sys-typescale-body-small-size); line-height: var(--md-sys-typescale-body-small-line); color: var(--color-on-surface-var); }
/* Delete ends every ⋯ menu, red, after its own line (Material 3: "On web, use
   a divider to separate menu items"). A Delete that is the only item has no
   line. Here, so every menu with this look keeps the rule without code. */
.dd-tl-dropdown > .dd-tl-dropdown-item--danger:last-child:not(:first-child) {
  margin-top: 4px;
  border-top: 1px solid var(--color-outline-variant);
}
/* On a phone or a touch screen every menu item is a 48px target, as Material 3
   asks of a menu item and of every target; with a mouse they stay compact. */
@media (max-width: 767px), (any-pointer: coarse) {
  :is([role^="menuitem"], .dd-tl-dropdown-item) { min-height: 48px; }
}

.dd-tl-body {
  margin-top: 6px;
  font-size: var(--md-sys-typescale-body-medium-size);
  color: var(--color-on-surface);
  line-height: 1.55;
  white-space: pre-wrap;
  word-break: break-word;
  /* Notes are often a pasted chat log — Arabic, English and mixed lines in one
     field — so each line gets its own base direction. Requires the body's
     content to carry no dir of its own; a nested isolate defeats it. */
  unicode-bidi: plaintext;
}
.dd-tl-due {
  margin-top: 6px;
  display: flex; align-items: center; gap: 6px;
  font-size: var(--md-sys-typescale-body-dense-size);
  color: var(--color-on-surface-var);
}
.dd-tl-due .material-symbols-outlined { font-size: 15px; }
.dd-tl-priority {
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  font-size: var(--md-sys-typescale-body-small-size); font-weight: 700;
}
.dd-tl-priority--high { background: var(--color-error-container); color: var(--color-error); }
.dd-tl-priority--low  { background: var(--color-surface-container-high); color: var(--color-on-surface-var); }
/* Overdue, as stamped by the Focus partition. Only the date says so: a whole
   red card would shout over everything else in the feed. */
.dd-tl-item--overdue .dd-tl-due--when > .material-symbols-outlined,
.dd-tl-item--overdue .dd-tl-due--when .dd-tl-when {
  color: var(--color-error);
}
.dd-tl-item--overdue .dd-tl-due--when .dd-tl-when { font-weight: 600; }
/* A logged call's outcome and length. Pill geometry as .dd-tl-priority; the
   colour says how it went: green reached someone, amber is worth another
   try, red means the number itself is wrong, voicemail stays neutral. */
.dd-tl-outcome {
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  font-size: var(--md-sys-typescale-body-small-size); font-weight: 600;
  background: var(--color-surface-container-high);
  color: var(--color-on-surface-var);
}
.dd-tl-outcome--connected    { background: var(--color-success-bg); color: var(--color-success-text); }
.dd-tl-outcome--no_answer,
.dd-tl-outcome--busy         { background: var(--color-warning-bg); color: var(--color-warning-text); }
.dd-tl-outcome--wrong_number { background: var(--color-error-container);   color: var(--color-error); }
.dd-tl-duration {
  display: inline-flex; align-items: center; gap: 3px;
  font-variant-numeric: tabular-nums;
}
.dd-tl-by {
  margin-top: 4px;
  font-size: var(--md-sys-typescale-body-dense-size);
  color: var(--color-on-surface-var);
}
/* The integration a change came in on, beside the person who set it up. */
.dd-tl-via { color: var(--color-primary); }

/* ── Status button variants ──────────────────────────────────────────────── */
/* Filled buttons on the success / error roles. Each role's on-colour clears
   AA against it in both themes (verify:tokens); hover is the state layer. */
.btn--success {
  background: var(--md-sys-color-success);
  color: var(--md-sys-color-on-success);
  border: none;
}
.btn--danger {
  background: var(--md-sys-color-error);
  color: var(--md-sys-color-on-error);
  border: none;
}
.btn.icon-only { padding: 8px; min-width: auto; }

/* ── Inline edit shared (existing .ie-* classes — keep working) ──────────── */
.ie-field { cursor: pointer; }
.ie-field:not(.ie-editing):hover .ie-display { color: var(--color-primary); }
.ie-hint { opacity: 0; transition: opacity .15s; font-size: var(--md-sys-typescale-body-medium-size); margin-inline-start: 4px; vertical-align: middle; color: var(--color-on-surface-var); }
.ie-field:hover .ie-hint { opacity: 1; }
.row-name-link { color: inherit; font-weight: 600; text-decoration: none; }
.row-name-link:hover { color: var(--color-primary); text-decoration: underline; }
/* A tel field being edited: intl-tel-input wraps the input in .iti, which is
   inline-block by default; give it the whole row, like the input it holds. */
.ie-field > .iti { display: block; flex: 1; min-width: 0; width: 100%; }
/* A WhatsApp username being edited: its "@" prefix and the input take the
   row the same way (_inlineEdit.js _withPrefix). */
.ie-field > .cf-money { flex: 1; min-width: 0; }
.ie-field > .cf-money .inline-input { min-width: 0; }
.inline-input {
  background: var(--color-surface-container-lowest);
  border: 1.5px solid var(--color-primary-container);
  border-radius: var(--radius-s);
  padding: 4px 8px;
  font-family: var(--font-body); font-size: var(--md-sys-typescale-body-dense-size);
  color: var(--color-on-surface);
  outline: none;
  width: 100%;
}
textarea.inline-input { min-height: 70px; resize: vertical; }
td .ie-field { display: inline-block; width: 100%; cursor: pointer; }
td .ie-field:hover { background: var(--color-surface-container); border-radius: var(--radius-s); }
.ie-empty { opacity: .4; }

/* Entity wrapper inside sidebar sections */
.dd-section__body > [data-entity-type] {
  display: flex; flex-direction: column; gap: 2px;
  background: var(--color-surface-container);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-m);
  padding: 8px 10px 10px;
}
.dd-section__body > [data-entity-type] .ie-field {
  padding: 5px 4px;
  border-radius: var(--radius-s);
}
.dd-section__body > [data-entity-type] .ie-field:last-child {
  margin-bottom: 2px;
}

/* ── Mobile (≤768) — stack body vertically ──────────────────────────────── */
@media (max-width: 768px) {
  .dd-topbar { padding: var(--space-2); }
  .dd-topbar__actions {
    width: 100%;
    justify-content: flex-start;
    flex-wrap: wrap;
    row-gap: var(--space-2);
  }
  .dd-topbar__actions .btn { flex: 0 1 auto; }
  /* Owner + followers get their own full-width row, above the Won/Lost/more
     actions — keeps the action row from feeling cramped on phones. */
  .dd-topbar__actions .rh-pills { flex: 0 0 100%; flex-wrap: wrap; }
  .dd-title { font-size: var(--md-sys-typescale-title-large-size); }
  .dd-stage-bar-wrap { padding: 0 var(--space-2) var(--space-2); }
  .dd-stage-bar { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .dd-stage { min-width: 110px; flex: 0 0 auto; }
  /* Disable the desktop "page-as-scroll-container" pattern on mobile — the
     outer .view is the scroll container, so .dd-page / .dd-main / .dd-feed
     must let content overflow up to .view. Otherwise the page silently
     clips at .dd-page's height and the user can't scroll. */
  .dd-page { overflow: visible; height: auto; }
  .dd-main { overflow: visible; height: auto; }
  .dd-feed { overflow: visible; }
  .dd-tabbar { position: sticky; background: var(--color-surface-container-lowest); top: 0; z-index: 4; }
  /* The quick actions stay on phones as one row (overflow under More), so
     logging a call or a meeting is one tap from the feed; the FAB keeps
     add / call / mail within thumb reach as well. */
  .dd-quick-actions { padding: var(--space-2) var(--space-3); }
  .dd-quick-btn { min-height: 40px; }
  .dd-body {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto;
    /* extra bottom space so the last feed item clears the floating FAB */
    padding: 0 var(--space-2) calc(96px + env(safe-area-inset-bottom, 0px));
    gap: var(--space-2);
    overflow: visible;
  }
  .dd-fab {
    display: flex; align-items: center; gap: 4px;
    position: fixed; left: 50%; transform: translateX(-50%);
    bottom: calc(var(--md-nav-bar-h) + 12px + env(safe-area-inset-bottom, 0px));
    z-index: 210;
    padding: 6px;
    background: var(--color-primary-container);
    border-radius: var(--radius-pill);
    box-shadow: var(--md-sys-elevation-3);
  }
  .dd-fab__btn {
    display: flex; align-items: center; justify-content: center;
    width: 48px; height: 48px;
    border: none; background: transparent; cursor: pointer;
    border-radius: 50%;
    /* On primary-container the ink is on-primary-container — on-primary
       (white) on #cde5ff was unreadable in the light theme. */
    color: var(--md-sys-color-on-primary-container);
    -webkit-tap-highlight-color: transparent;
    transition: background .15s;
  }
  .dd-fab__btn:active {
    background: color-mix(in srgb, var(--md-sys-color-on-primary-container) 10%, transparent);
  }
  .dd-fab__btn .material-symbols-outlined { font-size: 24px; }
  /* The "Back to …" pill (.drill-origin, _backTrail.js) would land on the FAB:
     stack it 12px above (the FAB's offset + 60px = 48px buttons + 2×6px
     padding), and give the feed room to scroll past both. Keep in step with
     the above. The html flags are set by JS while the document holds a
     .dd-fab (data-dd-fab) / a .drill-origin pill (data-drill-origin), in
     place of body:has(), which re-matches on every DOM change. */
  :root { --dd-fab-clearance: calc(var(--md-nav-bar-h) + 12px + 60px + 12px + env(safe-area-inset-bottom, 0px)); }
  html[data-dd-fab] .drill-origin { inset-block-end: var(--dd-fab-clearance); }
  html[data-drill-origin] .dd-body { padding-bottom: var(--dd-fab-clearance); }
  .dd-sidebar, .dd-main { height: auto; max-height: none; }
  /* Timeline pane (main) shows by default; sidebar (Details) is toggled in
     by the segmented control via .dd-body--show-details. */
  .dd-main    { order: 1; }
  .dd-sidebar { order: 2; overflow: visible; display: none; }
  .dd-body--show-details .dd-sidebar { display: flex; }
  .dd-body--show-details .dd-main    { display: none; }
  /* Product / owner pages have no timeline to switch to: their details stack
     above the figures, and there is no FAB to clear. */
  .dd-body--stack { padding-bottom: var(--space-4); }
  .dd-body--stack .dd-sidebar { display: flex; order: 0; }

  /* Timeline | Details segmented control */
  .dd-switch {
    display: flex; gap: 3px;
    margin: 0 var(--space-2) var(--space-2);
    padding: 3px;
    background: var(--color-surface-container);
    border-radius: var(--radius-pill);
  }
  .dd-switch__btn {
    flex: 1; min-height: 40px;
    border: none; background: transparent; cursor: pointer;
    border-radius: var(--radius-pill);
    font-family: var(--font-body); font-size: var(--md-sys-typescale-body-medium-size); font-weight: 600;
    color: var(--color-on-surface-var);
    transition: background .15s, color .15s;
  }
  .dd-switch__btn.active {
    background: var(--color-surface-container-lowest);
    color: var(--color-on-surface);
    box-shadow: var(--md-sys-elevation-1);
  }

  /* Bigger tap targets */
  .dd-tab   { padding: 12px 10px; min-height: 44px; }
  .dd-stage { min-height: 44px; }

  /* The FAB already offers "add" on a record page — drop the empty Focus
     section's Schedule button, which would otherwise sit right under the FAB.
     Kept on desktop. */
  .dd-feed .tl-focus-empty [data-focus-schedule] { display: none; }
}

/* Phone width: a narrower gutter on the tab bar, so Timeline · Quotes ·
   Changelog fit beside the filter at 375px (see the dd-tabbar @container). */
@media (max-width: 480px) {
  .dd-tabbar { padding-inline: var(--space-2); }
}

/* ═══════════════════════════════════════════════════════════════════════════
   GLOBAL SEARCH OVERLAY
   ═══════════════════════════════════════════════════════════════════════════ */

.search-overlay {
  position: fixed; inset: 0; z-index: 400;
  background: rgba(0,0,0,.45);
  backdrop-filter: blur(4px);
  display: flex; justify-content: center;
  padding-top: 15vh;
  opacity: 0; pointer-events: none;
  transition: opacity .15s ease;
}
.search-overlay.open { opacity: 1; pointer-events: auto; }

.search-overlay__dialog {
  width: 100%; max-width: 620px;
  max-height: 70vh;
  background: var(--color-surface-container-lowest);
  border-radius: var(--radius-l);
  box-shadow: var(--shadow-3);
  display: flex; flex-direction: column;
  overflow: hidden;
  align-self: flex-start;
}

.search-overlay__input-row {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--color-outline-variant);
  color: var(--color-on-surface-var);
}
.search-overlay__input-row input {
  flex: 1; border: none; outline: none; background: transparent;
  font-family: var(--font-body); font-size: var(--md-sys-typescale-body-large-size);
  color: var(--color-on-surface);
}
.search-overlay__input-row input::placeholder { color: var(--color-on-surface-var); }
/* The rule above sets outline:none unconditionally (higher specificity than the
   global :focus-visible), so re-establish a visible keyboard focus ring. */
.search-overlay__input-row input:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px; border-radius: var(--md-sys-shape-corner-extra-small);
}

.search-overlay__kbd {
  font-family: var(--font-body); font-size: var(--md-sys-typescale-label-small-size); font-weight: 600;
  padding: 2px 7px; border-radius: var(--md-sys-shape-corner-extra-small);
  border: 1px solid var(--color-outline-variant);
  color: var(--color-on-surface-var);
  background: var(--color-surface-container-low);
  line-height: 1.4;
}

.search-overlay__results {
  flex: 1; overflow-y: auto; padding: 6px 0;
}

.search-overlay__hint,
.search-overlay__loading {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px; padding: 40px 20px;
  color: var(--color-on-surface-var); font-size: var(--md-sys-typescale-body-medium-size); text-align: center;
}
.search-overlay__loading { flex-direction: row; padding: 24px 20px; }

@keyframes spin { to { transform: rotate(360deg); } }
.spin { animation: spin .7s linear infinite; }

.search-group { padding: 0; }
.search-group + .search-group { border-top: 1px solid var(--color-outline-variant); }

.search-group__title {
  display: flex; align-items: center; gap: 6px;
  padding: 10px 18px 4px;
  font-size: var(--md-sys-typescale-label-small-size); font-weight: 600;
  letter-spacing: .5px;
  color: var(--color-on-surface-var);
  position: sticky; top: 0;
  background: var(--color-surface-container-lowest);
  z-index: 1;
}

.search-result {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 18px; cursor: pointer;
  transition: background .1s;
}
.search-result:hover { background: var(--color-surface-container-low); }
/* Keyboard-active option: the bg delta alone is ~1.2:1, too faint as the sole
   cue — add a solid primary accent bar so arrow-key nav is clearly visible. */
.search-result--active {
  background: var(--color-surface-container-high);
  box-shadow: inset 3px 0 0 var(--color-primary);
}

.search-result__body {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; gap: 1px;
}
.search-result__primary {
  font-size: var(--md-sys-typescale-body-medium-size); font-weight: 500; color: var(--color-on-surface);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.search-result__primary mark,
.search-result__secondary mark {
  background: rgba(247,190,0,.3); color: inherit;
  border-radius: 2px; padding: 0 1px;
}
.search-result__secondary {
  font-size: var(--md-sys-typescale-body-small-size); color: var(--color-on-surface-var);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.search-result__arrow {
  font-size: 16px; color: var(--color-on-surface-var); opacity: 0;
  transition: opacity .1s;
}
.search-result:hover .search-result__arrow,
.search-result--active .search-result__arrow { opacity: .6; }

.search-result__chip {
  display: inline-block; font-size: var(--md-sys-typescale-label-small-size); font-weight: 500;
  padding: 1px 8px; border-radius: var(--radius-pill);
  background: var(--color-surface-container-high);
  color: var(--color-on-surface-var);
}
.search-result__chip--open   { background: var(--md-sys-color-primary-container); color: var(--md-sys-color-on-primary-container); }
.search-result__chip--won    { background: var(--md-sys-color-success-container); color: var(--md-sys-color-on-success-container); }
.search-result__chip--lost   { background: var(--md-sys-color-error-container);   color: var(--md-sys-color-on-error-container); }

/* Type chips under the input. One row that scrolls sideways on a phone rather
   than wrapping into three and pushing the results off screen. */
.search-overlay__chips {
  padding: 8px 14px;
  gap: 6px;
  border-bottom: 1px solid var(--color-outline-variant);
}
.search-overlay__chips .filter-chip { min-height: 28px; padding: 3px 10px; }
.search-overlay__chips-sep {
  width: 1px; height: 20px; margin: 0 2px;
  background: var(--color-outline-variant);
}
@media (max-width: 767px) {
  .search-overlay__chips { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .search-overlay__chips::-webkit-scrollbar { display: none; }
}

/* "Show all …" / "Show more" rows, and the recent-items leading glyphs. */
.search-result--more { color: var(--color-primary-text); }
.search-result--more .search-result__primary { color: inherit; }
.search-result__lead { font-size: var(--md-sys-typescale-body-large-size); color: var(--color-on-surface-var); opacity: .7; }
.search-result__icon { font-size: 15px; vertical-align: middle; }
.search-result__via { color: var(--color-on-surface-var); }
.search-group__label { flex: 1; }
.search-group__clear {
  border: none; background: none; cursor: pointer;
  font: inherit; letter-spacing: inherit;
  color: var(--color-primary-text);
  padding: 2px 6px; border-radius: var(--md-sys-shape-corner-extra-small);
}
.search-group__clear:hover { background: var(--color-surface-container-high); }

/* Quick-add row — "can't find it? create one" (no-results state + results footer) */
.search-quick-add {
  padding: 12px 16px 16px;
  border-top: 1px solid var(--color-outline-variant);
}
.search-quick-add__header {
  font-size: var(--md-sys-typescale-body-small-size); font-weight: 600;
  letter-spacing: .04em;
  color: var(--color-on-surface-var);
  margin-bottom: 8px;
}
.search-quick-add__btns { display: flex; flex-wrap: wrap; gap: 8px; }
.search-quick-add__btn {
  display: inline-flex; align-items: center; gap: 6px;
  max-width: 100%; min-height: 40px;
  padding: 8px 14px; font-size: var(--md-sys-typescale-body-dense-size); font-weight: 500;
  color: var(--color-primary-text);
  background: var(--color-surface-container-low);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: background .12s, border-color .12s;
}
.search-quick-add__btn > span:last-child {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.search-quick-add__btn:hover {
  background: var(--color-surface-container-high);
  border-color: var(--color-primary);
}

/* Mobile search overlay */
@media (max-width: 767px) {
  .search-overlay { padding-top: 0; align-items: flex-start; }
  .search-overlay__dialog {
    max-width: 100%; max-height: 100vh; max-height: 100dvh;
    border-radius: 0;
  }
  .search-overlay__kbd { display: none; }
}

/* Add-contact modal "clear organization" button — the 18px glyph alone gives a
   ~22px target; enforce a ≥24px hit area (AA 2.5.8). min-size doesn't fight the
   element's inline padding. */
#cf-org-clear {
  min-width: 24px; min-height: 24px;
  display: inline-flex; align-items: center; justify-content: center;
}

/* ── Email Integration ─────────────────────────────────────────────────── */

/* Email message card (used in email threads/lists) */
.email-msg-card {
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-s);
  margin-bottom: var(--space-2);
  background: var(--color-surface);
  transition: background .15s;
}
.email-msg-card:hover { background: var(--color-surface-variant); }
.email-msg-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 8px;
  margin-bottom: 4px;
}
.email-msg-from { font-weight: 600; font-size: var(--md-sys-typescale-body-medium-size); }
.email-msg-date { font-size: var(--md-sys-typescale-body-small-size); color: var(--color-on-surface-var); white-space: nowrap; }
.email-msg-subject { font-size: var(--md-sys-typescale-body-medium-size); margin-bottom: 4px; }
.email-msg-snippet {
  font-size: var(--md-sys-typescale-body-dense-size);
  color: var(--color-on-surface-var);
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.email-msg-direction {
  display: inline-block;
  font-size: var(--md-sys-typescale-body-small-size);
  font-weight: 600;
  padding: 2px 6px;
  border-radius: var(--md-sys-shape-corner-extra-small);
  margin-inline-end: 6px;
}
.email-msg-direction--sent {
  background: var(--color-primary-container);
  color: var(--color-on-primary-container);
}
.email-msg-direction--received {
  background: var(--color-tertiary-container);
  color: var(--color-on-tertiary-container);
}

/* Calendar push indicator */
.cal-push-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: var(--md-sys-typescale-body-small-size);
  color: var(--color-primary);
  background: var(--color-primary-container);
  padding: 2px 8px;
  border-radius: var(--md-sys-shape-corner-extra-small);
  cursor: pointer;
  text-decoration: none;
}
.cal-push-badge:hover { opacity: 0.85; }
.cal-push-badge .material-symbols-outlined { font-size: 14px; }

/* Calendar push button on activities */
.cal-push-btn {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  background: none;
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--md-sys-shape-corner-extra-small);
  padding: 2px 8px;
  font-size: var(--md-sys-typescale-body-small-size);
  color: var(--color-on-surface-var);
  cursor: pointer;
  transition: all .15s;
}
.cal-push-btn:hover {
  border-color: var(--color-primary);
  color: var(--color-primary);
  background: var(--color-primary-container);
}
.cal-push-btn .material-symbols-outlined { font-size: 14px; }
.cal-push-btn:disabled { opacity: .6; cursor: progress; }

/* Online meeting: Join chip on timeline cards, Join card in the activity
   drawer. The provider tint is the only per-provider rule; everything else
   is the same card whatever the link is. */
.meeting-tl-row { margin-top: 4px; flex-wrap: wrap; gap: 6px; }
.meeting-chip {
  --meeting-tint: var(--color-primary);
  display: inline-flex; align-items: center; gap: 4px;
  font-size: var(--md-sys-typescale-body-dense-size); font-weight: 600; line-height: 1.4;
  color: var(--color-on-primary); background: var(--meeting-tint);
  padding: 2px 10px; border-radius: var(--radius-pill);
  text-decoration: none; max-width: 100%;
}
.meeting-chip:hover { filter: brightness(1.08); }
.meeting-chip .material-symbols-outlined { font-size: 14px; }
.meeting-chip--meet,  .meeting-card--meet  { --meeting-tint: #1a73e8; }
.meeting-chip--zoom,  .meeting-card--zoom  { --meeting-tint: #0b5cff; }
.meeting-chip--teams, .meeting-card--teams { --meeting-tint: #5b5fc7; }
.meeting-chip--webex, .meeting-card--webex { --meeting-tint: #0a7a4f; }

.meeting-drawer:empty { display: none; }
.meeting-card {
  --meeting-tint: var(--color-primary);
  border: 1px solid color-mix(in srgb, var(--meeting-tint) 40%, var(--color-outline-variant));
  background: color-mix(in srgb, var(--meeting-tint) 6%, var(--color-surface-container-lowest));
  border-radius: var(--radius-m);
  padding: 12px;
}
.meeting-card__top { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.meeting-card__name { display: flex; flex-direction: column; min-width: 0; flex: 1 1 140px; }
.meeting-card__name b { font-size: var(--md-sys-typescale-body-medium-size); color: var(--color-on-surface); }
.meeting-card__name span { font-size: var(--md-sys-typescale-body-small-size); color: var(--color-on-surface-var); overflow-wrap: anywhere; }
.meeting-join {
  display: inline-flex; align-items: center; gap: 4px; text-decoration: none;
  background: var(--meeting-tint); border-color: var(--meeting-tint); color: #fff;
}
.meeting-join:hover { filter: brightness(1.08); color: #fff; }
.meeting-join .material-symbols-outlined { font-size: 16px; }
.meeting-card__rows { margin-top: 10px; display: flex; flex-direction: column; }
.meeting-row {
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  padding: 5px 0; border-top: 1px dashed var(--color-outline-variant);
  font-size: var(--md-sys-typescale-body-small-size); color: var(--color-on-surface-var);
}
.meeting-row > span:first-child { display: inline-flex; align-items: center; gap: 4px; }
.meeting-row .material-symbols-outlined { font-size: 14px; }
.meeting-row a { color: var(--color-primary-text); }
.meeting-val { display: inline-flex; align-items: center; gap: 4px; }
.meeting-val code { font-size: var(--md-sys-typescale-body-small-size); color: var(--color-on-surface); }
.meeting-copy {
  display: inline-grid; place-items: center; width: 24px; height: 24px;
  background: none; border: 0; border-radius: var(--radius-s);
  color: var(--color-on-surface-var); cursor: pointer; padding: 0;
}
.meeting-copy:hover { background: var(--color-surface-container-high); color: var(--color-primary); }
.meeting-copy .material-symbols-outlined { font-size: 15px; }
.meeting-more { display: inline-block; margin-top: 6px; font-size: var(--md-sys-typescale-body-small-size); }
.meeting-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 8px; }
.meeting-card + .meeting-actions { margin-top: 10px; }
.meeting-drawer > .meeting-actions:first-child { margin-top: 0; }

/* Settings → Email & Calendar: Google Calendar sync (settings_calendar.js).
   Header, then per account: a switch row, the two direction sections (hidden
   while sync is off) and a status bar. */
.cal-sync__header { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-3); }
.cal-sync__header h3 { margin: 0; }
.cal-sync__header p { margin: 2px 0 0; }
.cal-sync__icon {
  display: grid; place-items: center; flex: 0 0 44px; width: 44px; height: 44px; font-size: 24px;
  border-radius: var(--md-sys-shape-corner-medium);
  background: var(--color-primary-container); color: var(--color-on-primary-container);
}
.cal-sync + .cal-sync { margin-top: var(--space-4); }
.cal-sync__toggle {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2) var(--space-3);
  padding: 12px 14px; cursor: pointer;
  border: 1px solid var(--color-outline-variant); border-radius: var(--md-sys-shape-corner-medium);
  background: var(--color-surface-container-low);
}
.cal-sync__toggle-text { display: flex; flex-direction: column; flex: 1 1 200px; min-width: 0; }
.cal-sync__toggle-text b { color: var(--color-on-surface); font-size: var(--md-sys-typescale-body-medium-size); }
.cal-sync__account {
  padding: 3px 10px; border-radius: var(--radius-pill); font-size: var(--md-sys-typescale-body-small-size);
  border: 1px solid var(--color-outline-variant); background: var(--color-surface-container-lowest);
  color: var(--color-on-surface-var); overflow-wrap: anywhere;
}
.cal-sync__body {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); margin-top: var(--space-3);
}
.cal-sync__section {
  padding: 14px 16px; border: 1px solid var(--color-outline-variant);
  border-radius: var(--md-sys-shape-corner-medium);
}
.cal-sync__title {
  display: flex; align-items: center; gap: 6px; margin: 0 0 10px;
  font-size: var(--md-sys-typescale-body-medium-size); font-weight: 600; color: var(--color-on-surface);
}
.cal-sync__title .material-symbols-outlined { font-size: 18px; color: var(--color-primary); }
.cal-sync__rules { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.cal-sync__rules li { display: flex; align-items: flex-start; gap: 8px; font-size: var(--md-sys-typescale-body-dense-size); line-height: 1.45; color: var(--color-on-surface); }
.cal-sync__rules .material-symbols-outlined { font-size: 18px; color: var(--color-on-surface-var); }
.cal-sync__rule--yes .material-symbols-outlined { color: var(--color-success); }
.cal-sync__private { margin: 14px 0 0; padding-top: 14px; border-top: 1px solid var(--color-outline-variant); }
.cal-sync__private select { width: 100%; }
.cal-sync__private .caption,
.cal-sync__section > .caption { margin: 6px 0 0; }
.cal-sync__section > .cal-sync__lead { margin: 0 0 10px; }
.cal-sync__types { margin-bottom: 4px; }
/* The type's colour while off; a selected chip's icon takes the chip's own
   on-container colour, which a type colour on the filled chip would fight. */
.cal-sync__types .material-symbols-outlined { color: var(--type-color, currentColor); }
.cal-sync__types [aria-pressed="true"] .material-symbols-outlined { color: inherit; }
.cal-sync__footer {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2) var(--space-3);
  margin-top: var(--space-3); padding: 10px 14px; border-radius: var(--md-sys-shape-corner-medium);
  background: var(--color-surface-container);
}
.cal-sync__status { flex: 1 1 200px; font-size: var(--md-sys-typescale-body-dense-size); color: var(--color-on-surface-var); }
.cal-sync__dot--off { background: var(--color-outline); }
.cal-sync__dot--on { background: var(--color-success); }
.cal-sync__dot--error { background: var(--color-error); }
.cal-sync-error { color: var(--color-error); }
@media (max-width: 768px) {
  .cal-sync__body { grid-template-columns: minmax(0, 1fr); }
}

/* Account cards in settings */
.email-account-card {
  border: 1px solid var(--color-outline-variant);
}

/* ── Inline Email Compose ──────────────────────────────────────────────── */

.email-compose-inline {
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-m);
  background: var(--color-surface);
  overflow: hidden;
}

.ec-header-fields {
  border-bottom: 1px solid var(--color-outline-variant);
}
.ec-field-row {
  display: flex;
  align-items: center;
  padding: 6px 16px;
  border-bottom: 1px solid var(--color-outline-variant);
  gap: 8px;
}
.ec-field-row:last-child { border-bottom: none; }
.ec-label {
  font-size: var(--md-sys-typescale-label-small-size);
  color: var(--color-on-surface-var);
  min-width: 54px;
  letter-spacing: 0.04em;
  font-weight: 600;
}
.ec-field-value { flex: 1; font-size: var(--md-sys-typescale-body-medium-size); }
.ec-input {
  width: 100%;
  border: none;
  background: transparent;
  font-size: var(--md-sys-typescale-body-medium-size);
  font-family: inherit;
  color: var(--color-on-surface);
  outline: none;
  padding: 2px 0;
}
.ec-toggle-cc-btn {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--color-on-surface-var);
  padding: 4px;
  border-radius: var(--md-sys-shape-corner-extra-small);
  display: flex;
  align-items: center;
}
.ec-toggle-cc-btn:hover { background: var(--color-surface-variant); }

/* Personal templates (_emailTemplates.js, Yahia, 2026-10-19): a text button
   above the message, opening a panel of the rep's templates. */
.ec-templates-row { padding: var(--space-1) var(--space-2); border-bottom: 1px solid var(--color-outline-variant); }
.ec-templates-btn { gap: var(--space-1); }
.ec-tpl-panel {
  z-index: 400;   /* over the window when it sits in a dialog (300), under confirm/prompt (500) */
  width: min(320px, calc(100vw - 16px)); padding: var(--space-1) 0;
  background: var(--color-surface-container); color: var(--color-on-surface);
  border-radius: var(--md-sys-shape-corner-extra-small); box-shadow: var(--shadow-2);
}
.ec-tpl-search { margin: var(--space-1) var(--space-2); width: calc(100% - 2 * var(--space-2)); }
.ec-tpl-list { max-height: 320px; overflow-y: auto; }
.ec-tpl-row { display: flex; align-items: center; }
.ec-tpl-pick, .ec-tpl-save {
  flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  padding: 10px var(--space-3); background: none; border: none; cursor: pointer; text-align: start;
  color: inherit; font: inherit;
}
.ec-tpl-save { flex-direction: row; align-items: center; gap: var(--space-2); width: 100%; }
.ec-tpl-pick:hover, .ec-tpl-save:hover { background: var(--color-surface-container-high); }
.ec-tpl-pick .caption { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ec-tpl-name { font-weight: 500; }
.ec-tpl-empty { margin: 0; padding: 10px var(--space-3); }
.ec-tpl-divider { border: none; border-top: 1px solid var(--color-outline-variant); margin: var(--space-1) 0; }
@media (any-pointer: coarse) { .ec-tpl-pick, .ec-tpl-save { min-height: 48px; } }

/* Rich text editor */
.ec-body-area { padding: 0; }
.ec-rte {
  min-height: 200px;
  padding: 16px;
  font-size: var(--md-sys-typescale-body-medium-size);
  line-height: 1.6;
  font-family: inherit;
  color: var(--color-on-surface);
  outline: none;
  overflow-y: auto;
  max-height: 400px;
}
.ec-rte:empty::before {
  content: attr(data-placeholder);  /* localized via data-placeholder (was hardcoded English) */
  color: var(--color-on-surface-var);
  opacity: 0.6;
}
.ec-rte a { color: var(--color-primary-text); }
.ec-signature {
  margin-top: 16px;
  padding-top: 8px;
  border-top: 1px solid var(--color-outline-variant);
  color: var(--color-on-surface-var);
  font-size: var(--md-sys-typescale-body-dense-size);
}

/* Toolbar */
.ec-toolbar {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 6px 12px;
  border-top: 1px solid var(--color-outline-variant);
  background: var(--color-surface-variant);
  flex-wrap: wrap;
}
.ec-toolbar button {
  background: none;
  border: none;
  cursor: pointer;
  /* ~38px target (18px icon + padding). Was 4px 6px ≈ 26px — failed WCAG 2.5.8. */
  padding: 10px;
  min-width: 36px;
  min-height: 36px;
  border-radius: var(--md-sys-shape-corner-extra-small);
  color: var(--color-on-surface-var);
  display: flex;
  align-items: center;
  justify-content: center;
}
.ec-toolbar button:hover {
  background: var(--color-surface);
  color: var(--color-on-surface);
}
/* Active formatting state — mirrors aria-pressed="true" so the toggle is
   visible, not just announced. */
.ec-toolbar button.active {
  background: var(--color-surface-container-high);
  color: var(--color-primary-text);
}
.ec-toolbar button .material-symbols-outlined { font-size: 18px; }
.ec-toolbar-sep {
  width: 1px;
  height: 20px;
  background: var(--color-outline-variant);
  margin: 0 4px;
}

/* Contact autocomplete dropdown */
.ec-autocomplete {
  position: absolute;
  top: calc(100% + 2px);
  left: 0;
  right: 0;
  background: var(--color-surface-container-lowest);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--md-sys-shape-corner-small);
  box-shadow: var(--md-sys-elevation-3);
  z-index: 200;
  max-height: 240px;
  overflow-y: auto;
}
.ec-autocomplete-item {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 8px 12px;
  cursor: pointer;
}
.ec-autocomplete-item:hover,
.ec-autocomplete-item.active { background: var(--color-surface-container-high); }
.ec-autocomplete-item__name { font-size: var(--md-sys-typescale-body-dense-size); font-weight: 500; }
.ec-autocomplete-item__email { font-size: var(--md-sys-typescale-label-small-size); color: var(--color-on-surface-var); }

/* ── Guest picker (_guestPicker.js) ─────────────────────────────────────────
   The Guests field as Material 3 input chips in an outlined field: teammates
   picked by name, other addresses typed (Yahia, 2026-10-19). The box draws
   the field; the input inside it is bare. The suggestion list reuses
   .ec-autocomplete above. */
.guest-picker { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
/* The label's own look, for a picker placed outside .form-group and
   .drawer-field; inside them, their label rules win on specificity. */
.guest-picker__label {
  font-size: var(--md-sys-typescale-label-medium-size);
  line-height: var(--md-sys-typescale-label-medium-line);
  font-weight: var(--md-sys-typescale-label-medium-weight);
  color: var(--md-sys-color-on-surface-variant);
}
.form-group .guest-picker:focus-within > .guest-picker__label { color: var(--md-sys-color-primary); }
.form-group .guest-picker:has([aria-invalid="true"]) > .guest-picker__label { color: var(--md-sys-color-error); }
.guest-picker__field { position: relative; }
.guest-picker__box {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1);
  min-height: calc(var(--space-5) + var(--space-2));
  padding-block: calc(var(--space-1) * .75);
  padding-inline: var(--space-1);
  border: 1px solid var(--md-sys-color-outline);
  border-radius: var(--md-sys-shape-corner-extra-small);
  background: transparent;
  cursor: text;
  transition: border-color var(--md-sys-motion-duration-short3), box-shadow var(--md-sys-motion-duration-short3);
}
.drawer-field .guest-picker__box { background: var(--color-surface-container-lowest); }
.guest-picker__box:hover:not(:focus-within) { border-color: var(--md-sys-color-on-surface); }
/* The outlined field's focus: 2px primary, the second pixel inset. */
.guest-picker__box:focus-within {
  border-color: var(--md-sys-color-primary);
  box-shadow: inset 0 0 0 1px var(--md-sys-color-primary);
}
.guest-picker__box:has([aria-invalid="true"]) { border-color: var(--md-sys-color-error); }
.guest-picker__box:has([aria-invalid="true"]):focus-within { box-shadow: inset 0 0 0 1px var(--md-sys-color-error); }
.guest-picker--readonly .guest-picker__box {
  cursor: default;
  border-color: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent);
}
.guest-picker__chips { display: flex; flex-wrap: wrap; gap: var(--space-1); min-width: 0; max-width: 100%; }
.guest-picker__chips:empty { display: none; }
.guest-picker--readonly .guest-picker__chips:empty { display: block; }
.guest-picker--readonly .guest-picker__chips:empty::before {
  content: "—"; padding-inline: var(--space-2); color: var(--color-on-surface-var);
}
/* Bare inside the box. These selectors outrank .form-group input and
   .drawer-field input, their :focus and :disabled included. */
.guest-picker .guest-picker__input,
.guest-picker .guest-picker__input:focus,
.guest-picker .guest-picker__input:disabled {
  flex: 1 1 calc(var(--space-6) * 2.5);
  width: auto; min-width: calc(var(--space-6) * 2.5);
  min-height: var(--space-5);
  padding: 0 var(--space-2);
  border: 0; border-radius: 0; outline: none; box-shadow: none;
  background: transparent;
  font-family: var(--font-body);
  font-size: var(--md-sys-typescale-body-medium-size);
  color: var(--color-on-surface);
}
/* A phone zooms into a text box under 16px, so the box takes the size every
   other field gets there (the max-width: 767px block above). */
@media (max-width: 767px) {
  .guest-picker .guest-picker__input,
  .guest-picker .guest-picker__input:focus,
  .guest-picker .guest-picker__input:disabled { font-size: var(--md-sys-typescale-body-large-size); }
}
.guest-picker .guest-picker__note--error { color: var(--color-error); }
.guest-picker__empty { padding: var(--space-2) calc(var(--space-1) * 3); }

/* Material 3 input chip: 32dp tall, 8dp corners, an outline-variant border,
   label-large text. A teammate leads with their avatar (24dp), an address
   with a mail icon (18dp); the remove icon sits at the end side. */
.guest-chip {
  display: inline-flex; align-items: center; gap: var(--space-2);
  min-height: var(--space-5); max-width: 100%;
  padding-inline: var(--space-2) var(--space-1);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--md-sys-shape-corner-small);
  color: var(--color-on-surface-var);
  font-size: var(--md-sys-typescale-label-large-size);
  line-height: var(--md-sys-typescale-label-large-line);
  font-weight: var(--md-sys-typescale-label-large-weight);
  letter-spacing: var(--md-sys-typescale-label-large-tracking);
}
.guest-chip--person { padding-inline-start: var(--space-1); }
.guest-picker--readonly .guest-chip { padding-inline-end: var(--space-2); }
.guest-chip__avatar { display: inline-flex; flex-shrink: 0; }
.guest-chip__avatar .avatar-sm { width: var(--space-4); height: var(--space-4); }
.guest-chip__icon { flex-shrink: 0; }
.guest-chip__label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.guest-chip__remove {
  position: relative; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--space-4); height: var(--space-4);
  margin-inline-start: calc(var(--space-1) * -1);
  padding: 0; border: 0; border-radius: var(--md-sys-shape-corner-full);
  background: none; color: inherit; cursor: pointer;
}
.guest-chip__remove:hover { background: color-mix(in srgb, var(--color-on-surface-var) 8%, transparent); }
/* Material 3: a chip whose only action is remove is one focusable element,
   so the whole chip shows the focus. */
.guest-chip__remove:focus-visible { outline: none; }
.guest-chip:focus-within {
  outline: 2px solid var(--md-sys-color-primary); outline-offset: 1px;
  background: color-mix(in srgb, var(--color-on-surface-var) 12%, transparent);
}
/* A larger target for a finger, kept inside the gaps between chips so it
   never lands on a neighbour. */
@media (any-pointer: coarse) {
  .guest-chip__remove::after { content: ""; position: absolute; inset: calc(var(--space-1) * -2); }
}

/* Entity link combobox — link-type custom fields (see _entityCombobox.js).
   Reuses .ec-autocomplete / .ec-autocomplete-item for the dropdown + options.
   The input is styled self-contained (not reliant on .form-group) because the
   combobox is also mounted inside the inline-edit popover, outside any form. */
.cf-combobox { position: relative; display: block; }
.cf-combobox .cf-combobox__input {
  width: 100%;
  padding-block: 9px;
  padding-inline: 12px 36px;            /* trailing room for the × clear button */
  border: 1.5px solid var(--color-surface-container-high);
  border-radius: var(--radius-m);
  font-family: var(--font-body); font-size: var(--md-sys-typescale-body-medium-size);
  color: var(--color-on-surface);
  background: var(--color-surface-container-lowest);
  outline: none; transition: border-color .15s, box-shadow .15s;
}
.cf-combobox .cf-combobox__input:focus {
  border-color: var(--color-primary-container);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--md-sys-color-primary) 12%, transparent);
}
[data-theme="dark"] .cf-combobox .cf-combobox__input {
  background: var(--color-surface-container);
  border-color: var(--color-outline);
}
.cf-combobox__clear {
  position: absolute; inset-inline-end: 6px; top: 50%; transform: translateY(-50%);
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px;            /* comfortable tap target vs the bare glyph */
  border: none; background: none; cursor: pointer;
  font-size: var(--md-sys-typescale-body-large-size); line-height: 1; color: var(--color-on-surface-var);
  border-radius: 50%;
}
.cf-combobox__clear:hover { color: var(--color-on-surface); background: var(--color-surface-container-high); }
/* Close / remove buttons that used to hold a × glyph now hold the close icon;
   it takes the size the glyph had (the button's font-size), not the icon
   class's default 24px. */
:is(.cf-combobox__clear, .dd-remove-btn, .dd-filter__clear, .tag-chip__x,
    .act-attach-staged > button, [data-att-del]) > .material-symbols-outlined {
  font-size: inherit;
  line-height: 1;
  vertical-align: middle;
}
.cf-combobox__clear:focus-visible {
  outline: 2px solid var(--color-primary-container); outline-offset: 1px;
}
/* "Add 'X' as new …" — the last option of a combobox mounted with
   createLabel. Picking it shows a "New" badge in the input until the form
   saves. */
.ec-autocomplete-item--create {
  border-top: 1px solid var(--color-outline-variant);
  color: var(--color-primary);
}
.ec-autocomplete-item--create:first-child { border-top: none; }
.ec-autocomplete-item--create .ec-autocomplete-item__name {
  display: inline-flex; align-items: center; gap: 6px;
}
.ec-autocomplete-item--create .material-symbols-outlined { font-size: 18px; }
.cf-combobox--new .cf-combobox__input { padding-inline-end: 84px; }
.cf-combobox__new {
  position: absolute; inset-inline-end: 38px; top: 50%; transform: translateY(-50%);
  padding: 2px 8px; border-radius: var(--md-sys-shape-corner-full);
  font-size: var(--md-sys-typescale-label-small-size); font-weight: 600; line-height: 16px;
  background: var(--color-primary-container); color: var(--color-on-primary-container);
  pointer-events: none;
}
/* Phone + email for a person the Add Deal form is creating. */
.df-new-contact {
  display: flex; flex-direction: column; gap: var(--space-3);
  margin-top: 8px; padding-inline-start: 12px;
  border-inline-start: 2px solid var(--color-primary-container);
}
.df-new-contact .form-group { margin-bottom: 0; }
/* Activity start/end time pickers (_timeRange.js). Same input + dropdown as
   the entity combobox, in the custom fields' .cf-range row; each option is a
   row — time, duration, and a check on the current value. */
.cf-range > .time-field { flex: 1; min-width: 0; }
.time-field__list { min-width: 200px; }
/* The end field sits at the row's trailing edge: open its list toward the
   start so the wider-than-the-input popup never overflows the dialog. */
.time-field--end .time-field__list { left: auto; right: auto; inset-inline-end: 0; }
.time-field__opt.ec-autocomplete-item {
  flex-direction: row; align-items: center; justify-content: space-between; gap: var(--space-2);
  font-size: var(--md-sys-typescale-body-medium-size); white-space: nowrap;
}
.time-field__opt .material-symbols-outlined { font-size: 18px; }
.time-field__opt.is-current { color: var(--color-primary-text); font-weight: 500; }
.time-field__dur { color: var(--color-on-surface-var); font-weight: 400; margin-inline-start: 4px; }
/* The browser's own field styling applies inside .form-group; keep the combobox
   input's trailing room for the × regardless. */
.form-group .time-field .cf-combobox__input { padding-inline-end: 36px; }

/* Let the combobox dropdown escape the inline popover's scroll clip. */
.cf-inline-pop--combo { min-width: 260px; }
.cf-inline-pop--combo .cf-inline-pop__body { overflow: visible; max-height: none; }

/* Send bar */
.ec-send-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 12px;
  border-top: 1px solid var(--color-outline-variant);
}
.ec-send-left { display: flex; gap: 8px; }
.ec-icon-btn {
  background: none;
  border: none;
  cursor: pointer;
  padding: 6px;
  border-radius: var(--md-sys-shape-corner-extra-small);
  color: var(--color-on-surface-var);
  display: flex;
  align-items: center;
}
.ec-icon-btn:hover {
  background: var(--color-surface-variant);
  color: var(--color-error);
}
.ec-send-btn {
  display: inline-flex;
  align-items: center;
  padding: 8px 24px;
  font-size: var(--md-sys-typescale-body-medium-size);
  font-weight: 600;
}

/* ── Email Page ────────────────────────────────────────────────────────── */

/* Unread message */
.email-msg-card--unread { border-inline-start: 3px solid var(--color-primary); }
.email-msg-card--unread .email-msg-subject { font-weight: 700; }
.email-msg-card--unread .email-msg-from { font-weight: 700; }

/* Message row (clickable) */
.email-msg-row { cursor: pointer; padding: 12px 16px; }

/* Expanded message */
.email-msg-card--expanded {
  border-color: var(--color-primary);
  box-shadow: var(--md-sys-elevation-1);
}
.email-msg-body-wrap {
  padding: 0 16px 12px;
  border-top: 1px solid var(--color-outline-variant);
}
.email-msg-body {
  font-size: var(--md-sys-typescale-body-medium-size);
  line-height: 1.6;
  padding: 12px 0;
  max-height: 500px;
  overflow-y: auto;
  word-break: break-word;
}
.email-msg-body img { max-width: 100%; height: auto; }

/* Mobile adjustments */
@media (max-width: 600px) {
  .ec-toolbar { padding: 4px 8px; gap: 1px; }
  .ec-toolbar button { padding: 8px; min-width: 34px; min-height: 34px; }
  .ec-rte { min-height: 150px; padding: 12px; }
  .ec-field-row { padding: 4px 12px; }
  .ec-send-btn { padding: 6px 16px; font-size: var(--md-sys-typescale-body-dense-size); }
}

/* ═══════════════════════════════════════════════════════════════════════════
   DARK THEME PATCHES — components that don't auto-flip via tokens alone
   ═══════════════════════════════════════════════════════════════════════════ */

[data-theme="dark"] :is(.top-bar__logo-img, .login-page__brand-img) { filter: brightness(0) invert(1); }

[data-theme="dark"] .owner-select {
  background-color: var(--color-surface-container);
  border-color: var(--color-outline);
  color: var(--color-on-surface);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2398a8c0' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
}

/* Tables */
[data-theme="dark"] .data-table thead th { background: var(--color-surface-container); }
[data-theme="dark"] .data-table tbody tr:hover { background: var(--color-surface-container-high); }


/* Search overlay */
[data-theme="dark"] .search-overlay { background: rgba(0,0,0,.6); }
[data-theme="dark"] .search-overlay__input-row { border-color: var(--color-outline); }
[data-theme="dark"] .search-result__primary mark,
[data-theme="dark"] .search-result__secondary mark { background: rgba(247,190,0,.25); }

/* Search pill dark */
/* search-pill now uses semantic tokens — dark mode handled automatically */

/* Sort dropdown dark */
[data-theme="dark"] .sort-dropdown__trigger { background: var(--color-surface-container); border-color: var(--color-surface-container-high); }
[data-theme="dark"] .sort-dropdown__item:hover { background: var(--color-surface-container-high); }


/* ─────────────────────────────────────────────────────────────────────────
   Tasks Inbox + sidebar badge + activity drawer
   ───────────────────────────────────────────────────────────────────────── */

/* Sidebar nav badge (overdue + today count) */
.nav-label { flex: 1; min-width: 0; }
.nav-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: var(--md-sys-shape-corner-medium);
  background: var(--color-error);
  color: var(--color-on-error);
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: 700;
  font-family: var(--md-sys-typescale-font);
  flex-shrink: 0;
  margin-inline-start: auto;
  line-height: 1;
}
.nav-item.active .nav-badge {
  background: var(--color-on-error);
  color: var(--color-error);
}

/* Counts strip atop the Tasks Inbox */
.tasks-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: var(--space-4);
}
.tasks-strip-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  border-radius: var(--radius-pill);
  background: var(--color-surface-container-low);
  border: 1px solid var(--color-surface-container-high);
  font-size: var(--md-sys-typescale-body-dense-size);
  color: var(--color-on-surface-var);
  font-weight: 500;
  cursor: pointer;
  font-family: inherit;
  transition: filter .12s, transform .12s, box-shadow .12s;
}
.tasks-strip-chip:hover { filter: brightness(1.04); transform: translateY(-1px); }
.tasks-strip-chip:active { transform: translateY(0); }
.tasks-strip-chip:focus-visible {
  outline: 2px solid var(--color-primary-bright);
  outline-offset: 2px;
}
.tasks-strip-chip.active {
  outline: 2px solid var(--color-primary-bright);
  outline-offset: 2px;
  box-shadow: var(--md-sys-elevation-2);
}
.tasks-strip-num {
  font-size: var(--md-sys-typescale-body-large-size);
  font-weight: 700;
  color: var(--color-on-surface);
  min-width: 16px;
  text-align: center;
}
.tasks-strip-chip--overdue {
  background: var(--color-error-container);
  border-color: var(--color-error);
  color: var(--color-error);
}
.tasks-strip-chip--overdue .tasks-strip-num { color: var(--color-error); }
.tasks-strip-chip--today {
  background: var(--color-warning-bg);
  border-color: var(--color-warning);
  color: var(--color-warning-text);
}
.tasks-strip-chip--today .tasks-strip-num { color: var(--color-warning-text); }
.tasks-strip-chip--done {
  background: var(--color-surface-container-low);
  border-color: var(--color-surface-container-high);
  color: var(--color-success-text);
}
.tasks-strip-chip--done .tasks-strip-num { color: var(--color-success-text); }

/* Bucket sections */
.tasks-buckets { display: flex; flex-direction: column; gap: var(--space-4); }
.tasks-bucket {
  background: var(--color-surface-container-lowest);
  border: 1px solid var(--color-surface-container-high);
  border-radius: var(--md-sys-shape-corner-medium);
  overflow: hidden;
}
.tasks-bucket-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  background: var(--color-surface-container-low);
  border-bottom: 1px solid var(--color-surface-container-high);
}
.tasks-bucket-title { font-weight: 600; font-size: var(--md-sys-typescale-body-medium-size); }
.tasks-bucket-count {
  background: var(--color-surface-container-high);
  color: var(--color-on-surface-var);
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  font-size: var(--md-sys-typescale-body-small-size);
  font-weight: 600;
}
.tasks-bucket-header--overdue {
  background: var(--color-error-container);
  border-bottom-color: var(--color-error);
}
.tasks-bucket-header--overdue .tasks-bucket-title { color: var(--color-error); }
.tasks-bucket-header--overdue .tasks-bucket-count {
  background: var(--color-error);
  color: var(--color-on-error);
}
.tasks-bucket-header--today {
  background: var(--color-warning-bg);
  border-bottom-color: var(--color-warning);
}
.tasks-bucket-header--today .tasks-bucket-title { color: var(--color-warning-text); }
.tasks-bucket-header--today .tasks-bucket-count {
  background: var(--color-warning-bg);
  color: var(--color-warning-text);
}

/* Bucket rows */
.tasks-list { list-style: none; margin: 0; padding: 0; }
.task-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--color-surface-container-low);
  cursor: pointer;
  transition: background .12s;
}
.task-row:last-child { border-bottom: none; }
.task-row:hover { background: var(--color-surface-container-low); }
.task-row:focus { outline: 2px solid var(--color-primary-bright); outline-offset: -2px; }
.task-done-btn {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--color-on-surface-var);
  padding: 4px;
  border-radius: 50%;
  display: flex;
  align-items: center;
}
.task-done-btn:hover { color: var(--color-primary-bright); background: var(--color-surface-container-high); }
.task-done-btn .material-symbols-outlined { font-size: 22px; }
.task-icon {
  font-size: 20px;
  color: var(--color-on-surface-var);
  flex-shrink: 0;
}
.task-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.task-subject {
  font-weight: 500;
  font-size: var(--md-sys-typescale-body-large-size);
  color: var(--color-on-surface);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.task-entity-link {
  font-size: var(--md-sys-typescale-body-dense-size);
  color: var(--color-on-surface-var);
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  /* Don't stretch to full row width — limits the clickable hit-box to
     the visible text so clicks elsewhere in the row open the drawer
     instead of navigating. */
  align-self: flex-start;
  max-width: 100%;
}
.task-entity-link:hover { color: var(--color-primary-bright); text-decoration: underline; }
.task-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}
.task-prio {
  font-size: var(--md-sys-typescale-body-small-size);
  font-weight: 600;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
}
.task-prio--high { background: var(--color-error-container); color: var(--color-error); }
.task-prio--low  { background: var(--color-surface-container-high); color: var(--color-on-surface-var); }

/* Due-date pill */
.tasks-due-pill {
  font-size: var(--md-sys-typescale-body-small-size);
  font-weight: 600;
  padding: 3px 10px;
  border-radius: var(--radius-pill);
  white-space: nowrap;
  background: var(--color-surface-container-high);
  color: var(--color-on-surface-var);
}
.tasks-due-pill--overdue { background: var(--color-error-container); color: var(--color-error); }
.tasks-due-pill--today   { background: var(--color-warning-bg); color: var(--color-warning-text); }
.tasks-due-pill--upcoming { background: var(--color-surface-container-high); color: var(--color-on-surface-var); }
.tasks-due-pill--done {
  background: color-mix(in srgb, var(--color-success) 12%, transparent);
  color: var(--color-success);
}

/* Done bucket: dim the row + filled toggle to mark completion at a glance */
.task-row--done .task-subject { opacity: .8; }
.task-done-btn--done .material-symbols-outlined { color: var(--color-success-text); }
/* The activities list's done mark, where a strike-through used to be. */
.act-done-check {
  font-size: var(--md-sys-typescale-body-large-size);
  vertical-align: middle;
  color: var(--color-success-text);
}

/* "See all" link at the bottom of a truncated bucket */
.tasks-bucket-more {
  padding: 10px 16px;
  text-align: center;
  background: var(--color-surface-container-low);
  border-top: 1px solid var(--color-surface-container-high);
  font-size: var(--md-sys-typescale-body-dense-size);
}
.tasks-bucket-more a { color: var(--color-primary-bright); text-decoration: none; font-weight: 500; }
.tasks-bucket-more a:hover { text-decoration: underline; }

/* ── Activity drawer (slide-in side panel) ─────────────────────────────── */
/* The drawer is `aria-modal="true"`, and at z-index 49/50 it was under every
   piece of app chrome: the top bar (100), the mobile tab bar (200), the deal
   page's FAB (210) and the mobile sidebar (250). On a phone that buried its
   own header — so the Close button could not be tapped — and left the tab bar
   floating over a modal dialog. 290/291 clears all of them while staying
   below every overlay that can open FROM the drawer — .modal-overlay (300)
   and the destructive-confirm .dialog-overlay (500), which is what removing
   an attachment puts on screen. */
.drawer-backdrop {
  position: fixed; inset: 0;
  background: color-mix(in srgb, var(--md-sys-color-scrim) 32%, transparent);
  z-index: 290;
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s;
}
.drawer-backdrop.is-open { opacity: 1; pointer-events: auto; }

/* MD3 modal side sheet: surface-container-low, large corners on the edge
   that faces the content, level 1. Wider than the spec's 400px — it holds
   the full activity editor. */
.drawer {
  position: fixed;
  top: 0;
  right: 0;
  height: 100vh;
  height: 100dvh;
  width: 480px;
  max-width: 100vw;
  background: var(--md-sys-color-surface-container-low);
  border-start-start-radius: var(--md-sys-shape-corner-large);
  border-end-start-radius: var(--md-sys-shape-corner-large);
  box-shadow: var(--md-sys-elevation-1);
  z-index: 291;
  transform: translateX(100%);
  transition: transform .25s ease;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}
.drawer.is-open { transform: translateX(0); }

/* RTL: slide in from the left */
[dir="rtl"] .drawer {
  right: auto;
  left: 0;
  transform: translateX(-100%);
}
[dir="rtl"] .drawer.is-open { transform: translateX(0); }

.drawer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid var(--md-sys-color-outline-variant);
  position: sticky;
  top: 0;
  background: var(--md-sys-color-surface-container-low);
  z-index: 1;
}
.drawer-title {
  margin: 0;
  font-size: var(--md-sys-typescale-title-large-size);
  line-height: var(--md-sys-typescale-title-large-line);
  font-weight: var(--md-sys-typescale-title-large-weight);
}
.drawer-close {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--color-on-surface-var);
  padding: 6px;
  border-radius: 50%;
  display: flex;
  align-items: center;
}

.drawer-body { padding: 16px 20px; display: flex; flex-direction: column; gap: 14px; }

.drawer-field { display: flex; flex-direction: column; gap: 4px; }
/* The Log Activity and Log Call sheets label their fields as the drawer does. */
.drawer-field label,
.activity-form .form-group label,
.log-call-sheet .form-group label {
  font-size: var(--md-sys-typescale-body-small-size);
  letter-spacing: .3px;
  color: var(--color-on-surface-var);
  font-weight: 600;
}
.drawer-field input,
.drawer-field select,
.drawer-field textarea {
  padding: 8px 10px;
  border: 1px solid var(--md-sys-color-outline);
  border-radius: var(--md-sys-shape-corner-extra-small);
  background: var(--color-surface-container-lowest);
  font-family: inherit;
  font-size: var(--md-sys-typescale-body-medium-size);
  color: var(--color-on-surface);
}
/* Grow taller only: the default `resize: both` let a drag widen the notes
   past the drawer, pushing RTL text off its edge. */
.drawer-field textarea { resize: vertical; }
.drawer-field input:focus,
.drawer-field select:focus,
.drawer-field textarea:focus {
  outline: none;
  border-color: var(--md-sys-color-primary);
  box-shadow: inset 0 0 0 1px var(--md-sys-color-primary);
}
.drawer-field input:disabled,
.drawer-field select:disabled {
  background: var(--color-surface-container-low);
  color: var(--color-on-surface-var);
  cursor: not-allowed;
}
.drawer-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }

/* A heading every few fields, so the drawer reads as an outline instead of a
   column of seventeen identical boxes — on a phone the body is three screens
   tall and every field looks the same, so nothing tells you where to stop. */
.drawer-section {
  margin: 6px 0 0;
  padding-top: 12px;
  border-top: 1px solid var(--color-surface-container-high);
  font-size: var(--md-sys-typescale-body-small-size);
  letter-spacing: .3px;
  font-weight: 700;
  color: var(--color-on-surface-var);
}

/* Mark-as-done used to sit below the attachments, the links and the history
   disclosure — three screens down on a phone, which made the drawer's primary
   action the hardest thing in it to reach. */
.drawer-foot {
  position: sticky;
  bottom: 0;
  display: flex;
  gap: 8px;
  padding: 12px 20px calc(12px + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--color-surface-container-high);
  background: var(--color-surface);
  margin-top: auto;
  flex-wrap: wrap;
}
.drawer-foot .btn { flex: 1 1 auto; justify-content: center; }
.drawer-foot .btn--icon { flex: 0 0 auto; }

/* ── The location control (drawer + both log modals) ───────────────────── */
.loc-field { display: flex; gap: 6px; align-items: stretch; }
.loc-field input { flex: 1 1 auto; min-width: 0; }
.loc-btn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 38px;
  padding: 0 10px;
  border: 1px solid var(--color-surface-container-high);
  border-radius: var(--md-sys-shape-corner-small);
  background: var(--color-surface-container-low);
  color: var(--color-primary-bright);
  cursor: pointer;
}
.loc-btn:hover:not(:disabled) { background: var(--color-surface-container-high); }
.loc-btn:disabled { cursor: progress; opacity: .7; }
.loc-btn .material-symbols-outlined { font-size: 20px; }
.loc-btn.is-busy .material-symbols-outlined { animation: spin .7s linear infinite; }

.loc-links:empty { display: none; }
.loc-map-link {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: var(--md-sys-typescale-body-dense-size);
  color: var(--color-primary-bright);
  text-decoration: none;
}
.loc-map-link:hover { text-decoration: underline; }
.loc-map-link .material-symbols-outlined { font-size: 14px; }

.drawer-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 0;
  border-top: 1px solid var(--color-surface-container-low);
  font-size: var(--md-sys-typescale-body-dense-size);
  color: var(--color-on-surface);
}
.drawer-meta-label {
  font-size: var(--md-sys-typescale-body-small-size);
  letter-spacing: .3px;
  color: var(--color-on-surface-var);
  font-weight: 600;
}
.drawer-meta a { color: var(--color-primary-bright); text-decoration: none; }
.drawer-meta a:hover { text-decoration: underline; }

.drawer-meta--links { align-items: flex-start; flex-direction: column; gap: 6px; }
.drawer-link-list {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  width: 100%;
}
.drawer-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 10px;
  background: var(--color-surface-container-low);
  border: 1px solid var(--color-surface-container-high);
  border-radius: var(--radius-pill);
  font-size: var(--md-sys-typescale-body-dense-size);
  color: var(--color-on-surface);
  text-decoration: none;
}
.drawer-link:hover {
  background: var(--color-surface-container-high);
  color: var(--color-primary-bright);
  text-decoration: none;
}

.drawer-history { font-size: var(--md-sys-typescale-body-medium-size); }
.drawer-history > summary {
  cursor: pointer;
  padding: 8px 0;
  color: var(--color-on-surface-var);
  font-weight: 500;
}
.drawer-history-list { display: flex; flex-direction: column; gap: 6px; padding-top: 8px; }
.drawer-history-row {
  display: flex;
  justify-content: space-between;
  padding: 6px 10px;
  background: var(--color-surface-container-low);
  border-radius: var(--md-sys-shape-corner-small);
  font-size: var(--md-sys-typescale-body-dense-size);
}
.drawer-history-action { font-weight: 500; color: var(--color-on-surface); }
.drawer-history-when { color: var(--color-on-surface-var); }
.drawer-loading,
.drawer-error,
.drawer-empty { padding: 16px; color: var(--color-on-surface-var); font-size: var(--md-sys-typescale-body-dense-size); }

/* Mobile: drawer + buckets adapt */
@media (max-width: 600px) {
  /* overflow:hidden so the BODY owns the scroll and the sticky footer has
     something to stick to — otherwise the whole drawer scrolls and the footer
     rides away with it. */
  .drawer { width: 100vw; overflow: hidden; }
  .drawer-body { flex: 1 1 auto; overflow-y: auto; -webkit-overflow-scrolling: touch; }
  .tasks-strip { gap: 6px; }
  .tasks-strip-chip { padding: 6px 10px; font-size: var(--md-sys-typescale-body-small-size); }
  .task-row { padding: 10px 12px; gap: 8px; }
  .task-subject { font-size: var(--md-sys-typescale-body-medium-size); }
  .drawer-row { grid-template-columns: 1fr; }
}

/* Dark mode: warning text/bg tokens already swap to dark-friendly values
   in tokens.css, so the light-mode rules above already render correctly. */

/* ── Top-bar account menu ───────────────────────────────────────────────── */
.user-menu-wrap { position: relative; }

/* Carries the organization and the signed-in user in one control. Both used to
   render separately in the bar — the org as a chip, the user in the sidebar. */
.account-btn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  height: 40px;
  padding: 0 6px 0 12px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  background: none;
  color: inherit;
  font-family: inherit;
  cursor: pointer;
  max-width: 260px;
}
.account-btn:hover { background: var(--color-surface-container); }
.account-btn[aria-expanded="true"] {
  background: var(--color-surface-container);
  border-color: var(--color-outline-variant);
}
.account-btn__text {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  line-height: 1.25;
  min-width: 0;
}
.account-btn__org {
  font-size: var(--md-sys-typescale-label-large-size);
  font-weight: 700;
  max-width: 150px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.account-btn__user {
  font-size: var(--md-sys-typescale-label-medium-size);
  color: var(--color-on-surface-var);
  max-width: 150px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.account-btn__caret { font-size: 18px; color: var(--color-on-surface-var); }
/* The bar is narrow on tablets long before the mobile breakpoint; the avatar
   alone still identifies the account, and the org name is in the menu header. */
@media (max-width: 900px) {
  .account-btn { padding: 0 4px; max-width: none; }
  .account-btn__text, .account-btn__caret { display: none; }
}
[dir="rtl"] .account-btn__text { align-items: flex-start; }

.nav-user-avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--color-primary);
  color: var(--color-on-primary);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: 700;
  letter-spacing: 0.02em;
  flex-shrink: 0;
}
.nav-user-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Drops from the account button in the top bar. Logical properties, so RTL
   needs no override — rtl.css used to carry one only because this was
   `left: 100%; margin-left`. */
.user-menu-popover {
  position: absolute;
  top: 100%;
  inset-inline-end: 0;
  margin-top: 8px;
  min-width: 248px;
  overflow: hidden;
  z-index: 60;
}

.user-menu-popover__header {
  padding: 12px 14px;
  border-bottom: 1px solid var(--color-outline-variant);
}
.user-menu-popover__name {
  font-size: var(--md-sys-typescale-body-medium-size);
  font-weight: 600;
  color: var(--color-on-surface);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.user-menu-popover__email {
  margin-top: 2px;
  font-size: var(--md-sys-typescale-body-small-size);
  color: var(--color-on-surface-var);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.user-menu-popover__item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  background: none;
  border: none;
  cursor: pointer;
  padding: 10px 14px;
  font-family: var(--font-body);
  font-size: var(--md-sys-typescale-body-dense-size);
  color: var(--color-on-surface);
  text-align: left;
}
.user-menu-popover__item:hover { background: var(--color-surface-container); }
.user-menu-popover__sep {
  height: 1px;
  margin: 4px 0;
  background: var(--color-outline-variant);
}
/* The language item swaps a glyph for the icon, so it needs the icon's box. */
.user-menu-popover__item .lang-toggle__label {
  width: 18px;
  text-align: center;
  font-weight: 700;
  flex-shrink: 0;
}
.user-menu-popover__item .material-symbols-outlined {
  font-size: 18px;
  color: var(--color-on-surface-var);
}

[data-theme="dark"] .user-menu-popover {
  background: var(--color-surface-container-low);
  border-color: var(--color-outline);
}

/* The feedback SDK's floating button is never shown: it sat on every page's
   bottom corner, over drawer footers and pagers. This menu's "Send feedback"
   opens the same dialog (ExtFeedback.open() in app.js). */
#ext-fb-fab,
.ext-fb-fab { display: none !important; }

/* The base rule already drops the menu from the top-bar button; on a narrow
   screen it only needs to stop being wider than the viewport. */
@media (max-width: 767px) {
  .user-menu-popover {
    min-width: 0;
    max-width: calc(100vw - 16px);
  }
}

/* ── Followers + @Mentions + Notifications (v48) ────────────────────── */

/* Mention chip — inline span in rendered activity bodies */
.mention-chip {
  display: inline-block;
  background: var(--md-sys-color-surface-container-high);
  color: var(--color-primary);
  border-radius: var(--md-sys-shape-corner-small);
  padding: 0 6px;
  font-weight: 600;
  white-space: nowrap;
  cursor: default;
}
[data-theme="dark"] .mention-chip {
  background: var(--md-sys-color-tertiary-container);
  color: var(--md-sys-color-on-tertiary-container);
}

/* Mention autocomplete dropdown — positioned absolutely near the caret */
.mention-suggest {
  position: absolute;
  z-index: 9000;
  min-width: 220px;
  max-width: 320px;
  max-height: 280px;
  overflow-y: auto;
  padding: 4px;
}
.mention-suggest__item {
  display: flex;
  gap: 8px;
  align-items: center;
  padding: 6px 8px;
  border-radius: var(--md-sys-shape-corner-small);
  cursor: pointer;
}
.mention-suggest__item:hover,
.mention-suggest__item.is-active {
  background: var(--md-sys-color-surface-container-high);
}
[data-theme="dark"] .mention-suggest__item:hover,
[data-theme="dark"] .mention-suggest__item.is-active {
  background: rgba(255, 255, 255, 0.05);
}
.mention-suggest__meta { flex: 1; min-width: 0; }
.mention-suggest__name { font-size: var(--md-sys-typescale-body-dense-size); font-weight: 600; }
.mention-suggest__email {
  font-size: var(--md-sys-typescale-label-small-size); color: var(--md-sys-color-on-surface-variant);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Notification bell — unread badge stacked on the icon */
.notification-bell { position: relative; }
.notification-bell__badge {
  position: absolute;
  top: 4px;
  inset-inline-end: 4px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  /* MD3 large badge: error / on-error, label-small, full corners. */
  background: var(--md-sys-color-error);
  color: var(--md-sys-color-on-error);
  font-variant-numeric: tabular-nums;
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: var(--md-sys-typescale-label-small-weight);
  line-height: 16px;
  border-radius: var(--md-sys-shape-corner-full);
  text-align: center;
  pointer-events: none;
}

/* Notification dropdown — opens from the bell button */
.notification-dropdown {
  position: fixed;
  width: 360px;
  max-width: calc(100vw - 16px);
  z-index: 9000;
  display: flex;
  flex-direction: column;
  max-height: min(70vh, 520px);
}
.notification-dropdown__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 14px;
  border-bottom: 1px solid var(--md-sys-color-outline-variant);
}
.notification-dropdown__list { flex: 1; overflow-y: auto; }
.notification-dropdown__loading,
.notification-dropdown__empty { padding: 20px; text-align: center; }
.notification-dropdown__footer {
  padding: 8px 14px;
  border-top: 1px solid var(--md-sys-color-outline-variant);
  text-align: center;
}
/* The desktop-notification offer at the foot of the bell (_notificationBell.js). */
.notification-dropdown__desktop {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 8px 14px;
  border-top: 1px solid var(--md-sys-color-outline-variant);
  background: var(--md-sys-color-surface-container-low);
  color: var(--md-sys-color-on-surface-variant);
  font-size: var(--md-sys-typescale-body-small-size);
}
.notification-dropdown__desktop .material-symbols-outlined { flex: none; color: var(--md-sys-color-primary); }
.notification-dropdown__desktop .btn { margin-inline-start: auto; flex: none; white-space: nowrap; }
/* The account menu's What's New, for phones only (index.html). */
.user-menu-popover__item--phone { display: none; }
@media (max-width: 767px) {
  .user-menu-popover__item--phone:not([hidden]) { display: flex; }
}

/* Notification list item — used in dropdown + full center page */
.notification-item {
  display: flex;
  gap: 10px;
  padding: 10px 14px;
  align-items: flex-start;
  border-bottom: 1px solid var(--md-sys-color-outline-variant);
  text-decoration: none;
  color: inherit;
  position: relative;
}
[data-theme="dark"] .notification-item { border-color: rgba(255, 255, 255, 0.06); }
.notification-item:hover {
  background: var(--md-sys-color-surface-container-high);
}
[data-theme="dark"] .notification-item:hover { background: rgba(255, 255, 255, 0.04); }
.notification-item.is-unread { background: rgba(247, 190, 0, 0.08); }
.notification-item.is-unread:hover { background: rgba(247, 190, 0, 0.14); }
/* A notice about a quote, from no person: a leading icon in the avatar's
   circle (Material 3 lists), so it lines up with the mentions. */
.notification-item__icon { background: var(--md-sys-color-secondary-container); color: var(--md-sys-color-on-secondary-container); }
.notification-item__main { flex: 1; min-width: 0; }
.notification-item__title { font-size: var(--md-sys-typescale-body-dense-size); line-height: 1.4; }
/* An automation's message is its title, clamped as a preview is. */
.notification-item__message {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  overflow-wrap: anywhere;
}
.notification-item__preview {
  font-size: var(--md-sys-typescale-body-small-size);
  color: var(--md-sys-color-on-surface-variant);
  margin-top: 2px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.notification-item__meta { font-size: var(--md-sys-typescale-label-small-size); margin-top: 4px; }
.notification-item__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--md-sys-color-error);
  margin-top: 6px;
  flex-shrink: 0;
}

/* Notifications page (route) */
.notifications-page__filters {
  display: flex;
  gap: 8px;
  margin-bottom: 14px;
}
.notifications-page__filters .chip {
  padding: 6px 14px;
  border: 1px solid var(--md-sys-color-outline-variant);
  background: var(--md-sys-color-surface-container);
  border-radius: var(--md-sys-shape-corner-full);
  font-size: var(--md-sys-typescale-body-dense-size);
  font-weight: 500;
  cursor: pointer;
}
.notifications-page__filters .chip.is-active {
  background: var(--color-primary);
  color: var(--color-on-primary);
  border-color: transparent;
}
.notifications-page__list {
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-medium);
  background: var(--md-sys-color-surface-container);
  overflow: hidden;
}
.notifications-page__list .notification-item:last-child { border-bottom: 0; }

/* ─────────────────────────────────────────────────────────────────────────
   Record header pills (owner + followers) — used on deal/org/contact
   ───────────────────────────────────────────────────────────────────────── */
.rh-pills {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}
.rh-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 4px 10px 4px 6px;
  background: var(--color-surface-container);
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-full);
  cursor: pointer;
  font: inherit;
  color: var(--color-on-surface);
  line-height: 1.1;
  transition: background .15s ease, border-color .15s ease;
}
.rh-pill:hover:not([disabled]) {
  background: var(--color-surface-container-high);
  border-color: var(--color-outline);
}
.rh-pill[disabled], .rh-pill.is-static { cursor: default; opacity: .9; }
.rh-pill .avatar-sm { width: 24px; height: 24px; flex-shrink: 0; }
.rh-pill__text { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.15; min-width: 0; }
.rh-pill__title { font-size: var(--md-sys-typescale-body-dense-size); font-weight: 600; max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rh-pill__sub   { font-size: var(--md-sys-typescale-label-small-size); color: var(--color-on-surface-var); margin-top: 1px; }
.rh-pill__chev  { font-size: 18px; color: var(--color-on-surface-var); margin-inline-start: 2px; }
.rh-pill .material-symbols-outlined { font-size: 18px; }
.rh-followers .rh-pill__title { font-size: var(--md-sys-typescale-body-dense-size); font-weight: 500; }

[data-theme="dark"] .rh-pill {
  background: var(--md-sys-color-surface-container-high);
  border-color: var(--md-sys-color-outline-variant);
  color: var(--md-sys-color-on-surface);
}
[data-theme="dark"] .rh-pill:hover:not([disabled]) {
  background: rgba(255,255,255,.06);
  border-color: rgba(255,255,255,.15);
}

/* Popover for both pills */
.rh-popover {
  position: fixed;
  z-index: 1000;
  padding: 12px;
  min-width: 240px;
  /* placeMenu caps a menu at the screen's width inline; these keep theirs. */
  max-width: min(360px, calc(100vw - 16px)) !important;
}
.rh-popover__title { font-size: var(--md-sys-typescale-body-dense-size); font-weight: 600; margin-bottom: 8px; color: var(--color-on-surface-var); }
.rh-popover__body { margin-bottom: 12px; }
.rh-popover__body select.input { width: 100%; }
.rh-popover__footer {
  display: flex; justify-content: flex-end; gap: 6px;
  border-top: 1px solid var(--md-sys-color-outline-variant); padding-top: 10px; margin-top: 8px;
}

.rh-popover__list { max-height: 240px; overflow-y: auto; margin: -2px -4px 6px; }
.rh-follower-row {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 8px; border-radius: var(--md-sys-shape-corner-small);
}
.rh-follower-row:hover { background: var(--color-surface-container); }
[data-theme="dark"] .rh-follower-row:hover { background: rgba(255,255,255,.05); }
.rh-follower-row__name { flex: 1; font-size: var(--md-sys-typescale-body-dense-size); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rh-follower-row__remove { margin-inline-start: auto; }

.rh-followers__empty { padding: 10px 8px; font-size: var(--md-sys-typescale-body-dense-size); }

.rh-popover__actions {
  display: flex; flex-direction: column; gap: 2px;
  border-top: 1px solid var(--md-sys-color-outline-variant); padding-top: 6px; margin: 6px -4px 0;
}
.rh-popover__action {
  display: flex; align-items: center; gap: 8px;
  background: transparent; border: 0;
  padding: 8px; border-radius: var(--md-sys-shape-corner-small);
  font: inherit; color: inherit; cursor: pointer; text-align: start;
}
.rh-popover__action:hover { background: var(--color-surface-container); }
[data-theme="dark"] .rh-popover__action:hover { background: rgba(255,255,255,.05); }
.rh-popover__action .material-symbols-outlined { font-size: 18px; color: var(--color-on-surface-var); }
.rh-popover__action:disabled { cursor: default; opacity: .38; }
.rh-popover__action:disabled:hover { background: transparent; }
.rh-popover__note { margin: 0; padding: 0 8px 6px; font-size: var(--md-sys-typescale-body-small-size); }

/* Mobile: pills wrap, full-width popovers */
@media (max-width: 600px) {
  .rh-pill__sub { display: none; }
  .rh-pill__title { max-width: 90px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   REPORT BUILDER
   ═══════════════════════════════════════════════════════════════════════════ */

/* filter-chip BEM modifier alias (new code uses --active suffix) */
.filter-chip--active {
  background: var(--color-primary);
  color: var(--color-on-primary);
  border-color: var(--color-primary);
}

/* Deal/activity status badges */
.status-badge--won  { color: var(--md-sys-color-success); }
.status-badge--won .status-dot  { background: var(--md-sys-color-success); }
.status-badge--lost { color: var(--color-error); }
.status-badge--lost .status-dot { background: var(--color-error); }
.status-badge--open { color: var(--color-primary); }
.status-badge--open .status-dot { background: var(--color-primary-container); }

/* icon-btn danger variant */
.icon-btn--danger:hover { background: color-mix(in srgb, var(--md-sys-color-error) 10%, transparent); color: var(--color-error); }

/* ── Reports layout ────────────────────────────────────────────────────────── */
/* ── Reports landing: every saved report as a card, grouped by entity ──── */
.rl-head {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-bottom: var(--space-4);
}
.rl-head__search { flex: 1 1 280px; max-width: 420px; }
.rl-head .btn { margin-inline-start: auto; }
.rl-group { margin-bottom: var(--space-4); }
.rl-group__title {
  display: flex; align-items: center; gap: 8px;
  margin: 0 0 var(--sp-3); font-size: var(--md-sys-typescale-body-medium-size); font-weight: 600;
  color: var(--color-on-surface-var);
}
.rl-group__count {
  font-size: var(--md-sys-typescale-body-small-size); font-weight: 600; padding: 0 8px; border-radius: var(--md-sys-shape-corner-full);
  background: var(--color-surface-container);
}
.rl-others-toggle {
  display: inline-flex; align-items: center; gap: 8px; min-height: 48px; padding: 0 12px; margin-inline-start: -12px;
  border: none; border-radius: var(--md-sys-shape-corner-full); background: none; cursor: pointer;
  font: inherit; color: inherit;
}
.rl-others-toggle:hover { background: var(--color-surface-container); }
.rl-others-toggle:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.rl-author { margin-bottom: var(--space-3); }
.rl-author__name {
  display: flex; align-items: center; gap: 8px; margin: 0 0 var(--space-2);
  font-size: var(--md-sys-typescale-body-small-size); font-weight: 600; color: var(--color-on-surface-var);
}
/* min(260px, 100%): on a phone narrower than one card the track shrinks to the
   page instead of pushing the grid sideways. */
.rl-grid {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr));
}
.rl-card {
  display: flex; align-items: flex-start; gap: 12px; min-width: 0;
  padding: 14px 16px; border-radius: var(--md-sys-shape-corner-medium); text-decoration: none; color: inherit;
  border: 1px solid var(--color-outline-variant);
  background: var(--color-surface);
  transition: box-shadow .15s, border-color .15s;
}
.rl-card:hover { border-color: var(--color-primary); box-shadow: var(--shadow-1); }
.rl-card:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.rl-card__icon {
  flex: 0 0 auto; font-size: 20px; padding: 8px; border-radius: var(--md-sys-shape-corner-medium);
  background: var(--color-primary-container); color: var(--color-primary);
}
.rl-card__text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
/* Two lines, then an ellipsis — enough for a real report name. */
.rl-card__name {
  font-weight: 600; font-size: var(--md-sys-typescale-body-medium-size); line-height: 1.35; overflow-wrap: anywhere;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.rl-card__kind { font-size: var(--md-sys-typescale-body-small-size); line-height: 1.4; color: var(--color-on-surface-var); }
.rl-card__meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin-top: 4px;
  font-size: var(--md-sys-typescale-body-small-size); color: var(--color-on-surface-var);
}
.rl-card__badge {
  display: inline-flex; align-items: center; gap: 4px; padding: 1px 8px; border-radius: var(--md-sys-shape-corner-full);
  font-size: var(--md-sys-typescale-label-small-size); font-weight: 600; background: var(--color-surface-container); color: var(--color-on-surface-var);
}
.rl-card__badge .material-symbols-outlined { font-size: 14px; }
/* Star (M3 toggle icon button: outlined star off, filled star on). It sits
   beside the card's link, in the card's upper end corner, so the card leaves
   that corner free. Tertiary when on, as the deal page's primary-person star. */
.rl-cardwrap { position: relative; min-width: 0; display: flex; }
.rl-cardwrap > .rl-card { flex: 1; padding-inline-end: 52px; }
.rl-star {
  position: absolute; inset-block-start: 6px; inset-inline-end: 6px;
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border: none; border-radius: var(--md-sys-shape-corner-full);
  background: none; cursor: pointer; color: var(--color-on-surface-var);
}
.rl-star:hover { color: var(--color-on-tertiary-container); background: var(--color-tertiary-container); }
.rl-star:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.rl-star.is-starred { color: var(--md-sys-color-tertiary); }
@media (any-pointer: coarse) { .rl-star { width: 48px; height: 48px; inset-block-start: 2px; inset-inline-end: 2px; } }
/* A report's kind and what one of its rows is, under its title (with the
   title in one column, so a phone keeps them together above the buttons). */
.rb-pageheader__titles { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.rb-pageheader__titleline { display: flex; align-items: center; gap: 8px; min-width: 0; }
.rb-kind {
  display: flex; flex-wrap: wrap; align-items: flex-start; gap: 4px 12px; margin: 0;
  font-size: var(--md-sys-typescale-body-dense-size); color: var(--color-on-surface-var);
}
.rb-kind__row { display: inline-flex; align-items: flex-start; gap: 4px; font-weight: 500; color: var(--color-on-surface); }
.rb-kind__row .material-symbols-outlined { font-size: 16px; color: var(--color-primary); }
[data-theme="dark"] .rl-card { background: var(--color-surface-container-low); }

/* ── Report config area ───────────────────────────────────────────────────── */
.report-config-area {
  min-height: 300px;
}

/* ── Filter bar ──────────────────────────────────────────────────────────── */

/* ── KPI row (small variant) ──────────────────────────────────────────────── */
.kpi-grid--sm {
  /* auto-fit, not auto-fill: collapse the empty tracks so the cards that exist
     share the full width instead of sitting in narrow tracks beside dead space. */
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  margin-bottom: 0;
}

/* ── Report modal ─────────────────────────────────────────────────────────── */
/* Rides the shared #modal-overlay dialog; the tabs, panes and footer bring
   their own edge spacing, so the body is an unpadded flex column. */
.modal.report-modal { width: 820px; }   /* .modal's max-width:100% caps it; the phone sheet stays full-width */
.modal.report-modal .modal__body {
  padding: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-height: 0;
}


.rb-chartcard__notice {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: var(--md-sys-typescale-label-small-size);
  line-height: 1.3;
  color: var(--color-on-surface-var);
  cursor: help;
}
.rb-chartcard__notice .material-symbols-outlined { font-size: 14px; }
/* The report's notices, under its filters: one row, at its end, wrapping. */
.rb-notices { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 4px 16px; }

/* ── Report modal: template gallery ───────────────────────────────────────── */
/* Reuses .settings-tabs / .settings-tab__btn — the shared horizontal strip.
   Only the dialog's own edge spacing is different. */
/* .modal is already a max-height flex column — keep the chrome fixed so only
   the pane scrolls, otherwise 54 cards push the header off-screen. */
.report-modal__tabs { padding: 0 20px; margin-bottom: 0; flex: none; }

.report-modal__pane {
  display: flex;
  flex-direction: column;
  min-height: 0;   /* lets the inner list actually scroll inside the flex column */
}

.report-modal__tpl-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  padding: 14px 20px 10px;
}
.report-modal__tpl-head .caption { flex: 1; min-width: 0; }

/* The app's search bar (.search-bar); only its width is the dialog's. */
.rm-tpl-search { flex: 0 1 260px; }

/* Fixed height + own scroller: 54 cards must not grow the dialog past the
   viewport, and the header and tabs stay put while the list scrolls. */
.report-modal__tpl-list {
  flex: 1 1 auto;
  min-height: 200px;
  overflow-y: auto;
  padding: 0 20px 16px;
}

.rm-tpl-group + .rm-tpl-group { margin-top: 18px; }
.rm-tpl-group__title {
  margin: 0 0 8px;
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: 700;
  letter-spacing: .5px;
  color: var(--color-on-surface-var);
}
.rm-tpl-group__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}
/* A record has one to three kinds: a list, not a half-empty grid. */
.rm-tpl-group__grid--list { grid-template-columns: minmax(0, 1fr); }

.rm-tpl-card {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  width: 100%;
  padding: 10px 12px;
  text-align: start;
  background: var(--color-surface);
  /* Border, not just a background tint — the card has to read as a distinct
     surface in light mode too. */
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-medium);
  cursor: pointer;
  font: inherit;
  color: inherit;
  transition: border-color .12s ease, background .12s ease;
}
.rm-tpl-card:hover  { border-color: var(--color-primary); background: var(--color-surface-variant); }
.rm-tpl-card:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 1px;
}
.rm-tpl-card--busy { opacity: .55; pointer-events: none; }

.rm-tpl-card__icon {
  font-size: 20px;
  color: var(--color-primary);
  flex: none;
  margin-top: 1px;
}
.rm-tpl-card__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.rm-tpl-card__name { font-size: var(--md-sys-typescale-body-dense-size); font-weight: 600; }
.rm-tpl-card__desc {
  font-size: var(--md-sys-typescale-body-small-size);
  line-height: 1.35;
  color: var(--color-on-surface-var);
}
/* What one row of the report is: the line a reader picks a kind by. Text in
   the body colour, the icon in the brand one, so it does not read as a link. */
.rm-tpl-card__row {
  display: inline-flex; align-items: flex-start; gap: 4px; margin-top: 4px;
  font-size: var(--md-sys-typescale-body-small-size); font-weight: 500; color: var(--color-on-surface);
}
.rm-tpl-card__row .material-symbols-outlined { font-size: 16px; color: var(--color-primary); }

/* ── Mobile: report modal ─────────────────────────────────────────────────── */
@media (max-width: 700px) {
  .rm-tpl-group__grid { grid-template-columns: 1fr; }
  .report-modal__tpl-head { flex-direction: column; align-items: stretch; }
  /* flex-basis is main-axis: once the head stacks, a 200px basis is a 200px
     TALL search box. Reset the basis, not just the width. */
  .rm-tpl-search { flex: none; width: 100%; }
}

/* ── Report Builder v2 — toolbar, chips, popover ─────────────────────────── */

.report-filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 32px;
  padding: 4px 8px 4px 10px;
  background: var(--color-surface-variant);
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-small);
  font-size: var(--md-sys-typescale-body-small-size);
  cursor: pointer;
  transition: background .15s, border-color .15s;
  max-width: 280px;
  /* It may shrink; its label clips inside (.rb-sumchip__edit), so its x's
     target is not clipped with it. */
  min-width: 0;
  white-space: nowrap;
  color: var(--color-on-surface);
}
.report-filter-chip:hover {
  background: var(--color-surface-container);
  border-color: var(--color-primary);
}
.report-filter-chip__close {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px; height: 16px;
  border-radius: 50%;
  font-size: var(--md-sys-typescale-body-medium-size);
  line-height: 1;
  margin-inline-start: 2px;
  color: var(--color-on-surface);
}
.report-filter-chip__close:hover { background: rgba(0,0,0,.1); }


/* Modal overlay for filter / column-picker popovers — clean separation
   from the underlying page so it never looks like it's bleeding through KPIs. */
.report-popover-overlay {
  position: fixed;
  inset: 0;
  z-index: 400;
  background: rgba(15, 23, 42, .35);
  backdrop-filter: blur(2px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  animation: rp-overlay-in .12s ease-out;
}
@keyframes rp-overlay-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.report-popover {
  width: 420px;
  max-width: 100%;
  max-height: 80vh;
  overflow-y: auto;
  padding: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: 10px;
  animation: rp-pop-in .15s ease-out;
}
@keyframes rp-pop-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
.report-popover__header {
  display: flex;
  align-items: center;
  margin: -4px 0 4px;
}
.report-popover__heading {
  font-size: var(--md-sys-typescale-body-large-size);
  font-weight: 600;
  flex: 1;
}
.report-popover .icon-btn--sm {
  width: 28px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--md-sys-shape-corner-small);
  background: transparent; border: 0;
  cursor: pointer;
  color: var(--color-on-surface);
}
.report-popover .icon-btn--sm:hover { background: var(--color-surface-variant); }
.report-popover__row { display: flex; flex-direction: column; gap: 4px; }
.report-popover__row label.caption {
  font-size: var(--md-sys-typescale-label-small-size);
  letter-spacing: .5px;
  font-weight: 600;
  opacity: .7;
}
.report-popover__row select,
.report-popover__row input {
  width: 100%;
  padding: 6px 8px;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-small);
  font-size: var(--md-sys-typescale-body-dense-size);
  background: var(--color-surface);
  color: var(--color-on-surface);
}
.report-popover__values,
.report-popover__cols {
  max-height: min(420px, 60vh);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 4px 0;
}
.report-popover__group {
  padding: 8px 4px 2px;
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: 600;
  letter-spacing: .04em;
  color: var(--color-on-surface-var);
}
.report-popover__group:first-child { padding-top: 0; }
.report-popover__check {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px;
  font-size: var(--md-sys-typescale-body-dense-size);
  cursor: pointer;
}
.report-popover__check:hover { background: var(--color-surface-variant); border-radius: var(--md-sys-shape-corner-extra-small); }
/* A value's box sits at its name, as the lists' filter boxes do: the row's
   `input` rule is for the text boxes, not the checkboxes. */
.report-popover__check input { flex: 0 0 auto; width: auto; margin: 0; padding: 0; border: 0; accent-color: var(--color-primary); }
.report-popover__check input:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
/* The Columns dialog: the shown columns in order, a handle and arrows each. */
.rb-colrow { cursor: default; }
.rb-colrow[draggable="true"] { cursor: grab; }
.rb-colrow__handle { width: 18px; font-size: var(--md-sys-typescale-body-large-size); color: var(--color-on-surface-var); flex-shrink: 0; }
.rb-colrow__label { display: flex; align-items: center; gap: 6px; flex: 1; min-width: 0; cursor: pointer; }
.rb-colrow__move .material-symbols-outlined { font-size: 18px; }
.rb-colrow--drag { opacity: .5; }
.rb-colrow--drop { box-shadow: inset 0 2px 0 var(--color-primary); }
@media (max-width: 768px) {
  /* A finger cannot drag here: the arrows order, and the rows are finger-sized. */
  .rb-colrow { min-height: 44px; }
  .rb-colrow__handle { display: none; }
}
.report-popover__footer {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid var(--md-sys-color-outline-variant);
}

/* Sortable table header (used on .data-table--report) */
.data-table--report thead th {
  position: sticky;
  top: 0;
  background: var(--color-surface);
  z-index: 1;
}

[data-theme="dark"] .report-filter-chip {
  background: var(--color-surface-variant);
  border-color: var(--md-sys-color-outline-variant);
  color: var(--color-on-surface);
}
[data-theme="dark"] .report-filter-chip:hover { background: var(--color-surface-container); }
[data-theme="dark"] .report-popover__row select,
[data-theme="dark"] .report-popover__row input {
  background: var(--color-surface-container);
  border-color: var(--md-sys-color-outline-variant);
  color: var(--color-on-surface);
}
[data-theme="dark"] .data-table--report thead th { background: var(--color-surface); }
/* A report's columns at the widths its author set (_reportTable _sized): the
   table lays out by them. Text wraps, as on the records list; a word wider
   than its column stops at the edge, and so does a column's name. */
.data-table--sized { table-layout: fixed; }
.data-table--sized td { overflow: hidden; text-overflow: ellipsis; }
.data-table--sized :is(.rb-th__inner, .rb-th__btn) { min-width: 0; }
.data-table--sized :is(.rb-th__inner, .rb-th__btn) > span:first-child {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* While a report is edited, each column's edge sets its width: drag it, or
   press the arrows on it. 24px, on the header's end padding (widened to
   match), so never over a name or an arrow: Material 3 asks 44-48dp of a
   target, which a column's edge cannot have without covering the name. It
   stays inside its own header, which the next one would draw over. A thin
   line on the edge shows where; on a touch screen it always shows. */
.data-table th.rb-th--edge { padding-inline-end: 24px; }
.rb-colresize { position: absolute; top: 0; bottom: 0; inset-inline-end: 0; width: 24px; z-index: 2;
                cursor: col-resize; touch-action: none; }
.rb-colresize::after { content: ""; position: absolute; top: 25%; bottom: 25%; inset-inline-end: 0; width: 2px;
                       border-radius: 1px; background: var(--color-outline); opacity: 0; }
.rb-th:hover .rb-colresize::after, .rb-colresize:focus-visible::after { opacity: 1; }
.rb-colresize:focus-visible { outline: 2px solid var(--color-primary); outline-offset: -2px; }
@media (any-pointer: coarse) {
  .rb-colresize::after { opacity: 1; }
}

/* Record links inside a report row (_reportTable.js renderRowHtml).
   Real anchors, so right-click "Open in New Tab" and Cmd-click work — a <tr>
   with a click handler offers neither, which is why reviewing a report used to
   mean losing it every time you wanted to look at a record.

   A plain left-click on the row's own link is preventDefault()ed by
   analytics.js and opens in place, so the link must not read as a second
   control competing with the row: it inherits the cell's colour and only
   reveals itself on hover. Same bargain .task-entity-link strikes in the Tasks
   inbox. No align-self trick needed here — a cell anchor is inline and already
   hugs its text, so it cannot swallow the row's hit-box.

   --color-primary-bright is defined in both themes in tokens.css. */
.rb-cell-link {
  color: inherit;
  text-decoration: none;
}
.rb-cell-link:hover {
  color: var(--color-primary-bright);
  text-decoration: underline;
}
.rb-cell-link:focus-visible {
  outline: 2px solid var(--color-primary-bright);
  outline-offset: 2px;
  border-radius: var(--md-sys-shape-corner-extra-small);
}

/* ── Report Builder v2 — Stitch-inspired chart, pills, headers ───────────── */

/* Status pills — semantic colors (Stitch palette) */
.rb-pill {
  display: inline-block;
  padding: 3px 10px;
  border-radius: var(--md-sys-shape-corner-full);
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: 700;
  letter-spacing: .5px;
  line-height: 1.4;
}
.rb-pill--won  { background: var(--md-sys-color-success-container); color: var(--md-sys-color-on-success-container); }
.rb-pill--open { background: var(--md-sys-color-primary-container); color: var(--md-sys-color-on-primary-container); }
.rb-pill--lost { background: var(--md-sys-color-error-container);   color: var(--md-sys-color-on-error-container); }

/* Sortable th — Material Symbol arrows */
.rb-th { position: relative; }
.rb-th__inner {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  width: 100%;
}
.rb-th__sort {
  font-size: var(--md-sys-typescale-body-large-size) !important;
  opacity: .35;
  transition: opacity .15s;
}
.rb-th:hover .rb-th__sort { opacity: .8; }
.rb-th--sorted .rb-th__sort { opacity: 1; color: var(--color-primary); }
.rb-th--sorted { color: var(--color-primary); }

/* Refined KPI cards — Stitch typography (display value, small label) */
.kpi-grid--sm .kpi-card--sm {
  padding: 16px 18px;
}
.kpi-card--sm .kpi-card__label {
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: 700;
  letter-spacing: .5px;
  color: var(--color-on-surface-var);
  margin-bottom: 4px;
}
.kpi-card--sm .kpi-card__value {
  font-size: var(--md-sys-typescale-headline-small-size);
  font-weight: 800;
  line-height: 1.15;
  color: var(--color-on-surface);
}

/* ─────────────────────────────────────────────────────────────────────────
   Report Builder — Phase 1 (Pipedrive parity)
   .rb wraps the whole detail pane. All children are scoped so we don't
   leak styles into other views.
   ───────────────────────────────────────────────────────────────────────── */
/* One spacing rule for the page's blocks: the space between them is the
   gap of their parent (.rb, and .rb-canvas under it), never a block's own
   margin (Material 3: "Define padding and gaps on the parent container").
   24px on a desktop, 16px on a phone; "All reports" stands 6px above the
   title it belongs to. As properties, so what is placed against them (the
   pinned editing header) follows a change. */
.rb {
  --rb-gap: var(--space-4);
  --rb-pad: var(--space-1);
  --rb-back-gap: 6px;
  display: flex;
  flex-direction: column;
  gap: var(--rb-gap);
  padding: var(--rb-pad);
}
@media (max-width: 767px) {
  .rb { --rb-gap: var(--space-3); }
}

/* ── Header ──────────────────────────────────────────────────────────── */
.rb-head__title {
  font-size: var(--md-sys-typescale-headline-small-size);
  font-weight: 700;
  line-height: 1.25;
  margin: 0;
  outline: 0;
  padding: 2px 0;
  border-radius: var(--md-sys-shape-corner-extra-small);
  color: var(--color-on-surface);
  /* A name with no spaces breaks too, as on its card: it shares its line
     with the buttons, and must not run under them. */
  overflow-wrap: anywhere;
}
.rb-head__title:focus { background: var(--color-surface-container-low); padding: 2px 6px; }
/* While the report is edited the title is click-to-edit; show it. Read, it is
   a plain title. */
.rb-head__title[contenteditable="true"] { cursor: text; }
.rb-head__title[contenteditable="true"]:hover { background: var(--color-surface-container-low); }
/* Never squeezed by a long title: its room is the same, read or edited. */
.rb-title-edit { flex: none; opacity: .45; }
.rb-title-edit:hover { opacity: 1; }

/* Header buttons — Pipedrive look */
.rb-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 34px;
  padding: 0 12px;
  border-radius: var(--md-sys-shape-corner-small);
  border: 1px solid transparent;
  font-size: var(--md-sys-typescale-body-dense-size);
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: background .12s, border-color .12s, opacity .12s;
}
.rb-btn--primary {
  background: var(--color-primary);
  color: var(--color-on-primary);
  border-color: var(--color-primary);
}
.rb-btn--primary:hover { opacity: .92; }
/* Save sits disabled whenever the report is clean, which is most of the time.
   Without this it renders as a full-strength primary button that does nothing
   when clicked. Same opacity approach as .btn:disabled — it has to read on the
   ghost variant too, which a grey fill would not. The :hover half outranks
   .rb-btn--primary:hover above: equal specificity, later in source order. */
.rb-btn:disabled,
.rb-btn:disabled:hover,
.rb-icon-btn:disabled,
.rb-icon-btn:disabled:hover,
.rb-btn[aria-disabled="true"],
.rb-btn[aria-disabled="true"]:hover {
  opacity: .45;
  cursor: not-allowed;
}
.rb-btn--ghost {
  background: var(--color-surface-container-lowest);
  color: var(--color-on-surface);
  border-color: var(--color-outline-variant);
}
.rb-btn--ghost:hover { background: var(--color-surface-container-low); }
/* The lowest emphasis (Discard): the app's text button (.btn--ghost) colours,
   and the outlined button's fill on hover. */
.rb-btn--text { background: transparent; border-color: transparent; color: var(--color-on-surface-var); }
.rb-btn--text:hover { background: var(--color-surface-container-low); color: var(--color-on-surface); }
/* Two faces in one place (Edit and Done), each an icon and its label: both in
   the same cell, the other hidden, so the button is as wide as the wider. Each
   is centred whole, so the label stays next to its icon. */
.rb-btn__faces { display: inline-grid; }
.rb-btn__face { grid-area: 1 / 1; justify-self: center; display: inline-flex; align-items: center; gap: 6px; }
.rb-btn__face--other { visibility: hidden; }
.rb-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px; height: 34px;
  border-radius: var(--md-sys-shape-corner-small);
  background: transparent;
  border: 1px solid transparent;
  color: var(--color-on-surface-var);
  cursor: pointer;
}
.rb-icon-btn:hover {
  background: var(--color-surface-container-low);
  border-color: var(--color-outline-variant);
}
/* Disabled (a list's end, an export running): no hover look either. */
.rb-icon-btn:disabled:hover { background: transparent; border-color: transparent; }
/* Material 3 asks 48dp of a target on a touch screen, as the app's own .btn
   and .icon-btn give: every one of these buttons, on a phone and on any touch
   screen (no narrower either: Arabic's Save is one short word). A desktop
   with a mouse keeps its 34px. */
@media (max-width: 767px), (any-pointer: coarse) {
  .rb-btn { height: 48px; min-width: 48px; justify-content: center; }
  .rb-icon-btn { width: 48px; height: 48px; }
  /* A compact one keeps its 34px look and takes a press 48px across, as a
     chip's x does: Material 3's target may run beyond what is drawn. The
     rename button is one: the title's line keeps its height, so Done still
     lands where Edit was. */
  .rb-icon-btn.rb-icon-btn--compact { position: relative; width: 34px; height: 34px; }
  .rb-icon-btn--compact::before { content: ""; position: absolute; inset: calc((100% - 48px) / 2); }
}

/* ── One card family for the whole report pane ─────────────────────────
   Filter block, KPI cards, chart card and table card are siblings: same
   surface, same 1px outline, same radius, no shadow. tokens.css treats the
   surface-container ladder as the elevation signal; shadows only assist.
   KEEP IN SYNC with the dark-mode twin of this list further down this file
   (search "Dark mode tweaks") — it overrides background and border-color, so a
   member missing there is unified in light and split in dark. */
.rb-filter-block,
.rb-chartcard,
.rb-bd-card,
.rb-tablecard,
.rb-kpis .kpi-card {
  background: var(--color-surface-container-lowest);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-l);
  box-shadow: none;
}

/* ── Filters: chips in the filter card ───────────────────────────────── */
/* The record lists' chip row (.filter-chip-row, .active-filter-chip), inside
   the card: its words edit the filter, its x removes it. */
/* Two classes each: .filter-chip-row and .active-filter-chip come later in
   this file and would win a tie. */
.filter-chip-row.rb-filters { border-bottom: 0; }
.active-filter-chip.rb-fchip { padding-block: 0; padding-inline: 0 4px; }
.rb-fchip__edit {
  align-self: stretch;
  max-width: 420px; padding-block: 3px; padding-inline: 10px 2px; overflow: hidden; text-overflow: ellipsis;
  border: 0; background: none; color: inherit; font: inherit; cursor: pointer;
}
@media (hover: hover) { .rb-fchip__edit:hover { text-decoration: underline; } }
.rb-fchip__edit:focus-visible,
.rb-filters__add:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.rb-filters__add { padding: 3px 10px; font-size: var(--md-sys-typescale-body-small-size); }
/* Match all / any, starting a filter row: the chips' height and corner, as the
   chips it combines (finger-sized on a phone, below). */
/* Two classes: .rb-measure__select comes later in this file. */
.rb-measure__select.rb-filters__match { height: auto; min-height: 32px; border-radius: var(--md-sys-shape-corner-small); }
/* The editor's dates: side by side, and only for a custom range (the global
   [hidden] rule hides them otherwise). */
.report-popover__dates { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.report-popover__date { display: flex; flex-direction: column; gap: 4px; }
/* A record search's results hang below the dialog rather than scroll in it. */
.report-popover.report-popover--overflow { overflow: visible; }
@media (max-width: 768px) {
  /* Finger-sized: the filter chips and the quick filters. */
  .rb-fchip__edit, .rb-filters__add, .rb-filters .filter-chip-row__clear, .rb-xf .filter-chip-row__clear,
  .rb-measure__select.rb-filters__match, .rb-qf .filter-chip, .rb-qf .rb-measure__select { min-height: 44px; }
  .rb-fchip .active-filter-chip__x, .rb-xf .active-filter-chip__x,
  .rb-qf .active-filter-chip__x { min-width: 44px; min-height: 44px; justify-content: center; }
  .rb-fchip__edit { max-width: calc(100vw - 130px); }
  /* The report's editors come up from the bottom, as the Add report dialog
     does (two classes: the Summary editor's own width comes later). */
  .report-popover-overlay { align-items: flex-end; padding: 0; }
  .report-popover-overlay .report-popover {
    width: 100%; max-height: 85vh; border-radius: var(--radius-l) var(--radius-l) 0 0;
  }
}

/* ── Visualization picker icons (live inside the right rail) ────────── */
.rb-vizbar__icons {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 2px;
  background: var(--color-surface-container-low);
  border-radius: var(--md-sys-shape-corner-small);
}
.rb-viz {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 28px;
  border: 0;
  background: transparent;
  border-radius: var(--md-sys-shape-corner-small);
  color: var(--color-on-surface-var);
  cursor: pointer;
}
.rb-viz:hover:not([disabled]) { background: var(--color-surface-container); }
.rb-viz[disabled] { opacity: .4; cursor: not-allowed; }
.rb-viz--active { background: var(--color-primary); color: var(--color-on-primary) !important; }
.rb-viz--active:hover { background: var(--color-primary); }
.rb-viz .material-symbols-outlined { font-size: 18px !important; }

/* ── Chart card ──────────────────────────────────────────────────────── */
/* Surface, border and radius come from the shared card-family rule above.
   Its ⋯ sits at its top end corner, on its first row (its controls, or
   folded its title): 34px with a mouse, 48px on touch, as a KPI card's.
   --chart-row is that row's height, --chart-pad its side padding (less on a
   card under 260px, _chartFits; 8px there on touch, so four 48px
   chart-type buttons fit a card of the least width, 220px). */
.rb-chartcard {
  --chart-ctl: 34px;
  --chart-row: 32px;
  --chart-pad: 20px;
  position: relative;
  padding: 16px var(--chart-pad) 8px;
}
.rb-chartcard--folded { --chart-row: 28px; }
.rb-chartcard--narrow { --chart-pad: 12px; }
@media (max-width: 767px), (any-pointer: coarse) {
  .rb-chartcard { --chart-ctl: 48px; --chart-row: 52px; }
  .rb-chartcard--folded { --chart-row: 48px; }
  .rb-chartcard--narrow { --chart-pad: 8px; }
}
.rb-chartcard__menu {
  position: absolute; inset-inline-end: 8px;
  top: calc(26px + (var(--chart-row) - var(--chart-ctl)) / 2);
}
/* Folded (narrower than the zone, or on a phone): its title, and Chart
   options, which shows its controls under them or puts them away. Chart
   options stays beside the title wherever 6em of the title still fits: the
   title wraps first. */
.rb-chartcard__head { display: none; }
.rb-chartcard--folded .rb-chartcard__head {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  padding-block-start: 10px;
}
.rb-chartcard__title {
  flex: 1 1 6em; min-width: 0; min-height: var(--chart-row);
  display: flex; align-items: center;
  margin: 0; font-size: var(--md-sys-typescale-body-medium-size); font-weight: 600; color: var(--color-on-surface);
  overflow-wrap: anywhere;
}
.rb-chartcard__chevron { transition: transform .15s; }
.rb-chartcard--open .rb-chartcard__chevron { transform: rotate(180deg); }
.rb-chartcard--folded:not(.rb-chartcard--open) .rb-chartcard__controls { display: none; }
/* Its first row keeps clear of its ⋯ (its head shows only folded). */
.rb-chartcard:not(.rb-chartcard--folded) .rb-chartcard__controls,
.rb-chartcard__head { padding-inline-end: calc(var(--chart-ctl) + 16px - var(--chart-pad)); }
/* Open, its controls take as many lines as they need: nothing scrolls
   sideways in a card (the no-wrap rule under 900px is an unfolded card's).
   A setting too long for the line shortens its choice. */
.rb-chartcard--folded .rb-chartcard__controls > * { max-width: 100%; }
.rb-chartcard--folded .rb-chartcard__controls :is(.rb-segment__select, .rb-measure__select) > span:not(.material-symbols-outlined) {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Its lines set its groups apart: no separator is left alone at a line's
   end. */
.rb-chartcard--folded .rb-chartcard__ctlsep { display: none; }
/* Its drag handle at its top start corner, as a KPI card's, the rest of it
   shared with theirs (.rb-kpi-tile__handle): for a mouse only; a finger and
   the keyboard move a chart from its ⋯. */
.rb-chartcard__handle { inset-inline-start: 4px; top: calc(26px + (var(--chart-row) - 24px) / 2); }
@media (hover: hover) and (pointer: fine) and (min-width: 768px) {
  .rb-chartcard:has(> .rb-chartcard__handle):not(.rb-chartcard--folded) .rb-chartcard__controls,
  .rb-chartcard:has(> .rb-chartcard__handle) .rb-chartcard__head { padding-inline-start: calc(32px - var(--chart-pad)); }
}
.rb-segment__select,
.rb-measure__select {
  display: inline-flex; align-items: center; gap: 4px;
  height: 28px;
  padding: 0 8px;
  background: var(--color-surface-container-lowest);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--md-sys-shape-corner-small);
  font-size: var(--md-sys-typescale-body-dense-size);
  font-weight: 500;
  cursor: pointer;
  color: var(--color-on-surface);
}
.rb-segment__select[disabled],
.rb-measure__select[disabled] { opacity: .85; cursor: not-allowed; }
.rb-segment__select .material-symbols-outlined,
.rb-measure__select .material-symbols-outlined { font-size: 16px !important; opacity: .55; }
/* Material 3 asks 48dp of a target on a touch screen, as the page's other
   buttons give (.rb-btn): every setting button ("Group by: Stage") and every
   chart-type button, on a phone and on any touch screen. A mouse keeps the
   sizes above. Two classes where a rule above has two, finger-sized at 44px
   on a phone. */
@media (max-width: 767px), (any-pointer: coarse) {
  .rb-segment__select, .rb-measure__select,
  .rb-measure__select.rb-filters__match, .rb-qf .rb-measure__select { min-height: 48px; }
  .rb-viz { width: 48px; height: 48px; }
}

.rb-chartcard__body {
  display: flex;
  align-items: stretch;
  margin-top: 12px;
  gap: 6px;
}
.rb-chartcard__yrail {
  width: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}
.rb-chartcard__yrail-text {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  text-orientation: mixed;
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: 700;
  letter-spacing: .5px;
  color: var(--color-on-surface-var);
}

/* ── Horizontal bar chart ────────────────────────────────────────────── */
.rb-hbar {
  --rb-hbar-label-w: 120px;
  position: relative;
  padding: 8px 0 36px;
}
.rb-hbar__rows {
  display: flex; flex-direction: column;
  gap: 10px;
  position: relative;
  z-index: 1;
}
.rb-hbar__row {
  display: grid;
  grid-template-columns: var(--rb-hbar-label-w) 1fr;
  gap: 10px;
  align-items: center;
}
.rb-hbar__label {
  font-size: var(--md-sys-typescale-body-small-size);
  font-weight: 600;
  color: var(--color-on-surface);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: end;
  padding-inline-end: 6px;
}
.rb-hbar__track {
  position: relative;
  height: var(--rb-bar-h, 26px);
  display: flex;
  align-items: center;
}
.rb-hbar__fill {
  height: 100%;
  border-radius: 0 4px 4px 0;
  min-width: 2px;
  transition: filter .15s;
}
.rb-hbar__row:hover .rb-hbar__fill { filter: brightness(1.05); }
.rb-hbar__value {
  margin-inline-start: 8px;
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: 700;
  color: var(--color-on-surface);
  white-space: nowrap;
}
.rb-hbar__axis {
  position: absolute;
  /* Spans the bar track, not the whole chart, so a tick is a plain percentage
     of the track instead of a calc() against the label column. */
  inset-inline: var(--rb-hbar-label-w) 0;
  bottom: 8px;
  height: 22px;
  pointer-events: none;
  /* Its own container: the narrow-axis rule below follows the axis's width. */
  container-type: inline-size;
}
.rb-hbar__tick {
  position: absolute;
  top: 0;
  display: flex; flex-direction: column; align-items: center;
  transform: translateX(-50%);
}
.rb-hbar__tick-line {
  width: 1px; height: 6px;
  background: var(--color-outline-variant);
}
.rb-hbar__tick-text {
  margin-top: 2px;
  font-size: var(--md-sys-typescale-label-small-size);
  color: var(--color-on-surface-var);
  /* The last tick sits on the axis edge, so its shrink-to-fit box has no room
     left to grow into — without this the label wraps one word per line. */
  white-space: nowrap;
}
/* A narrow axis keeps every other value (_reportChart marks the rest), the
   same step doubled: six money labels need 400px ("12.5 مليون ج.م." is 70px),
   and a phone's axis is 174-236px. The axis is its own container, so a
   dashboard tile follows its own width too. */
@container (max-width: 400px) {
  .rb-hbar__tick--alt { visibility: hidden; }
}

/* ── Bottom data table card with tabs ────────────────────────────────── */
/* Surface, border and radius come from the shared card-family rule above. */
.rb-tablecard {
  overflow: hidden;
}
.rb-tablecard__tabs {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 6px 10px;
  border-bottom: 1px solid var(--color-outline-variant);
}
.rb-tab {
  height: 30px;
  padding: 0 12px;
  border: 0;
  background: transparent;
  font-size: var(--md-sys-typescale-body-dense-size);
  font-weight: 600;
  border-radius: var(--md-sys-shape-corner-small);
  color: var(--color-on-surface-var);
  cursor: pointer;
}
.rb-tab--active { background: var(--color-primary); color: var(--color-on-primary); }
.rb-tab[disabled] { opacity: .4; cursor: not-allowed; }
/* 48dp on a touch screen, as the report's other buttons are (.rb-btn). */
@media (max-width: 767px), (any-pointer: coarse) {
  .rb-tab { min-height: 48px; }
}
/* A table's body (the records table's, a Summary table's) is as tall as its
   zone's Height says at most (.rb-tables--short, .rb-tables--tall), then
   scrolls. */
.rb-tablecard__body,
.rb-sumcard__body {
  max-height: 480px;
  overflow: auto;
}
/* A table's head on its Summary: its Group by shortens its choice before
   the row runs out of room (a long field name), never pushing Columns and ⋯
   off. Its name ("Group by") stays whole, and a table's view switch,
   Columns and ⋯ keep their size (48px on a touch screen): only the choice
   gives way. On a phone the switch, Columns and ⋯ share the first line and
   Group by has the line under them to itself. */
.rb-tablecard__tabs > .rb-segment__select { min-width: 0; }
.rb-tablecard__tabs > .rb-segment__select > span:not(.material-symbols-outlined) {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rb-tablecard__tabs > .rb-segment__select > .rb-ctl__key,
.rb-tablecard__tabs > .rb-tab,
.rb-tablecard__tabs > .rb-icon-btn { flex: none; }
@media (max-width: 600px) {
  .rb-tablecard__tabs { flex-wrap: wrap; }
  .rb-tablecard__tabs > .rb-segment__select { order: 1; flex: 1 0 100%; }
}

/* ── Pageheader: back to the list + editable title + actions ─────────── */
/* The title row, and the editing band under it while the report is edited. */
.rb-pageheader { display: flex; flex-direction: column; gap: 12px; }
/* --rb-back-gap above the title: .rb's gap less this margin. "All reports"
   belongs to the title, not a block of its own. */
.rb-back-row {
  display: flex; align-items: center; gap: 12px; margin-bottom: calc(var(--rb-back-gap) - var(--rb-gap));
  font-size: var(--md-sys-typescale-body-dense-size); color: var(--color-on-surface-var);
}
.rb-back {
  display: inline-flex; align-items: center; gap: 4px; margin-inline-start: -8px;
  padding: 4px 8px; border-radius: var(--md-sys-shape-corner-full); text-decoration: none; color: var(--color-primary); font-weight: 600;
}
.rb-back:hover { background: var(--color-primary-container); }
.rb-back .material-symbols-outlined { font-size: 18px !important; }
.rb-pageheader__row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.rb-pageheader__actions { display: inline-flex; gap: 8px; align-items: center; margin-inline-start: auto; }
/* Editing on a desktop, the title row and the band stay at the top of the
   page's scroller (main.view) while the report scrolls under them; "All
   reports" scrolls away. Opaque, over the report's cards (their bars and
   column edges sit at z-index 1-2), under drawers (290), dialogs (300) and
   menus (400). As wide as the scroller: its padding and the report's are
   taken back as margin and given back as padding. A sticky box stops at the
   scroller's padding, so `top` takes that back too: pinned at 0 it left a
   24px strip above it where the cards scrolled into view. The space "All
   reports" leaves above the title (--rb-back-gap) is taken back the same
   way. Each is read from where it is set (.view, .rb), so changing one
   moves nothing by accident. The scroller keeps their height clear above
   what it scrolls to (_padUnderPinnedHeader). */
@media (min-width: 901px) {
  /* The buttons stay on the title's line, at its top: a long title wraps
     beside them, so Discard and Save showing up, or editing's rename button,
     never push them under it. */
  .rb-pageheader__row { flex-wrap: nowrap; align-items: flex-start; }
  .rb-pageheader__actions { flex: none; }
  .rb-pageheader--editing {
    position: sticky; top: calc(-1 * var(--view-pad-block)); z-index: 10;
    margin: calc(-1 * var(--rb-back-gap)) calc(-1 * (var(--rb-pad) + var(--view-pad-inline))) 0;
    padding: var(--rb-back-gap) calc(var(--rb-pad) + var(--view-pad-inline)) 12px;
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-outline-variant);
  }
  .view:has(.rb-pageheader--editing) { scroll-padding-top: calc(var(--rb-pinned-h, 0px) + 8px); }
  /* Not for the pinned controls themselves: the padding read them as hidden
     under the header, so focus coming back to ⋯ or Add scrolled the report
     back up. */
  .rb-pageheader--editing * { scroll-margin-top: calc(-1 * (var(--rb-pinned-h, 0px) + 8px)); }
}


/* ── Body: one column. The config used to live in a 280px right rail, ~700px
   away from the chart it configured; it now sits on the chart card head. ── */
.rb-body { display: block; }
.rb-canvas { display: flex; flex-direction: column; gap: var(--rb-gap); min-width: 0; }
/* What narrows the report, one group: its filters card and the quick-filter
   row, closer to each other than to the blocks around them. Each zone, its
   bar above its cards, is a group the same way. */
.rb-filtergroup,
.rb-kpi-zone,
.rb-chart-zone,
.rb-breakdowns,
.rb-table-zone { display: flex; flex-direction: column; gap: var(--sp-3); min-width: 0; }

/* ── Chart zone and table zone ─────────────────────────────────────────
   Each a grid of 12 columns, as a dashboard's tiles: a card takes the whole
   row unless laid out narrower, and the cards in a row end on one line. */
.rb-charts,
.rb-tables {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--rb-gap);
}
.rb-charts > .rb-chartcard,
.rb-tables > .rb-tablecard { grid-column: 1 / -1; min-width: 0; }

/* The charts: each card's span is the page's (_reportLayout.js zoneColumns,
   rowSpans), never narrower than --rb-chart-min. Height sets what the
   charts draw by (each read with its standard size as the fallback, so a
   dashboard tile, which sets none, keeps it): the columns' plot, the
   donut's ring and a horizontal bar's thickness. */
.rb-charts { --rb-chart-min: 220px; }
.rb-charts--short { --rb-plot-h: 160px; --rb-ring: 140px; --rb-bar-h: 18px; }
/* Ten tall bars and Other fit before the card scrolls, as ten do at the
   others' heights. */
.rb-charts--tall { --rb-plot-h: 360px; --rb-ring: 300px; --rb-bar-h: 32px; --rb-hbar-cap: 520px; }

/* The tables: one to a row, or two side by side where Per row asks for two
   (.rb-tables--pairs) and each has 360px, a lone last table the whole row.
   Two need 2 x 360px and the zone's gap: 744px, or 736px under 768px where
   the gap is 16px; a phone's zone is never as wide, so a phone keeps one to
   a row. Height caps every table's body at 288, 480 or 768px, each its own
   max-height on the bodies, not a property each cell inherits. */
.rb-table-zone { container: rb-tables / inline-size; }
@container rb-tables (min-width: 744px) {
  .rb-tables--pairs > .rb-tablecard { grid-column: span 6; }
  .rb-tables--pairs > .rb-tablecard:nth-child(odd):last-child { grid-column: 1 / -1; }
}
@media (max-width: 767px) {
  @container rb-tables (min-width: 736px) {
    .rb-tables--pairs > .rb-tablecard { grid-column: span 6; }
    .rb-tables--pairs > .rb-tablecard:nth-child(odd):last-child { grid-column: 1 / -1; }
  }
}
.rb-tables--short > .rb-tablecard > :is(.rb-tablecard__body, .rb-sumcard__body) { max-height: 288px; }
.rb-tables--tall > .rb-tablecard > :is(.rb-tablecard__body, .rb-sumcard__body) { max-height: 768px; }
/* A table's pager (Showing 1-50 of 175, per page, pages) stays in view at
   the foot of the table's scroll area, as the drill drawer's does, instead
   of waiting at the end of the rows. It keeps still when a wide table
   scrolls sideways, and sits above the sticky column heads' cells. */
.rb-tablecard__body > .pagination-row,
.rb-sumcard__body > .pagination-row {
  position: sticky; bottom: 0; inset-inline-start: 0; z-index: 2;
  background: var(--color-surface-container-lowest);
}

/* Chart card: relative position so empty-state overlay can sit on top. A
   container, so a horizontal bar chart's labels follow its own width. */
/* Cap the card: a many-row h-bar chart scrolls inside it instead of growing
   unbounded and shoving the data table below the fold. Any other chart
   grows the card (a narrow donut's legend under its ring). */
.rb-chartcard__chart { flex: 1; min-width: 0; position: relative; overflow-y: auto; container: rb-chart / inline-size; }
.rb-chartcard__chart:has(.rb-hbar) { max-height: var(--rb-hbar-cap, 460px); }

/* ── KPI zone ──────────────────────────────────────────────────────────
   Scoped to .rb-kpis so the dashboard's .kpi-grid--sm tiles are untouched.
   The cards share each row in --rb-cols columns, which the page works out
   for the grid's width (_reportLayout.js kpiColumns): never narrower than a
   money figure needs (--rb-card-min, more when tall: the page reads it), so
   a value is not cut short ("EGP 24…"), and rows evened out, so seven cards
   read four and three, not six and one; two at most on a phone. Every row
   as tall as the tallest card, so all the cards are one height; the value
   ellipsises so a compact money string can never overflow the card. */
.rb-kpis {
  --rb-card-min: 190px;
  gap: var(--sp-3);
  grid-template-columns: repeat(var(--rb-cols, 4), minmax(0, 1fr));
  grid-auto-rows: 1fr;
}
.rb-kpis--tall { --rb-card-min: 220px; }
/* A zone's bar above its cards: while editing, its name, how they are laid
   out and its Add; where the zone has a way to read its cards, its name and
   that way while reading too. */
.rb-zonebar { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2); }
.rb-zonebar__title {
  margin: 0;
  font-size: var(--md-sys-typescale-body-large-size);
  font-weight: 600;
  color: var(--color-on-surface);
}
/* Per row is not offered on a phone, where two KPI cards share a row at
   most and a card of any other zone has the row to itself; the author's
   choice still holds on a wider screen. */
@media (max-width: 600px) {
  .rb-zonebar [data-setting="perRow"] { display: none; }
}
/* min-width:0 is load-bearing: a grid item's auto min-size would refuse to
   shrink below the nowrap text, and the ellipsis below would never trigger. */
.rb-kpis .kpi-card {
  min-width: 0;
  padding: 14px 16px;
}
.rb-kpis .kpi-card:hover { box-shadow: var(--shadow-1); }
/* Up to two lines per label: "Marketing qualified leads" reads whole rather
   than as "MARKETING QUA…"; a long single word breaks rather than vanish. */
.rb-kpis .kpi-card__label {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  overflow-wrap: anywhere;
}
/* The figure's size is the height the author picked, not the window's
   width: Short, Standard (the default) or Tall. Each is a minimum, so larger
   text still grows the cards, all of them together. */
.rb-kpis .kpi-card__value {
  font-size: var(--md-sys-typescale-headline-small-size);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-variant-numeric: tabular-nums;
}
.rb-kpis--short .kpi-card__value { font-size: var(--md-sys-typescale-title-large-size); }
.rb-kpis--tall .kpi-card__value { font-size: var(--md-sys-typescale-headline-large-size); }
.rb-kpis--tall .kpi-card { min-height: 112px; }
/* A phone's sizes, the same at any width (Material 3: text size should not
   change with the container): a figure too wide for half the row puts the
   cards one to a row instead (_reportLayout.js kpiColumns). */
@media (max-width: 767px) {
  .rb-kpis .kpi-card__value { font-size: var(--md-sys-typescale-title-large-size); }
  .rb-kpis--tall .kpi-card__value { font-size: var(--md-sys-typescale-headline-small-size); }
}
@media (max-width: 600px) {
  /* A card alone on the last row, or only the Add KPI box, takes the row. */
  .rb-kpis > :last-child:nth-child(odd) { grid-column: 1 / -1; }
  /* Half a phone: a long name takes a third line. */
  .rb-kpis .kpi-card__label { -webkit-line-clamp: 3; }
}

/* ── Chart-card controls: what the right rail used to hold ─────────────── */
.rb-chartcard__controls {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 10px 0 2px;
  border-bottom: 1px solid var(--color-outline-variant);
  margin-bottom: 4px;
}
.rb-chartcard__ctlsep {
  width: 1px; height: 20px; flex: 0 0 auto;
  background: var(--color-outline-variant);
}
/* The control's own name, so a dropdown reading "Month" says what Month is. */
.rb-ctl__key {
  font-size: var(--md-sys-typescale-body-small-size); font-weight: 400;
  color: var(--color-on-surface-var);
  margin-inline-end: 2px;
}
.rb-ctl--set { border-color: var(--color-primary); }

/* ── Records drawer: the rows behind a figure (_drillDrawer.js) ────────── */
/* "Back to <figure>" on a record opened from a drawer or a report. */
.drill-origin {
  position: fixed; inset-block-end: 24px; inset-inline-start: 50%;
  transform: translateX(-50%); z-index: 280;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 16px; border: 0; border-radius: var(--md-sys-shape-corner-full);
  background: var(--color-inverse-surface); color: var(--color-inverse-on-surface);
  font: inherit; font-size: var(--md-sys-typescale-body-dense-size); cursor: pointer;
  box-shadow: var(--md-sys-elevation-3); max-width: min(90vw, 480px);
}
[dir="rtl"] .drill-origin { transform: translateX(50%); }
.drill-origin span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.drill-origin .material-symbols-outlined { font-size: 18px; }
.drill-origin:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
/* Phones: sit above the fixed bottom tab bar (and the home indicator). */
@media (max-width: 767px) {
  .drill-origin { inset-block-end: calc(var(--md-nav-bar-h) + 12px + env(safe-area-inset-bottom, 0px)); }
  /* On a deal the pill stacks above the action FAB — see .dd-fab. */
}
.dd-origin-lead {
  display: inline-flex; align-items: center; gap: 4px; margin-top: 2px;
  font-size: var(--md-sys-typescale-body-small-size); color: var(--color-on-surface-var); text-decoration: none;
}
.dd-origin-lead:hover { text-decoration: underline; }
.dd-origin-lead .material-symbols-outlined { font-size: 15px; }
.drawer--wide { width: min(960px, 100vw); }
.drill-drawer__title { min-width: 0; }
/* The records list's Columns button, beside Close. */
.drill-drawer__cols { margin-inline-start: auto; margin-inline-end: var(--space-2); }
.drill-drawer__title .drawer-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.drill-drawer__summary { margin-top: 2px; color: var(--color-on-surface-var); }
.drill-drawer__body { flex: 1; overflow: auto; padding: 0 var(--space-4); }
.drill-drawer__body .data-table { width: 100%; }
.drill-drawer__empty { text-align: center; padding: 24px; opacity: .6; }
.drill-drawer__foot {
  position: sticky; bottom: 0;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px 20px;
  background: var(--color-surface);
  border-top: 1px solid var(--color-surface-container-high);
}
.drill-drawer__pager { display: flex; gap: 4px; }
/* A KPI card that opens its records is a button that still looks like a card:
   no button border but the card's stripe, on its start edge in either
   language (.kpi-card). */
.kpi-card--drill {
  font: inherit; color: inherit; text-align: start; width: 100%;
  border-block: 0; border-inline-end: 0;
  cursor: pointer;
}
.kpi-card--drill:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
/* The dashboard's KPI cards are buttons, which centre what they hold: a card
   whose trend takes one line fewer would sit lower than its neighbours. */
.dash-kpis > .kpi-card--drill { display: flex; flex-direction: column; justify-content: flex-start; }
.rb-summary-table tr.rb-drillable:hover td { background: var(--color-surface-container-low); }

/* A drillable bar advertises itself; a non-drillable one must not. */
.rb-drillable { cursor: pointer; }
.rb-drillable:hover .rb-hbar__fill,
.rb-drillable:hover .rb-vbar__bar { filter: brightness(1.08); }
.rb-hbar__row[data-drillable="0"], .rb-vbar__col[data-drillable="0"] { cursor: default; }

/* ── Breakdown panels ──────────────────────────────────────────────────── */
/* The same rows grouped several ways, under the charts: a zone of cards, its
   bar (.rb-zonebar) above its panels, each a card of the report's family.
   As many share a row as the page works out for the grid's width
   (_reportLayout.js breakdownColumns: --rb-cols), each at least
   --rb-bd-min wide; one on a phone. A panel is as tall as the rows its
   Height shows (--rb-bd-rows, which the page writes on it: _reportLayout.js
   BREAKDOWN_ROWS), however many it has, each row --rb-bd-row tall and
   --rb-bd-row-gap from the next, so every panel is one height and their
   Show all buttons line up. Each is a minimum: larger text still grows
   them. The rows are the app's bar list (.h-bar-row, as the dashboard's
   stage list draws it); only the figure column is new: the amount, then
   its share lined up in a column of its own. */
.rb-breakdowns__note {
  margin: 0;
  font-size: var(--md-sys-typescale-body-small-size);
  color: var(--color-on-surface-var);
}
.rb-breakdowns__grid {
  --rb-bd-min: 280px;
  /* The tallest row a panel draws, a picked bar with its check in Cairo
     too, is about 40px; where its records button is 48px (.rb-icon-btn: a
     phone, a touch screen), 48px (below). */
  --rb-bd-row: 44px;
  --rb-bd-row-gap: var(--space-2);
  /* A panel's ⋯ (.rb-icon-btn): 34px with a mouse, 48px on touch. */
  --rb-bd-ctl: 34px;
  display: grid;
  gap: var(--sp-3);
  grid-template-columns: repeat(var(--rb-cols, 1), minmax(0, 1fr));
}
@media (max-width: 767px), (any-pointer: coarse) {
  .rb-breakdowns__grid { --rb-bd-row: 48px; --rb-bd-row-gap: var(--sp-3); --rb-bd-ctl: 48px; }
}
.rb-bd-card {
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: var(--sp-3) var(--space-3);
}
/* Its head: the drag handle while editing, its name, and its ⋯ at the end.
   As tall as the ⋯ while reading too: Edit and Done leave every panel its
   height, as a KPI card's ⋯ does. */
.rb-bd-card__head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-block-size: var(--rb-bd-ctl);
  margin-block-end: var(--space-2);
}
.rb-bd-card__title {
  flex: 1;
  margin: 0;
  min-width: 0;
  font-size: var(--md-sys-typescale-body-medium-size);
  font-weight: 600;
  color: var(--color-on-surface);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.rb-bd-card__menu { flex: none; }
/* Editing, its name is a button that changes its field ("Breakdown by
   Owner", as a table's Group by is): the field's name shortens before the
   head runs out of room; "Breakdown by" stays whole. */
.rb-bd-card__title--pick { display: flex; overflow: visible; }
.rb-bd-card__title--pick > .rb-segment__select { min-width: 0; max-width: 100%; }
.rb-bd-card__title--pick > .rb-segment__select > span:not(.material-symbols-outlined) {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rb-bd-card__title--pick > .rb-segment__select > .rb-ctl__key { flex: none; }
/* --rb-bd-rows-h: as tall as the panel's rows and the gaps between them. */
.rb-bd-card__rows {
  --rb-bd-rows-h: calc(var(--rb-bd-rows) * var(--rb-bd-row) + (var(--rb-bd-rows) - 1) * var(--rb-bd-row-gap));
  display: flex;
  flex-direction: column;
  gap: var(--rb-bd-row-gap);
  min-block-size: var(--rb-bd-rows-h);
}
.rb-bd-card .h-bar-row { margin: 0; min-block-size: var(--rb-bd-row); }
/* A bar that picks nothing (a field that does not filter) sits in the middle
   of its row, as one that picks does. */
.rb-bd-card .h-bar-row:not(.rb-bd-row) { display: flex; flex-direction: column; justify-content: center; }
.rb-bd-card__rows > .empty-state { flex: 1; }
/* Show all, at the panel's foot. While one panel has it, every panel keeps
   its line, empty where it has none, as the KPI cards keep one for their
   change (.rb-kpis--compare): the panels stay one height. */
.rb-bd-card__foot { margin-block-start: auto; padding-block-start: var(--space-2); }
.rb-bd-card__foot:empty { display: none; }
.rb-breakdowns__grid:has(.cf-more) .rb-bd-card__foot { display: block; min-block-size: calc(40px + var(--space-2)); }
.rb-bd-card__foot .cf-more { margin: 0; }
/* On a phone or a touch screen Show all is a 48px target, as the report's
   other buttons are (Yahia, 2026-10-07), and every panel keeps that much line
   for it, so the panels stay one height. */
@media (max-width: 767px), (any-pointer: coarse) {
  .rb-bd-card__foot .cf-more { min-height: 48px; box-sizing: border-box; }
  .rb-breakdowns__grid:has(.cf-more) .rb-bd-card__foot { min-block-size: calc(48px + var(--space-2)); }
}
/* Wider than a phone, every row of panels is as tall as its tallest, and an
   open panel keeps its size: the rest of its rows scroll within it
   (Material 3 cards: "On a desktop device, card content can expand and
   scroll within a card"). On a phone it grows instead ("On a mobile device,
   cards can't internally scroll"). Room at either side for a bar's hover and
   its focus ring, which reach past the rows. */
@media (min-width: 601px) {
  .rb-breakdowns__grid { grid-auto-rows: 1fr; }
  .rb-bd-card--open .rb-bd-card__rows {
    max-block-size: var(--rb-bd-rows-h);
    overflow-y: auto;
    margin-inline: calc(-1 * var(--space-2));
    padding-inline: var(--space-2);
  }
}
.rb-bd-card__rows:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.rb-bd-card .h-bar-meta { gap: 12px; }
.rb-bd-card .h-bar-meta > span:first-child {
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.rb-bd-fig { flex: none; font-variant-numeric: tabular-nums; }
.rb-bd-fig strong { font-size: var(--md-sys-typescale-body-dense-size); font-weight: 600; color: var(--color-on-surface); }
.rb-bd-fig span { display: inline-block; min-width: 4.5em; text-align: end; }
/* A bar that picks itself (_reportChart renderBreakdown): the whole bar is the
   toggle, the records button beside it. Picked, a check and full colour; the
   bars not picked in that panel go grey and stay there to pick. */
.rb-bd-row { display: flex; align-items: center; gap: 4px; }
.rb-bd-pick {
  flex: 1; min-width: 0; display: block; padding: 4px 6px; margin-inline-start: -6px;
  border: 0; border-radius: var(--md-sys-shape-corner-small); background: none;
  color: inherit; font: inherit; text-align: start; cursor: pointer;
}
.rb-bd-pick:hover { background: var(--color-surface-container); }
.rb-bd-pick:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 1px; }
/* Inside the name's span, so it must outweigh .h-bar-meta span:first-child. */
.rb-bd-pick .h-bar-meta .rb-bd-check { font-size: var(--md-sys-typescale-body-large-size); vertical-align: -3px; margin-inline-end: 4px; color: var(--color-primary); }
.rb-bd-row--on .h-bar-meta > span:first-child { font-weight: 600; }
.rb-bd-row--off .h-bar-fill { background: var(--color-outline-variant); }
.rb-bd-row--off .h-bar-meta span, .rb-bd-row--off .rb-bd-fig strong { color: var(--color-on-surface-var); }
.rb-bd-bar { flex: 1; min-width: 0; padding: 4px 0; }
.rb-bd-open { flex: none; }
.rb-bd-open .material-symbols-outlined { font-size: 18px; }
/* Material 3 asks 48dp of a target on a touch screen: the bar, as the
   records button beside it is (.rb-icon-btn). */
@media (any-pointer: coarse) {
  .rb-bd-pick { min-height: 48px; }
}
/* The picks, in the filter row: a long list of values stops at the chip. */
.rb-xf__chip { max-width: 100%; }
.rb-xf__name { min-width: 0; max-width: 280px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── Quick filters ─────────────────────────────────────────────────────── */
/* The button row between the report's filters and its KPIs. The buttons are
   the app's filter chips, and a button that is on is the chip's own selected
   state — a quick filter is a refinement, not the page's main action. */
.rb-qf {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}
.rb-qf__label {
  font-size: var(--md-sys-typescale-body-dense-size);
  font-weight: 600;
  color: var(--color-on-surface-var);
}
/* Edit mode: each chip is the app's removable chip, carrying Edit and Delete. */
.rb-qf .active-filter-chip__x .material-symbols-outlined { font-size: 16px; }
.rb-qf-editor { min-width: 0; }
/* The metric editor's chips line up with its fields, and Clear all stays
   beside them rather than across the dialog. */
.rb-qf-editor .filter-chip-row.rb-filters { padding: 0; }
.rb-qf-editor .filter-chip-row__clear { margin-inline-start: 0; }
/* A filter's editor in the metric editor: under the chips, the pop-up's
   rows and buttons in a region of their own (Material 3's inline expansion:
   a dialog does not open another over itself). */
.rb-filter-inline {
  display: flex; flex-direction: column; gap: 10px; margin-top: 8px; padding: 12px;
  border: 1px solid var(--color-outline-variant); border-radius: var(--radius-m);
  background: var(--color-surface-container-low);
}
.rb-filter-inline:focus { outline: none; }
/* Inside the form's field group, a value's name is not a field's caption. */
.rb-filter-inline .report-popover__check {
  font-size: var(--md-sys-typescale-body-dense-size); font-weight: 400; letter-spacing: normal; color: inherit;
}
/* The same space under every field, side by side or stacked on a phone. */
.rb-metric-form .form-row { margin-bottom: var(--space-3); }
.rb-metric-form .form-row > .form-group { margin-bottom: 0; }
/* A KPI card's settings, under its box: indented to the box's label. */
.rb-metric-card { padding-inline-start: var(--space-5); margin-top: var(--space-2); }

/* Currency, Pipeline and Compare: how every figure is read, one group at the
   end of the button row. On a phone, a row of their own whose buttons share
   it evenly instead of wrapping one short. */
.rb-qf__options { display: flex; flex-wrap: wrap; gap: 8px; margin-inline-start: auto; }
@media (max-width: 768px) {
  .rb-qf__options { width: 100%; margin-inline-start: 0; }
  .rb-qf__options > * { flex: 1 1 140px; justify-content: flex-start; height: auto; }
  .rb-qf__options > * > :nth-last-child(2) {
    margin-inline-end: auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
}
/* A KPI's change against the comparison window, under its value. The arrow
   says which way it moved; the colour says whether that is good news — more
   lost deals is red — and a figure that is neither (a variance) stays grey. */
.rb-kpi-delta {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.rb-kpi-delta .material-symbols-outlined { font-size: 16px; vertical-align: -3px; margin-inline-end: 2px; }
.rb-kpi-delta--good { color: var(--color-success-text); }
.rb-kpi-delta--bad { color: var(--color-error); }
.rb-kpi-delta__vs { color: var(--color-on-surface-var); }
/* While the report compares, every card keeps a line for its change, empty
   where it has none: the figures sit at the cards' foot, and stay in line
   across a row. One line of the change's text, and the space above it. */
.rb-kpis--compare .rb-kpi-tile__change { font-size: var(--md-sys-typescale-body-small-size); min-height: calc(var(--space-1) + 1lh); }

/* ── KPI tiles the report's author added ───────────────────────────────── */
/* The built-in cards' padding moves onto the tile's button, so the whole card
   opens its records and the menu button sits beside it, not inside it. Its
   block padding and its ⋯'s size are properties, read by what sits by them:
   short cards set the one, a touch screen the other. */
.rb-kpis .rb-kpi-tile {
  --tile-pad-block: 14px;
  --tile-ctl: 34px;
  position: relative;
  display: flex;
  padding: 0;
}
.rb-kpis--short .rb-kpi-tile { --tile-pad-block: 10px; }
@media (max-width: 767px), (any-pointer: coarse) {
  .rb-kpis .rb-kpi-tile { --tile-ctl: 48px; }
}
/* The card's words top to bottom, its value at the foot: values in a row line
   up however many lines their labels take. */
.rb-kpi-tile__open {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  padding: var(--tile-pad-block) 16px;
  background: none;
  border: 0;
  border-radius: inherit;
  font: inherit;
  color: inherit;
  text-align: start;
}
.rb-kpi-tile__open .kpi-card__value { margin-block-start: auto; }
button.rb-kpi-tile__open { cursor: pointer; }
/* The edit button in the card's top corner, beside the label only: the value
   keeps the card's whole width. The label keeps 6px clear of it: its width
   and 4px from the edge, less the card's own 16px. Centred on the label's
   first line, 8px under the card's padding as the handle is, at every
   height; a finger's larger one stops at the card's top edge. */
.rb-kpi-tile .rb-kpi-tile__menu {
  position: absolute; inset-inline-end: 4px; width: var(--tile-ctl); height: var(--tile-ctl);
  top: max(0px, calc(var(--tile-pad-block) + var(--space-2) - var(--tile-ctl) / 2));
}
.rb-kpi-tile:has(.rb-kpi-tile__menu) .kpi-card__label { padding-inline-end: calc(var(--tile-ctl) - 6px); }
/* Its drag handle in the other top corner, as the Columns dialog's rows
   have one, beside the label too. For a mouse only: a finger and the
   keyboard move a card from its ⋯. A chart card's is the same, placed on
   its own card (.rb-chartcard__handle); a table's starts its head's row
   (.rb-tablecard__handle), and so does a breakdown panel's
   (.rb-bd-card__handle). */
.rb-kpi-tile__handle,
.rb-chartcard__handle,
.rb-tablecard__handle,
.rb-bd-card__handle {
  display: none;
  position: absolute;
  align-items: center; justify-content: center; width: 24px; height: 24px;
  color: var(--color-on-surface-var); cursor: grab;
}
.rb-tablecard__handle,
.rb-bd-card__handle { position: static; flex: none; }
/* Centred on the label's first line, 4px above the card's padding at every
   height, and no lower: the figure under it opens its records, and a press
   there must not start a drag. */
.rb-kpi-tile__handle { top: calc(var(--tile-pad-block) - var(--space-1)); inset-inline-start: var(--space-1); }
.rb-kpi-tile__handle .material-symbols-outlined,
.rb-chartcard__handle .material-symbols-outlined,
.rb-tablecard__handle .material-symbols-outlined,
.rb-bd-card__handle .material-symbols-outlined { font-size: 18px; }
@media (hover: hover) and (pointer: fine) and (min-width: 768px) {
  .rb-kpi-tile__handle,
  .rb-chartcard__handle,
  .rb-tablecard__handle,
  .rb-bd-card__handle { display: inline-flex; }
  .rb-kpi-tile:has(.rb-kpi-tile__handle) .kpi-card__label { padding-inline-start: 14px; }
}
/* A zone's card lifts while it is dragged; the card it would take the place
   of is outlined, as a dashboard tile is (.dash-tile--drop). */
.rb-kpis .kpi-card.rb-kpi-tile--dragging,
.rb-charts .rb-chartcard--dragging,
.rb-tables .rb-tablecard--dragging,
.rb-breakdowns__grid .rb-bd-card--dragging { box-shadow: var(--shadow-3); }
/* The add card is a drill card's button (kpi-card--drill gives the reset and
   the focus ring); dashed and see-through, it reads as a place, not a figure. */
/* A report section that is empty or removed, while editing. */
.rb-section-add {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  width: 100%; min-height: 64px;
  border: 1px dashed var(--color-outline-variant); border-radius: var(--md-sys-shape-corner-medium);
  background: transparent; color: var(--color-primary); font: inherit; font-weight: 600; cursor: pointer;
}
.rb-section-add:hover { background: var(--color-surface-container-low); }
.rb-section-add:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
/* Editing a report: said once, under its title, with Add at its end. On a
   phone the words wrap; Add stays on the screen. */
.rb-editbar {
  display: flex; align-items: center; gap: 8px; padding: 8px 12px;
  border-radius: var(--radius-m); font-size: var(--md-sys-typescale-body-dense-size);
  background: var(--color-secondary-container); color: var(--color-on-secondary-container);
}
.rb-editbar .material-symbols-outlined { font-size: 18px; }
.rb-editbar__text { flex: 1 1 auto; min-width: 0; }
.rb-editbar .rb-btn { flex: none; }
.rb-kpis .rb-kpi-add,
[data-theme="dark"] .rb-kpis .kpi-card.rb-kpi-add {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border-style: dashed;
  background: transparent;
  font-weight: 600;
  color: var(--color-primary);
}
button.rb-kpi-tile__open:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }

/* ── Goal line ─────────────────────────────────────────────────────────── */
.rb-goal-line { position: absolute; pointer-events: none; z-index: 2; }
.rb-goal-line--hbar { top: 0; bottom: 28px; border-inline-start: 2px dashed var(--color-gold); }
.rb-goal-line--bar  { inset-inline: var(--rb-axis-gutter) 8px; border-top: 2px dashed var(--color-gold); }
.rb-goal-line__label {
  position: absolute; inset-inline-start: 4px; top: 0;
  font-size: var(--md-sys-typescale-label-small-size); font-weight: 700; white-space: nowrap;
  color: var(--color-on-surface-var);
}
.rb-goal-line--bar .rb-goal-line__label { top: -14px; }
.rb-num__attainment { font-size: var(--md-sys-typescale-body-dense-size); font-weight: 700; margin-top: 4px; }
.rb-num__attainment span { font-weight: 500; color: var(--color-on-surface-var); }
.rb-num__attainment--met { color: var(--color-success-text); }
.rb-num__attainment--near { color: var(--color-warning-text); }
.rb-num__attainment--behind { color: var(--color-error); }

/* Empty-state preview — faded sample chart with overlay caption */
.rb-chart-preview { opacity: .32; filter: saturate(.4); pointer-events: none; }
.rb-empty-overlay {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  pointer-events: none;
}
.rb-empty-overlay__msg {
  background: var(--color-surface-container-lowest); padding: 8px 14px; border-radius: var(--md-sys-shape-corner-small);
  box-shadow: var(--md-sys-elevation-2); font-size: var(--md-sys-typescale-body-dense-size); font-weight: 600;
  color: var(--color-on-surface);
}

/* ── Dark mode tweaks ────────────────────────────────────────────────── */
[data-theme="dark"] .rb-filter-block,
[data-theme="dark"] .rb-chartcard,
[data-theme="dark"] .rb-bd-card,
[data-theme="dark"] .rb-tablecard,
[data-theme="dark"] .rb-kpis .kpi-card {
  background: var(--color-surface);
  border-color: var(--color-outline-variant);
}
[data-theme="dark"] .rb-btn--ghost,
[data-theme="dark"] .rb-segment__select,
[data-theme="dark"] .rb-measure__select {
  background: var(--color-surface-container-low);
  border-color: var(--color-outline-variant);
  color: var(--color-on-surface);
}
[data-theme="dark"] .rb-tab--active { background: var(--color-primary-container); color: var(--md-sys-color-on-primary-container); }
[data-theme="dark"] .rb-empty-overlay__msg { background: var(--color-surface-container); color: var(--color-on-surface); }

/* Mobile (≤900px) */
@media (max-width: 900px) {
  .rb-head__title { font-size: var(--md-sys-typescale-title-large-size); }
  .rb-hbar { --rb-hbar-label-w: 90px; }
  /* A row of their own under the title, at its end as on a desktop, so Done
     still lands where Edit was; one line. */
  .rb-pageheader__actions { width: 100%; justify-content: flex-end; }
  /* Three dropdowns plus five icons do not wrap gracefully at 375px; scroll
     them instead so the chart keeps its height. A folded card's take the
     lines they need instead. */
  .rb-chartcard:not(.rb-chartcard--folded) .rb-chartcard__controls {
    flex-wrap: nowrap; overflow-x: auto; scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
  }
  .rb-chartcard:not(.rb-chartcard--folded) .rb-chartcard__controls > * { flex: 0 0 auto; scroll-snap-align: start; }
}
/* A narrow chart's bar labels take the room a phone gives them, whatever
   the screen: two charts to a row on a desktop. */
@container rb-chart (max-width: 600px) {
  .rb-hbar { --rb-hbar-label-w: 90px; }
}

/* ── Phase 2: viz variants + dropdown menu + segmented bars ──────────── */

/* Anchored dropdown menu (Measure-by, Segment-by) */
.rb-menu {
  position: fixed;
  z-index: 500;
  min-width: 220px;
  max-height: 320px;
  overflow-y: auto;
  padding: 4px;
  display: flex;
  flex-direction: column;
  animation: rb-menu-in .12s ease-out;
}
@keyframes rb-menu-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.rb-menu__item {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 7px 10px;
  border: 0;
  background: transparent;
  text-align: start;
  font-size: var(--md-sys-typescale-body-dense-size);
  border-radius: var(--md-sys-shape-corner-small);
  cursor: pointer;
  color: var(--color-on-surface);
}
.rb-menu__item:hover { background: var(--color-surface-container-low); }
.rb-menu__item--active { color: var(--color-primary); font-weight: 600; }
.rb-menu__check { font-size: var(--md-sys-typescale-body-large-size) !important; color: var(--color-primary); }
.rb-menu__label { flex: 1; }

/* H-bar segmented stack (when Segment by = status) */
.rb-hbar__stack {
  display: flex;
  height: 100%;
  border-radius: 0 4px 4px 0;
  overflow: hidden;
}
.rb-hbar__segment { height: 100%; }

/* Vertical bar chart (rb-vbar) — used when viz=bar */
.rb-vbar {
  position: relative;
  display: flex;
  align-items: flex-end;
  /* Narrows as columns crowd in: a fixed 14px gap left 21 months with 22px
     bars and every month name ellipsized to one letter. */
  --rb-col-gap: clamp(3px, 1.2%, 14px);
  gap: var(--rb-col-gap);
  height: var(--rb-plot-h, 240px);
  /* The start padding is the value-axis gutter the tick labels sit in —
     logical, so in RTL the gutter moves to the right with the axis. */
  padding: 20px 8px 8px;
  padding-inline-start: var(--rb-axis-gutter);
  container-type: inline-size;
  /* The plot area's edges, for the gridlines and goal line: the top padding,
     and the bottom padding + one axis label (.rb-vbar__label's fixed height)
     + the column gap. */
  --rb-plot-top: 20px;
  --rb-plot-base: 26px;
}
/* Gridlines span the plot only; each tick label hangs in the gutter, centred
   on its line. Logical offsets, so the axis moves to the right in RTL. */
.rb-vbar__axis { position: absolute; inset: 0; pointer-events: none; }
.rb-vbar__grid {
  position: absolute; inset-inline: var(--rb-axis-gutter) 8px;
  border-top: 1px dashed var(--color-outline-variant);
}
.rb-vbar__grid:first-child { border-top-style: solid; border-top-color: var(--color-outline); }
.rb-vbar__tick {
  position: absolute; inset-inline-end: calc(100% + 6px); top: -7px;
  font-size: var(--md-sys-typescale-label-small-size); line-height: 12px; white-space: nowrap;
  color: var(--color-on-surface-var);
  font-variant-numeric: tabular-nums;
}
.rb-vbar__col {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  height: 100%;
  justify-content: flex-end;
  position: relative;
}
.rb-vbar__bar {
  width: 100%;
  max-width: 48px;
  border-radius: 4px 4px 0 0;
  transition: filter .15s;
  cursor: pointer;
}
.rb-vbar__col:hover .rb-vbar__bar { filter: brightness(1.05); }
.rb-vbar__bar--stack {
  display: flex;
  flex-direction: column;
  background: transparent;
}
.rb-vbar__segment { width: 100%; }
.rb-vbar__segment:first-child { border-radius: 4px 4px 0 0; }
/* A fixed height, so an empty label (skipped by labelStep) still holds every
   bar on the same baseline. It may overflow its narrow column sideways: the
   columns beside a kept label are the skipped, empty ones. */
/* MD3 label-small (11px, 500). No extra tracking: at 11px a dense date axis
   ("01-10-2026" under every fourth of 28 bars) only clears its neighbour on
   a 390px phone without it. */
.rb-vbar__label {
  height: 12px;
  font-size: var(--md-sys-typescale-label-small-size);
  line-height: 12px;
  font-weight: var(--md-sys-typescale-label-small-weight);
  letter-spacing: 0;
  color: var(--color-on-surface-var);
  white-space: nowrap;
}
/* A dense month series carries the year on a second label line, so its plot
   base sits one line higher. */
.rb-vbar--years { --rb-plot-base: 38px; }
.rb-vbar--years .rb-vbar__label {
  height: 24px; display: flex; flex-direction: column; align-items: center;
}
.rb-vbar__year { font-weight: 500; letter-spacing: 0; opacity: .75; }
/* Twelve labels do not fit a phone-width chart: keep every other one
   (_renderBar never marks a label that names its year as --alt). A hidden
   label still counts as overflow, so it keeps to its own column: one that
   ran past the chart's edge gave the chart a sideways scroll. */
@container (max-width: 520px) {
  .rb-vbar__label--alt { visibility: hidden; max-width: 100%; overflow: hidden; }
}
/* Every column labelled (not dense) — there is no empty neighbour to spill
   into, so a long ranked name still ellipsizes inside its own column. */
.rb-vbar:not(.rb-vbar--dense) .rb-vbar__label {
  max-width: 100%; overflow: hidden; text-overflow: ellipsis;
}
/* A short series of dates (_reportChart marks it) names each bucket in full,
   and on a narrow chart by its shorter name, the year on a line under it
   (as a dense month series does): there "05-10-2026" was cut to "05-1…", in
   Arabic to "…2026" under every bar. Every other label is dropped there, so
   a kept one may take the room of the empty columns beside it. */
.rb-vbar__short { display: none; }
@container (max-width: 520px) {
  .rb-vbar--dates > * { --rb-plot-base: 38px; }
  .rb-vbar--dates .rb-vbar__label { height: 24px; display: flex; flex-direction: column; align-items: center; }
  .rb-vbar--dates .rb-vbar__label:not(.rb-vbar__label--alt) { max-width: 200%; }
  .rb-vbar--dates .rb-vbar__long { display: none; }
  .rb-vbar--dates .rb-vbar__short { display: block; }
}
/* The first and the last label are centred on their columns like the rest,
   but have no empty column outside them to spill into: only the value axis's
   gutter before the first and 8px after the last, and the chart area clips
   what crosses them ("15-10-2026" read "15-10-202", in Arabic "5-10-2026").
   So a dense date plot keeps room at each end, where the gutter or the 8px
   is less, for what its first and last label need past it: half the label
   (_reportChart sets it in ch: the chart takes the labels' size, so a ch is
   one of their characters, every text in it sets its own size), less the
   card's side padding (below) and the columns and gaps from the label's
   centre to the end. Columns and gaps are counted at their narrowest, so the
   room never falls short: room the label does not need narrows every
   column and brings every label nearer the next. A ranked axis sets no
   halves: its plot keeps the gutter and the 8px. The gridlines, the goal
   line and the line's box keep to the plot; logical, so in RTL the room
   follows the axis. */
.rb-vbar--dense {
  font-size: var(--md-sys-typescale-label-small-size);
  --rb-room-start: calc(var(--rb-edge-start, 0px) - var(--rb-spill, 0px));
  --rb-room-end: calc(var(--rb-edge-end, 0px) - var(--rb-spill, 0px));
  --rb-end-at: var(--rb-end-cols, .5);
  --rb-plot-least: calc(100% - max(var(--rb-axis-gutter), var(--rb-room-start)) - max(8px, var(--rb-room-end)));
  --rb-col: calc((var(--rb-plot-least) - (var(--rb-n, 1) - 1) * var(--rb-col-gap)) / var(--rb-n, 1));
  --rb-col-gap-least: min(var(--rb-col-gap), clamp(3px, var(--rb-plot-least) * .012, 14px));
  --rb-plot-start: max(var(--rb-axis-gutter), var(--rb-room-start) - var(--rb-col) / 2);
  --rb-plot-end: max(8px, var(--rb-room-end) - var(--rb-end-at) * var(--rb-col)
                          - (var(--rb-end-at) - .5) * var(--rb-col-gap-least));
  padding-inline: var(--rb-plot-start) var(--rb-plot-end);
}
/* A narrow chart drops every other label (above): where the last drawn is
   one of them, the room at the end is for the one before it. Narrow by the
   chart area's width, a report's or a dashboard tile's: a tile's body is a
   container for this. */
.dash-tile__body:has(.rb-vbar--dense) { container: rb-chart / inline-size; }
@container rb-chart (max-width: 520px) {
  .rb-vbar--dense {
    --rb-room-end: calc(var(--rb-edge-end-narrow, var(--rb-edge-end, 0px)) - var(--rb-spill, 0px));
    --rb-end-at: var(--rb-end-cols-narrow, var(--rb-end-cols, .5));
  }
}
.rb-vbar--dense :is(.rb-vbar__grid, .rb-goal-line--bar, .rb-line__svg) {
  inset-inline: var(--rb-plot-start) var(--rb-plot-end);
}
.rb-vbar--dense > .rb-line__svg { width: calc(100% - var(--rb-plot-start) - var(--rb-plot-end)); }
/* A report's chart area, and a dashboard tile's body, give the end labels
   their card's side padding first: the clip box grows by the padding on
   each side and the plot stays where it was, so the plot gives up only what
   is left. A short series of dates' labels (above) may reach past their
   columns too. */
.rb-chartcard__chart:has(.rb-vbar--dense, .rb-vbar--dates) { --rb-spill: var(--chart-pad); }
.dash-tile__body:has(.rb-vbar--dense, .rb-vbar--dates) { --rb-spill: var(--space-4); }
:is(.rb-chartcard__chart, .dash-tile__body):has(.rb-vbar--dense, .rb-vbar--dates) {
  margin-inline: calc(-1 * var(--rb-spill));
  padding-inline: var(--rb-spill);
}
/* The bar and its value share the space above the axis label, so the bar's
   percentage height is of that plot area and the value always rides directly
   on top of its own bar. It used to be pinned to the top of the whole column,
   where it sat on (or inside) any bar tall enough to reach it. */
.rb-vbar__plot {
  flex: 1; min-height: 0; width: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-end;
}
.rb-vbar__value {
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: 700;
  color: var(--color-on-surface);
  white-space: nowrap;
  pointer-events: none;
  transition: opacity .15s;
}
/* A dense chart (>8 columns — VALUES_HOVER_AFTER in analytics.js) can't fit a
   value over every bar — there they appear on hover only. Hover-only
   everywhere left touch users with no values at all. */
.rb-vbar--dense .rb-vbar__value { opacity: 0; }
/* The last column's value grows inward, or the tile's overflow clips it
   (the first column's has the axis gutter to spill into). */
.rb-vbar__col:last-child .rb-vbar__value { align-self: flex-end; }
.rb-vbar--dense .rb-vbar__col:hover .rb-vbar__value { opacity: 1; }
/* The line chart (_reportChart _renderLine), on the column chart's frame: no
   gap, so each column's centre is evenly spaced for the line to pass through;
   the line in a box over the plot area, mirrored with the columns in RTL. */
.rb-line { --rb-col-gap: 0px; }
.rb-line__svg {
  position: absolute; top: var(--rb-plot-top); bottom: var(--rb-plot-base);
  inset-inline: var(--rb-axis-gutter) 8px; width: calc(100% - var(--rb-axis-gutter) - 8px);
  height: calc(100% - var(--rb-plot-top) - var(--rb-plot-base)); overflow: visible; pointer-events: none;
}
[dir="rtl"] .rb-line__svg { transform: scaleX(-1); }
.rb-line .rb-vbar__plot { position: relative; }
/* A split chart's parts, named under it (_reportChart _partsLegend). */
.rb-parts-legend { display: flex; flex-wrap: wrap; gap: 4px 16px; margin: 8px 0 0; padding: 0; list-style: none;
                   font-size: var(--md-sys-typescale-body-small-size); color: var(--color-on-surface-var); }
.rb-parts-legend li { display: inline-flex; align-items: center; gap: 6px; }
/* Side by side: a bucket's parts as thin bars next to each other. */
.rb-vbar__bar--side { display: flex; align-items: flex-end; gap: 1px; height: 100%; background: transparent; cursor: pointer; }
.rb-vbar__part { flex: 1; min-width: 2px; border-radius: 2px 2px 0 0; }
/* As tall as its parts, so seven of them never reach the next row. */
.rb-hbar__track--side { height: auto; min-height: var(--rb-bar-h, 26px); padding-block: 3px; align-items: center; }
.rb-hbar__parts { flex: 1; display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.rb-hbar__part { height: 5px; border-start-end-radius: 2px; border-end-end-radius: 2px; }
.rb-chartcard__slot { display: contents; }
.rb-line__dot {
  position: absolute; left: 50%; width: 8px; height: 8px; border-radius: 50%;
  transform: translate(-50%, 50%); box-shadow: 0 0 0 2px var(--color-surface);
}
.rb-line__value { position: absolute; left: 50%; transform: translate(-50%, -8px); }
.rb-line .rb-vbar__col:last-child .rb-line__value { left: auto; inset-inline-end: 0; transform: translateY(-8px); }

/* Donut / pie chart */
.rb-pie {
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 16px 8px;
  flex-wrap: wrap;
}
/* No wider than a narrow card, its legend under it there, and as tall as it
   is wide: no blank bands above and below the ring. */
.rb-pie__svg { width: min(var(--rb-ring, 220px), 100%); height: auto; aspect-ratio: 1; flex-shrink: 0; }
.rb-pie__legend {
  list-style: none;
  margin: 0;
  padding: 0;
  flex: 1;
  min-width: min(240px, 100%);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.rb-pie__legend li {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--md-sys-typescale-body-dense-size);
  padding: 6px 8px;
  border-radius: var(--md-sys-shape-corner-small);
}
.rb-pie__legend li:hover { background: var(--color-surface-container-low); }
.rb-pie__swatch {
  width: 12px; height: 12px;
  border-radius: var(--md-sys-shape-corner-extra-small);
  flex-shrink: 0;
}
.rb-pie__legend-label { flex: 1; color: var(--color-on-surface); }
.rb-pie__legend-value { font-weight: 600; color: var(--color-on-surface); }
.rb-pie__legend-value em { font-style: normal; color: var(--color-on-surface-var); font-weight: 400; margin-inline-start: 4px; }

/* Single big number viz */
.rb-num {
  text-align: center;
  padding: 32px 16px 16px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  align-items: center;
}
.rb-num__caption {
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: 700;
  letter-spacing: .5px;
  color: var(--color-on-surface-var);
}
.rb-num__value {
  font-size: var(--md-sys-typescale-display-large-size);
  font-weight: 800;
  line-height: 1.05;
  color: var(--color-on-surface);
}
.rb-num__sub { color: var(--color-on-surface-var); }
.rb-num__breakdown {
  list-style: none;
  margin: 16px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  width: 100%;
  max-width: 360px;
}
.rb-num__breakdown li {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  border-radius: var(--md-sys-shape-corner-small);
  background: var(--color-surface-container-low);
  font-size: var(--md-sys-typescale-body-dense-size);
}
.rb-num__swatch {
  width: 10px; height: 10px; border-radius: 2px; flex-shrink: 0;
}
.rb-num__break-label { flex: 1; text-align: start; color: var(--color-on-surface); }
.rb-num__break-value { font-weight: 700; color: var(--color-on-surface); }

/* Chart-as-table viz */
.rb-vtable {
  padding: 8px;
  max-width: 480px;
  margin: 0 auto;
}
.rb-vtable table {
  width: 100%;
  border-collapse: collapse;
}
.rb-vtable th {
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: 700;
  letter-spacing: .5px;
  color: var(--color-on-surface-var);
  padding: 8px 12px;
  border-bottom: 1px solid var(--color-outline-variant);
}
.rb-vtable td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--color-outline-variant);
  font-size: var(--md-sys-typescale-body-dense-size);
  color: var(--color-on-surface);
}
.rb-vtable tr:last-child td { border-bottom: 0; }
.rb-vtable__swatch {
  display: inline-block;
  width: 10px; height: 10px;
  border-radius: 2px;
  margin-inline-end: 8px;
  vertical-align: middle;
}

/* Summary tab table styles */
.rb-summary-table {
  width: 100%;
}
.rb-summary-table th,
.rb-summary-table td {
  padding: 10px 14px;
  border-bottom: 1px solid var(--color-outline-variant);
}
.rb-summary-table th {
  background: var(--color-surface-container-low);
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: 700;
  letter-spacing: .5px;
  color: var(--color-on-surface-var);
  text-align: start;
}
.rb-summary-table tbody tr:hover { background: var(--color-surface-container-low); }

/* Summary toolbar: search the group column, number-filter chips, row count.
   All three run client-side (views/_reportSummary.js). */
.rb-sumbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  padding: 8px 14px;
  border-bottom: 1px solid var(--color-outline-variant);
}
.rb-sumbar__search {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: 0 1 240px;
  min-width: 0;
  height: 32px;
  padding: 0 10px;
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--md-sys-shape-corner-small);
  background: var(--color-surface);
}
.rb-sumbar__search:focus-within { border-color: var(--color-primary); }
.rb-sumbar__search .material-symbols-outlined { font-size: 18px !important; color: var(--color-on-surface-var); }
.rb-sumbar__search input {
  width: 100%;
  min-width: 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--color-on-surface);
  font-size: var(--md-sys-typescale-body-dense-size);
}
.rb-sumbar__chips { display: flex; flex-wrap: wrap; gap: 8px; min-width: 0; }
.rb-sumbar__count {
  margin-inline-start: auto;
  font-size: var(--md-sys-typescale-body-small-size);
  color: var(--color-on-surface-var);
  white-space: nowrap;
}
.rb-sumchip { padding: 2px 4px 2px 10px; cursor: default; }
.rb-sumchip__edit {
  max-width: 240px;
  padding: 2px 0;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.rb-sumchip__close { border: 0; background: transparent; padding: 0; cursor: pointer; }
.rb-sumchip__close .material-symbols-outlined { font-size: 14px !important; }

/* Summary header: a sort button and, on number columns, a filter button. */
.rb-th__btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  text-align: inherit;
  cursor: pointer;
}
.rb-th__filter {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 0;
  border: 0;
  border-radius: var(--md-sys-shape-corner-extra-small);
  background: transparent;
  color: inherit;
  cursor: pointer;
  opacity: .35;
  transition: opacity .15s;
}
.rb-th__filter .material-symbols-outlined { font-size: 15px !important; }
.rb-th:hover .rb-th__filter { opacity: .8; }
.rb-th__filter:hover { background: var(--color-surface-variant); }
.rb-th__filter--on { opacity: 1; color: var(--color-primary); }
.rb-th__btn:focus-visible,
.rb-th__filter:focus-visible,
.rb-sumchip button:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
  border-radius: var(--md-sys-shape-corner-extra-small);
  opacity: 1;
}
.report-popover--sumfilter { width: 320px; }
@media (max-width: 600px) {
  .rb-sumbar__search { flex: 1 1 100%; }
}

/* ──────────────────────────────────────────────────────────────────────────
   MD3 utilities (snackbar, dialog-overlay, skeleton, skip-link, focus-visible)
   Ported from sibling extensions for visual parity. New code uses these.
   ────────────────────────────────────────────────────────────────────────── */

/* ── Skip link (WCAG 2.4.1) ─────────────────────────────────────────── */
.skip-link {
  position: absolute;
  top: -48px; inset-inline-start: 0;
  background: var(--md-sys-color-primary);
  color: var(--md-sys-color-on-primary);
  padding: var(--space-2) var(--space-3);
  z-index: 3000;
  border-radius: 0;
  border-end-end-radius: var(--md-sys-shape-corner-small);
  transition: top .2s ease;
  text-decoration: none;
  font-weight: 500;
}
.skip-link:focus {
  top: 0;
  outline: 2px solid var(--md-sys-color-on-primary);
  outline-offset: -2px;
}

/* ── Screen-reader-only utility — visually hidden, AT-announced. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0);
  white-space: nowrap; border: 0;
}

/* ── Focused main region — suppress the global focus ring ──────────────── */
/* The router moves focus to <main id="view"> on every hash change so SR
   users hear the new page. The visible outline would be a distracting
   blue ring on every navigation; suppress it for this element only. */
#view:focus-visible { outline: none; }

/* ── Focus visible (consistent across all interactive elements) ────────── */
:focus-visible {
  outline: 2px solid var(--md-sys-color-primary);
  outline-offset: 2px;
}
.btn:focus-visible {
  outline: 2px solid var(--md-sys-color-primary);
  outline-offset: 2px;
}
.btn--primary:focus-visible {
  outline-color: var(--md-sys-color-on-primary);
  outline-offset: -3px;
}

/* ── MD3 Snackbar ──────────────────────────────────────────────────────── */
.snackbar-container {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 600;
  display: flex;
  flex-direction: column-reverse;
  align-items: center;
  gap: 8px;
  pointer-events: none;
  max-width: calc(100% - 32px);
}
@media (max-width: 767px) {
  .snackbar-container { bottom: calc(var(--md-nav-bar-h) + 16px + env(safe-area-inset-bottom, 0px)); }
}

.snackbar {
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 288px;
  max-width: 600px;
  padding: 14px 16px;
  background: var(--md-sys-color-inverse-surface);
  color: var(--md-sys-color-inverse-on-surface);
  border-radius: var(--md-sys-shape-corner-extra-small);
  box-shadow: var(--md-sys-elevation-3);
  font-size: var(--md-sys-typescale-body-medium-size);
  line-height: 20px;
  animation: snackbarIn var(--md-sys-motion-duration-medium2) var(--md-sys-motion-easing-standard-decelerate);
}
.snackbar.fade-out {
  animation: snackbarOut var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard) forwards;
}
.snackbar-icon { font-size: 20px; flex-shrink: 0; }
.snackbar.snackbar-success .snackbar-icon { color: var(--md-sys-color-success); }
.snackbar.snackbar-error   .snackbar-icon { color: var(--md-sys-color-error); }
.snackbar.snackbar-info    .snackbar-icon { color: var(--md-sys-color-inverse-primary); }
.snackbar-message { flex: 1; white-space: pre-line; } /* multi-line messages (e.g. every push blocker) keep their breaks */
/* MD3: the snackbar action is a text button in inverse-primary. */
.snackbar-action {
  background: none; border: none;
  color: var(--md-sys-color-inverse-primary);
  cursor: pointer;
  font: inherit; font-weight: 600;
  text-transform: none; letter-spacing: 0;
  padding: 4px 8px;
  border-radius: var(--md-sys-shape-corner-full);
  flex-shrink: 0;
}
.snackbar-action:hover { background: rgba(255, 255, 255, 0.08); }
.snackbar-close {
  background: none; border: none;
  color: var(--md-sys-color-inverse-on-surface);
  cursor: pointer;
  padding: 4px;
  border-radius: var(--md-sys-shape-corner-full);
  display: flex; align-items: center;
  opacity: 0.7;
  flex-shrink: 0;
}
.snackbar-close:hover { opacity: 1; }
.snackbar-close .material-symbols-outlined { font-size: 18px; }

@keyframes snackbarIn {
  from { transform: translateY(100%); opacity: 0; }
  to   { transform: translateY(0);    opacity: 1; }
}
@keyframes snackbarOut {
  from { opacity: 1; }
  to   { opacity: 0; transform: translateY(8px); }
}
@media (prefers-reduced-motion: reduce) {
  .snackbar, .snackbar.fade-out { animation: none; }
}

/* ── MD3 Dialog overlay (used by #confirmDialog + future shared dialogs) ─ */
.dialog-overlay {
  position: fixed; inset: 0; z-index: 500;
  display: none;
  align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--md-sys-color-scrim) 32%, transparent);
  padding: var(--space-3);
}
.dialog-overlay.open { display: flex; }
.dialog-overlay .dialog {
  background: var(--md-sys-color-surface-container-lowest);
  color: var(--md-sys-color-on-surface);
  box-shadow: var(--md-sys-elevation-3);
  border-radius: var(--md-sys-shape-corner-extra-large);
  padding: 24px;
  min-width: 280px;
  max-width: 560px;
  width: 100%;
  animation: modal-in var(--md-sys-motion-duration-medium2) var(--md-sys-motion-easing-standard-decelerate);
}
.dialog-overlay .dialog h3 {
  font-size: var(--md-sys-typescale-title-large-size);
  font-weight: 600;
  line-height: 28px;
  color: var(--md-sys-color-on-surface);
  margin-bottom: 12px;
}
.dialog-overlay .dialog__body {
  font-size: var(--md-sys-typescale-body-medium-size);
  color: var(--md-sys-color-on-surface-variant);
  margin-bottom: 24px;
  white-space: pre-wrap;
}
.dialog__prompt-description {
  display: block;
  margin-bottom: var(--space-3);
}
.dialog__prompt-field { margin: 0; }
.dialog__prompt-field > span {
  color: var(--md-sys-color-on-surface-variant);
  font-size: var(--md-sys-typescale-body-small-size);
  font-weight: 600;
}
.dialog-overlay .dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

/* ── MD3 Skeleton loaders (shimmer placeholder) ────────────────────────── */
.skeleton-card {
  background: var(--md-sys-color-surface-container-low);
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-medium);
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.skeleton-line, .skeleton-fill {
  background: linear-gradient(
    90deg,
    var(--md-sys-color-surface-container) 25%,
    var(--md-sys-color-surface-container-high) 50%,
    var(--md-sys-color-surface-container) 75%
  );
  background-size: 200% 100%;
  animation: shimmer 1.5s ease-in-out infinite;
  border-radius: var(--md-sys-shape-corner-extra-small);
}
.skeleton-line { height: 14px; }
/* Stands in for a figure inside its own line, so the line keeps its height. */
.skeleton-fill { display: inline-block; max-width: 100%; line-height: 1; vertical-align: middle; }
/* Placeholders staying under what replaced them while it comes in (_motion.js). */
.motion-held { position: absolute; z-index: -1; pointer-events: none; overflow: hidden; }
.skeleton-title  { width: 60%; height: 18px; }
.skeleton-chip   { width: 80%; height: 28px; border-radius: 14px; }
.skeleton-chip.short { width: 50%; }

@keyframes shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .skeleton-line, .skeleton-fill { animation: none; }
}

/* ── Skeleton containers — shape-matching loading placeholders ─────────── */
/* .skeleton-line/.skeleton-card above provide the shimmer + tokens;
   the containers below just lay them out per route type. */

.skeleton-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 8px 0;
  min-height: 280px;
}

.skeleton-table {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 8px 0;
  min-height: 480px;
}
.skeleton-table__head,
.skeleton-table__row {
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--md-sys-color-outline-variant);
}
.skeleton-table__head { padding-bottom: 8px; }
.skeleton-table__body { display: flex; flex-direction: column; }

.skeleton-kanban {
  display: flex;
  gap: 12px;
  padding: 8px 0;
  width: 100%;
  flex: 1 1 auto;
  min-height: 60vh;
  overflow: hidden;
}
.skeleton-kanban__col {
  flex: 1 1 0;
  min-width: 280px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  background: var(--md-sys-color-surface-container-low);
  border-radius: var(--md-sys-shape-corner-medium);
  padding: 12px;
}

.skeleton-detail {
  display: grid;
  grid-template-columns: 320px 1fr;
  gap: 16px;
  padding: 8px 0;
  min-height: 60vh;
}
.skeleton-detail__sidebar,
.skeleton-detail__body {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
@media (max-width: 768px) {
  .skeleton-detail { grid-template-columns: 1fr; }
}

.skeleton-form {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 8px 0;
  min-height: 360px;
}

/* ─────────────────────────────────────────────────────────────────────────
   Workflow builder UI
   ──────────────────────────────────────────────────────────────────── */

/* The rule's name: a headline edited in place, with a pen beside it. It wraps
   rather than being cut (M3: "Don't truncate the headline text"). Its text
   stays in line with other record titles; the box around it shows on hover
   and while it is edited. */
.wf-name-row { display: flex; align-items: center; min-width: 0; }
.wf-name {
  min-width: 4ch;
  padding: 2px 6px;
  margin-inline-start: -6px;
  border-radius: var(--md-sys-shape-corner-extra-small);
  outline: 0;
  cursor: text;
  overflow-wrap: anywhere;
}
.wf-name:hover { background: var(--color-surface-container-low); }
.wf-name:focus {
  background: var(--color-surface-container-lowest);
  box-shadow: inset 0 0 0 2px var(--color-primary);
}
.wf-name:empty::before { content: attr(data-placeholder); color: var(--color-on-surface-var); }
/* The pen beside a title someone may rename (a workflow, a deal, a contact,
   an organization). Beside a record's title it sits closer than the row's
   12px gap, which is for the status badge. */
.dd-title-edit { flex: none; min-width: 40px; min-height: 40px; color: var(--color-on-surface-var); }
.dd-title-row > .dd-title-edit { margin-inline-start: -8px; }
/* The workflow editor's top bar (.dd-topbar) sits flush with the editor below,
   inside the view's own padding. */
.dd-topbar--flush { padding-inline: 0; }

/* Tablist — MD3 secondary tabs with a colored underline on the active one. */
.tablist {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--color-outline-variant);
  margin: 0 0 var(--space-4) 0;
}
.tab {
  appearance: none;
  background: transparent;
  border: none;
  font: inherit;
  font-weight: 500;
  color: var(--color-on-surface-var);
  padding: 12px 18px;
  cursor: pointer;
  position: relative;
  border-radius: 8px 8px 0 0;
  min-height: 48px;
}
.tab:hover { background: var(--color-surface-container-low); color: var(--color-on-surface); }
.tab.active { color: var(--color-primary-text); }
.tab.active::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 3px;
  background: var(--color-primary);
  border-radius: 3px 3px 0 0;
}
.tab:disabled { opacity: .5; cursor: not-allowed; }
.tab:focus-visible { outline: 2px solid var(--color-primary); outline-offset: -2px; }

/* While a selected tab's indicator slides (_tablist.js), the indicator is this
   one layer behind the tabs, and the tabs draw none of their own. */
.tab-sliding { position: relative; isolation: isolate; }
.tab-sliding > * { background: transparent; transition: none; }
.tab-sliding > .active,
.tab-sliding > .is-on { background: transparent; border-bottom-color: transparent; }
.tab-slide { position: absolute; inset-block-start: 0; left: 0; z-index: -1; pointer-events: none; }
/* The board's selected tab is white on a filled pill: its text waits for the
   pill to arrive rather than show white on the page. */
.tab-sliding > .btab.is-on { animation: tab-text-arrives var(--tab-text-ms, 360ms) ease-in; }
@keyframes tab-text-arrives { from { color: var(--color-on-surface-var); } }

/* Tabpanel: remove any inherited focus outline so the editor doesn't paint
   a giant box. WAI-ARIA doesn't require focus styling here — the panel
   contains focusable children that get their own focus rings. */
[role="tabpanel"]:focus { outline: none; }

/* Card spacing inside the editor — cards now have subtle elevation + roomier padding */
.wf-panel {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.wf-panel > .card {
  padding: var(--space-4);
  background-color: var(--color-surface-container-lowest);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-m);
  box-shadow: var(--shadow-1);
}
.wf-panel > .card > h3 {
  margin: 0 0 var(--space-3) 0;
  color: var(--color-on-surface);
}
.wf-panel > .card > .muted {
  margin: -8px 0 var(--space-3) 0;
  font-size: var(--md-sys-typescale-body-dense-size);
  line-height: 1.5;
}

/* Form rows — stacked label + control, 2-col grid on wide screens */
.wf-panel .form-row {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: var(--space-3);
}
.wf-panel .form-row:last-child { margin-bottom: 0; }
.wf-panel .form-row > span:not(.muted) {
  color: var(--color-on-surface-var);
  font-size: var(--md-sys-typescale-body-small-size);
  font-weight: 600;
  letter-spacing: 0.04em;
}
/* Arabic letters connect — letter-spacing breaks ligature joining. Drop it
   in RTL. */
[dir="rtl"] .wf-panel .form-row > span:not(.muted) {
  letter-spacing: normal;
}
.wf-panel .form-row > .muted {
  margin-top: 4px;
  font-size: var(--md-sys-typescale-body-small-size);
  color: var(--color-on-surface-var);
  letter-spacing: 0;
  font-weight: 400;
}
/* Inline checkbox group (replaces the old misuse of `.form-row` for the
   convert_lead Organization/Contact/Deal trio). Horizontal, wraps. */
.wf-panel .wf-checks {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.wf-panel .wf-checks label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
}
.wf-trigger-config {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* Weekday chips — pill row used by the Weekly schedule picker.
   Mobile-friendly: wraps freely, each chip stays tappable at 32px+ tall. */
.wf-weekday-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.wf-weekday-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 32px;
  padding: 6px 12px;
  font: inherit;
  font-size: var(--md-sys-typescale-label-large-size);
  font-weight: var(--md-sys-typescale-label-large-weight);
  color: var(--md-sys-color-on-surface-variant);
  background-color: transparent;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-small);
  cursor: pointer;
}
/* MD3 filter chip, selected. */
.wf-weekday-chip[aria-pressed="true"] {
  color: var(--md-sys-color-on-secondary-container);
  background-color: var(--md-sys-color-secondary-container);
  border-color: transparent;
}

/* Read-only preview line under the schedule picker — shows the human-readable
   summary plus the cron string we'll save. */
.wf-cron-preview {
  font-size: var(--md-sys-typescale-body-small-size);
  color: var(--color-on-surface-var);
  margin-top: -4px;
}
.wf-cron-preview code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: var(--md-sys-typescale-body-small-size);
  padding: 1px 6px;
  border-radius: var(--md-sys-shape-corner-extra-small);
  background-color: var(--color-surface-container-high);
  color: var(--color-on-surface);
}

/* ─── Modern MD3 filled form controls (the redesign target) ───────────
   Scoped to `.wf-panel` so it covers workflow.js + _criteriaBuilder.js
   + _actionEditor.js inputs without needing per-class additions, and
   safely excludes the page-header rule-name input (it lives in
   `.page-header`, not `.wf-panel`). */
.wf-panel input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="hidden"]),
.wf-panel select,
.wf-panel textarea {
  width: 100%;
  box-sizing: border-box;
  min-height: 40px;
  padding: 10px 14px;
  font: inherit;
  font-size: var(--md-sys-typescale-body-medium-size);
  color: var(--color-on-surface);
  /* `background-color` (not `background:` shorthand) so the chevron caret
     on `select` survives — the hover/focus rules also use background-color. */
  background-color: var(--color-surface-container-high);
  border: 1px solid transparent;
  border-bottom: 2px solid var(--color-outline-variant);
  border-radius: var(--radius-s) var(--radius-s) 0 0;
  outline: none;
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  transition:
    background-color .15s ease,
    border-color .15s ease,
    box-shadow .15s ease;
}
.wf-panel input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="hidden"])::placeholder,
.wf-panel textarea::placeholder {
  color: var(--color-on-surface-var);
}
.wf-panel input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="hidden"]):hover,
.wf-panel select:hover,
.wf-panel textarea:hover {
  background-color: var(--color-surface-container-highest);
}
.wf-panel input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="hidden"]):focus,
.wf-panel select:focus,
.wf-panel textarea:focus,
.wf-panel input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="hidden"]):focus-visible,
.wf-panel select:focus-visible,
.wf-panel textarea:focus-visible {
  background-color: var(--color-surface-container-lowest);
  border-bottom-color: var(--color-primary);
  /* Solid 2px ring as fallback for Safari <16.4 / Firefox <113 that don't
     support color-mix(). Modern browsers override with the soft 3px ring. */
  box-shadow: 0 0 0 2px var(--color-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 18%, transparent);
}
.wf-panel input:disabled,
.wf-panel select:disabled,
.wf-panel textarea:disabled {
  opacity: .55;
  cursor: not-allowed;
  background-color: var(--color-surface-container-low);
}
.wf-panel textarea {
  resize: vertical;
  line-height: 1.5;
  padding-top: 12px;
  padding-bottom: 12px;
}
/* Only force a tall minimum on textareas that DON'T declare their own row
   count — respect `rows="3"` on the webhook body-template, etc. */
.wf-panel textarea:not([rows]) {
  min-height: 96px;
}

/* Custom dropdown caret — replaces the default OS arrow for consistency.
   Inline SVG; we encode '#' as %23 and use an on-surface-variant grey
   that reads fine on both light and dark fills. */
.wf-panel select {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%2341474f' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat;
  background-position: right 12px center;
  padding-inline-end: 38px;
  cursor: pointer;
}
/* RTL: flip caret to the LEFT (which is `inline-end` in RTL writing mode),
   and give it the same ~38px clearance there so long Arabic option text
   doesn't overlap the chevron. */
[dir="rtl"] .wf-panel select,
html[dir="rtl"] .wf-panel select {
  background-position: left 12px center;
  padding-inline-end: 38px;
  padding-inline-start: 14px;
}
/* IE/Edge legacy: hide the duplicate native arrow */
.wf-panel select::-ms-expand { display: none; }

/* Number inputs — narrower, no spinner arrows (cleaner look) */
.wf-panel input[type="number"] {
  max-width: 120px;
  -moz-appearance: textfield;
}
.wf-panel input[type="number"]::-webkit-outer-spin-button,
.wf-panel input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/* Inline switch in the page header (rule Enabled toggle) */
.switch--inline { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; }
/* A native checkbox drawn as a switch: keyboard, label click and the
   `checked` state all stay the browser's. Any checkbox with role="switch". */
/* MD3 switch: 52×32 track. Off = surface-container-highest with a 2px
   outline and a 16px outline-coloured handle; on = primary track with a 24px
   on-primary handle. */
input[type="checkbox"][role="switch"] {
  appearance: none; -webkit-appearance: none; flex: 0 0 auto; position: relative; margin: 0;
  width: 52px; height: 32px; border-radius: var(--md-sys-shape-corner-full); cursor: pointer;
  background: var(--md-sys-color-surface-container-highest);
  border: 2px solid var(--md-sys-color-outline);
  transition: background var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard),
              border-color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard);
}
input[type="checkbox"][role="switch"]::after {
  content: ""; position: absolute; top: 50%; inset-inline-start: 6px; width: 16px; height: 16px;
  transform: translateY(-50%);
  border-radius: 50%; background: var(--md-sys-color-outline);
  transition-property: inset-inline-start, width, height, background-color;
  transition-duration: var(--md-sys-motion-duration-short4);
  transition-timing-function: var(--md-sys-motion-easing-standard);
}
input[type="checkbox"][role="switch"]:checked {
  background: var(--md-sys-color-primary);
  border-color: var(--md-sys-color-primary);
}
input[type="checkbox"][role="switch"]:checked::after {
  inset-inline-start: 22px; width: 24px; height: 24px;
  background: var(--md-sys-color-on-primary);
}
input[type="checkbox"][role="switch"]:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
input[type="checkbox"][role="switch"]:disabled { opacity: .6; cursor: progress; }

/* Criteria builder — group container + condition rows */
.criteria-builder { display: flex; flex-direction: column; gap: var(--space-3); }
.criteria-group {
  background: var(--color-surface-container-low);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-m);
  padding: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.criteria-group__header {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.criteria-group__header select { max-width: 220px; }
.criteria-group__children { display: flex; flex-direction: column; gap: 6px; }
.criteria-group__footer {
  display: flex;
  gap: 8px;
  margin-top: 4px;
  flex-wrap: wrap;
}
.criteria-leaf {
  display: grid;
  grid-template-columns: minmax(140px, 1.4fr) minmax(120px, 0.9fr) minmax(140px, 1.6fr) auto;
  gap: 10px;
  align-items: center;
  /* Small negative inset + matching padding extends the hover-target
     beyond the controls' bounding box. Kept smaller than the parent's
     `gap: 6px` so adjacent leaves don't overlap on hover. */
  padding: 3px;
  margin: -3px;
  border-radius: var(--radius-s);
  transition: background-color .12s ease;
}
.criteria-leaf:hover {
  background-color: var(--color-surface-container-lowest);
}
/* `is_empty` / `is_not_empty` comparators render `<span class="muted">—</span>`
   in place of the value input. Pin it to the value column on every layout. */
.criteria-leaf > .muted {
  text-align: center;
  color: var(--color-on-surface-var);
}
/* Slight visual divider between sibling condition rows */
.criteria-group__children > * + * {
  position: relative;
}

/* Action editor — single action card, modernized */
.action-card {
  /* Step one tier away from the parent `.wf-panel > .card` (which is
     `surface-container-lowest`) so the nested card has actual fill contrast,
     not just a 1px border. */
  background-color: var(--color-surface-container-low);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-m);
  padding: var(--space-3);
  margin-bottom: var(--space-3);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.action-card:hover {
  border-color: var(--color-outline);
  box-shadow: var(--shadow-1);
}
.action-card__head {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  padding-bottom: var(--space-3);
  margin-bottom: var(--space-3);
  border-bottom: 1px solid var(--color-outline-variant);
}
.action-card__head > .action-type {
  flex: 1 1 200px;
  min-width: 180px;
}
.action-card__head .action-remove { margin-inline-start: auto; }
.action-card__body { display: flex; flex-direction: column; gap: var(--space-2); }
.action-timing {
  display: inline-flex;
  gap: 4px;
  padding: 4px;
  background-color: var(--color-surface-container-low);
  border-radius: var(--md-sys-shape-corner-full);
}
.action-timing label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--md-sys-typescale-body-dense-size);
  padding: 6px 12px;
  border-radius: var(--md-sys-shape-corner-full);
  cursor: pointer;
  color: var(--color-on-surface-var);
  transition: background-color .12s ease, color .12s ease;
  /* `position: relative` so the visually-hidden radio inside this label
     is positioned against the label, not the viewport. */
  position: relative;
}
.action-timing label:hover { color: var(--color-on-surface); }
/* `.is-active` is a JS-applied fallback for browsers without `:has()` support
   (Firefox <121, Safari <15.4). Keep both selectors so both work. */
.action-timing label:has(input:checked),
.action-timing label.is-active {
  background-color: var(--color-surface-container-lowest);
  color: var(--color-primary);
  font-weight: 600;
  box-shadow: var(--shadow-1);
}
/* Keyboard focus indicator on the wrapping label (the radio inside is 0×0
   and invisible, so the label needs to show its own ring). Same color-mix
   fallback pattern as the input focus rings. */
.action-timing label:has(input:focus-visible) {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}
.action-timing input[type="radio"] {
  /* Hide the native radio circle visually but keep it in the tab order and
     keyboard-operable. Position is anchored to the label (position:relative
     above) so it can't escape to the viewport. */
  appearance: none;
  -webkit-appearance: none;
  width: 0;
  height: 0;
  margin: 0;
  position: absolute;
  inset: 0;
  opacity: 0;
}
.cr-mappings { display: flex; flex-direction: column; gap: 6px; }
.cr-map {
  display: grid;
  grid-template-columns: minmax(120px, 1fr) minmax(100px, 120px) minmax(140px, 2fr) auto;
  gap: 10px;
  align-items: center;
  padding: 6px;
  margin: -6px;
  border-radius: var(--radius-s);
}
.cr-map:hover { background-color: var(--color-surface-container-low); }

/* ── Workflow editor: mobile (< 600px) ───────────────────────────────── */
@media (max-width: 600px) {
  .wf-panel > .card { padding: var(--space-3); }
  .criteria-leaf {
    grid-template-columns: 1fr 1fr;
    grid-template-areas:
      "field  field"
      "cmp    value"
      "rm     rm";
    gap: 8px;
  }
  .criteria-leaf .criteria-field { grid-area: field; }
  .criteria-leaf .criteria-cmp   { grid-area: cmp; }
  .criteria-leaf .criteria-value { grid-area: value; }
  /* `is_empty` / `is_not_empty` render `<span class="muted">—</span>`
     instead of `.criteria-value` — pin it to the same cell. */
  .criteria-leaf > .muted { grid-area: value; }
  .criteria-leaf .criteria-remove { grid-area: rm; justify-self: end; }
  .cr-map {
    grid-template-columns: 1fr 1fr;
    grid-template-areas:
      "field  field"
      "type   value"
      "rm     rm";
  }
  .cr-map .cr-map-field  { grid-area: field; }
  .cr-map .cr-map-type   { grid-area: type; }
  .cr-map .cr-map-value  { grid-area: value; }
  .cr-map .cr-map-remove { grid-area: rm; justify-self: end; }
  .action-card__head { gap: 8px; }
  .action-card__head > .action-type { flex-basis: 100%; }
  .action-timing { flex-basis: 100%; justify-content: center; }
}

/* ── Workflow editor: dark mode pass ─────────────────────────────────── */
/* Use `background-color` (not `background:` shorthand) — shorthand would
   reset the chevron caret's background-image/repeat/position. */
[data-theme="dark"] .wf-panel input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="hidden"]),
[data-theme="dark"] .wf-panel select,
[data-theme="dark"] .wf-panel textarea {
  background-color: var(--color-surface-container-high);
  color: var(--color-on-surface);
  border-bottom-color: var(--color-outline-variant);
}
[data-theme="dark"] .wf-panel input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="hidden"]):hover,
[data-theme="dark"] .wf-panel select:hover,
[data-theme="dark"] .wf-panel textarea:hover {
  background-color: var(--color-surface-container-highest);
}
[data-theme="dark"] .wf-panel input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="hidden"]):focus,
[data-theme="dark"] .wf-panel select:focus,
[data-theme="dark"] .wf-panel textarea:focus {
  background-color: var(--color-surface-container);
  /* `--color-primary-fixed*` in dark mode are ~#1f3a52/#2c4a66 — virtually
     identical to the dark surfaces. Use `--color-primary-container`
     (#6aa3d0 in dark) which keeps ~6:1 contrast against the surface. */
  border-bottom-color: var(--color-primary-container);
  /* Solid 2px ring fallback for browsers without color-mix(). */
  box-shadow: 0 0 0 2px var(--color-primary-container);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary-container) 30%, transparent);
}
[data-theme="dark"] .wf-panel select {
  /* Re-encode the caret with a lighter stroke for dark surfaces */
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%23c1c7d0' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
}
[data-theme="dark"] .action-timing {
  background-color: var(--color-surface-container);
}
/* Active-pill text — `--color-primary-container` (#6aa3d0 in dark)
   gives ~5.7:1 contrast on `surface-container-high` (#243044). The
   `*-fixed*` variants both resolve to dark navy in dark mode and fail. */
[data-theme="dark"] .action-timing label:has(input:checked),
[data-theme="dark"] .action-timing label.is-active {
  background-color: var(--color-surface-container-high);
  color: var(--color-primary));
}
/* Match the focus ring color to the dark-mode primary accent. */
[data-theme="dark"] .action-timing label:has(input:focus-visible) {
  outline-color: var(--color-primary-container);
}

/* Workflow list row link covers the whole name cell so any click hits it. */
.wf-row-link { display: block; color: inherit; text-decoration: none; }
.wf-row-link:hover { color: var(--color-primary); }
.row-actions { text-align: end; white-space: nowrap; }

/* Merge-field picker popover */
.merge-picker {
  background: var(--color-surface-container-lowest);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-m);
  box-shadow: var(--shadow-3);
  /* Over a step's panel, which is a page of its own on a phone (z-index
     300), as menus are (_moreMenu.js). */
  z-index: 400;
  font-size: var(--md-sys-typescale-body-medium-size);
}
.merge-picker__header {
  padding: 8px 12px;
  font-size: var(--md-sys-typescale-body-small-size);
  font-weight: 600;
  letter-spacing: .04em;
  color: var(--color-on-surface-var);
  border-bottom: 1px solid var(--color-outline-variant);
}
.merge-picker__list { padding: 4px 0; }
.merge-picker__item {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 8px 12px; cursor: pointer; user-select: none;
}
.merge-picker__item:hover,
.merge-picker__item--active { background: var(--color-surface-container-low); }
.merge-picker__token { font-family: var(--font-mono); font-size: var(--md-sys-typescale-body-small-size); }

/* ── Workflows: the step list beside the side sheet (_workflowSteps.js) ────
   Material 3's list-detail layout: the steps on one side, the selected
   step's form in a standard side sheet on the other ("Place side sheets along
   the edge of the screen, usually on the right"; in Arabic, the left — the
   grid follows the page's direction). Below 760px of room the list fills it
   and a step opens as a page of its own ("Selecting a list item should open
   a page with the details"). Measured on the editor, not the window: the
   side nav takes its share first. */
.wf-builder-host { container: wf-builder / inline-size; }
.wf-builder {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(360px, 440px);
  gap: var(--space-4);
  align-items: start;
}
.wf-steps { min-width: 0; }
.wf-step-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.wf-step {
  background: var(--color-surface-container-lowest);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-m);
}
.wf-step.is-selected > .wf-step__row {
  background: var(--color-secondary-container);
  color: var(--color-on-secondary-container);
  border-radius: calc(var(--radius-m) - 1px);
}
.wf-step__row { display: flex; align-items: center; gap: 4px; padding-inline-end: 4px; }
.wf-step__main {
  flex: 1 1 auto; min-width: 0;
  display: flex; align-items: center; gap: var(--space-3);
  min-height: 56px; padding: 8px var(--space-3);
  background: none; border: 0; border-radius: var(--radius-m);
  color: inherit; font: inherit; text-align: start; cursor: pointer;
}
.wf-step__main:hover { background: var(--color-surface-container-low); }
.wf-step.is-selected > .wf-step__row .wf-step__main:hover { background: none; }
.wf-step__main:focus-visible { outline: 2px solid var(--color-primary); outline-offset: -2px; }
.wf-step__num {
  min-width: 2.25em; text-align: center;
  font-size: var(--md-sys-typescale-body-small-size);
  color: var(--color-on-surface-var);
  font-variant-numeric: tabular-nums;
}
.wf-step__icon { color: var(--color-primary); }
.wf-step__text { display: flex; flex-direction: column; min-width: 0; }
.wf-step__overline {
  font-size: var(--md-sys-typescale-body-small-size);
  color: var(--color-on-surface-var);
}
.wf-step__title { font-weight: 500; }
.wf-step__summary {
  font-size: var(--md-sys-typescale-body-small-size);
  color: var(--color-on-surface-var);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.wf-step--trigger { border-color: var(--color-primary); }
/* An If's branches and a For each's steps nest under it, indented. Material 3
   lists: "Gaps or dividers can separate lists into items and groups"; inset
   dividers part an If's branches. */
.wf-step__groups { padding: 0 var(--space-3) var(--space-3); padding-inline-start: calc(var(--space-3) + 2.25em); }
.wf-branch { display: flex; flex-direction: column; gap: var(--space-2); }
.wf-branch__label {
  font-size: var(--md-sys-typescale-body-small-size);
  font-weight: 600;
  color: var(--color-on-surface-var);
}
.wf-step__divider { border: 0; border-top: 1px solid var(--color-outline-variant); margin: var(--space-3) 0; }
.wf-step-list--nested { border-inline-start: 2px solid var(--color-outline-variant); padding-inline-start: var(--space-3); }
.wf-step-list--nested:empty { display: none; }
.wf-add-step { align-self: flex-start; display: inline-flex; align-items: center; gap: 4px; }
.wf-steps__add { margin-top: var(--space-3); }

/* The side sheet. "A close icon button is highly recommended" on a wide
   screen; the page of its own on a phone goes back instead. It scrolls with
   the page: a sheet with a scroll of its own put a second scrollbar (and a
   sideways one) inside the first. Its forms lay out for its own width. */
.wf-sheet {
  container: wf-sheet / inline-size;
  min-width: 0;
  background: var(--color-surface-container-low);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-l);
}
.wf-sheet__head {
  display: flex; align-items: center; gap: var(--space-2);
  padding-block: var(--space-2);
  padding-inline: var(--space-4) var(--space-2);
  border-bottom: 1px solid var(--color-outline-variant);
}
.wf-sheet__title { flex: 1 1 auto; margin: 0; font-size: var(--md-sys-typescale-title-medium-size); font-weight: 500; }
.wf-sheet__title:focus { outline: none; }
.wf-sheet__back { display: none; }
/* The sheet's close and back keep M3's small size (40px) but not the outline:
   standard icon buttons, as a side sheet's header has. */
.wf-sheet__head .btn--icon { border-color: transparent; }
.wf-sheet__body { padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-3); }
.wf-sheet__body .form-row { margin-bottom: 0; }
.wf-sheet__form { display: flex; flex-direction: column; gap: var(--space-3); }
/* A step tested on a real record (_workflowTest.js): the sheet's last section. */
.wf-test {
  display: flex; flex-direction: column; gap: var(--space-2);
  margin-top: var(--space-2); padding-top: var(--space-3);
  border-top: 1px solid var(--color-outline-variant);
}
.wf-test__title { margin: 0; font-size: var(--md-sys-typescale-title-small-size); font-weight: 600; }
.wf-test__pick { min-width: 0; }
.wf-test__run { align-self: flex-start; }
.wf-test__result:empty { display: none; }
.wf-test__result {
  display: flex; flex-direction: column; gap: 4px; padding: var(--space-3);
  border-radius: var(--md-sys-shape-corner-medium); background: var(--color-surface-container-low);
}
.wf-test__result p { margin: 0; }
.wf-test__result blockquote {
  margin: 0; padding-inline-start: var(--space-3); border-inline-start: 3px solid var(--color-outline-variant);
  overflow-wrap: anywhere;
}
.wf-test__note { color: var(--color-on-surface-var); }
.wf-test__result.is-stale > :not(.wf-test__stale) { opacity: .55; }
.wf-test__stale { font-weight: 500; }
.wf-test__error { color: var(--color-error); }
.wf-test__safe { font-size: var(--md-sys-typescale-body-small-size); }
.wf-sheet__note { margin: 0; font-size: var(--md-sys-typescale-body-small-size); }
.wf-sheet__section { margin: var(--space-2) 0 0; font-size: var(--md-sys-typescale-title-small-size); }
.wf-sheet__empty {
  display: flex; flex-direction: column; align-items: center; gap: var(--space-2);
  padding: var(--space-6) var(--space-4); text-align: center; color: var(--color-on-surface-var);
}
.wf-sheet__empty .material-symbols-outlined { font-size: var(--md-sys-typescale-headline-large-size); }
.wf-sheet__empty p { margin: 0; }
.wf-builder:not(.has-selection) .wf-sheet__head { display: none; }
/* An action's form in the sheet: the sheet is its card. */
.wf-sheet .action-card { background: none; border: 0; padding: 0; margin: 0; box-shadow: none; }
.wf-sheet .action-card:hover { box-shadow: none; }

/* Find records: a condition row is field · comparison · value · ✕, and the
   value as it reads ("Lead › Phone") under it. */
.fr-conds { display: flex; flex-direction: column; gap: var(--space-2); }
.fr-cond {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto;
  grid-template-areas: "field cmp remove" "value value value" "reads reads reads";
  gap: 6px;
  align-items: center;
}
.fr-cond .fr-field { grid-area: field; }
.fr-cond .fr-cmp { grid-area: cmp; }
.fr-cond .fr-remove { grid-area: remove; }
.fr-value-wrap { grid-area: value; display: flex; align-items: center; gap: 4px; }
.fr-value-wrap .fr-value { flex: 1 1 auto; min-width: 0; }
.fr-value-reads { grid-area: reads; font-size: var(--md-sys-typescale-body-small-size); }
.fr-add, .cd-add { align-self: flex-start; }

/* A condition row in the sheet: field and ✕ on one line, comparison and
   value under it — the phone layout, chosen by the sheet's width, since the
   sheet is narrow on every screen. */
@container wf-sheet (max-width: 600px) {
  .criteria-group { padding: var(--space-2); }
  .criteria-group__header select { max-width: none; flex: 1 1 auto; }
  .criteria-leaf {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto;
    grid-template-areas: "field field rm" "cmp value value";
    gap: 6px;
  }
  .criteria-leaf .criteria-field { grid-area: field; }
  .criteria-leaf .criteria-cmp   { grid-area: cmp; }
  .criteria-leaf .criteria-value { grid-area: value; min-width: 0; }
  .criteria-leaf > .muted { grid-area: value; }
  .criteria-leaf .criteria-remove { grid-area: rm; }
  .cr-map {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto;
    grid-template-areas: "field field rm" "type value value";
  }
  .cr-map .cr-map-field  { grid-area: field; }
  .cr-map .cr-map-type   { grid-area: type; }
  .cr-map .cr-map-value  { grid-area: value; min-width: 0; }
  .cr-map .cr-map-remove { grid-area: rm; }
  .action-card__head > .action-type { flex-basis: 100%; }
}

/* If / Otherwise: one section per branch. */
.cd-branch { display: flex; flex-direction: column; gap: var(--space-2); padding-bottom: var(--space-3); border-bottom: 1px solid var(--color-outline-variant); }
.cd-branch__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.cd-branch__head h3 { margin: 0; font-size: var(--md-sys-typescale-title-small-size); }
.cd-otherwise-row { align-self: flex-start; }

/* The '#' picker's groups: what the rule started on, what each step found. */
.merge-picker__group {
  padding: 8px 12px 4px;
  font-size: var(--md-sys-typescale-body-small-size);
  font-weight: 600;
  color: var(--color-on-surface-var);
}
.merge-picker__group + .merge-picker__item,
[role="group"] + [role="group"] > .merge-picker__group { border-top: 0; }
[role="group"] + [role="group"] { border-top: 1px solid var(--color-outline-variant); }

/* A menu's next group starts after a line, as its Delete does. */
.dd-tl-dropdown > .dd-tl-dropdown-item--divided {
  margin-top: 4px;
  border-top: 1px solid var(--color-outline-variant);
}

@container wf-builder (max-width: 759px) {
  .wf-builder { grid-template-columns: minmax(0, 1fr); }
  .wf-sheet { display: none; }
  .wf-builder.has-selection .wf-sheet {
    display: block;
    position: fixed; inset: 0; z-index: 300;
    overflow-y: auto; border: 0; border-radius: 0;
    background: var(--color-surface);
  }
  .wf-builder.has-selection .wf-sheet__back { display: inline-flex; }
  .wf-builder.has-selection .wf-sheet__close { display: none; }
  .wf-builder.has-selection .wf-sheet__head { padding-inline: var(--space-1) var(--space-3); }
  .wf-step__groups { padding-inline-start: var(--space-3); }
  .wf-step-list--nested { padding-inline-start: var(--space-2); }
}

/* ── Workflows: run history of a rule with steps (_workflowRunHistory.js) ──
   One card per firing: when, the record that fired it, what each Find step
   found, and what ran — numbered as the step list numbers them. */
/* Status and the days: two chips that open menus, one height, one row. */
.wf-history__filters { margin: 0 0 var(--space-3); }
.wf-menu-chip { padding-inline-end: 8px; gap: 4px; }
.wf-menu-chip > span[dir] { max-width: 16em; overflow: hidden; text-overflow: ellipsis; }
.wf-history__filters .filter-chip-row__clear { margin-inline-start: var(--space-1); }
.wf-runs { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-3); }
.wf-run {
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-m);
  background: var(--color-surface-container-lowest);
  display: flex; flex-direction: column; gap: var(--space-2);
}
.wf-run__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-2) var(--space-3); }
.wf-run__when { font-weight: 600; font-variant-numeric: tabular-nums; }
.wf-run__by { color: var(--color-on-surface-var); font-size: var(--md-sys-typescale-body-small-size); }
/* A workflow's Changes tab: a Material 3 list, an avatar, then what and who. */
.wf-changes { list-style: none; margin: 0; padding: 0; }
.wf-change { display: flex; align-items: flex-start; gap: var(--space-3); padding: var(--space-2) 0; }
.wf-change + .wf-change { border-top: 1px solid var(--color-outline-variant); }
.wf-change__text { min-width: 0; }
.wf-change__what { margin: 0; }
/* A WhatsApp step that can't send yet says why, above its fields. */
.wf-wa-blocked { display: flex; gap: var(--space-2); align-items: flex-start; padding: var(--space-2) var(--space-3);
  border-radius: var(--md-sys-shape-corner-small); background: var(--color-surface-container-high); }
.wf-change__who { margin: 2px 0 0; color: var(--color-on-surface-var); font-size: var(--md-sys-typescale-body-small-size); }
.wf-changes__note { margin: var(--space-3) 0 0; font-size: var(--md-sys-typescale-body-small-size); }
td > .wf-run__by { display: block; }
/* Rerun sits at the run's trailing edge. */
.wf-run__head .wf-rerun { margin-inline-start: auto; }
.wf-history-table .wf-rerun { margin-inline-start: var(--space-2); }
.wf-run__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
/* Number · what · status, the number in its own column so a long line wraps
   under the text, not under the number; a notice's text on the row below. */
.wf-run__list > li {
  display: grid;
  grid-template-columns: 2.25em minmax(0, 1fr) auto;
  align-items: baseline;
  column-gap: var(--space-2);
  row-gap: 2px;
}
.wf-runs__num {
  min-width: 2.25em;
  font-size: var(--md-sys-typescale-body-small-size);
  color: var(--color-on-surface-var);
  font-variant-numeric: tabular-nums;
}
.wf-runs__detail { grid-column: 2 / -1;
  font-size: var(--md-sys-typescale-body-small-size); color: var(--color-on-surface-var); }
.wf-run__none { margin: 0; font-size: var(--md-sys-typescale-body-small-size); }
.wf-runs__earlier { margin: var(--space-4) 0 var(--space-2); font-size: var(--md-sys-typescale-title-small-size); }

/* ── Workflows: example templates section ──────────────────────────────── */
.wf-examples-card {
  margin: var(--space-3) 0;
  background: var(--color-surface-container-low);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-m);
}
/* `<summary>` element styled as a clickable header with chevron. Removes
   the default disclosure marker so the chevron can flip on `[open]`. */
.wf-examples-summary {
  list-style: none;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3);
  cursor: pointer;
  user-select: none;
}
.wf-examples-summary::-webkit-details-marker { display: none; }
.wf-examples-summary:hover { background: var(--color-surface-container); }
.wf-examples-summary:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: -2px;
  border-radius: var(--radius-m);
}
.wf-examples-summary__text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 auto;
  min-width: 0;
}
.wf-examples-summary__count {
  flex: 0 0 auto;
  font-size: var(--md-sys-typescale-body-small-size);
  white-space: nowrap;
}
.wf-examples-summary__chevron {
  flex: 0 0 auto;
  color: var(--color-on-surface-var);
  transition: transform .15s ease;
}
.wf-examples-card[open] .wf-examples-summary__chevron { transform: rotate(180deg); }
.wf-examples-title {
  font-size: var(--md-sys-typescale-body-large-size);
  font-weight: 600;
  color: var(--color-on-surface);
}
.wf-examples-subtitle {
  color: var(--color-on-surface-var);
  font-size: var(--md-sys-typescale-body-dense-size);
}
.wf-examples-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: var(--space-3);
  padding: 0 var(--space-4) var(--space-4);
}
/* A template is a card on one topic (Material 3: "Use a card to display
   content and actions on a single topic"): its icon, its name and record
   type, what it does, and its one action at the foot. The name and the
   description wrap — they were cut to a few letters beside a button that
   took half the card. The button is a text button: the card's own action,
   not the page's main one (that is New rule). */
.wf-example-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4) var(--space-2);
  background: var(--color-surface-container-lowest);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-m);
  transition: border-color .15s ease;
}
.wf-example-card:hover { border-color: var(--color-outline); }
.wf-example-head { display: flex; align-items: center; gap: var(--space-3); }
.wf-example-icon {
  flex: 0 0 auto;
  width: 40px; height: 40px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-pill);
  background: var(--color-secondary-container);
  color: var(--color-on-secondary-container);
}
.wf-example-icon .material-symbols-outlined { font-size: 22px; }
.wf-example-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.wf-example-name {
  margin: 0;
  font-size: var(--md-sys-typescale-title-small-size);
  font-weight: 600;
  line-height: 1.3;
  color: var(--color-on-surface);
}
.wf-example-module {
  font-size: var(--md-sys-typescale-label-medium-size);
  color: var(--color-on-surface-var);
}
.wf-example-desc {
  flex: 1 1 auto;
  margin: 0;
  color: var(--color-on-surface-var);
  font-size: var(--md-sys-typescale-body-small-size);
  line-height: 1.45;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.wf-example-cta { display: flex; justify-content: flex-end; }
.wf-example-cta .btn { white-space: nowrap; }

@media (max-width: 600px) {
  .wf-examples-grid { grid-template-columns: 1fr; padding: 0 var(--space-3) var(--space-3); }
}

/* ── Workflows: the rules table ─────────────────────────────────────────
   The shared data table, in a card. Each rule's switch acts at once (Material
   3: "The effects of a switch should start immediately, without needing to
   save"); its ⋮ opens or deletes it (Delete last, red). On a phone the
   module, trigger and step count fold into a line under the name. */
.wf-rules-card { padding: 0; overflow: hidden; }
.wf-rules-table td { vertical-align: middle; }
.wf-rules-table .wf-row-link { display: block; color: inherit; text-decoration: none; }
.wf-rules-table .wf-row-link:hover strong { color: var(--color-primary-text); text-decoration: underline; }
.wf-row-desc, .wf-row-meta { margin-top: 2px; font-size: var(--md-sys-typescale-body-small-size); }
.wf-row-desc { max-width: 64ch; }
.wf-row-meta { display: none; }
/* A rule's followers as faces, overlapping, the rest as a count. */
.wf-faces { display: inline-flex; align-items: center; }
.wf-faces .avatar-sm { width: 24px; height: 24px; box-shadow: 0 0 0 2px var(--color-surface); }
.wf-faces .avatar-sm + .avatar-sm { margin-inline-start: -6px; }
.wf-faces__more { margin-inline-start: 6px; font-size: var(--md-sys-typescale-body-small-size); color: var(--color-on-surface-var); }
.wf-col-num { text-align: end; font-variant-numeric: tabular-nums; }
.wf-rules-table .row-actions { width: 1%; white-space: nowrap; text-align: end; padding-inline-end: var(--space-2); }
@media (max-width: 720px) {
  .wf-rules-table .wf-col-wide { display: none; }
  .wf-row-meta { display: block; }
}

/* ── Workflows: pre-save blast-radius preview chip ─────────────────────── */
/* Lives in the page header next to Save. Shows how many records currently
   match the module + criteria. Default state is the "match" variant; modifier
   classes paint capped / no-criteria / error states. */
.wf-preview-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: var(--md-sys-shape-corner-full);
  background-color: var(--color-primary-fixed);
  color: var(--color-on-primary-container);
  font-size: var(--md-sys-typescale-body-small-size);
  font-weight: 500;
  line-height: 1.4;
  border: 1px solid var(--color-outline-variant);
  /* Cap width on narrow viewports so it doesn't push Save off the row. */
  max-width: 320px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}
.wf-preview-chip .material-symbols-outlined {
  font-size: 16px;
  flex-shrink: 0;
}
.wf-preview-chip--all {
  /* No conditions set yet — neutral surface, not a strong "you'll fire on these" cue */
  background-color: var(--color-surface-container-high);
  color: var(--color-on-surface-var);
}
.wf-preview-chip--capped {
  /* Scan limit was hit — flag with the warning tint so the admin knows
     the real count may be higher than displayed. */
  background-color: var(--color-warning-bg);
  color: var(--md-sys-color-on-warning-container);
  border-color: var(--color-warning);
}
.wf-preview-chip--error {
  background-color: var(--color-error-container);
  color: var(--color-on-error-container);
  border-color: var(--color-error);
}
[data-theme="dark"] .wf-preview-chip {
  background-color: var(--color-surface-container-high);
  color: var(--color-on-surface);
}
@media (max-width: 600px) {
  /* On phones the chip wraps to its own line under the title; let it span
     full width minus padding so the count is readable. */
  .wf-preview-chip {
    max-width: 100%;
    white-space: normal;
  }
}

/* ── AI account brief ───────────────────────────────────────────────────────── */
.brief-root { min-height: 180px; }
.brief-loading {
  display: flex; align-items: center; justify-content: center; gap: var(--space-3);
  padding: var(--space-6) var(--space-4); color: var(--color-on-surface-var);
}
.brief-spinner {
  width: 20px; height: 20px; border-radius: 50%;
  border: 2px solid var(--color-outline-variant);
  border-top-color: var(--color-primary);
  animation: brief-spin 0.7s linear infinite;
}
@keyframes brief-spin { to { transform: rotate(360deg); } }
.brief-empty {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: var(--space-2); padding: var(--space-6) var(--space-4);
}
.brief-empty__icon { font-size: 40px; color: var(--color-primary); }
.brief-empty__title { font-weight: 600; font-size: var(--md-sys-typescale-body-large-size); }
.brief-empty__body { color: var(--color-on-surface-var); max-width: 44ch; line-height: 1.5; }
.brief-empty .btn { margin-top: var(--space-2); }
.brief-head {
  display: flex; flex-direction: column; gap: var(--space-2);
  padding-bottom: var(--space-3); margin-bottom: var(--space-3);
  border-bottom: 1px solid var(--color-outline-variant);
}
.brief-headline { margin: 0; font-size: var(--md-sys-typescale-body-large-size); font-weight: 600; line-height: 1.4; }
.brief-meta {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-3); flex-wrap: wrap;
}
.brief-sections { display: flex; flex-direction: column; gap: var(--space-4); }
.brief-section__h {
  margin: 0 0 var(--space-2); font-size: var(--md-sys-typescale-title-small-size); font-weight: 600;
  color: var(--color-primary);
}
.brief-section p { margin: 0 0 var(--space-2); line-height: 1.5; }
.brief-bullets {
  margin: 0; padding-inline-start: 1.2em;
  display: flex; flex-direction: column; gap: 4px;
}
.brief-bullets li { line-height: 1.45; }
.brief-actions {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: var(--space-2);
}
.brief-action {
  display: flex; align-items: flex-start; gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-outline-variant); border-radius: var(--md-sys-shape-corner-medium);
}
.brief-action__pri {
  flex: 0 0 auto; font-size: var(--md-sys-typescale-label-small-size); font-weight: 700;
  letter-spacing: 0.03em; padding: 2px 8px; border-radius: var(--md-sys-shape-corner-full); white-space: nowrap;
  background: var(--color-surface-container-high); color: var(--color-on-surface-var);
}
.brief-action--high .brief-action__pri {
  background: var(--color-error-container); color: var(--color-on-error-container);
}
.brief-action--medium .brief-action__pri {
  background: var(--color-primary-container); color: var(--color-on-primary-container);
}
.brief-action__txt { line-height: 1.45; }
.brief-foot {
  margin-top: var(--space-4); padding-top: var(--space-3);
  border-top: 1px solid var(--color-outline-variant); text-align: center;
}

/* Reduced motion — kill entry animations. Must stay at end of file: the
   mobile modal-slide-up rule earlier in the file would otherwise win the
   cascade at equal specificity. */
@media (prefers-reduced-motion: reduce) {
  .modal { animation: none; }
  .report-popover-overlay,
  .report-popover,
  .rb-menu { animation: none; }
}

/* ─────────────────────────────────────────────────────────────────────────
   Bulk CSV/Excel import wizard (views/import.js)
   ───────────────────────────────────────────────────────────────────────── */
.import-stepper {
  display: flex;
  gap: var(--space-2);
  list-style: none;
  margin: 0 0 var(--space-4);
  padding: 0;
  flex-wrap: wrap;
}
.import-step {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 14px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-outline-variant);
  color: var(--color-on-surface-var);
  font-size: var(--md-sys-typescale-body-medium-size);
}
.import-step--active {
  border-color: var(--color-primary);
  color: var(--color-on-primary);
  background: var(--color-primary);
  font-weight: 600;
}
.import-step--done { color: var(--color-success-text); border-color: var(--color-success); }
.import-step__num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px; height: 22px;
  border-radius: 50%;
  background: var(--color-surface-container-high);
  font-size: var(--md-sys-typescale-body-dense-size);
  font-weight: 600;
}
.import-step__num .material-symbols-outlined { font-size: 16px; }
.import-step--active .import-step__num { background: var(--color-on-primary); color: var(--color-primary); }
.import-step--done .import-step__num { background: var(--color-success); color: var(--color-on-primary); }

.import-dropzone {
  border: 2px dashed var(--color-outline);
  border-radius: var(--radius-l);
  padding: 40px 20px;
  text-align: center;
  cursor: pointer;
  transition: border-color .15s, background .15s;
  background: var(--color-surface-container-lowest);
}
.import-dropzone:hover,
.import-dropzone:focus-visible { border-color: var(--color-primary); background: var(--color-surface-container-low); outline: none; }
.import-dropzone--over { border-color: var(--color-primary); background: var(--color-primary-container); }
.import-dropzone__icon { font-size: 40px; color: var(--color-primary); }
.import-dropzone__title { font-size: var(--md-sys-typescale-body-large-size); font-weight: 600; margin-top: 8px; }
.import-dropzone__hint { font-size: var(--md-sys-typescale-body-dense-size); color: var(--color-on-surface-var); margin-top: 4px; }

.import-status { min-height: 20px; margin-top: var(--space-3); font-size: var(--md-sys-typescale-body-medium-size); }
.import-status--error { color: var(--color-error); white-space: pre-wrap; }

.import-template-row {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: var(--space-3);
  font-size: var(--md-sys-typescale-body-dense-size);
  color: var(--color-on-surface-var);
}
.import-phone-note {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
  font-size: var(--md-sys-typescale-body-small-size);
  color: var(--color-on-surface-var);
}
.import-template-link {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: var(--color-primary-text);
  font-weight: 600;
  cursor: pointer;
  text-decoration: underline;
}
.import-template-link:hover { text-decoration: none; }
.import-template-link:disabled { opacity: .5; cursor: default; }

.import-hint { font-size: var(--md-sys-typescale-body-medium-size); color: var(--color-on-surface-var); margin: 0 0 var(--space-3); }
.import-required-note { color: var(--color-primary-text); font-weight: 600; margin-inline-start: 6px; }

.import-map-table td { vertical-align: middle; }
.import-samples { display: flex; flex-wrap: wrap; gap: 4px; max-width: 320px; }
.import-sample {
  font-size: var(--md-sys-typescale-body-small-size);
  background: var(--color-surface-container-high);
  border-radius: var(--radius-s);
  padding: 1px 6px;
  color: var(--color-on-surface-var);
}
.import-sample--empty { font-style: italic; background: transparent; }
.import-map-select { min-width: 190px; }
.import-allowed { font-size: var(--md-sys-typescale-body-small-size); color: var(--color-on-surface-var); margin-block-start: 4px; max-width: 260px; }
.import-allowed bdi { white-space: nowrap; }

.import-actions { display: flex; justify-content: flex-end; gap: var(--space-2); margin-top: var(--space-4); }

.import-stats { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-bottom: var(--space-4); }
.import-stat {
  flex: 1 1 120px;
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-m);
  padding: 14px 16px;
  text-align: center;
}
.import-stat__num { font-size: var(--md-sys-typescale-headline-medium-size); font-weight: 700; line-height: 1.1; }
.import-stat__label { font-size: var(--md-sys-typescale-body-dense-size); color: var(--color-on-surface-var); margin-top: 2px; }
.import-stat--new .import-stat__num { color: var(--color-success-text); }
.import-stat--dup .import-stat__num { color: var(--color-warning-text); }
.import-stat--err .import-stat__num { color: var(--color-error); }
/* "Can't tell" — rows the match keys couldn't judge. Deliberately not styled
   as an error: nothing is wrong with the row, we just have no way to look. */
.import-stat--unknown .import-stat__num { color: var(--color-on-surface-var); }
.import-stat--unknown { border-style: dashed; }

.import-dupmode {
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-m);
  padding: var(--space-3);
  margin-bottom: var(--space-4);
}
.import-dupmode legend { font-weight: 600; padding: 0 6px; }
.import-radio,
.import-checkbox { gap: 8px; font-size: var(--md-sys-typescale-body-medium-size); cursor: pointer; }
.import-radio { display: flex; align-items: flex-start; padding: 6px 0; }
.import-radio input { margin-top: 3px; }

/* Update-by-ID reads as a fact to check, not a warning: the primary colour
   marks it as the deliberate path, and the diff table carries the scrutiny. */
.import-dupmode--id { border-color: var(--color-primary); }
.import-dupmode--id legend { color: var(--color-primary); }
.import-stat--update .import-stat__num { color: var(--color-primary); }

.import-diff { font-size: var(--md-sys-typescale-body-dense-size); }
.import-diff__from { color: var(--color-on-surface-var); text-decoration: line-through; }
.import-diff__to { font-weight: 600; }

/* The bulk acknowledgement is the last thing between the admin and rewriting
   hundreds of records, so it sits apart from the choices above it. */
.import-bulk-ack {
  margin: var(--space-4) 0 0;
  padding: var(--space-3);
  border: 1px solid var(--color-warning);
  border-radius: var(--radius-m);
  font-weight: 600;
}

/* The result step. Deliberately calm — the work already succeeded; the undo
   beside it is an option, not an alarm. */
.import-done__head { display: flex; align-items: center; gap: var(--space-2); }
.import-done__head h2 { margin: 0; font-size: var(--md-sys-typescale-title-large-size); }
.import-done__head .material-symbols-outlined {
  color: var(--color-success-text);
  font-size: 28px;
}
.import-done__list {
  margin: var(--space-3) 0;
  padding-inline-start: var(--space-4);
  font-size: var(--md-sys-typescale-body-large-size);
  line-height: 1.9;
}
/* Why some of the skipped rows were skipped: a note on the line above it. */
.import-done__sub {
  list-style: none;
  margin-inline-start: var(--space-4);
  font-size: var(--md-sys-typescale-body-medium-size);
  color: var(--color-on-surface-var);
  line-height: 1.5;
}

.import-sample--count { opacity: .7; font-style: italic; }
.import-hint--drop { color: var(--color-on-surface-var); font-style: italic; }

/* "Show all fields" in the Add Contact form. A quiet text button, not a
   secondary action: the common fields above it are the normal path. */
.cf-more {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: var(--space-2) 0;
  padding: 6px 0;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--color-primary);
  font: inherit;
  font-weight: 500;
  min-height: 40px;          /* touch target on a phone */
}
.cf-more .material-symbols-outlined { font-size: 18px; }

.import-errors { margin-bottom: var(--space-4); }
.import-errors__head { font-weight: 600; margin-bottom: 6px; color: var(--color-error); }

/* The unjudgeable-rows fieldset asks for a decision rather than reporting a
   fact, so it is flagged with the warning colour the duplicate block is not.
   --color-warning (not -text) on the border: the -text token is the near-black
   on-container ink, which reads as a plain heavy border rather than a warning. */
.import-dupmode--warn { border-color: var(--color-warning); }
.import-dupmode--warn legend { color: var(--color-warning-text); }

/* Composes .import-dupmode + --warn for the box; only the text size differs. */
.import-warn { font-size: var(--md-sys-typescale-body-medium-size); }

/* Match-field picker (step 2). Wraps to one column on a phone. */
.import-matchfields { margin-top: var(--space-4); }
.import-matchfields__list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  margin-bottom: var(--space-2);
}
.import-checkbox {
  display: inline-flex;
  align-items: center;
  /* Comfortable touch target on mobile without changing the desktop rhythm. */
  min-height: 32px;
}
.import-matchfields__summary {
  margin: 0;
  font-size: var(--md-sys-typescale-body-dense-size);
  color: var(--color-on-surface-var);
}
.import-matchfields__summary--warn { color: var(--color-warning-text); font-weight: 600; }

@media (max-width: 560px) {
  .import-stat { flex-basis: 45%; }
  .import-map-select { min-width: 140px; }
  .import-matchfields__list { flex-direction: column; gap: var(--space-1); }
  .import-checkbox { min-height: 40px; }
}

/* ── Edara sync progress bar ──────────────────────────────────────────────
   Shown while a connect/sync job runs (settings.js _showProgress). The
   --indeterminate modifier is used when the running job reports no pct
   (standalone Advanced syncs / re-attach to a non-connect family job). */
.sync-progress {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: var(--space-2);
}
.sync-progress__track {
  flex: 1;
  height: 8px;
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--color-outline-variant);
  overflow: hidden;
}
.sync-progress__fill {
  height: 100%;
  width: 0%;
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--color-primary);
  transition: width 0.4s ease;
}
.sync-progress--indeterminate .sync-progress__fill {
  width: 30%;
  animation: sync-progress-slide 1.2s ease-in-out infinite;
}
/* margin-inline-start keeps the slide direction correct under RTL. */
@keyframes sync-progress-slide {
  from { margin-inline-start: -30%; }
  to   { margin-inline-start: 100%; }
}
.sync-progress__label {
  font-size: var(--md-sys-typescale-body-small-size);
  color: var(--color-on-surface-var);
  min-width: 38px;
  text-align: end;
  font-variant-numeric: tabular-nums;
}
/* ── Revenue Action Center — MD3 surfaces and hierarchy ───────────────── */
.rac-page { max-width: 1560px; margin: 0 auto; color: var(--md-sys-color-on-surface); }
.rac-header { align-items: flex-start; gap: var(--space-4); }
.rac-header p { margin: var(--space-1) 0 0; color: var(--md-sys-color-on-surface-variant); }
.rac-freshness {
  display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0;
  min-height: 32px; margin-top: 2px; padding: 0 12px;
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface-container);
  color: var(--md-sys-color-on-surface-variant); font-size: var(--md-sys-typescale-body-small-size); font-weight: 500;
}
.rac-freshness .material-symbols-outlined { font-size: 17px; }
.rac-freshness > span:last-child,
.rac-card__value, .rac-value-block strong, .rac-evidence strong, .rac-kpi small {
  direction: ltr; unicode-bidi: isolate;
}

.rac-kpis {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-3); margin: var(--space-4) 0;
}
.rac-kpi {
  display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center;
  column-gap: 14px; row-gap: 5px; min-height: 112px; padding: var(--space-3);
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-large);
  background: var(--md-sys-color-surface-container-lowest);
  box-shadow: var(--md-sys-elevation-1);
  transition: box-shadow var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard),
              transform var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard);
}
.rac-kpi:hover { box-shadow: var(--md-sys-elevation-2); transform: translateY(-1px); }
.rac-kpi > .material-symbols-outlined {
  display: grid; place-items: center; width: 48px; height: 48px;
  border-radius: var(--md-sys-shape-corner-medium);
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container); font-size: 24px;
}
.rac-kpi--all > .material-symbols-outlined {
  background: var(--md-sys-color-primary-container); color: var(--md-sys-color-on-primary-container);
}
.rac-kpi--risk > .material-symbols-outlined,
.rac-kpi--returns > .material-symbols-outlined {
  background: var(--md-sys-color-error-container); color: var(--md-sys-color-on-error-container);
}
.rac-kpi div { display: grid; gap: 3px; min-width: 0; }
.rac-kpi strong { color: var(--md-sys-color-on-surface); font-size: var(--md-sys-typescale-headline-medium-size); line-height: 1; letter-spacing: -.02em; }
.rac-kpi div span { overflow: hidden; color: var(--md-sys-color-on-surface-variant); font-size: var(--md-sys-typescale-body-dense-size); text-overflow: ellipsis; white-space: nowrap; }
.rac-kpi small { grid-column: 2; color: var(--color-primary-text); font-size: var(--md-sys-typescale-body-dense-size); font-weight: 700; }

.rac-filters {
  display: flex; align-items: end; flex-wrap: wrap; gap: 12px;
  margin-bottom: var(--space-3); padding: var(--space-3);
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-large);
  background: var(--md-sys-color-surface-container-low);
}
.rac-filters label { display: grid; gap: 6px; color: var(--md-sys-color-on-surface-variant); font-size: var(--md-sys-typescale-label-small-size); font-weight: 700; }
.rac-filters select, .rac-search input {
  height: 44px; border: 1px solid var(--md-sys-color-outline);
  border-radius: var(--md-sys-shape-corner-small);
  background: var(--md-sys-color-surface-container-lowest);
  color: var(--md-sys-color-on-surface); font: inherit; outline: none;
}
.rac-filters select { min-width: 160px; padding-block: 0; padding-inline: 12px 34px; font-size: var(--md-sys-typescale-body-dense-size); }
.rac-filters select:focus, .rac-search input:focus {
  border-color: var(--md-sys-color-primary); box-shadow: 0 0 0 3px color-mix(in srgb, var(--md-sys-color-primary) 14%, transparent);
}
.rac-tabs { display: flex; gap: var(--space-2); flex: 1 1 100%; overflow-x: auto; padding: 2px; scrollbar-width: thin; }
.rac-page .filter-chip {
  background: var(--md-sys-color-surface-container-lowest);
  border-color: var(--md-sys-color-outline);
  color: var(--md-sys-color-on-surface-variant);
}
.rac-page .filter-chip:hover {
  background: var(--md-sys-color-surface-container-high);
  border-color: var(--md-sys-color-on-surface-variant);
  color: var(--md-sys-color-on-surface);
}
.rac-tabs .filter-chip { min-height: 40px; padding: 7px 15px; white-space: nowrap; }
.rac-tabs .filter-chip--active {
  background: var(--md-sys-color-primary-container);
  border-color: var(--md-sys-color-primary-container);
  color: var(--md-sys-color-on-primary-container);
  box-shadow: var(--md-sys-elevation-1);
}
.rac-tabs .filter-chip span { opacity: .72; margin-inline-start: 4px; }
.rac-search { position: relative; display: flex !important; align-items: center; flex: 1 1 240px; min-width: 220px; }
.rac-search .material-symbols-outlined { position: absolute; inset-inline-start: 13px; z-index: 1; color: var(--md-sys-color-on-surface-variant); font-size: 20px; pointer-events: none; }
.rac-search input { width: 100%; padding: 0 12px; padding-inline-start: 42px; font-size: var(--md-sys-typescale-body-dense-size); }
.rac-search input::placeholder { color: var(--md-sys-color-on-surface-variant); opacity: .8; }

.rac-workspace {
  display: grid; grid-template-columns: minmax(390px, .9fr) minmax(430px, 1.1fr);
  gap: var(--space-3); align-items: stretch;
}
.rac-queue, .rac-detail {
  min-width: 0; border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-large);
  background: var(--md-sys-color-surface-container-lowest);
  box-shadow: var(--md-sys-elevation-1); overflow: hidden;
}
.rac-queue { display: flex; flex-direction: column; min-height: 520px; }
.rac-list { display: grid; align-content: start; flex: 1; max-height: 650px; overflow: auto; padding: var(--space-2); }
.rac-card {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center;
  gap: 14px; width: 100%; min-height: 86px; padding: 12px;
  border: 0; border-radius: var(--md-sys-shape-corner-medium);
  color: var(--md-sys-color-on-surface); background: transparent;
  font-family: inherit; text-align: start; cursor: pointer;
  transition: background var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard);
}
.rac-card + .rac-card { margin-top: 4px; }
.rac-card:hover { background: var(--md-sys-color-surface-container); }
.rac-card:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: -3px; }
.rac-card.is-selected {
  background: var(--md-sys-color-primary-container); color: var(--md-sys-color-on-primary-container);
  box-shadow: var(--md-sys-elevation-1);
}
.rac-card__icon {
  display: grid; place-items: center; width: 46px; height: 46px; flex-shrink: 0;
  border-radius: var(--md-sys-shape-corner-medium);
  background: var(--md-sys-color-secondary-container); color: var(--md-sys-color-on-secondary-container);
}
.rac-card__icon .material-symbols-outlined { font-size: 23px; }
.rac-card__icon--risk, .rac-card__icon--returns { background: var(--md-sys-color-error-container); color: var(--md-sys-color-on-error-container); }
.rac-card__icon--product { background: var(--md-sys-color-tertiary-container); color: var(--md-sys-color-on-tertiary-container); }
.rac-card__body { display: grid; gap: 4px; min-width: 0; }
.rac-card__top { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.rac-card__top strong { font-size: var(--md-sys-typescale-body-medium-size); font-weight: 700; }
.rac-card__top strong, .rac-card__title, .rac-card__meta { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rac-card__title { color: var(--md-sys-color-on-surface); font-size: var(--md-sys-typescale-body-dense-size); line-height: 1.35; }
.rac-card__meta { color: var(--md-sys-color-on-surface-variant); font-size: var(--md-sys-typescale-label-small-size); line-height: 1.35; }
.rac-card__value { color: var(--color-primary-text); font-size: var(--md-sys-typescale-body-medium-size); font-weight: 750; white-space: nowrap; }
.rac-card.is-selected .rac-card__title,
.rac-card.is-selected .rac-card__meta,
.rac-card.is-selected .rac-card__value { color: var(--md-sys-color-on-primary-container); }
.rac-card.is-selected .rac-card__meta { opacity: .82; }
.rac-priority {
  display: inline-flex; align-items: center; width: fit-content; min-height: 22px;
  padding: 2px 8px; border-radius: var(--md-sys-shape-corner-full);
  font-size: var(--md-sys-typescale-label-small-size); font-weight: 750; line-height: 1;
}
.rac-priority--high { color: var(--md-sys-color-on-error-container); background: var(--md-sys-color-error-container); }
.rac-priority--medium { color: var(--md-sys-color-on-tertiary-container); background: var(--md-sys-color-tertiary-container); }
.rac-priority--low { color: var(--md-sys-color-on-secondary-container); background: var(--md-sys-color-secondary-container); }

.rac-detail { min-height: 520px; padding: var(--space-4); overflow: auto; }
.rac-detail__empty { display: grid; place-items: center; align-content: center; min-height: 470px; color: var(--md-sys-color-on-surface-variant); text-align: center; }
.rac-detail__empty .material-symbols-outlined { margin-bottom: var(--space-2); color: var(--md-sys-color-primary); font-size: 48px; }
.rac-detail__hero {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: start;
  gap: var(--space-3); padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--md-sys-color-outline-variant);
}
.rac-detail__hero h2 { margin: 3px 0 4px; color: var(--md-sys-color-on-surface); font-size: var(--md-sys-typescale-title-large-size); line-height: 1.25; }
.rac-detail__hero p { margin: 0; color: var(--md-sys-color-on-surface-variant); font-size: var(--md-sys-typescale-body-medium-size); line-height: 1.45; }
.rac-eyebrow { color: var(--color-primary-text); font-size: var(--md-sys-typescale-label-small-size); font-weight: 750; letter-spacing: .5px; }
.rac-value-block {
  display: grid; gap: 5px; margin: var(--space-3) 0; padding: var(--space-3);
  border-radius: var(--md-sys-shape-corner-large);
  background: var(--md-sys-color-primary-container); color: var(--md-sys-color-on-primary-container);
}
.rac-value-block span, .rac-value-block strong, .rac-value-block small { color: inherit; }
.rac-value-block span { font-size: var(--md-sys-typescale-body-small-size); font-weight: 600; }
.rac-value-block strong { font-size: var(--md-sys-typescale-headline-medium-size); line-height: 1.15; letter-spacing: -.02em; }
.rac-value-block small { opacity: .82; }
.rac-evidence, .rac-context {
  margin-top: var(--space-3); padding: var(--space-3);
  border-radius: var(--md-sys-shape-corner-medium);
  background: var(--md-sys-color-surface-container-low);
}
.rac-evidence h3, .rac-context h3 { margin: 0 0 var(--space-2); color: var(--md-sys-color-on-surface); font-size: var(--md-sys-typescale-body-medium-size); }
.rac-evidence > div, .rac-context > div {
  display: flex; justify-content: space-between; gap: var(--space-4);
  min-height: 42px; padding: 10px 0; border-bottom: 1px solid var(--md-sys-color-outline-variant);
}
.rac-evidence > div:last-child, .rac-context > div:last-child { border-bottom: 0; padding-bottom: 0; }
.rac-evidence span, .rac-context span { color: var(--md-sys-color-on-surface-variant); font-size: var(--md-sys-typescale-body-dense-size); }
.rac-evidence strong, .rac-context strong { color: var(--md-sys-color-on-surface); font-size: var(--md-sys-typescale-body-dense-size); text-align: end; }
.rac-actions {
  display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-4); padding-top: var(--space-3);
  border-top: 1px solid var(--md-sys-color-outline-variant);
}
.rac-actions .btn { min-height: 44px; gap: 6px; padding: 8px 15px; text-decoration: none; }
.rac-actions .material-symbols-outlined { font-size: 18px; }
.rac-actions__notice {
  display: flex; align-items: center; flex: 1 1 100%; gap: var(--space-2); margin: 0;
  padding: 10px 12px; border-radius: var(--md-sys-shape-corner-medium);
  background: var(--md-sys-color-surface-container); color: var(--md-sys-color-on-surface-variant);
  font-size: var(--md-sys-typescale-body-dense-size);
}
.rac-page .btn {
  border: 1px solid transparent;
  box-shadow: none;
  transition: background-color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard),
              border-color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard),
              color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard),
              box-shadow var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard),
              transform var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard);
}
.rac-page .btn:hover { box-shadow: var(--md-sys-elevation-1); transform: translateY(-1px); }
.rac-page .btn:active { box-shadow: none; transform: translateY(0); }
.rac-page .btn--primary {
  background: var(--md-sys-color-primary);
  color: var(--md-sys-color-on-primary);
}
.rac-page .btn--primary:hover {
  background: color-mix(in srgb, var(--md-sys-color-primary) 92%, var(--md-sys-color-on-primary));
  box-shadow: var(--md-sys-elevation-2);
}
.rac-action--deal {
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
}
.rac-action--deal:hover {
  background: color-mix(in srgb, var(--md-sys-color-secondary-container) 90%, var(--md-sys-color-on-secondary-container));
}
.rac-action--assign {
  background: var(--md-sys-color-surface-container-highest);
  color: var(--md-sys-color-on-surface);
}
.rac-action--assign:hover {
  background: color-mix(in srgb, var(--md-sys-color-surface-container-highest) 88%, var(--md-sys-color-on-surface));
}
.rac-action--snooze {
  background: var(--md-sys-color-tertiary-container);
  color: var(--md-sys-color-on-tertiary-container);
}
.rac-action--snooze:hover {
  background: color-mix(in srgb, var(--md-sys-color-tertiary-container) 90%, var(--md-sys-color-on-tertiary-container));
}
.rac-action--dismiss {
  background: var(--md-sys-color-error-container);
  color: var(--md-sys-color-on-error-container);
}
.rac-action--dismiss:hover {
  background: color-mix(in srgb, var(--md-sys-color-error-container) 88%, var(--md-sys-color-on-error-container));
}
.rac-page .rac-action--account {
  background: transparent;
  border-color: var(--color-primary-text);
  color: var(--color-primary-text);
}
.rac-page .rac-action--account:hover {
  background: color-mix(in srgb, var(--color-primary-text) 10%, transparent);
  border-color: var(--color-primary-text);
}
.rac-page .btn:disabled {
  background: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent);
  color: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent);
  box-shadow: none; cursor: not-allowed; opacity: 1; transform: none;
}
.rac-pagination {
  padding: 0 var(--space-3);
  border-top: 1px solid var(--md-sys-color-outline-variant);
  background: var(--md-sys-color-surface-container-low);
}

@media (max-width: 1200px) {
  .rac-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .rac-workspace { grid-template-columns: minmax(340px, .82fr) minmax(390px, 1.18fr); }
}
@media (max-width: 800px) {
  .rac-header { display: block; }
  .rac-freshness { margin-top: var(--space-3); }
  .rac-kpis { grid-template-columns: 1fr 1fr; }
  .rac-kpi { min-height: 96px; padding: 12px; }
  .rac-kpi strong { font-size: var(--md-sys-typescale-title-large-size); }
  .rac-filters { align-items: stretch; }
  .rac-tabs, .rac-search { flex-basis: 100%; min-width: 100%; }
  .rac-filters label:not(.rac-search) { flex: 1 1 140px; }
  .rac-filters select { width: 100%; min-width: 0; }
  .rac-workspace { display: block; }
  .rac-queue, .rac-detail { min-height: 0; }
  .rac-list { max-height: none; }
  .rac-detail { margin-top: var(--space-3); padding: var(--space-3); }
  .rac-card { grid-template-columns: auto minmax(0, 1fr); }
  .rac-card__value { grid-column: 2; }
}
@media (max-width: 480px) {
  .rac-kpis { grid-template-columns: 1fr; gap: var(--space-2); }
  .rac-kpi { grid-template-columns: auto 1fr auto; min-height: 88px; }
  .rac-kpi small { grid-column: 3; grid-row: 1; align-self: center; }
  .rac-filters { padding: 12px; }
  .rac-card { padding: 10px; }
  .rac-detail__hero { grid-template-columns: auto minmax(0, 1fr); }
  .rac-detail__hero > .rac-priority { grid-column: 2; }
  .rac-actions .btn { flex: 1 1 45%; justify-content: center; }
}

/* Revenue Action Center — scope, management analytics, configuration. */
.rac-modebar {
  display: flex; align-items: end; flex-wrap: wrap; gap: var(--space-3);
  margin: var(--space-3) 0;
}
.rac-modebar > .filter-chips { flex: 1; }
.rac-modebar .filter-chip { min-height: 40px; padding: 7px 16px; }
.rac-modebar .filter-chip--active {
  background: var(--md-sys-color-primary-container);
  border-color: var(--md-sys-color-primary-container);
  color: var(--md-sys-color-on-primary-container);
  box-shadow: var(--md-sys-elevation-1);
}
.rac-scope { display: grid; gap: 4px; color: var(--md-sys-color-on-surface-variant); font-size: var(--md-sys-typescale-label-small-size); font-weight: 700; }
.rac-scope select {
  min-width: 160px; height: 40px; padding-block: 0; padding-inline: 12px 34px;
  border: 1px solid var(--md-sys-color-outline); border-radius: var(--md-sys-shape-corner-small);
  background: var(--md-sys-color-surface-container-lowest); color: var(--md-sys-color-on-surface);
}
.rac-shadow {
  display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-3); padding: 10px 14px;
  border-radius: var(--md-sys-shape-corner-medium);
  background: var(--md-sys-color-tertiary-container); color: var(--md-sys-color-on-tertiary-container);
  font-size: var(--md-sys-typescale-body-dense-size); font-weight: 600;
}
.rac-shadow .material-symbols-outlined { font-size: 20px; }
.rac-management { display: grid; gap: var(--space-3); }
.rac-management__header { display: flex; align-items: start; justify-content: space-between; gap: var(--space-3); }
.rac-management__header h2 { margin: 0; }
.rac-management__header p { margin: 4px 0 0; color: var(--md-sys-color-on-surface-variant); }
.rac-analytics-kpis { display: grid; grid-template-columns: repeat(4,minmax(0,1fr)); gap: var(--space-3); }
.rac-analytics-kpi {
  display: flex; align-items: center; gap: var(--space-3); min-height: 96px; padding: var(--space-3);
  border: 1px solid var(--md-sys-color-outline-variant); border-radius: var(--md-sys-shape-corner-large);
  background: var(--md-sys-color-surface-container-lowest); box-shadow: var(--md-sys-elevation-1);
}
.rac-analytics-kpi > .material-symbols-outlined {
  display: grid; place-items: center; width: 44px; height: 44px; border-radius: var(--md-sys-shape-corner-medium);
  background: var(--md-sys-color-secondary-container); color: var(--md-sys-color-on-secondary-container);
}
.rac-analytics-kpi div { display: grid; gap: 4px; }
.rac-analytics-kpi small { color: var(--md-sys-color-on-surface-variant); }
.rac-analytics-kpi strong { color: var(--md-sys-color-on-surface); font-size: var(--md-sys-typescale-title-large-size); }
.rac-analytics-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
.rac-analytics-card {
  /* Grid item: min-width:auto would size it to the min-content width of the
     .table-scroll inside, so a wide table pushed the whole .rac-management
     grid — and with it main#view — sideways instead of scrolling in place.
     min-width:0 lets the track win, so the overflow lands on .table-scroll. */
  min-width: 0;
  padding: var(--space-3); border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-large); background: var(--md-sys-color-surface-container-lowest);
}
.rac-analytics-card h3 { margin: 0 0 var(--space-3); }
.rac-analytics-card h4 { margin: 0 0 var(--space-2); color: var(--md-sys-color-on-surface); font-size: var(--md-sys-typescale-body-dense-size); }
.rac-metric-list { display: grid; }
.rac-metric-list > div, .rac-metric-list > .rac-drill { display: flex; justify-content: space-between; gap: var(--space-3); padding: 10px 0; border-bottom: 1px solid var(--md-sys-color-outline-variant); }
.rac-metric-list > :last-child { border-bottom: 0; }
/* Figures that open their accounts or recommendations (_drillDrawer). */
.rac-drill { font: inherit; color: inherit; text-align: start; width: 100%; background: none; border: 0; cursor: pointer; }
.rac-metric-list > .rac-drill { border-radius: 0; border-bottom: 1px solid var(--md-sys-color-outline-variant); }
.rac-metric-list > .rac-drill:hover strong, .rac-drill--inline:hover { color: var(--md-sys-color-primary); text-decoration: underline; }
.rac-drill--inline { width: auto; padding: 0; }
.rac-analytics-kpi.rac-drill { border: 1px solid var(--md-sys-color-outline-variant); }
.rac-drill:focus-visible { outline: 2px solid var(--md-sys-color-primary); outline-offset: 2px; }
.rac-kpi--button { font: inherit; color: inherit; text-align: start; width: 100%; cursor: pointer; }
.rac-kpi--button[aria-pressed="true"] { border-color: var(--md-sys-color-primary); box-shadow: var(--md-sys-elevation-2); }
.rac-metric-list span { color: var(--md-sys-color-on-surface-variant); }
.rac-metric-list strong { text-align: end; }

/* Admin Settings — Revenue Action configuration. */
.revenue-settings { display: grid; gap: var(--space-3); max-width: 1120px; }
.revenue-settings__header,
.revenue-settings__section {
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-large);
  background: var(--md-sys-color-surface-container-lowest);
  box-shadow: var(--md-sys-elevation-1);
}
.revenue-settings__header {
  display: flex; align-items: center; gap: var(--space-3); padding: var(--space-4);
}
.revenue-settings__icon {
  display: grid; place-items: center; width: 52px; height: 52px; flex: 0 0 52px;
  border-radius: var(--md-sys-shape-corner-large);
  background: var(--md-sys-color-primary-container); color: var(--md-sys-color-on-primary-container);
  font-size: 26px;
}
.revenue-settings__header h2 { margin: 0; color: var(--md-sys-color-on-surface); font-size: var(--md-sys-typescale-title-large-size); }
.revenue-settings__header p { margin: 4px 0 0; color: var(--md-sys-color-on-surface-variant); }
.revenue-settings__section { padding: var(--space-4); }
.revenue-settings__section h3 { margin: 0 0 var(--space-3); color: var(--md-sys-color-on-surface); }
.revenue-settings__toggles,
.revenue-settings__fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-2); }
.revenue-settings__toggle {
  display: flex; align-items: center; gap: var(--space-2); min-height: 52px; padding: 10px 12px;
  border: 1px solid var(--md-sys-color-outline-variant); border-radius: var(--md-sys-shape-corner-medium);
  background: var(--md-sys-color-surface-container-low); color: var(--md-sys-color-on-surface);
  cursor: pointer;
}
.revenue-settings__toggle:hover { background: var(--md-sys-color-surface-container); }
.revenue-settings__toggle input { width: 20px; height: 20px; flex: 0 0 auto; accent-color: var(--md-sys-color-primary); }
.revenue-settings__fields .form-group { margin: 0; }
.revenue-settings__fields input { min-height: 48px; background: var(--md-sys-color-surface-container-lowest); color: var(--md-sys-color-on-surface); }
.revenue-settings__footer {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  padding: var(--space-3) var(--space-4); border-radius: var(--md-sys-shape-corner-large);
  background: var(--md-sys-color-secondary-container); color: var(--md-sys-color-on-secondary-container);
}
.revenue-settings__footer p { display: flex; align-items: center; gap: var(--space-2); margin: 0; }
.revenue-settings__footer p .material-symbols-outlined,
.revenue-settings__footer .btn .material-symbols-outlined { font-size: 19px; }

/* Organization detail — lazy account-health story. */
.rac-health { display: grid; gap: var(--space-3); }
.rac-health__heading { display: flex; align-items: start; justify-content: space-between; gap: var(--space-3); }
.rac-health__heading h2 { margin: 0; font-size: var(--md-sys-typescale-title-large-size); }
.rac-health__heading p { margin: 4px 0 0; color: var(--md-sys-color-on-surface-variant); }
.rac-health-grid { display: grid; grid-template-columns: repeat(4,minmax(0,1fr)); gap: var(--space-2); }
.rac-health-metric { display: grid; gap: 4px; padding: 14px; border-radius: var(--md-sys-shape-corner-medium); background: var(--md-sys-color-surface-container-low); }
.rac-health-metric small,.rac-health-metric span { color: var(--md-sys-color-on-surface-variant); }
.rac-health-metric strong { color: var(--md-sys-color-on-surface); font-size: var(--md-sys-typescale-title-large-size); }
.rac-health-layout { display: grid; grid-template-columns: 1.15fr .85fr; gap: var(--space-3); }
.rac-health-card { padding: var(--space-3); border: 1px solid var(--md-sys-color-outline-variant); border-radius: var(--md-sys-shape-corner-large); background: var(--md-sys-color-surface-container-lowest); }
.rac-health-card h3 { margin: 0 0 var(--space-3); }
.rac-health-rec { display: grid; grid-template-columns: auto minmax(0,1fr) auto; align-items: center; gap: 10px; min-height: 58px; padding: 8px; border-radius: var(--radius-m); color: var(--md-sys-color-on-surface); text-decoration: none; }
.rac-health-rec:hover { background: var(--md-sys-color-surface-container); }
.rac-health-rec > .material-symbols-outlined { color: var(--color-primary-text); }
.rac-health-rec span:nth-child(2) { display: grid; min-width: 0; }
.rac-health-rec small { color: var(--md-sys-color-on-surface-variant); }
.rac-health-timeline { position: relative; display: grid; }
.rac-health-event { display: grid; grid-template-columns: auto minmax(0,1fr) auto; align-items: center; gap: 12px; min-height: 62px; padding: 9px 4px; border-bottom: 1px solid var(--md-sys-color-outline-variant); }
.rac-health-event:last-child { border-bottom: 0; }
.rac-health-event > .material-symbols-outlined { display: grid; place-items: center; width: 38px; height: 38px; border-radius: 50%; background: var(--md-sys-color-secondary-container); color: var(--md-sys-color-on-secondary-container); }
.rac-health-event div { display: grid; min-width: 0; }
.rac-health-event small { color: var(--md-sys-color-on-surface-variant); }

@media (max-width: 1000px) {
  .rac-analytics-kpis,.rac-health-grid { grid-template-columns: 1fr 1fr; }
  .rac-health-layout { grid-template-columns: 1fr; }
}
@media (max-width: 600px) {
  .rac-modebar { align-items: stretch; }
  .rac-modebar > .filter-chips,.rac-scope,.rac-scope select { width: 100%; }
  .rac-analytics-kpis,.rac-analytics-grid,.rac-health-grid { grid-template-columns: 1fr; }
  .revenue-settings__toggles,.revenue-settings__fields { grid-template-columns: 1fr; }
  .revenue-settings__footer { align-items: stretch; flex-direction: column; }
  .revenue-settings__footer .btn { justify-content: center; width: 100%; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   MD3 STATE LAYER
   ═══════════════════════════════════════════════════════════════════════════
   A hover/focus/press vocabulary for interactive surfaces. Before this the app
   had none: a few components swapped their background on hover, most did
   nothing, and .btn faded its own label to signal press.

   The layer is a pseudo-element tinted with currentColor at the MD3 state
   opacity, so it adapts to whatever colour the component already uses and
   needs no per-theme rules. Add `.stateful` to a new component, or its class
   to the one list below — each family in it lost its own :hover background
   rule, so hover is one mechanism rather than two stacked. The list is
   written once: the states are nested under it (`&`), so a nested rule has
   the list's specificity, the same as the old flat selectors.

   Keep every :is() argument a single class: that is what holds specificity
   where the plain selector list had it. */
:is(.stateful, .btn, .filter-chip, .pagination-btn, .view-switcher__btn, .icon-btn, .modal__close, .nav-item, .hamburger-btn, .drawer-close, .toolbar-btn, .tag-filter-btn, .wf-weekday-chip, .dd-type-filter__btn, .dd-type-filter__clear) {
  position: relative;

  &::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: currentColor;
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--md-sys-motion-duration-short2) var(--md-sys-motion-easing-standard);
  }
  &:hover::after        { opacity: var(--md-sys-state-hover); }
  &:focus-visible::after { opacity: var(--md-sys-state-focus); }
  &:active::after       { opacity: var(--md-sys-state-pressed); }
  /* A disabled control must not look pressable. */
  &:is(:disabled, [disabled])::after { opacity: 0; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   MD3 MENUS
   ═══════════════════════════════════════════════════════════════════════════
   One container spec for every dropdown menu, which had grown eight different
   corners (4–12px), three surfaces and a border-plus-shadow on most: MD3 menus
   are surface-container, extra-small corners, level 2, no outline. Items take
   label-large on-surface at 40px (48px on a phone or under a coarse pointer
   — the touch target, as the menuitem rule above does). Placed after the component rules so it wins at equal specificity;
   keep every :is() argument a single class. */
:is(.sort-dropdown__menu, .saved-views-dropdown, .dd-tl-dropdown, .user-menu-popover,
    .rb-menu, .tag-dropdown, .pe-product-menu, .mention-suggest) {
  background: var(--md-sys-color-surface-container);
  color: var(--md-sys-color-on-surface);
  border: none;
  border-radius: var(--md-sys-shape-corner-extra-small);
  box-shadow: var(--md-sys-elevation-2);
}
:is(.sort-dropdown__item, .user-menu-popover__item, .rb-menu__item) {
  min-height: 40px;
  font-size: var(--md-sys-typescale-label-large-size);
  line-height: var(--md-sys-typescale-label-large-line);
  letter-spacing: var(--md-sys-typescale-label-large-tracking);
  color: var(--md-sys-color-on-surface);
}
@media (max-width: 767px), (any-pointer: coarse) {
  :is(.sort-dropdown__item, .user-menu-popover__item, .rb-menu__item) { min-height: 48px; }
}
/* Popover panels (not menus) — the notification list, record-header and
   report popovers: surface-container, medium corners, level 2, no outline.
   The component rules carry layout only; their surface lives here. */
:is(.notification-dropdown, .rh-popover, .report-popover) {
  background: var(--md-sys-color-surface-container);
  color: var(--md-sys-color-on-surface);
  border: none;
  border-radius: var(--md-sys-shape-corner-medium);
  box-shadow: var(--md-sys-elevation-2);
}

/* ═══════════════════════════════════════════════════════════════════════════
   TODAY — landing surface
   ═══════════════════════════════════════════════════════════════════════════
   Composed from existing endpoints (/analytics/dashboard, /activities/my-tasks)
   and existing components (.card, .kpi-grid, .kpi-card, .tasks-due-pill,
   .empty-state). The only new shapes are the page grid and the row, which
   nothing else needed. */
.today-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 340px;
  gap: var(--space-3);
  align-items: start;
}
@media (max-width: 900px) { .today-grid { grid-template-columns: minmax(0, 1fr); } }

.today-card { padding: 0; margin-bottom: var(--space-3); overflow: hidden; }
.today-card__head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 14px 18px;
  border-bottom: 1px solid var(--color-outline-variant);
}
.today-card__title {
  font-size: var(--md-sys-typescale-title-medium-size);
  line-height: var(--md-sys-typescale-title-medium-line);
  font-weight: var(--md-sys-typescale-title-medium-weight);
  margin: 0;
}
.today-card__count {
  font-size: var(--md-sys-typescale-label-medium-size);
  font-weight: 700;
  color: var(--color-on-primary-container);
  background: var(--color-primary-container);
  border-radius: var(--radius-pill);
  padding: 1px 9px;
}
.today-card__link {
  margin-inline-start: auto;
  font-size: var(--md-sys-typescale-label-medium-size);
  font-weight: 600;
  color: var(--color-primary);
  text-decoration: none;
}

.today-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 18px;
  border-bottom: 1px solid var(--color-outline-variant);
  color: inherit;
  text-decoration: none;
}
.today-row:last-child { border-bottom: 0; }
.today-row__icon { font-size: 20px; color: var(--color-on-surface-var); flex-shrink: 0; }
.today-row__body { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
.today-row__title {
  font-size: var(--md-sys-typescale-body-medium-size);
  line-height: var(--md-sys-typescale-body-medium-line);
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.today-row__meta {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  font-size: var(--md-sys-typescale-body-dense-size);
  color: var(--color-on-surface-var);
}
.today-row__trailing {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: var(--md-sys-typescale-label-large-size);
  flex-shrink: 0;
}

/* Follow up today (app/followups.py): above "Needs you", in the main column.
   A row is a .today-row with its record link and three actions; Draft opens
   the panel under it. */
.today-main { min-width: 0; }
.followup-item { border-bottom: 1px solid var(--color-outline-variant); }
.followup-item:last-child { border-bottom: 0; }
.followup-row { border-bottom: 0; }
a.followup-row__link { color: inherit; text-decoration: none; }
a.followup-row__link:hover { text-decoration: underline; }
.followup-row__actions { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }
@media (max-width: 600px) {
  .followup-row { flex-wrap: wrap; }
  .followup-row__actions { width: 100%; padding-inline-start: 32px; flex-wrap: wrap; }
}
.followup-draft {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: 0 18px 14px 50px;
}
@media (max-width: 600px) { .followup-draft { padding-inline: 18px; } }
.followup-draft__choose {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  font-size: var(--md-sys-typescale-body-dense-size);
  color: var(--color-on-surface-var);
}
.followup-draft__close { margin-inline-start: auto; }
.followup-draft__note,
.followup-draft__status {
  margin: 0;
  font-size: var(--md-sys-typescale-body-small-size);
  color: var(--color-on-surface-var);
}
.followup-draft__status.is-error { color: var(--color-error); }
.followup-draft__body { display: flex; flex-direction: column; gap: var(--space-2); }
.followup-draft__body:empty { display: none; }
.followup-draft .form-group { margin-bottom: 0; }
.followup-draft__actions { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }

/* Term shown but not offered — the tenant no longer sells subscriptions. */
.pe-readonly { color: var(--md-sys-color-on-surface-variant); font-size: var(--md-sys-typescale-body-small-size); }

/* ── Dashboard: tiles on a 12-column grid ────────────────────────────────
   Width is a PRESET, never stored geometry — a preset reflows on its own at
   every breakpoint, where saved coordinates need a mobile fallback nobody
   maintains. Spans live in classes rather than inline styles, which is why
   this block needs no !important to reflow (the old hardcoded dashboard set
   grid-template-columns inline on every row and did).                       */
.dash-toolbar {
  display: flex; align-items: center; gap: var(--sp-3);
  margin-bottom: var(--space-3); flex-wrap: wrap;
}
.dash-toolbar__title { font-weight: 600; font-size: var(--md-sys-typescale-body-large-size); }
.dash-toolbar__picker {
  height: 34px; padding: 0 10px; font: inherit; font-size: var(--md-sys-typescale-body-dense-size);
  border: 1px solid var(--color-outline-variant); border-radius: var(--md-sys-shape-corner-small);
  background: var(--color-surface-container-lowest);
  color: var(--color-on-surface);
}

.dash-grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--space-3);
  /* Tiles in a row share its height, so a short donut does not leave a
     ragged hole beside a tall bar chart. */
  align-items: stretch;
}
.dash-tile--small  { grid-column: span 3; }
.dash-tile--medium { grid-column: span 6; }
.dash-tile--full   { grid-column: span 12; }
.dash-tile { min-width: 0; display: flex; flex-direction: column; }
/* A tile too narrow for its Arrange controls beside its title (a small tile,
   whose buttons are 48px on a touch screen and still too wide with a mouse
   below 1300px) puts them on a line of their own at its end, and wraps them
   there, rather than run out of the tile. */
.dash-tile__head {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-bottom: 10px;
}
.dash-tile__title {
  font-size: var(--md-sys-typescale-body-dense-size); font-weight: 600; margin: 0;
  color: var(--color-on-surface);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dash-tile__body { min-width: 0; overflow-x: auto; flex: 1; }
.dash-tile__body > .donut-wrap { height: 100%; justify-content: center; }
/* A big compact currency figure ("EGP 376.3B") still overruns a 140px auto-fill
   track, and a clipped number is worse than a smaller one. */
.dash-tile .kpi-grid--sm { grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); }
.dash-tile .kpi-card__value { font-size: var(--md-sys-typescale-headline-small-size); overflow-wrap: anywhere; }
/* MD3 text does not scale with its container, but a figure must not break
   mid-number either. A report's KPI row drops columns to make room
   (_reportLayout kpiColumns); a dashboard tile's width is fixed, so here
   each card is a size container and a card too narrow for its figure takes
   the next step down the type scale. Breakpoints are the content widths
   "EGP 376.3B" needs (Inter 800): 24px 137px, 22px 126px; the kiosk's
   36px 205px, 28px 160px. A card is never under 170px (the minmax above,
   ~134px of content), so 22px is the floor; overflow-wrap is the last resort. */
.dash-tile .kpi-card { container: dash-kpi / inline-size; }
@container dash-kpi (max-width: 136px) {
  .dash-tile .kpi-card__value { font-size: var(--md-sys-typescale-title-large-size); }
}
/* Kiosk: bigger steps where they fit; below 160px the ladder above applies. */
@container dash-kpi (min-width: 205px) {
  html[data-kiosk] .dash-tile .kpi-card__value { font-size: var(--md-sys-typescale-display-small-size); }
}
@container dash-kpi (160px <= width < 205px) {
  html[data-kiosk] .dash-tile .kpi-card__value { font-size: var(--md-sys-typescale-headline-medium-size); }
}
.dash-tile__kpi {
  font-family: var(--font-display); font-size: var(--md-sys-typescale-headline-medium-size); font-weight: 700;
  color: var(--color-primary);
}
.dash-tile__missing { flex-direction: column; gap: 6px; opacity: .7; }

.dash-tile__controls {
  display: inline-flex; flex-wrap: wrap; justify-content: flex-end; gap: 4px; align-items: center;
  margin-inline-start: auto;
}
.dash-tile__size {
  height: 28px; font: inherit; font-size: var(--md-sys-typescale-body-small-size); padding: 0 6px;
  border: 1px solid var(--color-outline-variant); border-radius: var(--md-sys-shape-corner-small);
  background: var(--color-surface-container-lowest); color: var(--color-on-surface);
}
.dash-grid--editing .dash-tile { cursor: grab; outline: 1px dashed var(--color-outline-variant); }
.dash-tile--dragging { opacity: .5; }
.dash-tile--drop,
.rb-kpi-tile--drop,
.rb-chartcard--drop,
.rb-tablecard--drop,
.rb-bd-card--drop { outline: 2px solid var(--color-primary); }

/* Shared list-row shape for the at-risk / top-deals / recent-wins tiles. The
   old dashboard inlined these styles three times. */
.dash-row { display: flex; align-items: center; gap: 12px; padding: 10px 0; }
.dash-row--divided { border-bottom: 1px solid var(--color-outline-variant); }
/* Dashboard figures that open their records: buttons and links that keep the
   look of the text and bars they replace. */
.dash-drill {
  display: block; width: 100%;
  font: inherit; color: inherit; text-align: start;
  background: none; border: 0; padding: 0;
  cursor: pointer; border-radius: var(--radius-s);
}
.dash-drill.donut-legend-item { display: flex; }
.dash-drill:hover .h-bar-fill { filter: brightness(1.08); }
.dash-drill:focus-visible, .dash-row--link:focus-visible, .dash-tile__link:focus-visible {
  outline: 2px solid var(--color-primary); outline-offset: 2px;
}
.dash-row--link { color: inherit; text-decoration: none; }
.dash-row--link:hover .dash-row__title, .dash-tile__link:hover { text-decoration: underline; }
.dash-tile__link { color: inherit; text-decoration: none; }
.dash-row__main { flex: 1; min-width: 0; }
.dash-row__title {
  font-weight: 600; font-size: var(--md-sys-typescale-body-medium-size);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dash-row__value--won  { color: var(--color-success-text); }
.dash-row__value--risk { color: var(--color-primary); }

@media (max-width: 900px) {
  .dash-tile--small { grid-column: span 6; }
}
@media (max-width: 767px) {
  .dash-tile--small, .dash-tile--medium { grid-column: span 12; }
  /* HTML5 drag never fires on touch, so the buttons are the only reorder
     path here — and they are present on desktop too, because the drag path
     has no keyboard equivalent either. */
  .dash-grid--editing .dash-tile { cursor: default; }
}

/* ── Freshness caption ────────────────────────────────────────────────────
   Same visual grammar as the products scan notice: both say "this figure is
   true, with a caveat", so a user learns the pattern once. */
.rb-chartcard__notice--stale,
.dash-tile__freshness--stale { color: var(--color-warning-text); }
.dash-tile__freshness {
  margin-top: 8px; font-size: var(--md-sys-typescale-label-small-size);
  color: var(--color-on-surface-var);
}

/* ── Kiosk: a wall-display view of a signed-in session ─────────────────────
   Not a public link — see the comment on the menu handler. Hides the app
   chrome and enlarges the figures for a room-distance read. html[data-kiosk]
   is set by JS while the document holds a .dash-toolbar--kiosk. */
html[data-kiosk] .sidebar,
html[data-kiosk] .bottom-nav,
html[data-kiosk] .search-pill,
html[data-kiosk] .page-header,
html[data-kiosk] .analytics-tabs { display: none !important; }
html[data-kiosk] .view { margin-inline-start: 0; padding: var(--space-4); }
.dash-toolbar--kiosk .rb-btn,
.dash-toolbar--kiosk .rb-icon-btn { display: none; }
/* The kiosk's figure sizes sit with the dash-kpi ladder (.dash-tile above). */
html[data-kiosk] .dash-tile__title { font-size: var(--md-sys-typescale-body-large-size); }

/* ── Bulk "Edit fields" modal ──────────────────────────────────────────────
   One row per field: an apply checkbox that names the field, and the value
   box it controls. The box stays disabled until the field is ticked, so a
   half-typed value cannot travel with the request.

   Two columns on a laptop, stacked on a phone. Logical properties throughout
   — the checkbox leads the row in English and trails it in Arabic. */
.bulk-edit-grid {
  display: grid;
  gap: var(--space-2);
  margin: var(--space-3) 0;
}
.bulk-edit-row {
  display: grid;
  grid-template-columns: minmax(9rem, 14rem) 1fr;
  align-items: center;
  gap: var(--space-2) var(--space-3);
}
.bulk-edit-row__apply {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--md-sys-typescale-body-medium-size);
  cursor: pointer;
  min-height: 40px;          /* touch target on a phone */
}
.bulk-edit-row__value input,
.bulk-edit-row__value select { width: 100%; }
/* A disabled box is the resting state here, not a failure, so it recedes
   rather than looking broken. */
.bulk-edit-row__value input:disabled,
.bulk-edit-row__value select:disabled {
  background: var(--color-surface-variant);
  color: var(--color-on-surface-var);
  cursor: not-allowed;
}

@media (max-width: 560px) {
  .bulk-edit-row { grid-template-columns: 1fr; gap: 4px; }
  .bulk-edit-row__apply { min-height: 44px; }
}

/* ── A contact's other companies ────────────────────────────────
   Sits at the foot of the organisation card. Rows, not chips: each one needs
   two touch targets beside it, and a wrapped chip with buttons inside is
   unreadable at 375px. Logical properties throughout — the actions trail the
   name in English and lead it in Arabic. */
.contact-orgs {
  margin-top: var(--space-3);
  padding-top: var(--space-2);
  border-top: 1px solid var(--color-outline-variant);
}
.contact-orgs__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin-bottom: 4px;
}
.contact-orgs__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  min-height: 32px;
}
/* The shared icon button carries a shadow, which reads fine on the two buttons
   in the card header but stacks into a ladder of boxes down a list of six. The
   48px height stays — it is the tap target. */
.contact-orgs__actions { display: flex; gap: 2px; flex: none; }
.contact-orgs__actions .btn { box-shadow: none; }
/* A company that has since been deleted stays on the record — the person did
   work there — but reads as history rather than as a live link. */
.contact-orgs__row--gone .dd-link {
  color: var(--color-on-surface-var);
  text-decoration: line-through;
}

/* ── A record's other emails and phones (_contactPoints.js) ─────────────
   Rows under the primary email / phone, each with its label where a field's
   name sits, and the three small actions trailing it (leading it in Arabic —
   logical properties). The add button and the inline form are a quiet line,
   not a section: most records have none of these. */
.cpoint-list { display: flex; flex-direction: column; }
.cpoint-row { gap: var(--space-2); }
.cpoint-row__value { flex: 1; min-width: 0; text-align: end; overflow-wrap: anywhere; }
.cpoint-row__value [data-ucm-phone] { white-space: nowrap; }
.cpoint-row__menu { flex: none; box-shadow: none; }
/* On a person card the fields stack, label over value: so do these, with the
   ⋯ beside the label. */
.cpoint-row--stacked { display: grid; grid-template-columns: 1fr auto; align-items: center; column-gap: var(--space-1); }
.cpoint-row--stacked .cpoint-row__value { grid-row: 2; grid-column: 1 / -1; text-align: start; }
.cpoint-row--stacked .cpoint-row__menu { grid-row: 1; grid-column: 2; }
.cpoint-add {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  align-self: flex-start;
  min-height: 32px;
  padding: 0;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--color-primary);
  font: inherit;
  font-size: var(--md-sys-typescale-body-dense-size);
}
.cpoint-form, .cpoint-extra__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) 0;
}
.cpoint-form__value-wrap { flex: 1 1 160px; min-width: 0; }
.cpoint-form__value-wrap .iti, .cpoint-form__value-wrap input { width: 100%; }
.cpoint-form__label { flex: 0 1 auto; width: auto; }
.cpoint-form__buttons { display: flex; gap: var(--space-1); }
.cpoint-extra { display: flex; flex-direction: column; }
/* In a create form's half-width column the number takes the line, and the
   label and its ✕ share the next one. */
.cpoint-extra__row .cpoint-form__label { flex: 1 1 0; width: auto; min-width: 0; }
.form-group .cpoint-add { margin-top: var(--space-1); }

/* ── "Deals or deal products?" ─────────────────────────────────────────────
   The chooser both the Import and the Export button open. Stacked full-width
   buttons rather than a list of links: each one is a destination, and on a
   phone a two-line target is far easier to hit than a text link. */
.ie-kind { display: flex; flex-direction: column; gap: var(--space-2); }
.ie-kind__btn {
  display: block;
  width: 100%;
  text-align: start;
  padding: var(--space-3);
  min-height: 0;
  line-height: 1.5;
}
.ie-kind__label { display: block; font-weight: 600; }
.ie-kind__hint  { display: block; white-space: normal; }
/* With formats the row is a heading plus one button per format — they wrap
   under the heading on a phone rather than squeezing beside it. */
.ie-kind__row {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-outline-variant);
}
.ie-kind__row:last-child { border-bottom: 0; }
.ie-kind__text { flex: 1; min-width: 180px; }
.ie-kind__formats { display: flex; flex-wrap: wrap; gap: var(--space-2); }

/* Named for the class settings_api_keys.js already asked for and never got. */
.btn--danger-outlined { color: var(--color-error); border-color: var(--color-error); }
.btn--danger-outlined:hover { background: color-mix(in srgb, var(--color-error) 8%, transparent); }

/* ── Duplicate review ──────────────────────────────────────────────────────
   One card for the whole review, a toolbar over it, and one block per group of
   records that look like the same person or company — the shape the list pages
   use, so this page belongs to them rather than floating a stack of boxes.
   The rows are radio labels (.import-radio carries the layout): the chosen one
   stays, the rest go to Trash. */
.dup-group {
  /* Sideways padding lives on the rows, so a row highlights edge to edge the
     way a list row does. */
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-surface-container-high);
}
.dup-group:last-child { border-bottom: none; }
.dup-group__head,
.dup-group__foot { padding-inline: var(--space-4); }
.dup-group__head {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin-bottom: var(--space-2);
}
.dup-rule {
  font-size: var(--md-sys-typescale-body-small-size); padding: 2px 10px; border-radius: var(--radius-pill);
  background: var(--color-surface-variant); color: var(--color-on-surface-var);
}
.dup-row { padding: 8px var(--space-4); }
.dup-row:hover { background: var(--color-surface-variant); }
/* min-width:0 so a long email ellipsises instead of pushing the row wide. */
.dup-row__main { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.dup-row__main .caption { overflow: hidden; text-overflow: ellipsis; }
.dup-row__carries { color: var(--color-primary); }
.dup-row__open { font-size: var(--md-sys-typescale-body-dense-size); white-space: nowrap; margin-inline-start: auto; }
.dup-group__foot {
  display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px;
  margin-top: var(--space-2);
}

/* On a phone the toolbar above tightens to --space-2; the rows follow it in,
   so the card's contents keep one edge. */
@media (max-width: 767px) {
  .dup-group__head,
  .dup-group__foot,
  .dup-row { padding-inline: var(--space-2); }
}

/* ── Column filter popovers and active-filter chips (_columnPicker.js) ── */
.col-head { display:inline-flex; align-items:center; gap:4px }
.col-filter-btn { background:none; border:none; cursor:pointer; padding:2px; margin-inline-start:2px;
                  color:var(--color-on-surface-var); border-radius:var(--md-sys-shape-corner-extra-small); display:inline-flex; align-items:center }
.col-filter-btn:hover { background:var(--color-surface-container-high) }
.col-filter-btn.is-active { color:var(--color-primary) }
.filter-pop { position:fixed; background:var(--color-surface); border:1px solid var(--color-outline-variant);
              border-radius:var(--md-sys-shape-corner-medium); box-shadow:var(--md-sys-elevation-5); padding:10px; min-width:280px; max-width:340px;
              max-height:440px; display:flex; flex-direction:column; z-index:1000; font-size:var(--md-sys-typescale-body-dense-size) }
.filter-pop__title { font-weight:600; font-size:var(--md-sys-typescale-body-small-size); color:var(--color-on-surface-var);
                     margin:0 0 8px; letter-spacing:.03em }
.filter-pop__search { width:100%; box-sizing:border-box; padding:6px 8px; border:1px solid var(--color-outline-variant);
                      border-radius:var(--md-sys-shape-corner-small); font-size:var(--md-sys-typescale-body-dense-size); margin-bottom:6px }
.filter-pop__list { max-height:220px; overflow-y:auto; margin:0 -4px 8px; padding:0 4px; display:flex; flex-direction:column; gap:2px }
.filter-pop__row { display:flex; align-items:center; gap:8px; padding:4px 6px; border-radius:var(--md-sys-shape-corner-extra-small); cursor:pointer }
.filter-pop__row:hover { background:var(--color-surface-container-high) }
.filter-pop__row input[type=checkbox] { margin:0; accent-color:var(--color-primary) }
.filter-pop__row-label { flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.filter-pop__count { color:var(--color-on-surface-var); font-size:var(--md-sys-typescale-label-small-size); font-variant-numeric:tabular-nums }
.filter-pop__presets { display:flex; flex-wrap:wrap; gap:4px; margin-bottom:8px }
.filter-pop__preset { font-size:var(--md-sys-typescale-body-small-size); padding:3px 9px; border-radius:var(--md-sys-shape-corner-full); border:1px solid var(--color-outline-variant);
                      background:var(--color-surface); cursor:pointer; color:inherit }
.filter-pop__preset.is-active { background:var(--color-primary-container); color:var(--color-on-primary-container); border-color:transparent }
.filter-pop__row-actions { display:flex; gap:6px; margin:6px 0 8px }
/* ── Column picker (the modal openColumnPicker() renders) ──────────────── */
.cp-list { display: flex; flex-direction: column; gap: 4px; }
.cp-row {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-small);
  background: transparent; cursor: grab;
}
.cp-row.cp-row--hidden { opacity: .65; cursor: default; }
.cp-row.cp-row--dragging { opacity: .4; }
.cp-row.cp-row--drop-target {
  border-color: var(--md-sys-color-primary);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--md-sys-color-primary) 20%, transparent);
}
.cp-row .cp-handle { cursor: grab; opacity: .5; font-size: var(--md-sys-typescale-body-large-size); }
.cp-row .cp-label { flex: 1; font-size: var(--md-sys-typescale-body-medium-size); }
.cp-bulk { display: flex; gap: 8px; margin: 0 0 8px; }
@media (max-width: 767px) { .cp-bulk .btn { min-height: 44px; font-size: var(--md-sys-typescale-body-medium-size); } }
.filter-pop__op-row { display:flex; gap:6px; margin-bottom:6px; align-items:center }
.filter-pop__op-select, .filter-pop__input { padding:6px 8px; border:1px solid var(--color-outline-variant);
                                             border-radius:var(--md-sys-shape-corner-small); font-size:var(--md-sys-typescale-body-dense-size); background:var(--color-surface); color:inherit }
.filter-pop__input { flex:1 }
.filter-pop__foot { display:flex; justify-content:flex-end; gap:6px; margin-top:6px; padding-top:8px;
                    border-top:1px solid var(--color-surface-container-high) }
.filter-pop__btn { padding:6px 12px; border-radius:var(--md-sys-shape-corner-small); border:1px solid var(--color-outline-variant);
                   background:var(--color-surface); cursor:pointer; font-size:var(--md-sys-typescale-body-small-size); color:inherit }
.filter-pop__btn--primary { background:var(--color-primary); color:var(--color-on-primary); border-color:transparent }
.filter-pop__btn--ghost { background:none; border:none }
.filter-pop__empty { color:var(--color-on-surface-var); font-size:var(--md-sys-typescale-body-small-size); padding:12px 4px; text-align:center }
.filter-pop__loading { color:var(--color-on-surface-var); font-size:var(--md-sys-typescale-body-small-size); padding:12px 4px; text-align:center }
.filter-chip-row { display:flex; flex-wrap:wrap; gap:8px; padding:8px 12px; align-items:center;
                   border-bottom:1px solid var(--color-surface-container-high) }
/* Its own name, not .filter-chip: these are removable tokens with an x, not
   the toggle chips. Declaring .filter-chip here once repainted every toolbar
   chip on five list pages. */
/* nowrap / font-weight / border are not decoration — they are the three
   properties these tokens inherited from .filter-chip while they shared its
   name. Without nowrap a long
   summary ("Amount ≥ 1000", a date range) wraps mid-token. cursor:pointer
   and the transition are deliberately NOT carried over: the span is not
   clickable (its __x button is) and nothing here changes state. */
.active-filter-chip { display:inline-flex; align-items:center; gap:4px; min-height:32px; padding:3px 6px 3px 10px;
               border-radius:var(--md-sys-shape-corner-small);
               background:var(--color-primary-container); color:var(--color-on-primary-container);
               font-size:var(--md-sys-typescale-body-small-size); line-height:1.4; white-space:nowrap; font-weight:500;
               border:1px solid var(--color-outline) }
.active-filter-chip__x { position:relative; background:none; border:none; cursor:pointer; padding:2px; color:inherit; opacity:.75; display:inline-flex; align-items:center }
/* A chip's x keeps its look and takes a press 48px tall: Material 3 asks every
   chip for a 48dp target, "if required, beyond the visible container of the
   chip". Sideways it runs to its chip's edge and no further, so it never takes
   a press meant for the chip's own name or for the next chip. */
.active-filter-chip__x::before,
.report-filter-chip__close::before { content:""; position:absolute; top:50%; height:48px; transform:translateY(-50%);
                                     inset-inline-start:0; inset-inline-end:-6px }
.active-filter-chip__x:hover { opacity:1 }
.filter-chip-row__clear { margin-inline-start:auto; font-size:var(--md-sys-typescale-body-small-size); color:var(--color-primary); background:none; border:none; cursor:pointer; padding:2px 4px }
.filter-chip-row__clear:hover { text-decoration:underline }

/* ── CRM Assistant panel (views/_assistant.js) ─────────────────────────── */
/* Not modal: it sits beside the page so a user can keep working. 280 keeps it
   above app chrome (top bar 100, tab bar 200, FAB 210, mobile sidebar 250)
   and BELOW the record drawer (290/291) and modals (300), which a record
   link clicked in the chat may open on top of it. */
:root { --assistant-w: 420px; }   /* the panel, and the room a docked one takes */
.assistant-panel {
  position: fixed;
  top: var(--md-top-app-bar-h);
  inset-inline-end: 0;
  bottom: 0;
  width: var(--assistant-w);
  max-width: 100vw;
  display: flex;
  flex-direction: column;
  background: var(--color-surface);
  color: var(--color-on-surface);
  border-inline-start: 1px solid var(--color-outline-variant);
  box-shadow: var(--shadow-3);
  z-index: 280;
  transform: translateX(105%);
  visibility: hidden;
  transition: transform .22s ease, visibility 0s linear .22s;
}
[dir="rtl"] .assistant-panel { transform: translateX(-105%); }
/* The assistant button's own note (Yahia, 2026-10-18, as Docs Hub has it):
   an M3 persistent rich tooltip under the top-bar button. Over the top bar
   (100), under the open panel (280) and dialogs. */
.assistant-nudge {
  position: fixed; z-index: 270; width: min(320px, calc(100vw - 16px));
  padding: 12px var(--space-3) var(--space-2); border-radius: var(--md-sys-shape-corner-medium);
  background: var(--color-surface-container); color: var(--color-on-surface);
  box-shadow: var(--shadow-2); border: 1px solid var(--color-outline-variant);
  animation: assistant-nudge-in .2s ease-out;
}
.assistant-nudge::before {
  content: ""; position: absolute; top: -7px; left: calc(var(--caret, 24px) - 6px);
  width: 12px; height: 12px; transform: rotate(45deg);
  background: inherit; border-top: 1px solid var(--color-outline-variant);
  border-left: 1px solid var(--color-outline-variant);
}
.assistant-nudge__title {
  margin: 0 0 var(--space-1);
  font-size: var(--md-sys-typescale-title-small-size); line-height: var(--md-sys-typescale-title-small-line);
  font-weight: var(--md-sys-typescale-title-small-weight);
}
.assistant-nudge__body {
  margin: 0; color: var(--color-on-surface-var);
  font-size: var(--md-sys-typescale-body-medium-size); line-height: var(--md-sys-typescale-body-medium-line);
}
.assistant-nudge__actions { display: flex; justify-content: flex-end; gap: var(--space-1); margin-top: var(--space-2); }
@keyframes assistant-nudge-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .assistant-nudge { animation: none; } }

.assistant-panel.is-open {
  transform: none;
  visibility: visible;
  transition: transform .22s ease;
}
.assistant-head {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-2) var(--space-1) var(--space-4);
  border-bottom: 1px solid var(--color-outline-variant);
}
.assistant-head__icon { color: var(--color-primary); }
.assistant-head__title { flex: 1; margin: 0; font-size: var(--md-sys-typescale-body-large-size); font-weight: 600; }
.assistant-log {
  flex: 1;
  overflow-y: auto;
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  overscroll-behavior: contain;
}
.assistant-msg {
  font-size: var(--md-sys-typescale-body-medium-size);
  line-height: 1.5;
  overflow-wrap: anywhere;
}
.assistant-msg--user {
  align-self: flex-end;
  max-width: 85%;
  padding: 10px 14px;
  border-radius: var(--radius-l);
  border-bottom-right-radius: var(--radius-s);   /* the corner nearest the sender */
  background: var(--color-primary-container);
  color: var(--color-on-primary-container);
  white-space: pre-wrap;
}
/* Physical corners: the bubble's own dir="auto" follows its text, but the
   side it sits on follows the page. */
[dir="rtl"] .assistant-msg--user { border-bottom-right-radius: var(--radius-l); border-bottom-left-radius: var(--radius-s); }
/* A reply is text on the panel, not a box: only the user's turns are bubbles. */
.assistant-msg--assistant {
  align-self: stretch;  /* replies carry tables; give them the panel's width */
}
.assistant-msg.is-streaming { white-space: pre-wrap; }
.assistant-msg p { margin: 0 0 8px; }
.assistant-msg p:last-child { margin-bottom: 0; }
.assistant-msg ul, .assistant-msg ol { margin: 4px 0 8px; padding-inline-start: 20px; }
.assistant-msg code {
  font-family: var(--font-mono);
  font-size: var(--md-sys-typescale-body-small-size);
  background: var(--color-surface-container-high);
  padding: 1px 4px;
  border-radius: var(--radius-s);
}
.assistant-heading { font-weight: 600; }
.assistant-link { color: var(--color-primary-text); font-weight: 500; }
/* A file a tool built (#download/7): the panel fetches and saves it. */
.assistant-download { display: inline-flex; align-items: center; gap: 2px; }
.assistant-download[aria-busy="true"] { opacity: .6; cursor: progress; }
.assistant-table-wrap { overflow-x: auto; margin: 4px 0 8px; }
.assistant-table { border-collapse: collapse; font-size: var(--md-sys-typescale-body-dense-size); min-width: 100%; }
.assistant-table th, .assistant-table td {
  padding: 4px 8px;
  border-bottom: 1px solid var(--color-outline-variant);
  text-align: start;
  white-space: nowrap;
}
.assistant-table th { font-weight: 600; color: var(--color-on-surface-var); }
.assistant-notice {
  align-self: stretch;
  font-size: var(--md-sys-typescale-body-dense-size);
  padding: 8px 12px;
  border-radius: var(--radius-m);
  background: var(--color-surface-container-low);
  border: 1px solid var(--color-outline-variant);
  color: var(--color-on-surface-var);
}
.assistant-notice--error {
  background: var(--color-error-container);
  border-color: var(--color-error);
  color: var(--color-on-error-container);
}
.assistant-action-line {
  align-self: flex-start;
  display: flex;
  align-items: center;
  gap: 6px;
  padding-block: 4px;
  padding-inline: 10px 12px;
  border-radius: var(--radius-pill);
  background: var(--color-surface-container-low);
  border: 1px solid var(--color-outline-variant);
  font-size: var(--md-sys-typescale-body-dense-size);
  color: var(--color-on-surface-var);
}
.assistant-action-line.is-ok .material-symbols-outlined { color: var(--color-success); }
.assistant-action-line .material-symbols-outlined { font-size: 18px; }
.assistant-card {
  align-self: stretch;
  border: 1px solid var(--color-primary);
  border-radius: var(--radius-l);
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface-container-lowest);
}
.assistant-card.is-busy { opacity: .7; }
/* Debrief (app/assistant/debrief.py): the record pages' and call sheet's
   entry, shown while the workspace has it on; the chip over the input. */
[data-debrief], #lcDebrief { display: none; }
html[data-assistant-debrief] [data-debrief] { display: inline-flex; }
html[data-assistant-debrief] #lcDebrief:not([hidden]) { display: inline-flex; align-items: center; gap: 4px; }
.assistant-context {
  display: flex; align-items: center; gap: 6px; margin: 0 var(--space-3) 6px;
  padding: 4px 4px 4px 10px; border-radius: var(--radius-pill);
  background: var(--color-primary-container); color: var(--color-on-primary-container);
  font-size: var(--md-sys-typescale-body-small-size);
}
.assistant-context > span:nth-child(2) { flex: 1; min-width: 0; }
/* A change set (changeset.py): one block per change, each with its tick box. */
.assistant-card__set { display: grid; gap: 8px; margin-bottom: 8px; }
.assistant-card__set-row {
  display: grid; grid-template-columns: auto 1fr; gap: 8px; align-items: start;
  padding: 8px; border-radius: var(--radius-m); background: var(--color-surface-container-low);
}
.assistant-card__set-row input { margin-top: 3px; }
.assistant-card__set-row summary { cursor: pointer; font-weight: 600; font-size: var(--md-sys-typescale-body-dense-size); }
.assistant-card__set-row .assistant-card__fields { margin-top: 6px; }
.assistant-card__set-row:has(input:not(:checked)) details { opacity: .55; }
/* The AI credit (views/_aiCredit.js): the balance under the chat, and the
   card that recharges it. */
.assistant-credit {
  background: none; border: none; padding: 0; font: inherit; color: var(--color-primary);
  cursor: pointer; text-decoration: underline; text-underline-offset: 2px;
}
.assistant-credit.is-low { color: var(--color-warning-text); font-weight: 600; }
.assistant-recharge__intro,
.assistant-recharge__note { margin: 0 0 8px; font-size: var(--md-sys-typescale-body-dense-size); color: var(--color-on-surface-var); }
.assistant-recharge__note.is-error { color: var(--color-error); }
.assistant-recharge__note.is-ok { color: var(--color-success); font-weight: 600; }
.assistant-recharge__packs { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-bottom: 8px; }
.assistant-recharge__pack {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 10px 8px; border-radius: var(--radius-m);
  border: 1px solid var(--color-outline-variant); background: var(--color-surface-container-low);
  color: var(--color-on-surface); cursor: pointer; font: inherit;
}
.assistant-recharge__pack:hover:not(:disabled) { border-color: var(--color-primary); }
.assistant-recharge__pack:disabled { opacity: .6; cursor: default; }
.assistant-recharge__amount { font-size: var(--md-sys-typescale-title-medium-size); font-weight: 600; }
.assistant-recharge__price { font-size: var(--md-sys-typescale-body-small-size); color: var(--color-on-surface-var); text-align: center; }
.assistant-recharge__profile { display: grid; gap: 8px; }
.assistant-recharge__profile .form-label { display: grid; gap: 4px; font-size: var(--md-sys-typescale-body-dense-size); }
.assistant-recharge__kinds { display: flex; gap: 16px; font-size: var(--md-sys-typescale-body-dense-size); }
.assistant-recharge__profile [type=submit] { justify-self: start; }
.asst-credit__balance { font-size: var(--md-sys-typescale-title-medium-size); font-weight: 600; margin: 0 0 var(--space-2); }
.asst-credit__balance.is-low { color: var(--color-warning-text); }
.asst-credit__recharge { margin-top: var(--space-2); }
.asst-credit__recharge:empty { display: none; }
.asst-credit__sub { margin: var(--space-4) 0 var(--space-2); font-size: var(--md-sys-typescale-body-large-size); }
.asst-credit__table { width: 100%; }
.asst-credit__table .num { text-align: end; font-variant-numeric: tabular-nums; }
.assistant-card__step {
  margin: 0 0 2px; font-size: var(--md-sys-typescale-body-small-size);
  font-weight: 600; color: var(--color-primary);
}
.assistant-card__title { margin: 0 0 8px; font-weight: 600; }
.assistant-card__fields { margin: 0; display: grid; gap: 4px; }
.assistant-card__row { display: grid; grid-template-columns: minmax(84px, 30%) 1fr; gap: 8px; font-size: var(--md-sys-typescale-body-dense-size); }
.assistant-card__row dt { color: var(--color-on-surface-var); }
.assistant-card__row dd { margin: 0; overflow-wrap: anywhere; white-space: pre-wrap; }
.assistant-card__warn {
  display: flex; gap: 6px; align-items: flex-start;
  margin: 8px 0 0; font-size: var(--md-sys-typescale-body-small-size); color: var(--color-warning-text);
}
.assistant-card__warn .material-symbols-outlined { font-size: 16px; }
.assistant-card__risk { margin: 0 0 8px; }
.assistant-card__intent { margin: 8px 0 0; font-size: var(--md-sys-typescale-body-small-size); }
.assistant-card__intent > span:first-child { color: var(--color-on-surface-var); }
.assistant-card__request { margin-top: 8px; font-size: var(--md-sys-typescale-body-small-size); }
.assistant-card__request summary { cursor: pointer; color: var(--color-on-surface-var); }
.assistant-card__request pre {
  margin: 6px 0 0; padding: var(--space-2); max-height: 220px; overflow: auto;
  border: 1px solid var(--color-outline-variant); border-radius: var(--radius-s);
  background: var(--color-surface-container); white-space: pre-wrap; overflow-wrap: anywhere;
  font-size: var(--md-sys-typescale-body-small-size); text-align: left;
}
.assistant-card__btns { display: flex; gap: var(--space-2); margin-top: var(--space-3); }
.assistant-card__btns .btn { min-height: 40px; }
.assistant-card__hint { margin: 6px 0 0; font-size: var(--md-sys-typescale-body-small-size); color: var(--color-on-surface-var); }
.assistant-empty { margin: auto 0; }
.assistant-suggestions { display: flex; flex-wrap: wrap; gap: var(--space-2); justify-content: center; }
.assistant-chip {
  border: 1px solid var(--color-outline-variant);
  background: var(--color-surface);
  color: var(--color-on-surface);
  border-radius: var(--radius-pill);
  padding: 8px 14px;
  min-height: 40px;
  font: inherit;
  font-size: var(--md-sys-typescale-body-dense-size);
  cursor: pointer;
}
.assistant-chip:hover { background: var(--color-surface-container); }
.assistant-progress {
  display: flex; align-items: center; gap: 8px;
  padding: 0 var(--space-4) var(--space-2);
  font-size: var(--md-sys-typescale-body-small-size); color: var(--color-on-surface-var);
}
.assistant-dots { display: inline-flex; gap: 3px; }
.assistant-dots i {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--color-primary);
  animation: assistant-dot 1s infinite ease-in-out;
}
.assistant-dots i:nth-child(2) { animation-delay: .15s; }
.assistant-dots i:nth-child(3) { animation-delay: .3s; }
@keyframes assistant-dot { 0%, 80%, 100% { opacity: .25; } 40% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .assistant-panel, .assistant-panel.is-open { transition: none; }
  .assistant-dots i { animation: none; opacity: .7; }
}
/* One rounded box: the files waiting to go, the text on its own full-width
   row, and the tools under it — so the buttons never squeeze the text. */
.assistant-composer {
  display: flex;
  flex-direction: column;
  margin: var(--space-1) var(--space-3) var(--space-2);
  border: 1px solid var(--color-outline);
  border-radius: var(--radius-xl);
  background: var(--color-surface);
}
.assistant-composer:has(.assistant-input:focus) { outline: 2px solid var(--color-primary); outline-offset: -1px; }
.assistant-input {
  resize: none;
  min-height: 44px;
  max-height: 160px;
  padding: 12px 14px 4px;
  border: 0;
  outline: 0;
  background: none;
  color: var(--color-on-surface);
  font: inherit;
  font-size: var(--md-sys-typescale-body-medium-size);
  line-height: 1.4;
}
.assistant-input::placeholder { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.assistant-composer__bar {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 0 6px 6px;
}
.assistant-send {
  margin-inline-start: auto;
  width: 40px; height: 40px; flex: none;
  border: none; border-radius: 50%;
  background: var(--color-primary);
  color: var(--color-on-primary);
  cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
[dir="rtl"] .assistant-send .material-symbols-outlined { transform: scaleX(-1); }
.assistant-panel.is-busy .assistant-send { background: var(--color-surface-container-high); color: var(--color-on-surface); }
/* Attach and mic sit under the input; 40px targets like the send button
   (min-*: 0 undoes .icon-btn's 48px floor). */
.assistant-tool { width: 40px; height: 40px; min-width: 0; min-height: 0; flex: none; color: var(--color-on-surface-var); }
.assistant-tool:disabled { opacity: .4; cursor: default; }
.assistant-tool.is-recording {
  background: var(--color-error);
  color: var(--color-on-error);
  border-radius: 50%;
}
.assistant-panel.is-recording .assistant-input,
.assistant-panel.is-recording .assistant-send,
.assistant-panel.is-recording [data-act="attach"],
.assistant-panel.is-recording .assistant-voice-lang { opacity: .4; pointer-events: none; }
/* The language the mic listens for (not the screen's language). */
.assistant-voice-lang {
  flex: none;
  min-width: 36px; height: 28px; padding: 0 var(--space-2);
  border: 1px solid var(--color-outline-variant); border-radius: var(--radius-pill);
  background: none; color: var(--color-on-surface-var);
  font: inherit; font-size: var(--md-sys-typescale-label-medium-size); font-weight: 600;
  cursor: pointer;
}
.assistant-voice-lang:hover { background: var(--color-surface-container-high); color: var(--color-on-surface); }
.assistant-voice-lang:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
/* Files waiting to go with the next message, and the ones a sent message carried. */
.assistant-files {
  display: flex; flex-wrap: wrap; gap: 6px;
  padding: var(--space-2) var(--space-2) 0;
}
.assistant-file-chip {
  display: inline-flex; align-items: center; gap: 4px;
  max-width: 100%;
  padding: 2px 4px 2px 8px;
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-pill);
  background: var(--color-surface);
  color: var(--color-on-surface);
  font-size: var(--md-sys-typescale-body-small-size);
}
.assistant-file-chip .material-symbols-outlined { font-size: 16px; color: var(--color-on-surface-var); }
.assistant-file-chip__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 180px; }
.assistant-file-chip__x {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px;
  border: none; border-radius: 50%;
  background: none; color: inherit; cursor: pointer;
}
.assistant-file-chip__x:hover { background: var(--color-surface-container); }
.assistant-msg__files { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 4px; }
.assistant-msg--user .assistant-file-chip { padding-inline-end: 8px; }
/* Under a reply served from saved answers. */
.assistant-cached {
  display: flex; align-items: center; gap: 4px;
  margin: -4px 0 4px;
  font-size: var(--md-sys-typescale-label-small-size); color: var(--color-on-surface-var);
}
.assistant-cached .material-symbols-outlined { font-size: 14px; }
.assistant-cached__refresh {
  border: none; background: none; padding: 4px 6px;
  color: var(--color-primary); font: inherit; font-weight: 600; cursor: pointer;
  border-radius: var(--radius-s);
}
.assistant-cached__refresh:hover { background: var(--color-surface-container); }
/* 👍/👎 under a turn's last reply, and the "what went wrong" box after a 👎. */
.assistant-rate { display: flex; gap: 2px; margin: -4px 0 4px; }
.assistant-rate__btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; padding: 0;
  border: none; background: none; border-radius: var(--radius-pill);
  color: var(--color-on-surface-var); cursor: pointer;
}
.assistant-rate__btn[data-rate="-1"] svg { transform: rotate(180deg); }
.assistant-rate__btn:hover { background: var(--color-surface-container); color: var(--color-on-surface); }
.assistant-rate__btn[aria-pressed="true"] { color: var(--color-primary); background: var(--color-primary-container); }
.assistant-rate__btn[data-rate="-1"][aria-pressed="true"] { color: var(--color-error); background: var(--color-error-container); }
.assistant-why {
  display: flex; flex-direction: column; gap: 8px;
  margin: 0 0 8px; padding: var(--space-3);
  border: 1px solid var(--color-outline-variant); border-radius: var(--radius-m);
  background: var(--color-surface-container-low);
}
.assistant-why__q { margin: 0; font-size: var(--md-sys-typescale-body-small-size); font-weight: 600; }
.assistant-why__chips { display: flex; flex-wrap: wrap; gap: 6px; }
.assistant-why__chips .assistant-chip { min-height: 32px; padding: 4px 12px; }
.assistant-why__chips .assistant-chip[aria-pressed="true"] {
  border-color: var(--color-primary); background: var(--color-primary-container); color: var(--color-on-primary-container);
}
.assistant-why__comment {
  width: 100%; box-sizing: border-box; resize: vertical;
  padding: 8px 10px; font: inherit; font-size: var(--md-sys-typescale-body-dense-size);
  border: 1px solid var(--color-outline-variant); border-radius: var(--radius-s);
  background: var(--color-surface); color: var(--color-on-surface);
}
.assistant-why__btns { display: flex; gap: 8px; }
.assistant-why__team { display: flex; align-items: center; gap: 6px; font-size: var(--md-sys-typescale-body-small-size); }
/* An answer the check still doubts: the user may send it to the Edara team. */
.assistant-escalate {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  margin: 0 0 6px; padding: 6px 10px;
  border-radius: var(--radius-m);
  background: var(--color-tertiary-container);
  color: var(--color-on-tertiary-container);
  font-size: var(--md-sys-typescale-body-small-size);
}
/* The Edara team's answer to an escalated question. */
.assistant-msg--team {
  align-self: stretch;
  padding: 10px 14px;
  border-radius: var(--radius-l);
  border-inline-start: 3px solid var(--color-primary);
  background: var(--color-primary-container);
  color: var(--color-on-primary-container);
}
.assistant-msg__from { margin: 0 0 4px; font-weight: 600; font-size: var(--md-sys-typescale-label-small-size); }
#assistantBtn.has-team-answer { position: relative; }
/* ::before — .icon-btn's ::after is its hover state layer. */
#assistantBtn.has-team-answer::before {
  content: ""; position: absolute; top: 6px; inset-inline-end: 6px; z-index: 1;
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--color-error); box-shadow: 0 0 0 2px var(--color-surface);
}
.assistant-foot {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 0 12px;
  text-align: center;
  padding: 0 var(--space-3) var(--space-2);
  padding-bottom: max(var(--space-2), env(safe-area-inset-bottom, 0));
  font-size: var(--md-sys-typescale-label-small-size); color: var(--color-on-surface-var);
}
/* Phones: a full-screen sheet over the page, sized to the visible viewport
   so the composer stays above the on-screen keyboard. */
@media (max-width: 600px) {
  .assistant-panel {
    top: 0;
    width: 100vw;
    height: var(--assistant-vh, 100dvh);
    bottom: auto;
    border-inline-start: none;
  }
  /* iOS zooms the page on focus into anything under 16px. */
  .assistant-input { font-size: var(--md-sys-typescale-body-large-size); }
  .assistant-composer { margin-inline: var(--space-2); }
  .assistant-expand, .assistant-collapse { display: none; }
}

/* The chat (log → foot) is one element, moved between the panel and the
   #assistant page; it fills whichever host holds it. */
.assistant-chat { flex: 1; min-height: 0; display: flex; flex-direction: column; position: relative; }
/* History, in the panel: it takes the chat's place until a chat is picked. */
.assistant-panel__history { display: none; }
.assistant-panel.is-history .assistant-panel__history { display: flex; flex: 1; min-height: 0; }
.assistant-panel.is-history .assistant-chat { display: none; }
.assistant-panel.is-history [data-act="history"] { color: var(--color-primary); }

/* Wide screens: the open panel docks; the page narrows beside it, in one
   step (animating the padding would lay out the whole shell every frame).
   The width must match DOCK_MEDIA in views/_assistant.js. */
@media (min-width: 1280px) {
  html.assistant-docked .layout { padding-inline-end: var(--assistant-w); }
}

/* min-width: 0 — a flex item's default floor is its content, and a long
   one-line title would push the history past its column. */
.assistant-hist { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; }
.assistant-hist__top {
  display: flex; align-items: center; gap: var(--space-1);
  padding: var(--space-2) var(--space-3);
}
/* .search-bar, on the lowest surface so it shows on the page's history column. */
.assistant-hist__search { flex: 1; background: var(--color-surface-container-lowest); }
/* What the assistant remembers: a fold above the chat list. */
.assistant-memory { margin: 0 var(--space-3) var(--space-2); font-size: var(--md-sys-typescale-body-small-size); }
.assistant-memory summary {
  cursor: pointer; padding: 6px var(--space-1);
  font-weight: 600; color: var(--color-on-surface-var);
  border-radius: var(--radius-s);
}
.assistant-memory summary:hover { background: var(--color-surface-container); }
.assistant-memory__hint { margin: 4px var(--space-1); color: var(--color-on-surface-var); }
.assistant-memory__list { max-height: 30vh; overflow-y: auto; }
.assistant-memory__item {
  display: flex; align-items: center; gap: var(--space-2);
  padding: 4px var(--space-1); border-bottom: 1px solid var(--color-outline-variant);
}
.assistant-memory__item > span:first-child { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.assistant-memory__tag {
  flex: none; padding: 2px 8px; border-radius: var(--radius-pill);
  background: var(--color-secondary-container); color: var(--color-on-secondary-container);
}
.assistant-hist__list {
  flex: 1; overflow-y: auto; overscroll-behavior: contain;
  padding: 0 var(--space-2) var(--space-3);
}
.assistant-hist__group {
  margin: var(--space-3) var(--space-2) 4px;
  font-size: var(--md-sys-typescale-body-small-size); font-weight: 600; color: var(--color-on-surface-var);
}
.assistant-hist__item {
  display: flex; align-items: center;
  border-radius: var(--radius-m);
}
.assistant-hist__item:hover { background: var(--color-surface-container); }
.assistant-hist__item.is-current { background: var(--color-secondary-container); color: var(--color-on-secondary-container); }
.assistant-hist__open {
  flex: 1; min-width: 0; min-height: 44px;
  display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 1px;
  padding: 6px var(--space-2);
  border: 0; background: none; color: inherit; font: inherit; text-align: start; cursor: pointer;
  border-radius: inherit;
}
.assistant-hist__title {
  max-width: 100%; font-size: var(--md-sys-typescale-body-medium-size);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.assistant-hist__when { font-size: var(--md-sys-typescale-body-small-size); color: var(--color-on-surface-var); }
.assistant-hist__del { opacity: 0; color: var(--color-on-surface-var); }
.assistant-hist__item:hover .assistant-hist__del,
.assistant-hist__item:focus-within .assistant-hist__del { opacity: 1; }
@media (hover: none) { .assistant-hist__del { opacity: 1; } }
.assistant-hist__more { display: block; margin: var(--space-2) auto 0; }
.assistant-hist__empty {
  margin: var(--space-6) var(--space-4); text-align: center;
  font-size: var(--md-sys-typescale-body-dense-size); color: var(--color-on-surface-var);
}

/* #assistant: history beside a wide chat. */
/* Zero padding through the view's own variables, so the phone rule still
   clears the bottom tab bar. */
.view:has(> .assistant-page) { --view-pad-block: 0px; --view-pad-inline: 0px; overflow: hidden; display: flex; }
.assistant-page { flex: 1; min-width: 0; display: grid; grid-template-columns: 300px 1fr; }
.assistant-page__side {
  display: flex; flex-direction: column; min-width: 0; min-height: 0;
  border-inline-end: 1px solid var(--color-outline-variant);
  background: var(--color-surface-container-low);
}
.assistant-page__side-head {
  display: flex; align-items: center; gap: var(--space-2);
  padding: var(--space-2) var(--space-2) 0 var(--space-4);
}
.assistant-page__title {
  flex: 1; min-width: 0; margin: 0; font-size: var(--md-sys-typescale-body-large-size); font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.assistant-page__history { flex: 1; min-height: 0; display: flex; }
.assistant-page .assistant-hist__back { display: none; }
.assistant-page__main { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
/* Collapse and Close at the main column's top end. History, New chat and the
   title live in the side column here; on narrow screens the bar is the header. */
.assistant-page__bar {
  display: flex; align-items: center; justify-content: flex-end; gap: var(--space-1);
  padding: var(--space-1) var(--space-2) 0;
}
.assistant-page__bar-title { flex: 1; font-weight: 600; }
@media (min-width: 901px) { .assistant-page__narrow { display: none; } }
/* Readable line length; the composer lines up with the messages. */
.assistant-page__chat { flex: 1; min-height: 0; display: flex; justify-content: center; }
.assistant-page__chat .assistant-chat { width: 100%; max-width: 880px; }
.assistant-page__chat .assistant-msg--user { max-width: 75%; }
@media (max-width: 900px) {
  .assistant-page { grid-template-columns: 1fr; }
  .assistant-page__side { display: none; border: 0; }
  .assistant-page.is-history .assistant-page__side { display: flex; }
  .assistant-page.is-history .assistant-page__main { display: none; }
  .assistant-page .assistant-hist__back { display: inline-flex; }
  .assistant-page__bar {
    padding-bottom: var(--space-1);
    border-bottom: 1px solid var(--color-outline-variant);
  }
}

.asst-settings__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--space-3);
  margin-top: var(--space-4);
}
.asst-lessons { margin-top: var(--space-4); }
.asst-lessons__add { display: flex; gap: var(--space-2); margin-bottom: var(--space-3); }
.asst-lessons__add input { flex: 1; min-width: 0; }
.asst-lessons__row {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2);
  padding: var(--space-2) 0; border-top: 1px solid var(--color-outline-variant);
}
.asst-lessons__row.is-archived .asst-lessons__text > span:first-child { color: var(--color-on-surface-var); text-decoration: line-through; }
.asst-lessons__text { flex: 1 1 260px; min-width: 0; display: flex; flex-direction: column; gap: 2px; overflow-wrap: anywhere; }
.asst-lessons__btns { display: flex; align-items: center; gap: 4px; }

/* ═══════════════════════════════════════════════════════════════════════════
   ICON SIZES
   ═══════════════════════════════════════════════════════════════════════════
   MD3 icons are 24px by default and 18/20px inside dense controls. These
   replace the per-span inline `style="font-size:…px"` the views carried.
   Two classes of specificity and last in the file, so a size set here wins
   over a component's own `.x .material-symbols-outlined` rule, as the inline
   style did. */
.material-symbols-outlined.icon-14 { font-size: 14px; }
.material-symbols-outlined.icon-16 { font-size: 16px; }
.material-symbols-outlined.icon-18 { font-size: 18px; }
.material-symbols-outlined.icon-20 { font-size: 20px; }
.material-symbols-outlined.icon-24 { font-size: 24px; }

/* ── Settings → Edara: Synchronizations, Linking, Sync errors ─────────────── */
.edara-tab__intro { margin: 0 0 var(--space-3); max-width: 72ch; }
.edara-card {
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-l);
  padding: var(--space-3);
  margin-bottom: var(--space-3);
  background: var(--color-surface-container-lowest);
  min-width: 0;
}
.edara-card__title {
  margin: 0 0 var(--space-2);
  font-size: var(--md-sys-typescale-title-medium-size);
  font-weight: var(--md-sys-typescale-title-medium-weight);
}
.edara-card__actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-2); }
.edara-rules { list-style: none; margin: 0; padding: 0; }
.edara-rule {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2);
  padding: var(--space-2) 0;
  border-top: 1px solid var(--color-outline-variant);
}
.edara-rule:first-child { border-top: none; }
.edara-rule > input { width: auto; flex: none; }
.edara-rule__text { flex: 1 1 16rem; min-width: 0; cursor: pointer; }
.edara-rule__code { color: var(--color-on-surface-var); margin-inline-end: var(--space-1); font-variant-numeric: tabular-nums; }
.edara-rule__note { display: block; }
.edara-rule--paused .edara-rule__text { opacity: 0.6; }
.edara-rule__state { flex: none; }
.edara-entity-chips { margin-bottom: var(--space-3); }
.edara-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); gap: var(--space-2); margin-bottom: var(--space-3); }
.edara-stat {
  display: flex; flex-direction: column; gap: var(--space-1);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-m);
}
.edara-stat__value { font-size: var(--md-sys-typescale-headline-small-size); font-variant-numeric: tabular-nums; }
.edara-stat--warn { border-color: var(--color-warning); }
.edara-form { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: var(--space-3); align-items: end; }
.edara-form .form-group { margin: 0; }
.edara-form__triggers { border: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-1); }
.edara-form__triggers legend { padding: 0; margin-bottom: var(--space-1); }
.edara-form .edara-check { display: flex; align-items: center; gap: var(--space-2); }
.edara-check input { width: auto; }
.edara-form .edara-card__actions { grid-column: 1 / -1; margin: 0; }
.edara-search { display: flex; gap: var(--space-2); margin-bottom: var(--space-2); max-width: 28rem; }
.edara-search .form-group { flex: 1; min-width: 0; margin: 0; }
.edara-search .btn { align-self: center; }
.edara-nowrap { white-space: nowrap; }
.edara-review { list-style: none; margin: 0; padding: 0; }
.edara-review__item { padding: var(--space-2) 0; border-top: 1px solid var(--color-outline-variant); }
.edara-review__item:first-child { border-top: none; }
.edara-review__head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.edara-review__candidates { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-2); }
.edara-errors__bar { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--space-2); margin-bottom: var(--space-2); }
.edara-errors__bar .edara-search { flex: 1 1 16rem; margin: 0; }
.edara-errors__stuck { color: var(--color-warning-text); }
.edara-errors { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.edara-error {
  border: 1px solid var(--color-outline-variant);
  border-inline-start: 4px solid var(--color-error);
  border-radius: var(--radius-m);
  padding: var(--space-2) var(--space-3);
  min-width: 0;
}
.edara-error--repeat { border-inline-start-color: var(--color-warning); }
.edara-error__head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.edara-error__head input { width: auto; }
.edara-error__msg { display: flex; align-items: flex-start; gap: var(--space-2); margin: var(--space-2) 0; }
.edara-error pre, .edara-attempts pre {
  flex: 1; min-width: 0; margin: 0;
  white-space: pre-wrap; overflow-wrap: anywhere;
  font-family: var(--font-mono); font-size: var(--md-sys-typescale-body-small-size);
  background: var(--color-surface-container-low);
  color: var(--color-on-surface);
  border-radius: var(--radius-s);
  padding: var(--space-2);
}
.edara-error details summary { cursor: pointer; color: var(--color-primary); }
.edara-attempts { margin: var(--space-2) 0 0; padding-inline-start: var(--space-4); display: flex; flex-direction: column; gap: var(--space-2); }
.edara-exchange { margin-top: var(--space-1); }
.edara-exchange code { font-size: var(--md-sys-typescale-body-small-size); overflow-wrap: anywhere; }

/* A won deal's scene (views/_celebrations.js). No scrim and no focus trap: the page behind stays usable. */
.celebration-scene {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(560px, calc(100vw - 32px));
  height: auto;
  aspect-ratio: 16 / 9;
  border-radius: var(--md-sys-shape-corner-extra-large);
  box-shadow: var(--md-sys-elevation-5);
  z-index: 9999;
  cursor: pointer;
}


/* Interface preferences (views/_interfaceModal.js). Outlined cards hold each
   choice with its preview. Wider than a basic dialog: the previews sit side by side. */
.interface-prefs-modal.modal--wide { width: min(1000px, 96vw); }
.interface-prefs { display: flex; flex-direction: column; gap: var(--space-4); }
.interface-prefs__group { border: 0; margin: 0; padding: 0; min-width: 0; }
.interface-prefs__group legend {
  padding: 0; margin-bottom: var(--space-2);
  font-size: var(--md-sys-typescale-title-small-size); font-weight: 600; color: var(--color-on-surface);
}

.ip-motions { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); }
.ip-motion {
  display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-3);
  border: 1px solid var(--color-outline-variant); border-radius: var(--md-sys-shape-corner-medium);
  background: var(--color-surface-container-lowest); cursor: pointer;
}
.ip-motion:has(input:checked) { border-color: var(--color-primary); box-shadow: inset 0 0 0 1px var(--color-primary); }
.ip-motion__head { display: flex; align-items: flex-start; gap: var(--space-2); }
.ip-motion__head input { flex-shrink: 0; margin: 2px 0 0; }
.ip-motion__text { display: flex; flex-direction: column; min-width: 0; }
.ip-motion__text b { color: var(--color-on-surface); font-size: var(--md-sys-typescale-body-medium-size); }

.ip-demo {
  display: flex; height: 150px; overflow: hidden; contain: paint;
  border-radius: var(--md-sys-shape-corner-small); background: var(--color-surface-container-low);
}
.ip-demo i { display: block; border-radius: var(--md-sys-shape-corner-extra-small); background: var(--color-surface-container-highest); }
.ip-demo__rail {
  flex: 0 0 34px; display: flex; flex-direction: column; gap: 6px; padding: 10px 6px;
  background: var(--color-surface-container);
}
.ip-demo__rail i { height: 10px; }
.ip-demo[data-at="0"] .ip-demo__rail i:first-child,
.ip-demo[data-at="1"] .ip-demo__rail i:last-child { background: var(--color-primary); }
.ip-demo__page { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; padding: 10px; }
.ip-demo .ip-demo__title { flex: none; width: 45%; height: 10px; background: var(--color-outline-variant); }
.ip-demo__tiles { flex: none; display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.ip-demo__tiles i { height: 28px; }
.ip-demo .ip-demo__chart {
  flex: 1; min-height: 0; display: flex; align-items: flex-end; gap: 8px; padding: 8px 10px 0;
  background: var(--color-surface-container-high);
}
.ip-demo .ip-demo__bar { flex: 1; border-radius: var(--md-sys-shape-corner-extra-small) var(--md-sys-shape-corner-extra-small) 0 0; background: var(--color-primary); }
.ip-demo__row { flex: 1; min-height: 0; }

/* Page animations are all it holds, and a phone has none to choose. */
@media (max-width: 767px) {
  #userMenuInterface { display: none; }
}


/* Custom views (views/_views.js): the picker on every table, and its editor. */
.vp-host { display: flex; align-items: center; gap: var(--space-2); flex-shrink: 0; }
.vp-pill {
  display: inline-flex; align-items: stretch; min-height: 36px; max-width: 200px;
  border: 1px solid var(--color-outline-variant); border-radius: var(--md-sys-shape-corner-small);
  background: var(--color-surface-container-lowest);
}
.vp-pill.is-on { border-color: var(--color-primary); background: var(--md-sys-color-secondary-container); }
.vp-pill__open, .vp-pill__btn {
  display: inline-flex; align-items: center; gap: var(--space-1); border: 0; background: none; cursor: pointer;
  color: var(--color-on-surface); font: inherit; font-size: var(--md-sys-typescale-body-small-size); font-weight: 600;
}
.vp-pill__open { padding-inline: var(--space-2) var(--space-1); min-width: 0; }
.vp-pill__btn { padding-inline: var(--space-1); border-inline-start: 1px solid var(--color-outline-variant); }
.vp-pill__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vp-pop {
  position: fixed; z-index: 250; display: flex; flex-direction: column; max-height: min(460px, 75vh);
  border-radius: var(--md-sys-shape-corner-medium); background: var(--md-sys-color-surface-container-high);
  box-shadow: var(--md-sys-elevation-3); padding-block-start: var(--space-3);
}
.vp-pop__search { margin-inline: var(--space-3); }
.vp-tabs { display: flex; margin-block-start: var(--space-2); border-bottom: 1px solid var(--color-outline-variant); }
.vp-tab {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 2px; padding-block: var(--space-2);
  border: 0; border-bottom: 2px solid transparent; background: none; cursor: pointer; color: var(--color-on-surface-var);
  font: inherit; font-size: var(--md-sys-typescale-label-medium-size);
}
.vp-tab[aria-selected="true"], .vp-tab.active { color: var(--color-primary); border-bottom-color: var(--color-primary); }
.vp-list { flex: 1; min-height: 120px; overflow-y: auto; padding-block: var(--space-1); }
.vp-group { padding: var(--space-2) var(--space-3) var(--space-1); font-size: var(--md-sys-typescale-label-small-size); font-weight: 600; color: var(--color-on-surface-var); }
.vp-row { display: flex; align-items: center; padding-inline-end: var(--space-1); }
.vp-row:hover { background: var(--color-surface-container-highest); }
.vp-row.is-on { background: var(--md-sys-color-secondary-container); }
.vp-row__open {
  flex: 1; min-width: 0; min-height: 48px; display: flex; align-items: center; gap: var(--space-2);
  padding-inline: var(--space-3) var(--space-1); border: 0; background: none; cursor: pointer; text-align: start;
  font: inherit; font-size: var(--md-sys-typescale-body-medium-size); color: var(--color-on-surface);
}
.vp-row__lead { width: 18px; flex-shrink: 0; color: var(--color-on-surface-var); }
.vp-row__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vp-row__btn {
  width: 36px; height: 36px; display: grid; place-items: center; border: 0; border-radius: 50%;
  background: none; cursor: pointer; color: var(--color-on-surface-var);
}
.vp-row__btn:hover { background: var(--color-surface-container-high); }
.vp-row__btn.is-on { color: var(--color-primary); }
.vp-empty { padding: var(--space-4) var(--space-3); text-align: center; }
.vp-pop__add {
  display: flex; align-items: center; gap: var(--space-2); min-height: 48px; padding-inline: var(--space-3);
  border: 0; border-top: 1px solid var(--color-outline-variant); background: none; cursor: pointer;
  color: var(--color-primary); font: inherit; font-size: var(--md-sys-typescale-body-medium-size); font-weight: 600;
}

.view-dialog-scrim {
  position: fixed; inset: 0; z-index: 240; display: grid; place-items: center; padding: var(--space-4);
  background: color-mix(in srgb, var(--md-sys-color-scrim) 32%, transparent);
}
.view-dialog-scrim[hidden] { display: none; }
.view-sheet {
  width: min(680px, 100%); max-height: 90vh; display: flex; flex-direction: column; overflow: hidden;
  border-radius: var(--md-sys-shape-corner-extra-large); background: var(--md-sys-color-surface-container-high);
  box-shadow: var(--md-sys-elevation-3);
}
.view-preview-bar {
  position: fixed; z-index: 240; inset-block-end: var(--space-5); inset-inline-start: 50%; transform: translateX(-50%);
  display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-3) var(--space-2) var(--space-4);
  border-radius: var(--md-sys-shape-corner-small); box-shadow: var(--md-sys-elevation-3);
  background: var(--md-sys-color-inverse-surface); color: var(--md-sys-color-inverse-on-surface);
}
[dir="rtl"] .view-preview-bar { transform: translateX(50%); }
.view-preview-bar .btn { color: var(--md-sys-color-inverse-primary); }
.view-sheet__head { display: flex; align-items: center; justify-content: space-between; padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--color-outline-variant); }
.view-sheet__head h2 { margin: 0; font-size: var(--md-sys-typescale-title-large-size); font-weight: 400; }
.view-sheet__body { flex: 1; overflow-y: auto; padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-4); }
.view-sheet__foot { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-3) var(--space-4); border-top: 1px solid var(--color-outline-variant); }
.vs-group h3 { margin: 0 0 var(--space-1); font-size: var(--md-sys-typescale-title-small-size); font-weight: 600; }
.vs-group > .caption { margin: 0 0 var(--space-2); }
.vs-conds .rb-filters__match { display: none; }
.vs-note { padding: var(--space-2) var(--space-3); border-radius: var(--md-sys-shape-corner-small); background: var(--md-sys-color-surface-container-high); margin: 0; }
.view-sheet select, .view-sheet input[type="text"], .view-sheet input:not([type]), .view-sheet input[type="number"], .view-sheet input[type="date"] {
  width: 100%; min-height: 40px; padding-inline: var(--space-2); box-sizing: border-box;
  border: 1px solid var(--color-outline); border-radius: var(--md-sys-shape-corner-extra-small);
  background: var(--color-surface-container-lowest); color: var(--color-on-surface); font: inherit;
}
.vs-row { display: flex; gap: var(--space-3); }
.vs-row > * { flex: 1; min-width: 0; }
.vs-row--top { align-items: flex-start; }
.vs-col { display: flex; align-items: center; min-height: 40px; }
.vs-col label { flex: 1; display: flex; align-items: center; gap: var(--space-2); cursor: pointer; min-width: 0; font-size: var(--md-sys-typescale-body-medium-size); }
.vs-cols__rest { margin-block-start: var(--space-2); padding-block-start: var(--space-2); border-top: 1px solid var(--color-outline-variant); }
