/* ==========================================================================
   Web3D dashboard design system - Apple HIG (iOS 27 / macOS 27) on the web,
   Hebrew, RTL. One stylesheet, one order: tokens, base, controls, layout,
   components, page-specific, responsive, accessibility. Old token names
   survive as aliases at the end of the token block so untouched code keeps
   working. The dark palette is written twice (an explicit switch and the
   system preference) and the two blocks must stay byte-identical.
   ========================================================================== */

/* ------------------------------------------------------------- 1. fonts -- */

@font-face {
  font-family: "Heebo";
  src: url("/assets/fonts/heebo-variable.ttf") format("truetype");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* ------------------------------------------------------------ 1. tokens -- */

:root {
  color-scheme: light;

  /* Native system fonts supply each platform's glyphs; the local Heebo is the Hebrew fallback (CSP: no external fonts). */
  --font-ui: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Noto Sans Hebrew", sans-serif;
  --font-sans: -apple-system, BlinkMacSystemFont, system-ui, "Segoe UI", Roboto, "Heebo", "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  /* Type ramp, in rem so it follows the reader's default text size (HIG Layout,
     "Be prepared for text-size changes"). Pointer devices take the macOS ramp
     (+2pt for Hebrew, HIG RTL); the touch ramp below keeps iOS' 17px body.
     At the 16px default: body .9375rem = 15px, title 1 1.375rem = 22px,
     footnote .75rem = 12px, caption .6875rem = 11px. Weights 400/500/600. */
  --text-large-title: 600 1.625rem/2rem var(--font-sans);
  --text-title-1: 600 1.375rem/1.625rem var(--font-sans);
  --text-title-2: 600 1.0625rem/1.375rem var(--font-sans);
  --text-title-3: 600 .9375rem/1.25rem var(--font-sans);
  --text-headline: 600 .9375rem/1.25rem var(--font-sans);
  --text-body: 400 .9375rem/1.25rem var(--font-sans);
  --text-callout: 400 .875rem/1.1875rem var(--font-sans);
  --text-subhead: 400 .8125rem/1.125rem var(--font-sans);
  --text-footnote: 400 .75rem/1rem var(--font-sans);
  --text-caption-1: 400 .6875rem/.875rem var(--font-sans);
  --text-caption-2: 400 .6875rem/.8125rem var(--font-sans);
  --text-control: 500 .9375rem/1.25rem var(--font-sans);

  /* spacing, sizes */
  --space-1: 4px;  --space-2: 8px;  --space-3: 12px; --space-4: 16px;
  --space-5: 20px; --space-6: 24px; --space-8: 32px; --space-10: 40px; --space-12: 48px;
  --gutter: 16px;
  --gutter-wide: 24px;
  --content-max: 1280px;
  /* Control chrome tracks the ramp it has to hold: the ramp is in rem, so a
     reader who raises the browser text size grew the label inside a pill that
     never grew, and the text spilled out of it. The rem term does the tracking
     and the px term is the floor, so the touch minimum still holds when the
     reader shrinks the text instead. At the default size both read 44px. */
  --control-h: max(2.75rem, 44px);
  --control-h-sm: max(2.75rem, 44px);
  --row-h: 44px;
  --toolbar-h: 56px;
  --sidebar-w: 232px;
  --sidebar-w-collapsed: 64px;
  --sidebar-row-h: 44px;
  --bottom-nav-h: 58px;
  --menu-row-h: 44px;
  --hdr-h: 52px;

  /* radii (concentric: inner = outer - padding) */
  --radius-xs: 6px;
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 16px;
  --radius-xl: 20px;
  --radius-pill: 999px;
  --radius-control: 8px;
  --r-control: 8px;
  --radius-row: 8px;
  --radius-menu: 14px;
  --radius-sheet: 20px;
  --radius-nav: 34px;
  --radius-nav-item: 30px;
  --island-pad: 6px;
  --thumb-pad: 2px;

  /* elevation */
  --shadow-sm: 0 1px 2px rgba(0,0,0,.04), 0 1px 3px rgba(0,0,0,.06);
  --shadow-md: 0 4px 12px rgba(0,0,0,.08);
  --shadow-lg: 0 12px 32px rgba(0,0,0,.12);
  --shadow-popover: 0 0 0 0.5px rgba(0,0,0,.08), 0 8px 28px rgba(0,0,0,.14);
  --shadow-thumb: 0 1px 3px rgba(0,0,0,.12), 0 0 0 0.5px rgba(0,0,0,.04);
  /* Content cards carry a hairline ring, not a drop: --shadow-sm is for the
     floating layer (menus, sheets, the toast, the segmented thumb) only. */
  --card-shadow: 0 0 0 0.5px var(--glass-rim);
  --card-border: 0 solid transparent;

  --hairline: 0.5px;
  /* Motion: SwiftUI .smooth on pointer devices (no overshoot); the touch ramp
     swaps --spring for .snappy, used by selection thumbs only. */
  --ease: cubic-bezier(.2, .8, .2, 1);
  --spring: cubic-bezier(.2, .8, .2, 1);
  --ease-touch: cubic-bezier(.34, 1.2, .64, 1);
  --duration-fast: 140ms; --duration: 320ms; --duration-slow: 350ms;
  --duration-thumb: 320ms;
  /* The transient layer - menus, popovers, the phone bar's specular - morphs
     in and out over this; the screens (--duration) take longer, the hover
     and state feedback (--duration-fast) less. */
  --duration-transient: 240ms;

  /* backgrounds (grouped set, iOS semantics: the page, a card on it, an inset on the card) */
  --bg: #FFFFFF;
  --bg-grouped: #F2F2F7;
  --bg-grouped-2: #FFFFFF;
  --bg-grouped-3: #F2F2F7;
  --bg-elevated: #FFFFFF;
  --bg-sidebar: #EBEBF0;
  --sidebar-selected: #DCDCE2;

  /* labels */
  --label: #000000;
  --label-secondary: rgba(60,60,67,.78);
  --label-tertiary: rgba(60,60,67,.55);
  --label-quaternary: rgba(60,60,67,.30);
  --placeholder: var(--label-secondary);

  /* fills (controls, never text) */
  --fill: rgba(120,120,128,.20);
  --fill-2: rgba(120,120,128,.16);
  --fill-3: rgba(118,118,128,.12);
  --fill-4: rgba(116,116,128,.08);

  --separator: rgba(60,60,67,.29);
  --separator-opaque: #C6C6C8;
  --separator-strong: rgba(60,60,67,.40);
  /* Dense rules (table rows, list rows) take the quiet hairline; the structural
     edges - the sidebar, the header, a group boundary - keep --separator. */
  --separator-quiet: rgba(60,60,67,.12);
  --hover: var(--fill-4);
  --pressed: var(--fill-3);
  --text: var(--label);
  --text-2: var(--label-secondary);

  /* gray ramp */
  --gray: #8E8E93; --gray-2: #AEAEB2; --gray-3: #C7C7CC; --gray-4: #D1D1D6; --gray-5: #E5E5EA; --gray-6: #F2F2F7;

  /* accent - system blue until brand-theme.js installs the client's colour.
     There is no separate brand token; the client's brand colour IS the accent. */
  --accent: #0066CC;
  --accent-text: #0058B3;
  --accent-fill: #0066CC;
  --accent-hover: #005CB8;
  --accent-pressed: #0052A3;
  --on-accent: #FFFFFF;
  --tint: rgba(0,102,204,.10);
  --tint-strong: rgba(0,102,204,.14);
  --ring: rgba(0,102,204,.40);

  /* semantic (deltas and status only; never decorative) */
  --green: #34C759; --green-text: #177036;
  --red: #FF383C;   --red-text: #C80013;
  --orange: #FF8D28; --orange-text: #A64A00;
  --green-tint: rgba(52,199,89,.12);
  --red-tint: rgba(255,56,60,.12);
  --orange-tint: rgba(255,141,40,.12);
  --yellow: #FFCC00;

  /* charts */
  --chart-1: var(--accent);
  --chart-2: #FF8D28;
  --chart-3: #AF52DE;
  --chart-4: #8E8E93;
  /* The compared period is the only mark inside the plot that carries its own
     meaning, and the marker circles stroke in the card colour, so this grey
     line alone distinguishes it. #AEAEB2 measured 2.21:1 on the card; this is
     3.3:1 in light and 4.9:1 in dark, both over the 3:1 floor. */
  --chart-compare: #8E8E93;
  --chart-grid: rgba(60,60,67,.12);
  --chart-axis-text: var(--label-secondary);
  --segment-selected: var(--bg-elevated);

  /* Liquid Glass (derived: Apple publishes no numbers). Bars .78, menus and
     sheets .88; blur 24px saturate(160%) is written literally where used. */
  --glass-fill: rgba(250,250,252,.78);
  --glass-fill-thick: rgba(250,250,252,.88);
  --glass-fill-edge: rgba(250,250,252,.84);
  --glass-sidebar: rgba(235,235,240,.88);
  --glass-island: rgba(250,250,252,.72);
  --glass-fallback: var(--bg-elevated);
  --glass-highlight: rgba(255,255,255,.55);
  --glass-highlight-weak: rgba(255,255,255,.25);
  /* The specular the phone bar catches for a moment when its selection moves. */
  --glass-highlight-strong: rgba(255,255,255,.95);
  --glass-lowlight: rgba(41,41,55,.10);
  --glass-rim: rgba(0,0,0,.10);
  --glass-hover: rgba(24,29,44,.07);
  --glass-press: rgba(24,29,44,.13);
  --glass-shadow: 0 1px 2px rgba(0,0,0,.04), 0 8px 24px rgba(0,0,0,.08);
  --glass-shadow-thick: 0 0 0 0.5px rgba(0,0,0,.08), 0 12px 40px rgba(0,0,0,.14);
  --glass-edge: rgba(0,0,0,.12);
  --glass-contact: rgba(255,255,255,.35);
  --nav-indicator: rgba(255,255,255,.72);
  --nav-indicator-rim: rgba(0,0,0,.44);
  --status-rim: rgba(0,0,0,.08);

  /* aliases */
  --surface: var(--bg-grouped-2);
  --surface-1: var(--bg-grouped-2);
  --surface-2: var(--bg-grouped-3);
  --surface-3: var(--bg-sidebar);
  --page: var(--bg-grouped);
  --ink-1: var(--label);
  --ink-2: var(--label-secondary);
  --ink-3: var(--label-secondary);
  --grid: var(--chart-grid);
  --baseline: var(--separator);
  --border: var(--separator-opaque);
  --border-control: var(--separator);
  --s1: var(--chart-1);  --s1-wash: var(--tint);
  --s2: var(--chart-2);  --s2-wash: var(--orange-tint);
  --s3: var(--chart-3);  --s3-wash: var(--tint);
  --s4: var(--chart-4);
  --good: var(--green);  --good-ink: var(--green-text);
  --warn: var(--orange); --warn-ink: var(--orange-text);
  --serious: var(--orange); --serious-ink: var(--orange-text);
  --crit: var(--red-text);
  --chip: var(--fill-3);
  --wash: var(--fill-4);
  --shadow: var(--shadow-sm);
  --menu-shadow: var(--shadow-popover);
  --control-fill: var(--fill-3);
  --control-hover: var(--fill-2);
  --control-pressed: var(--fill);
  --action: var(--accent-fill);
  --action-ink: var(--on-accent);
  --r: var(--radius-md);
  --row-alt: var(--bg-grouped);
  --menu-surface: var(--bg-elevated);
  --font: var(--font-sans);
  --dirx: -1;
}

@supports (color: color-mix(in srgb, red, blue)) {
  :root {
    --tint: color-mix(in srgb, var(--accent) 10%, transparent);
    --tint-strong: color-mix(in srgb, var(--accent) 14%, transparent);
    --ring: color-mix(in srgb, var(--accent) 35%, transparent);
  }
}

@media (min-width: 768px) { :root { --gutter: var(--gutter-wide); } }
[dir="ltr"] { --dirx: 1; }

/* Pointer devices: macOS control scale (36px controls, 32px sidebar rows,
   36px compact controls inside rows, 28px minimum hit). */
@media (hover: hover) and (pointer: fine) {
  :root { --control-h: max(2.25rem, 36px); --control-h-sm: max(2.25rem, 36px); --sidebar-row-h: 32px; --menu-row-h: 36px; }
}
/* Touch: the iOS ramp (17px body), 44px controls and a snappy thumb (350ms). */
@media (pointer: coarse) {
  :root {
    --duration-thumb: 350ms;
    --text-large-title: 600 1.75rem/2.125rem var(--font-sans);
    --text-title-1: 600 1.625rem/2rem var(--font-sans);
    --text-title-2: 600 1.25rem/1.5625rem var(--font-sans);
    --text-title-3: 600 1.0625rem/1.375rem var(--font-sans);
    --text-headline: 600 1.0625rem/1.375rem var(--font-sans);
    --text-body: 400 1.0625rem/1.375rem var(--font-sans);
    --text-callout: 400 1rem/1.3125rem var(--font-sans);
    --text-subhead: 400 .9375rem/1.25rem var(--font-sans);
    --text-footnote: 400 .8125rem/1.125rem var(--font-sans);
    --text-caption-1: 400 .75rem/1rem var(--font-sans);
    --text-caption-2: 400 .6875rem/.8125rem var(--font-sans);
    --text-control: 500 1.0625rem/1.375rem var(--font-sans);
    --spring: var(--ease-touch);
  }
}

/* Dark: base #1C1C1E, cards elevated to #2C2C2E, insets #3A3A3C. The block below is
   repeated for the system preference; keep the two byte-identical. */
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #1C1C1E;
  --bg-grouped: #1C1C1E;
  --bg-grouped-2: #2C2C2E;
  --bg-grouped-3: #3A3A3C;
  --bg-elevated: #2C2C2E;
  --bg-sidebar: #121214;
  --sidebar-selected: #2C2C2E;

  --label: #FFFFFF;
  --label-secondary: rgba(235,235,245,.75);
  --label-tertiary: rgba(235,235,245,.45);
  --label-quaternary: rgba(235,235,245,.18);

  --fill: rgba(120,120,128,.36); --fill-2: rgba(120,120,128,.32);
  --fill-3: rgba(118,118,128,.24); --fill-4: rgba(116,116,128,.18);

  --separator: rgba(84,84,88,.60);
  --separator-opaque: #38383A;
  --separator-strong: rgba(84,84,88,.80);
  --separator-quiet: rgba(84,84,88,.30);

  --gray: #8E8E93; --gray-2: #636366; --gray-3: #48484A; --gray-4: #3A3A3C; --gray-5: #2C2C2E; --gray-6: #1C1C1E;

  --accent: #0A84FF;
  --accent-text: #64ACFF;
  --accent-fill: #0071E3;
  --accent-hover: #0A84FF;
  --accent-pressed: #0062C4;
  --on-accent: #FFFFFF;
  --tint: rgba(10,132,255,.16);
  --tint-strong: rgba(10,132,255,.22);
  --ring: rgba(10,132,255,.50);

  --green: #30D158; --green-text: #4AD968;
  --red: #FF4245;   --red-text: #FF7E81;
  --orange: #FF9230; --orange-text: #FF9F42;
  --green-tint: rgba(48,209,88,.16); --red-tint: rgba(255,66,69,.16); --orange-tint: rgba(255,146,48,.16);
  --yellow: #FFD600;

  --chart-2: #FF9230; --chart-3: #BF5AF2; --chart-4: #8E8E93;
  --chart-compare: #98989D;
  --chart-grid: rgba(235,235,245,.10);
  --segment-selected: #636366;

  --shadow-popover: 0 0 0 0.5px rgba(0,0,0,.40), 0 8px 28px rgba(0,0,0,.50);
  --shadow-thumb: 0 1px 3px rgba(0,0,0,.40), 0 0 0 0.5px rgba(255,255,255,.06);
  --card-shadow: none;
  --card-border: var(--hairline) solid var(--separator);

  --status-rim: rgba(0,0,0,.40);
  --glass-fill: rgba(30,30,32,.72);
  --glass-fill-thick: rgba(30,30,32,.82);
  --glass-fill-edge: rgba(30,30,32,.80);
  --glass-sidebar: rgba(18,18,20,.82);
  --glass-island: rgba(30,30,32,.72);
  --glass-highlight: rgba(255,255,255,.14);
  --glass-highlight-weak: rgba(255,255,255,.06);
  --glass-highlight-strong: rgba(255,255,255,.34);
  --glass-lowlight: rgba(0,0,0,.40);
  --glass-rim: rgba(0,0,0,.50);
  --glass-hover: rgba(255,255,255,.10);
  --glass-press: rgba(255,255,255,.17);
  --glass-shadow: 0 1px 2px rgba(0,0,0,.40), 0 8px 24px rgba(0,0,0,.50);
  --glass-shadow-thick: 0 0 0 0.5px rgba(0,0,0,.50), 0 12px 40px rgba(0,0,0,.60);
  --glass-edge: rgba(255,255,255,.12);
  --glass-contact: rgba(255,255,255,.10);
  --nav-indicator: rgba(255,255,255,.12);
  --nav-indicator-rim: rgba(255,255,255,.34);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: #1C1C1E;
    --bg-grouped: #1C1C1E;
    --bg-grouped-2: #2C2C2E;
    --bg-grouped-3: #3A3A3C;
    --bg-elevated: #2C2C2E;
    --bg-sidebar: #121214;
    --sidebar-selected: #2C2C2E;

    --label: #FFFFFF;
    --label-secondary: rgba(235,235,245,.75);
    --label-tertiary: rgba(235,235,245,.45);
    --label-quaternary: rgba(235,235,245,.18);

    --fill: rgba(120,120,128,.36); --fill-2: rgba(120,120,128,.32);
    --fill-3: rgba(118,118,128,.24); --fill-4: rgba(116,116,128,.18);

    --separator: rgba(84,84,88,.60);
    --separator-opaque: #38383A;
    --separator-strong: rgba(84,84,88,.80);
    --separator-quiet: rgba(84,84,88,.30);

    --gray: #8E8E93; --gray-2: #636366; --gray-3: #48484A; --gray-4: #3A3A3C; --gray-5: #2C2C2E; --gray-6: #1C1C1E;

    --accent: #0A84FF;
    --accent-text: #64ACFF;
    --accent-fill: #0071E3;
    --accent-hover: #0A84FF;
    --accent-pressed: #0062C4;
    --on-accent: #FFFFFF;
    --tint: rgba(10,132,255,.16);
    --tint-strong: rgba(10,132,255,.22);
    --ring: rgba(10,132,255,.50);

    --green: #30D158; --green-text: #4AD968;
    --red: #FF4245;   --red-text: #FF7E81;
    --orange: #FF9230; --orange-text: #FF9F42;
    --green-tint: rgba(48,209,88,.16); --red-tint: rgba(255,66,69,.16); --orange-tint: rgba(255,146,48,.16);
    --yellow: #FFD600;

    --chart-2: #FF9230; --chart-3: #BF5AF2; --chart-4: #8E8E93;
    --chart-compare: #98989D;
    --chart-grid: rgba(235,235,245,.10);
    --segment-selected: #636366;

    --shadow-popover: 0 0 0 0.5px rgba(0,0,0,.40), 0 8px 28px rgba(0,0,0,.50);
    --shadow-thumb: 0 1px 3px rgba(0,0,0,.40), 0 0 0 0.5px rgba(255,255,255,.06);
    --card-shadow: none;
    --card-border: var(--hairline) solid var(--separator);

    --status-rim: rgba(0,0,0,.40);
    --glass-fill: rgba(30,30,32,.72);
    --glass-fill-thick: rgba(30,30,32,.82);
    --glass-fill-edge: rgba(30,30,32,.80);
    --glass-sidebar: rgba(18,18,20,.82);
    --glass-island: rgba(30,30,32,.72);
    --glass-highlight: rgba(255,255,255,.14);
    --glass-highlight-weak: rgba(255,255,255,.06);
    --glass-highlight-strong: rgba(255,255,255,.34);
    --glass-lowlight: rgba(0,0,0,.40);
    --glass-rim: rgba(0,0,0,.50);
    --glass-hover: rgba(255,255,255,.10);
    --glass-press: rgba(255,255,255,.17);
    --glass-shadow: 0 1px 2px rgba(0,0,0,.40), 0 8px 24px rgba(0,0,0,.50);
    --glass-shadow-thick: 0 0 0 0.5px rgba(0,0,0,.50), 0 12px 40px rgba(0,0,0,.60);
    --glass-edge: rgba(255,255,255,.12);
    --glass-contact: rgba(255,255,255,.10);
    --nav-indicator: rgba(255,255,255,.12);
    --nav-indicator-rim: rgba(255,255,255,.34);
  }
}

/* -------------------------------------------------------------- 2. base -- */

*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html {
  font-family: var(--font-sans);
  /* HIG Layout, "Be prepared for text-size changes": 100% is the size the
     reader chose in the browser, and the whole ramp below is in rem, so every
     label, number and control scales with it. This is the web's Dynamic Type. */
  font-size: 100%;
  /* The viewport is the one scrollport, and a sticky bar floats over its top
     edge, so the browser is told where the readable area really starts: without
     this it parks a keyboard-focused control under the header and the focus ring
     is never seen (WCAG 2.2 SC 2.4.11, HIG Accessibility). The band is --hdr-h
     at its shortest and 64px with the title and the freshness line on two rows,
     so the reserve is measured from the taller case plus the ring's 4px. */
  scroll-padding-top: calc(var(--hdr-h) + var(--space-4));
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-kerning: normal;
  letter-spacing: normal;
  background: var(--bg-grouped);
}

body {
  background: var(--bg-grouped);
  color: var(--label);
  font: var(--text-body);
  font-optical-sizing: auto;
  min-height: 100dvh;
}
body[dir="rtl"] { direction: rtl; }
html.sheet-open { overflow: hidden; }

h1, h2, h3, h4 { margin: 0; letter-spacing: normal; overflow-wrap: anywhere; }
p { margin: 0; }
a { color: var(--accent-text); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 3px; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; padding: 0; margin: 0; }
button:disabled { cursor: default; }
input, select, textarea { font: inherit; color: var(--label); }
svg { display: inline-block; vertical-align: middle; }
.glyph { flex: none; fill: none; }
[dir="rtl"] .mirror { transform: scaleX(-1); }
.no-flip { transform: none; }

/* One focus ring everywhere: the accent, 2px, 2px out. */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
:where(.btn, .select-trigger, .popup, .segmented > button, .tab, .legend-pill, .dd-row, .select-option, .card-info, .metric-name):focus-visible { border-radius: inherit; }

.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;
}
/* Numbers are tabular wherever they appear. */
.num, .stamp, .select-sub, .metric-number, .metric-value, .metric-row-value, .change-label, .funnel-stage-value, td.num, th.num, .ctable, table.main, .tlist, .dd-date, .radar-number, .formula-preview, .fatigue-values, .metric-caption { font-variant-numeric: tabular-nums; font-feature-settings: "tnum"; }
.muted { color: var(--label-secondary); }
.dim { opacity: .5; pointer-events: none; transition: opacity var(--duration) var(--ease); }
.ltr { direction: ltr; text-align: left; unicode-bidi: isolate; font-variant-numeric: tabular-nums; }
/* One stroke geometry for every drawn symbol (HIG Icons: "match the weights of
   interface icons and adjacent text"). The number is per drawing grid, because
   the viewBox sets the scale: 2 units on a 24 grid at 18px and 1.667 on a 16
   grid at 12px both land on the 1.5px / 1.25px the labels beside them ask for.
   A CSS declaration beats the markup's stroke-width attribute, so the weight is
   decided here once instead of in every inline SVG. */
.ico, .ic { width: 18px; height: 18px; flex: none; stroke-width: 2; }
.glyph { stroke-width: 1.667; }
.glyph > * { stroke-width: inherit; }
.card-info .glyph, .popover-notes .popover-title .glyph { stroke-width: 1.5; }
.spin { animation: rot 1s linear infinite; }
@keyframes rot { to { transform: rotate(360deg); } }

/* Liquid Glass, two layers. The navigation layer blurs: the header once
   content scrolls under it (a hard 1px bottom edge, macOS style), the phone's
   floating tab bar, and the transient surfaces (pop-up menus, popovers, sheets,
   the toast) while they are shown. Everything else is opaque: cards, tiles,
   tables, thumbs, the sidebar, panels - never glass in the content layer,
   never glass on glass. .material carries the fill, specular and rim without
   a blur, so a surface only blurs through the allow-list below. The -webkit-
   prefix always carries literal values (Safari 18 var() bug) and blur is never
   animated. */
.material, .glass {
  background: var(--glass-fill);
  box-shadow: inset 0 1px 0 var(--glass-highlight), inset 0 -1px 0 var(--glass-lowlight), 0 0 0 0.5px var(--glass-rim), var(--glass-shadow);
}

/* ----------------------------------------------------------- 3. buttons -- */

/* Bordered buttons are 8px rounded rectangles at the control size; the one
   primary call to action in a view is a filled capsule. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: var(--control-h); min-height: var(--control-h); padding: 0 14px;
  border: 0; border-radius: var(--radius-sm);
  background: var(--fill-3); color: var(--label);
  font: var(--text-control); white-space: nowrap; text-decoration: none; cursor: pointer;
  user-select: none; -webkit-user-select: none;
  transition: background-color var(--duration-fast) var(--ease), color var(--duration-fast) var(--ease), transform var(--duration-fast) var(--ease);
}
.btn:hover:not(:disabled) { background: var(--fill-2); text-decoration: none; }
.btn:active:not(:disabled) { background: var(--fill); transform: scale(.98); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .4; cursor: default; }

.btn.primary, .btn-primary {
  background: var(--accent-fill); color: var(--on-accent); border-radius: var(--radius-pill); font-weight: 600;
}
.btn.primary:hover:not(:disabled), .btn-primary:hover:not(:disabled) { background: var(--accent-hover); }
.btn.primary:active:not(:disabled), .btn-primary:active:not(:disabled) { background: var(--accent-pressed); }

.btn.gray { background: var(--fill-3); color: var(--label); }
.btn.gray:hover:not(:disabled) { background: var(--fill-2); }

.btn.plain, .text-button, .mini-toggle {
  background: transparent; color: var(--accent-text); padding: 0 10px;
  font-weight: 500; border-radius: var(--radius-sm); text-decoration: none;
}
.btn.plain:hover:not(:disabled), .text-button:hover:not(:disabled), .mini-toggle:hover { background: var(--fill-4); text-decoration: none; }
.btn.plain:active:not(:disabled), .text-button:active:not(:disabled) { background: var(--fill-3); }

.btn.danger, .btn-confirm { background: transparent; color: var(--red-text); }
.btn.danger:hover:not(:disabled), .btn-confirm:hover:not(:disabled) { background: var(--red-tint); }

.btn-sm, .btn.btn-sm { height: var(--control-h); min-height: var(--control-h); padding: 0 12px; font: var(--text-control); }
.btn[aria-expanded="true"] { background: var(--tint); color: var(--accent-text); }

/* The login call to action fills its card at the touch size on every device. */
.btn-primary { display: flex; width: 100%; height: 44px; min-height: 44px; }

.text-button {
  display: inline-flex; align-items: center; min-height: var(--control-h); padding: 0 8px;
  font: var(--text-control); text-align: start; cursor: pointer;
}
.text-button:disabled { opacity: .4; }
.mini-toggle { min-height: var(--control-h); padding: 0 12px; font: var(--text-control); }
/* Inside a table row the compact 36px size the spec allows (44px under a finger, below). */
:where(td, tr, .tlist, .userline) :is(.text-button, .btn-sm, .btn.btn-sm) { height: 36px; min-height: 36px; padding-inline: 8px; }
@media (pointer: coarse) {
  :where(td, tr, .tlist, .userline) :is(.text-button, .btn-sm, .btn.btn-sm) { height: var(--control-h-sm); min-height: var(--control-h-sm); }
}
:where(td, tr, .tlist) .btn-sm { padding-inline: 12px; }

/* Symbol-only bar buttons: a round hit area, no bezel (HIG toolbars). */
.icon-btn, .library-icon-button {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: var(--control-h); height: var(--control-h); min-height: var(--control-h); padding: 0;
  border: 0; border-radius: 50%; background: transparent; color: var(--label); cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease);
}
.icon-btn:hover, .library-icon-button:hover { background: var(--fill-3); }
.icon-btn .btn-label { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* ---------------------------------------------------- 3. segmented, chips -- */

/* Equal segments sized from the widest label (1fr columns on an indefinite
   container), never from a magic min-width. Each button reserves its bold
   width up front so the track never jitters when the selection moves, and an
   opaque elevated thumb (select-menu.js) slides between the segments. */
.segmented {
  position: relative; display: inline-grid; grid-auto-flow: column; grid-auto-columns: 1fr; isolation: isolate;
  align-items: stretch; height: var(--control-h); max-width: 100%; padding: var(--thumb-pad);
  background: var(--fill-3); border-radius: var(--radius-pill);
}
.segmented > button {
  position: relative; z-index: 2; pointer-events: auto; display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-width: 0; padding: 0 14px;
  font: var(--text-control); color: var(--label-secondary); white-space: nowrap;
  border-radius: var(--radius-pill); background: transparent;
  transition: color var(--duration-fast) var(--ease), background-color var(--duration-fast) var(--ease), box-shadow var(--duration-fast) var(--ease);
}
.segmented > button:hover { color: var(--label); }
/* Reserve the bold width (a zero-height copy of the label at 600) so the track never jitters when selection moves. */
.segmented > button::after { content: attr(data-label); font-weight: 600; visibility: hidden; height: 0; overflow: hidden; pointer-events: none; }
/* Equal segments are sized from the widest label, so a reader who raises the
   browser's text size reaches a width where the longest label no longer fits
   its own segment. It then shortens with an ellipsis, as a segment's title
   does on the platform, instead of spilling over the track's rounded end.
   The clip belongs to the label's own span and never to the button: the
   button carries the segment's hit zone as the absolutely positioned ::before
   below, and every way of clipping a box - overflow, mask, clip-path alike -
   takes that zone with it. Measured in Chrome on both: elementFromPoint over
   the 2px of track padding above a clipped segment answers the track.
   The ellipsis lands at the end of the label's own writing direction, which
   `plaintext` reads from its first letter: without it a Latin name in this
   right-to-left page is cut at the head and "Google Ads" came back as
   "...le Ads" instead of "Googl...". */
.segmented > button > .segment-label { max-width: 100%; overflow: hidden; text-overflow: ellipsis; unicode-bidi: plaintext; }
/* The 2px track padding answers to the segment under it (UISegmentedControl: the whole 44px control is the target), the thumb keeps its inset. */
.segmented > button::before, .tab::before { content: ""; position: absolute; inset-block: calc(-1 * var(--thumb-pad)); inset-inline: 0; }
.segmented > button:first-of-type::before, .tab:first-of-type::before { inset-inline-start: calc(-1 * var(--thumb-pad)); }
.segmented > button:last-of-type::before, .tab:last-of-type::before { inset-inline-end: calc(-1 * var(--thumb-pad)); }
.segmented > button[aria-checked="true"], .segmented > button[aria-pressed="true"] {
  background: var(--segment-selected); font-weight: 600; color: var(--label); box-shadow: var(--shadow-thumb);
}
/* When the thumb is drawn, the checked button is just text on top of it. */
.segmented.has-thumb > button[aria-checked="true"], .segmented.has-thumb > button[aria-pressed="true"] { background: transparent; box-shadow: none; }
.segmented.has-thumb > button[aria-checked="true"], .segmented.has-thumb > button[aria-pressed="true"],
.segmented.has-thumb > button[aria-selected="true"], .segmented.has-thumb > button.is-selected { color: var(--label); font-weight: 600; }
/* The thumb is an opaque elevated surface: a fill on a fill, never glass in a track. */
.segmented-thumb, .tabs-thumb {
  position: absolute; z-index: 0; top: var(--thumb-pad); bottom: var(--thumb-pad); left: 0;
  width: var(--thumb-w, 0px); transform: translateX(var(--thumb-x, 0px));
  border-radius: var(--radius-pill);
  background: var(--segment-selected);
  box-shadow: var(--shadow-thumb);
  pointer-events: none;
  transform-origin: center center;
  scale: var(--pill-sx, 1) var(--pill-sy, 1);
  transition: transform var(--duration-thumb) var(--spring), width var(--duration-thumb) var(--spring), scale var(--duration-thumb) var(--spring);
}
.segmented:not(.has-thumb) > .segmented-thumb, .tabs:not(.has-thumb) > .tabs-thumb { display: none; }
/* ---- the pill answers the hand (app.js, the scrub gesture) ----
   Pressing the selected segment lifts the thumb a touch even with no script
   behind it; while a drag has it, app.js writes the same two properties frame
   by frame - a uniform lift plus a stretch along the drag that grows with the
   speed of the pointer and thins the pill across it. Only `scale` moves, and
   the settle is --spring: no overshoot on a pointer, the touch ramp's softer
   landing on a finger. Reduce Motion pins scale to 1 further down, so a
   reader who asked for stillness gets it whatever the script writes. */
.segmented.has-thumb:has(> button[aria-checked="true"]:active) > .segmented-thumb,
.tabs.has-thumb:has(> .tab.on:active) > .tabs-thumb { --pill-sx: 1.04; --pill-sy: 1.04; }
/* The glass catches the light harder under the hand: one specular line along
   the pill's top edge, as one layer's opacity and nothing else. */
.segmented-thumb::after, .tabs-thumb::after, .bottom-nav-indicator::after, .sidebar-indicator::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  box-shadow: inset 0 1px 0 var(--glass-highlight-strong);
  opacity: 0; transition: opacity var(--duration-fast) var(--ease);
}
.segmented.is-pressing > .segmented-thumb::after, .tabs.is-pressing > .tabs-thumb::after,
.sidebar-nav.is-pressing > .sidebar-indicator::after, .bottom-nav-inner.is-pressing > .bottom-nav-indicator::after { opacity: 1; }
/* Under the pointer the pill IS the animation, so it carries no transition of
   its own along the track; its length is set each frame and never animated. */
.segmented.is-dragging > .segmented-thumb, .tabs.is-dragging > .tabs-thumb {
  transition: transform 0s, width 0s, scale var(--duration-fast) var(--ease);
}
.bottom-nav-inner.is-dragging > .bottom-nav-indicator {
  transition: transform 0s, width 0s, opacity var(--duration-fast) var(--ease), scale var(--duration-fast) var(--ease);
}
.sidebar-nav.is-dragging > .sidebar-indicator {
  transition: transform 0s, opacity var(--duration-fast) var(--ease), scale var(--duration-fast) var(--ease);
}
.segmented.is-dragging, .tabs.is-dragging, .sidebar-nav.is-dragging, .bottom-nav-inner.is-dragging { user-select: none; -webkit-user-select: none; cursor: grabbing; }
.segmented.is-dragging > button, .tabs.is-dragging > .tab, .sidebar-nav.is-dragging > .sidebar-item, .bottom-nav-inner.is-dragging > .bottom-nav-item { cursor: grabbing; }
/* :active belongs to the item the press landed on until the release, wherever
   the pointer has gone since, so for the whole scrub the reader saw one item
   lifted or filled while the pill travelled to another. The press state comes
   off for the duration of a drag: the pill and .is-drag-target below are what
   say where the selection is. */
.bottom-nav-inner.is-dragging > .bottom-nav-item:active { transform: none; }
.tabs.is-dragging > .tab:active:not(.on),
.segmented.is-dragging > button:active:not([aria-checked="true"]):not([aria-pressed="true"]),
.sidebar-nav.is-dragging > .sidebar-item:active { background: transparent; }
/* The label the pill is over reads as the chosen one while the drag lasts.
   The rail is the exception: its rows are variable-width Hebrew and carry no
   weight change for selection either, so a bolder label there would reflow
   the row under the hand. */
.segmented.is-dragging > button.is-drag-target, .segmented.is-dragging > button[aria-checked="true"],
.segmented.is-dragging > button[aria-selected="true"], .segmented.is-dragging > button.is-selected,
.tabs.is-dragging > .tab.is-drag-target { color: var(--label); font-weight: 600; }
.bottom-nav-inner.is-dragging > .bottom-nav-item.is-drag-target { color: var(--accent-text); }
.sidebar-nav.is-dragging > .sidebar-item.is-drag-target { color: var(--label); }
/* An inactive segment is greyed by a token, never dissolved: at opacity .4 the
   secondary label measured 1.74:1 light and 2.23:1 dark, and this is the one
   control that carries WHY a view is unavailable (the reason is its title and
   its aria-label), so a sighted reader could not see there was anything to
   hover. WCAG 1.4.3 exempts an inactive component from the text ratio, and the
   tertiary label is the step iOS greys a disabled control by. */
.segmented > button:disabled { color: var(--label-tertiary); cursor: default; }
.segmented[aria-disabled="true"] { opacity: .6; }
.select-segmented { display: inline-flex; max-width: 100%; }

/* Chips are 8px rounded rectangles (capsules belong to the primary action and
   the segmented tracks only). */
.chip, .chip-c, .pill, .pf, .src {
  display: inline-flex; align-items: center; gap: 5px;
  height: 24px; padding: 0 10px; border-radius: var(--radius-sm);
  background: var(--fill-4); color: var(--label-secondary);
  font: 500 .75rem/1rem var(--font-sans); white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.chip .glyph, .pill .glyph, .src .glyph { width: 12px; height: 12px; }
.pill.on { color: var(--green-text); background: var(--green-tint); }
.pill.warn { color: var(--orange-text); background: var(--orange-tint); }
.pill.bad { color: var(--red-text); background: var(--red-tint); }
.pill .d { display: none; }
/* A state that changes - a campaign paused, a delta that turned, a source that
   fell, an alert - moves its colour over the feedback duration rather than
   jumping to it. Colour only: nothing here changes size. */
.pill, .status-dot, .change-label, .src, .src i, .alert {
  transition: background-color var(--duration-fast) var(--ease), color var(--duration-fast) var(--ease), border-color var(--duration-fast) var(--ease);
}

/* Status the way App Store Connect and System Settings show it: an 8px dot in
   one semantic colour beside text in the label colour, never a tinted capsule
   per state. Green ready/running, yellow a process in progress, orange needs
   your attention, red rejected/deleted, grey paused, hollow grey unavailable.
   The text is always there, so colour is never the only channel. */
.pill.status { height: auto; padding: 0; gap: 7px; background: transparent; border-radius: 0; color: var(--label); font: var(--text-subhead); }
.status-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--status-color, var(--gray)); box-shadow: inset 0 0 0 0.5px var(--status-rim); font-style: normal; }
.pill.status.on { --status-color: var(--green); }
.pill.status.wait { --status-color: var(--yellow); }
.pill.status.warn { --status-color: var(--orange); }
.pill.status.bad { --status-color: var(--red); }
.pill.status.off { --status-color: var(--gray); color: var(--label-secondary); }
.pill.status.hollow { color: var(--label-secondary); }
.pill.status.hollow .status-dot { background: transparent; box-shadow: inset 0 0 0 1.5px var(--gray); }
/* "דורש טיפול" opens its explanation: a quiet info glyph, a fill on hover, no tint. */
.pill.status[aria-haspopup] { cursor: pointer; border-radius: var(--radius-sm); margin-inline: -8px; padding-inline: 8px; }
.pill.status[aria-haspopup] .glyph { width: 14px; height: 14px; color: var(--label-tertiary); }
.pill.status[aria-haspopup]:hover, .pill.status[aria-haspopup][aria-expanded="true"] { background: var(--fill-4); }
.pill.status[aria-haspopup]:hover .glyph, .pill.status[aria-haspopup][aria-expanded="true"] .glyph { color: var(--accent-text); }
button.pill { cursor: pointer; }
button.pill:hover, button.pill[aria-expanded="true"] { background: var(--fill-3); }

/* Platform: the app mark beside plain text, not a grey capsule. */
table.main .pf { height: auto; padding: 0; gap: 6px; background: transparent; color: var(--label); font: inherit; border-radius: 0; }
.pf-mark { display: inline-block; width: 16px; height: 16px; border-radius: 25%; flex: none; }   /* 36px art with rx 9 -> a quarter at 16px */
.src i { width: 6px; height: 6px; border-radius: 50%; background: var(--label-tertiary); display: inline-block; font-style: normal; }
.src.on i { background: var(--green); }
.src.off i { background: var(--red); }
.src.off { color: var(--label-secondary); }
.src.stale i { background: var(--orange); }
.src.stale { color: var(--label-secondary); }

/* A 44px hit zone around the 24px legend pill, visual size unchanged. */
.legend-pill { position: relative; }
.legend-pill::before { content: ""; position: absolute; inset-inline: 0; inset-block: -10px; }

/* The change label: a drawn arrow and the delta in the semantic text colour on
   no fill at all. HIG Color asks you not to colour the background of several
   controls at once, and both reference products carry --danger/--success as
   text only - six filled chips in one KPI row outshouted the client's own
   accent, which is the one colour that is meant to anchor the screen. Colour is
   never the only channel: the arrow and the explicit sign carry the direction.
   `no-direction` is a metric with no better way to move (spend), so it keeps
   the neutral grey even when the number has moved. */
.change-label {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  height: 22px; padding: 0 2px; border: 0; border-radius: var(--radius-xs);
  font: 600 .8125rem/1rem var(--font-sans); font-variant-numeric: tabular-nums; font-feature-settings: "tnum";
  direction: ltr; unicode-bidi: isolate; white-space: nowrap; letter-spacing: normal;
  color: var(--label-secondary); background: transparent; cursor: pointer;
}
.change-label.up { color: var(--green-text); }
.change-label.down { color: var(--red-text); }
.change-label.flat { color: var(--label-secondary); }
.change-label.no-direction { color: var(--label-secondary); }
/* The arrow carries four units of trailing space inside its own viewBox, so
   the pair needs no gap of its own. */
.change-label .change-arrow { width: 12px; height: 9px; flex: none; }
/* A 44px hit zone around the 22px label, visual size unchanged. */
.change-label::before { content: ""; position: absolute; inset-inline: -4px; inset-block: -11px; }
.change-label:hover, .change-label[aria-expanded="true"] { background: var(--fill-4); }

/* Apple's switch: green is the one place it is not a delta. */
.toggle {
  position: relative; display: inline-block; flex: none;
  width: 51px; height: 31px; border-radius: var(--radius-pill);
  background: var(--fill-2); transition: background-color var(--duration) var(--ease);
}
.toggle::after {
  content: ""; position: absolute; top: 2px; inset-inline-start: 2px;
  width: 27px; height: 27px; border-radius: 50%; background: #fff;
  box-shadow: 0 3px 8px rgba(0,0,0,.15), 0 1px 1px rgba(0,0,0,.16);
  transition: transform var(--duration) var(--ease);
}
.toggle[aria-checked="true"], .toggle:has(input:checked) { background: var(--green); }
.toggle[aria-checked="true"]::after, .toggle:has(input:checked)::after { transform: translateX(-20px); }
[dir="ltr"] .toggle[aria-checked="true"]::after, [dir="ltr"] .toggle:has(input:checked)::after { transform: translateX(20px); }
.toggle input { position: absolute; inset: 0; opacity: 0; margin: 0; width: 100%; height: 100%; cursor: pointer; }
.toggle:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Under a finger the switch is 51x31 - Apple's own size, and 13px short of the
   44px target. A transparent overlay carries the rest without changing what is
   drawn. Rows that wrap the switch in their own label are already 44px tall;
   this covers the ones that place the label beside it. */
@media (pointer: coarse) {
  .toggle::before { content: ""; position: absolute; inset: -7px 0; }
}

/* -------------------------------------------- 3. pop-up buttons and menus -- */

.select-control { position: relative; display: block; min-width: 0; }
.select-control > select.select-native, select.select-native {
  position: absolute; width: 1px; height: 1px;
  min-width: 0; max-width: 1px; min-height: 0;
  padding: 0; margin: 0; border: 0;
  overflow: hidden; clip-path: inset(50%); opacity: 0; pointer-events: none;
}
/* The toolbar's selects wait for select-menu.js so no native control flashes at boot. */
.toolbar select:not(.select-native) { visibility: hidden; }
.select-trigger, .popup, .filters #dateBtn, .report-channel-trigger {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  width: 100%; min-width: 0; height: var(--control-h); min-height: var(--control-h); padding: 0 12px;
  background: var(--surface); color: var(--label); border: 0;
  border-radius: var(--radius-control); font: var(--text-control); text-align: start; cursor: pointer;
  box-shadow: 0 0 0 0.5px var(--separator-opaque), 0 1px 2px rgba(0,0,0,.04);
  transition: background-color var(--duration-fast) var(--ease), box-shadow var(--duration-fast) var(--ease);
}
.select-trigger:hover:not(:disabled), .popup:hover:not(:disabled), .filters #dateBtn:hover, .report-channel-trigger:hover {
  background: var(--bg-grouped-3);
}
.select-trigger:disabled, .report-channel-trigger[aria-disabled="true"] { opacity: .4; cursor: default; }
.select-trigger[aria-expanded="true"], .popup[aria-expanded="true"], .dd.open #dateBtn {
  background: var(--bg-grouped-3);
  box-shadow: 0 0 0 0.5px var(--separator-strong), 0 1px 3px rgba(0,0,0,.06);
}
/* The line box is a ratio, not a measurement: a fixed 18px held a 15px label
   and clipped a 34px one at a raised browser text size. 1.2 reads 18px at the
   default size and grows with the label from there. */
.select-text, .popup-text { display: flex; flex-direction: column; min-width: 0; line-height: 1.2; }
.select-value, .popup-text > span:first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.select-sub {
  font: var(--text-caption-1); color: var(--label-secondary);
  direction: ltr; unicode-bidi: isolate; text-align: start;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.has-sub .select-value { font: 500 .875rem/1rem var(--font-sans); }
.select-arrow { flex: none; display: inline-flex; color: var(--label-secondary); }
.select-arrow .glyph, .popup > .glyph { width: 12px; height: 12px; }
.popup > .glyph { color: var(--label-secondary); }

/* Every pop-up menu is one material: thick glass, the transient layer, with
   one rim and one ambient shadow. Things that look the same behave the same,
   so the account menu and the channel picker use the same surface as the date
   and select menus. Rows are fills on glass, concentric with the 6px menu
   padding (14 - 6 = 8). */
.select-menu, .dd-menu, .user-menu-items, .report-channel-panel {
  background: var(--glass-fill-thick); color: var(--label);
  border: 0; border-radius: var(--radius-menu);
  box-shadow: inset 0 1px 0 var(--glass-highlight), inset 0 -1px 0 var(--glass-lowlight), var(--glass-shadow-thick);
  padding: 6px; font: var(--text-callout); text-align: start;
  transform-origin: top; animation: pop-in var(--duration-transient) var(--ease);
}
/* A menu that opens INSIDE another glass surface is opaque: glass never sits on
   glass (WWDC25/323, "glass can not sample other glass"). The formula
   completions live inside the editor sheet, and any pop-up menu portaled to
   <body> while a sheet is open is over that sheet. */
.formula-suggestions, html.sheet-open .select-menu {
  background: var(--bg-elevated); color: var(--label);
  border: 0; border-radius: var(--radius-menu);
  box-shadow: var(--shadow-popover);
  padding: 6px; font: var(--text-callout); text-align: start;
  transform-origin: top; animation: pop-in var(--duration-transient) var(--ease);
}
/* The blur allow-list: it exists only while the surface is shown, so hidden menus cost nothing. */
.select-menu:not([hidden]), .dd.open .dd-menu, .dd.is-closing .dd-menu, .popover, .report-channel-picker[open] .report-channel-panel, .sheet, .toast.on, .user-menu[open] .user-menu-items {
  -webkit-backdrop-filter: blur(24px) saturate(160%);
          backdrop-filter: blur(24px) saturate(160%);
}
/* ...and it stops at the sheet's edge. */
html.sheet-open .select-menu { -webkit-backdrop-filter: none; backdrop-filter: none; }
/* A menu, a popover or a sheet morphs out of the control that opened it: the
   box scales from that control's centre (select-menu.js, app.js and
   fitDateMenu set transform-origin from the trigger's rect) while its fill
   fades in with it, and closing plays the same move backwards (is-closing,
   taken off with the node once the animation has ended). Transform and
   opacity only; the blur is never animated, it is simply on while the surface
   is shown. */
@keyframes pop-in { from { opacity: 0; transform: scale(.94); } to { opacity: 1; transform: none; } }
@keyframes pop-out { from { opacity: 1; transform: none; } to { opacity: 0; transform: scale(.94); } }
@keyframes fade-out { from { opacity: 1; } to { opacity: 0; } }
.popover.is-closing, .select-menu.is-closing, .dd.is-closing .dd-menu { animation: pop-out var(--duration-transient) var(--ease) both; pointer-events: none; }
.dd.is-closing .dd-menu { display: block; }
.scrim.is-closing { animation: fade-out var(--duration-transient) var(--ease) both; pointer-events: none; }
/* The account menu hangs from its summary at the inline end, so it grows from that corner. */
[dir="rtl"] .user-menu-items { transform-origin: top left; }
[dir="ltr"] .user-menu-items { transform-origin: top right; }
.select-menu {
  position: fixed; z-index: 1000; min-width: 240px; max-width: calc(100vw - 16px);
  max-height: 360px; overflow-y: auto; overscroll-behavior: contain;
}
.select-option, .dd-row, .user-menu-items .btn, .report-channel-option {
  display: flex; align-items: center; gap: 10px; width: 100%; min-height: var(--menu-row-h);
  padding: 6px 10px; border: 0; border-radius: var(--radius-sm); background: transparent;
  color: var(--label); font: var(--text-callout); text-align: start; cursor: pointer;
}
.user-menu-items .btn { height: auto; justify-content: flex-start; font-weight: 400; }
/* Rows on a blurred surface take the cool, very low alpha glass fills; the warm
   --fill-* ramp is built for opaque surfaces and goes muddy over a blur. */
.select-option:hover:not([aria-disabled="true"]), .select-option.active, .dd-row:hover, .user-menu-items .btn:hover:not(:disabled), .report-channel-option:hover { background: var(--glass-hover); }
.select-option:active:not([aria-disabled="true"]), .dd-row:active, .user-menu-items .btn:active:not(:disabled), .report-channel-option:active { background: var(--glass-press); }
/* Inside a sheet the menu is opaque again, so it goes back to the opaque ramp. */
html.sheet-open .select-menu .select-option:hover:not([aria-disabled="true"]), html.sheet-open .select-menu .select-option.active { background: var(--fill-3); }
html.sheet-open .select-menu .select-option:active:not([aria-disabled="true"]) { background: var(--fill-2); }
.select-option[aria-disabled="true"] { opacity: .4; cursor: default; }
.select-check, .dd-row .chk {
  flex: 0 0 16px; width: 16px; display: inline-flex; justify-content: center;
  color: var(--accent-text); visibility: hidden; font-weight: 600;
}
.select-option[aria-selected="true"] .select-check, .dd-row.sel .chk { visibility: visible; }
.select-option-text, .dd-text { display: flex; flex-direction: column; min-width: 0; }
.select-group { padding: 10px 10px 4px; color: var(--label-secondary); font: var(--text-footnote); }
.select-menu [role="group"] + [role="group"] { margin-top: 6px; padding-top: 6px; border-top: var(--hairline) solid var(--separator); }

.dd { position: relative; }
.dd.open { z-index: 120; }
.dd-menu {
  position: absolute; top: calc(100% + 6px); inset-inline-start: 0;
  min-width: 320px; max-width: calc(100vw - 16px); display: none; z-index: 120;
  overflow-y: auto; overscroll-behavior: contain;
  box-shadow: inset 0 1px 0 var(--glass-highlight), inset 0 -1px 0 var(--glass-lowlight), var(--glass-shadow-thick);
}
.dd-menu.dropup {
  top: auto;
  bottom: calc(100% + 6px);
  transform-origin: bottom;
}
.dd.open .dd-menu { display: block; }
.dd-foot {
  position: sticky; bottom: -6px; margin-bottom: -6px; background: var(--glass-fill-thick);
  border-top: var(--hairline) solid var(--separator); margin-top: 6px;
  padding: 12px; display: grid; grid-template-columns: 1fr 1fr; gap: 8px 10px; align-items: center; justify-items: center;
  z-index: 10;
}
.dd-foot-title {
  grid-column: 1 / -1; width: 100%; font: 600 .8125rem/1.125rem var(--font-sans); color: var(--label);
  margin-bottom: 2px; text-align: start;
}
.dd-date-group { display: flex; flex-direction: column; gap: 4px; width: 100%; }
.dd-date-label { font: 500 .75rem/1rem var(--font-sans); color: var(--label-secondary); text-align: start; }
.dd-foot .dd-date {
  height: var(--control-h); min-height: var(--control-h); width: 100%; padding: 0 8px;
  border: 0; border-radius: var(--radius-control); background: var(--bg-grouped-3); box-shadow: inset 0 0 0 1px var(--separator);
  color: var(--label); direction: ltr; text-align: center; font: var(--text-subhead); font-variant-numeric: tabular-nums;
}
/* The shared ring, like every other control: the 40%-alpha shadow that
   replaced it measured about 2.1:1 and the rule keyed off :focus, so it was
   painted for a pointer press too. */
.dd-foot .dd-date:focus-visible { border-color: var(--accent); }
.dd-foot .dd-date::placeholder { color: var(--placeholder); }
.dd-foot .btn { grid-column: 1 / -1; width: 100%; }

/* ------------------------------------------------------ 3. search field -- */

.search-field { position: relative; display: block; min-width: 0; }
.search-field .search-glyph {
  position: absolute; inset-inline-start: 12px; top: 50%; transform: translateY(-50%);
  width: 16px; height: 16px; color: var(--label-secondary); pointer-events: none;
}
.search-field input, .filters input[type="search"] {
  width: 100%; min-width: 0; height: var(--control-h); min-height: var(--control-h);
  padding: 0 36px 0 40px; padding-inline-start: 36px; padding-inline-end: 40px;
  border: 0; border-radius: var(--radius-control); background: var(--fill-3); color: var(--label);
  font: var(--text-control); font-weight: 400;
  transition: background-color var(--duration-fast) var(--ease);
}
.search-field input:focus, .filters input[type="search"]:focus { background: var(--fill-2); }
.search-field input::placeholder, .filters input[type="search"]::placeholder { color: var(--placeholder); opacity: 1; }
.search-field input::-webkit-search-cancel-button, .search-field input::-webkit-search-decoration { -webkit-appearance: none; appearance: none; display: none; }
.search-field .search-clear {
  position: absolute; inset-inline-end: 4px; top: 50%; transform: translateY(-50%);
  width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center;
  color: var(--label-secondary); border-radius: 50%;
}
.search-field .search-clear::before { content: ""; position: absolute; inset: -8px; }   /* 44px hit area around the 28px glyph */
.search-field .search-clear:hover { color: var(--label); background: var(--fill-4); }
.search-field .search-clear .glyph { width: 16px; height: 16px; }
.search-field:not(.has-value) .search-clear { display: none; }
.search-field.has-value input { padding-inline-end: 40px; }
/* The shortcut chip belongs to pointer devices only; the page hides it on
   non-Mac keyboards. It reads left to right ("⌘ K"), and a logical inset
   would resolve against that direction and land it on the glyph's side, so
   its side is physical: the page's inline end, away from the magnifier. */
.search-field .search-kbd {
  position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
  display: none; align-items: center; justify-content: center; height: 20px; padding: 0 6px;
  font: 500 .6875rem/1 var(--font-sans); color: var(--label-secondary);
  background: var(--bg-grouped-2); box-shadow: 0 0 0 0.5px var(--separator-opaque); border-radius: var(--radius-xs);
  pointer-events: none; direction: ltr; unicode-bidi: isolate;
  transition: opacity var(--duration-fast) var(--ease);
}
[dir="rtl"] .search-field .search-kbd { right: auto; left: 8px; }
.search-field:focus-within .search-kbd, .search-field.has-value .search-kbd { opacity: 0; }
@media (hover: hover) and (pointer: fine) {
  .search-field .search-kbd { display: inline-flex; }
  /* The text stops short of the chip while it is shown (the clear button takes its place once there is a value). */
  .search-field:has(> .search-kbd:not([hidden])):not(.has-value) input { padding-inline-end: 44px; }
}

/* ----------------------------------------------------------- 3. forms -- */

.field, .form-field, .context-field, .filter-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
/* A caption is a label element or carries .field-label; a bare span is never
   one (select-menu.js wraps its control in span.select-control). */
.field > label, .form-field > label, .frm label, .field-label, .form-field .field-label {
  font: var(--text-footnote); font-weight: 500; color: var(--label-secondary); margin: 0 4px -2px 0; margin-inline-start: 4px;
}
.field > input, .field > select, .field > textarea,
.form-field input, .form-field select, .form-field textarea, .frm input, .frm select, .frm textarea,
.comparison-custom input, .subject-cell input, #formulaFilter > input, .edit-input {
  width: 100%; min-width: 0; height: var(--control-h); min-height: var(--control-h); padding: 0 12px;
  font: var(--text-body); color: var(--label);
  background: var(--bg-grouped-3); border: 0; border-radius: var(--radius-control);
  box-shadow: inset 0 0 0 1px var(--separator);
}
.frm textarea, .form-field textarea { height: auto; min-height: 96px; padding: 10px 12px; resize: vertical; line-height: 22px; }
.field .hint, .field > .help, .field-help, .help { font: var(--text-footnote); color: var(--label-secondary); margin: 0; }
.field[data-invalid="true"] > input { box-shadow: inset 0 0 0 1px var(--red-text); }
.field[data-invalid="true"] > .help, .field[data-invalid="true"] > .hint { color: var(--red-text); }
input::placeholder, textarea::placeholder { color: var(--placeholder); opacity: 1; }
input[type="checkbox"], input[type="radio"] { accent-color: var(--accent-fill); width: 18px; height: 18px; margin: 0; }
.ltr, .frm .ltr, input[dir="ltr"] { direction: ltr; text-align: left; }
#code { letter-spacing: 5px; font-variant-numeric: tabular-nums; text-align: center; }
#code::placeholder { letter-spacing: normal; }

/* ----------------------------------------------------- 3. grouped lists -- */

.group-title { font: var(--text-footnote); color: var(--label-secondary); margin: 0 16px 6px; }
.group { background: var(--bg-grouped-2); border-radius: var(--radius-md); overflow: hidden; border: var(--card-border); }
.group-row { display: flex; align-items: center; min-height: var(--row-h); padding: 0 16px; gap: 12px; }
.group-row + .group-row { border-top: var(--hairline) solid var(--separator); margin-inline-start: 16px; padding-inline-start: 0; }
.group-row > .group-label { flex: 1 1 auto; min-width: 0; font: var(--text-body); color: var(--label); }
.group-row > .group-value { color: var(--label-secondary); font: var(--text-body); font-variant-numeric: tabular-nums; }
.group-subtitle { margin: 5px 0 0; font: var(--text-footnote); color: var(--label-secondary); max-width: 620px; }
.group-footer { font: var(--text-footnote); color: var(--label-secondary); margin: 6px 16px 0; }
.group-footer:empty { display: none; }
.group + .group-title, .group-footer + .group-title, .group-section + .group-section { margin-top: var(--space-8); }


/* ----------------------------------------------------------- 4. shell ---- */

/* One document with a sidebar pane fixed over it. HIG Sidebars (8 June 2026):
   "as with other controls such as toolbars and tab bars, sidebars can float
   above content in the Liquid Glass layer" - so the page runs the full width
   and passes beneath the pane, which is the one place besides the bars where
   glass belongs. The document insets its own content by the pane's width, so
   nothing readable ever sits under the blur. */
.shell {
  display: block;
  min-height: 100dvh;
  position: relative;
  background: var(--bg-grouped);
}

.document {
  min-width: 0;
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  background: var(--bg-grouped);
  padding-inline-start: var(--sidebar-w);
  transition: padding-inline-start var(--duration) var(--ease);
}
.shell.is-collapsed .document { padding-inline-start: var(--sidebar-w-collapsed); }
/* The page inside the flex column shrinks with it: tables scroll inside their own card. */
.library-content { flex: 1 1 auto; width: 100%; min-width: 0; max-width: var(--content-max); margin-inline: auto; padding: 0 var(--gutter); }
.library-content > .wrap { max-width: none; padding-inline: 0; }
.wrap { max-width: var(--content-max); margin: 0 auto; padding: var(--space-4) var(--gutter) var(--space-12); }

/* The pane: the one-step-darker tint at the opacity HIG Color asks for in a
   large element, the shared 24px blur, and ONE edge - the structural hairline.
   A second 0.5px rim on the same pixel is what T1-002 took off the menus. */
.sidebar {
  position: fixed;
  inset-block: 0;
  inset-inline-start: 0;
  width: var(--sidebar-w);
  max-height: 100dvh;
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: 12px 10px 14px;
  background: var(--glass-sidebar);
  -webkit-backdrop-filter: blur(24px) saturate(160%);
          backdrop-filter: blur(24px) saturate(160%);
  box-shadow: inset 0 1px 0 var(--glass-highlight);
  border-inline-end: 1px solid var(--separator);
  z-index: 95;
  transition: width var(--duration) var(--ease), padding var(--duration) var(--ease);
}
.shell.is-collapsed .sidebar { width: var(--sidebar-w-collapsed); }
.sidebar::-webkit-scrollbar { width: 4px; }
.sidebar::-webkit-scrollbar-thumb { background: var(--separator); border-radius: var(--radius-pill); }

.sidebar-head { min-height: 44px; display: flex; align-items: center; gap: 6px; margin-bottom: 12px; flex: none; }
/* The agency's mark leads the head (index.html): a mark, not a banner - 22px
   in a 44px head - and the auto margin hands the rest of the row to the
   collapse and close buttons, so the drawer's close control keeps its place
   at the trailing edge on a 390px screen. */
.sidebar-brand { display: flex; align-items: center; min-width: 0; margin-inline-end: auto; padding-inline-start: 10px; }
.sidebar-brand img { display: block; height: 22px; width: auto; max-width: 100%; object-fit: contain; opacity: .8; }
.sidebar-toggle, .sidebar-close {
  width: var(--control-h-sm); height: var(--control-h-sm); display: grid; place-items: center; border-radius: var(--radius-sm);
  color: var(--label-secondary); background: transparent; border: 0; cursor: pointer; flex: none;
  transition: background-color var(--duration-fast) var(--ease), color var(--duration-fast) var(--ease);
}
.sidebar-toggle:hover, .sidebar-close:hover { background: var(--fill-3); color: var(--label); }
.sidebar-close { display: none; }

/* Rows: 32px on a pointer, 44px on touch. HIG Sidebars (8 June 2026, "Updated
   guidance for sidebar icon colors"): "By default, sidebar icons use your app's
   accent color... people expect all sidebar icons to appear in that color." So
   EVERY glyph carries the client's accent and selection is the row fill alone,
   the way both Finder and Mail read - no weight change, which would reflow a
   variable-width RTL label. All the glyphs dim together when the window is not
   key (data-window-active, set by theme.js), which is what the accent is there
   to express. The glyph's stroke comes from the one .ic rule in the base. */
.sidebar-nav { position: relative; isolation: isolate; display: flex; flex-direction: column; gap: 2px; flex: none; }
/* The selection pill behind the rows (placeRailIndicator): it slides between
   rows on the one transform, the way the tab bar's indicator does, and the
   row's own fill stands in wherever the rail has no layout to measure - the
   phone drawer before it opens. Only transform and opacity move. */
.sidebar-indicator {
  position: absolute; z-index: 0; inset-inline: 0; top: 0;
  height: var(--rail-h, 0px); transform: translateY(var(--rail-y, 0px));
  border-radius: var(--radius-sm); background: var(--sidebar-selected);
  opacity: 0; pointer-events: none;
  transform-origin: center center;
  scale: var(--pill-sx, 1) var(--pill-sy, 1);
  transition: transform var(--duration) var(--ease), opacity var(--duration-fast) var(--ease), scale var(--duration-thumb) var(--spring);
}
.sidebar-indicator.is-visible { opacity: 1; }
.sidebar-nav > .sidebar-item { position: relative; z-index: 1; }
.sidebar-nav.has-indicator > .sidebar-item.is-selected, .sidebar-nav.has-indicator > .sidebar-item[aria-current="page"] { background: transparent; }
.sidebar-item {
  display: flex; align-items: center; gap: 10px;
  min-height: var(--sidebar-row-h); padding: 4px 10px;
  border-radius: var(--radius-sm); border: 0; background: transparent;
  color: var(--label); font: var(--text-control); font-weight: 400;
  text-decoration: none; text-align: start; width: 100%; cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease), color var(--duration-fast) var(--ease);
}
.sidebar-item:hover { background: var(--fill-4); color: var(--label); text-decoration: none; }
.sidebar-item:active { background: var(--fill-3); }
.sidebar-item.is-selected, .sidebar-item[aria-current="page"] { background: var(--sidebar-selected); color: var(--label); }
.sidebar-item .ic { width: 18px; height: 18px; color: var(--accent); flex: none; transition: opacity var(--duration-fast) var(--ease); }
html[data-window-active="false"] .sidebar-item .ic { opacity: .5; }
.sidebar-item-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sidebar-spacer { flex: 1 1 auto; min-height: 16px; }
.sidebar-bottom { flex: none; display: flex; flex-direction: column; gap: 4px; padding-top: 12px; border-top: 1px solid var(--separator); }
/* The mark used to close the rail and kept this block from ever being empty.
   A client's session removes the one row left in it (initTools), and a bare
   rule above nothing reads as a mistake, so the block goes with its contents. */
.sidebar-bottom:not(:has(> *:not([hidden]))) { display: none; }

/* Collapsed: glyphs only. */
.shell.is-collapsed .sidebar { padding-inline: 8px; }
.shell.is-collapsed .sidebar-head { justify-content: center; flex-direction: column; gap: 6px; }
.shell.is-collapsed .sidebar-item-label,
.shell.is-collapsed .sidebar-brand { display: none; }
.shell.is-collapsed .sidebar-item { justify-content: center; padding: 4px; width: 44px; margin-inline: auto; }
.shell.is-collapsed .sidebar-indicator { width: 44px; margin-inline: auto; }

/* Phone bar and drawer. The bar is the phone's navigation bar and its one
   scroll edge, so it carries the same material as the scrolled desktop header
   rather than a solid fill: HIG Layout (9 Sept 2026) says to use a scroll edge
   effect instead of "a solid or semi-opaque background color beneath controls",
   and HIG Scroll views asks for one edge per view - which is why .hdr below it
   stays in the flow. Same fill, same hard 1px edge, same height as the desktop
   bar, so the two read as one bar at two sizes. */
.sidebar-scrim { display: none; }
.library-mobile-bar {
  display: none; align-items: center; justify-content: space-between; gap: 12px;
  min-height: 52px;
  padding: calc(6px + env(safe-area-inset-top)) max(12px, env(safe-area-inset-right)) 6px max(12px, env(safe-area-inset-left));
  background: transparent;
  border-bottom: 0;
  position: sticky; top: 0; z-index: 89;
}
/* A scroll edge effect is what APPEARS when content passes under a bar, not a
   resting decoration: at the top of the page the bar carried the material and
   the hairline already, so the one surface that should react to scrolling
   never changed. The fill and the edge fade in over the first 80px on the
   bar's ::before (the rule the desktop header shares, above); the sentinel
   that tells the desktop header the page has left the top tells this bar too
   - one observer, one truth - and turns the blur on. On this tier the page
   header is static, so the bar is the view's only edge. */
.document:has(.hdr[data-scrolled="true"]) .library-mobile-bar {
  -webkit-backdrop-filter: blur(24px) saturate(160%);
          backdrop-filter: blur(24px) saturate(160%);
}
.library-mobile-bar .mobile-brand-title { flex: 1 1 auto; min-width: 0; text-align: center; font: var(--text-headline); color: var(--label); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* The floating tab bar (iPhone): a glass capsule, monochrome glyphs, one tinted
   selected item over a concentric 30px indicator (34 - 4). */
.bottom-nav {
  display: none;
  position: fixed;
  inset-inline: max(16px, env(safe-area-inset-left), env(safe-area-inset-right));
  bottom: calc(12px + env(safe-area-inset-bottom));
  z-index: 92;
  height: var(--bottom-nav-h);
  padding: 4px;
  border-radius: var(--radius-nav);
  background: var(--glass-fill);
  -webkit-backdrop-filter: blur(24px) saturate(160%);
          backdrop-filter: blur(24px) saturate(160%);
  box-shadow: inset 0 1px 0 var(--glass-highlight), inset 0 -1px 0 var(--glass-lowlight), 0 0 0 0.5px var(--glass-rim), 0 10px 30px rgba(0,0,0,.15);
  transition: opacity var(--duration-fast) var(--ease), visibility 0s linear 0s;
}
/* A sheet covers the tab bar (HIG tab bars): it leaves with the scrim's fade,
   so one glass layer is shown at a time, never one blurred over another. */
html.sheet-open .bottom-nav, body:has(> .popover.as-sheet) .bottom-nav {
  opacity: 0; visibility: hidden;
  transition: opacity var(--duration-fast) var(--ease), visibility 0s linear var(--duration-fast);
}
.bottom-nav-inner { position: relative; display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); align-items: stretch; height: 100%; isolation: isolate; }
.bottom-nav-indicator {
  position: absolute; z-index: 0; top: 0; bottom: 0; left: 0;
  transform: translateX(var(--nav-x, 0px)); width: var(--nav-w, 0px);
  border-radius: var(--radius-nav-item);
  background: var(--nav-indicator);
  /* The fill alone cannot carry the selection: white at .72 over the bar
     composites to 1.04:1 in light and the dark pill to 1.44:1, while the two
     labels differ by 1.76:1, so which destination is selected rested on font
     weight. A pill dark enough to make 3:1 on its own would be a filled
     capsule, which is not what a tab bar looks like, so the 3:1 that WCAG 2.2
     SC 1.4.11 asks of a state lives in the rim: one hairline, measured in each
     palette against the bar it sits on. */
  box-shadow: 0 0 0 1px var(--nav-indicator-rim), 0 1px 3px rgba(0,0,0,.08);
  transform-origin: center center;
  scale: var(--pill-sx, 1) var(--pill-sy, 1);
  transition: transform var(--duration) var(--ease), width var(--duration) var(--ease), opacity var(--duration-fast) var(--ease), scale var(--duration-thumb) var(--spring);
  opacity: 0; pointer-events: none;
}
.bottom-nav-indicator.is-visible { opacity: 1; }
/* The glass catches the move: when the indicator slides to another item
   (placeNavIndicator), a brighter specular flashes along the bar's top edge
   and decays over the transient duration - the highlight token stepping up to
   its strong value and back, as one layer's opacity, nothing else. */
.bottom-nav::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  box-shadow: inset 0 1px 0 var(--glass-highlight-strong);
  opacity: 0;
}
.bottom-nav.is-catching::after { animation: specular var(--duration-transient) var(--ease) both; }
@keyframes specular { from { opacity: 1; } to { opacity: 0; } }
/* Tab bars settle without overshoot; the press lifts the item at most 5%. */
.bottom-nav-item {
  position: relative; z-index: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  min-width: 0; padding: 4px 2px; border-radius: var(--radius-nav-item);
  color: var(--label-secondary); font: 500 .6875rem/.8125rem var(--font-sans); text-align: center; text-decoration: none;
  background: transparent; border: 0; cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: transform var(--duration-fast) var(--ease), color var(--duration-fast) var(--ease);
}
.bottom-nav-item svg { width: 22px; height: 22px; }
.bottom-nav-item:active { transform: scale(1.05); }
/* The selected label reads --accent-text, not --accent. --accent is derived
   against the PAGE (3:1 in light, 4.5:1 in dark), and the indicator pill is
   lighter than the page, so on it --accent measured 3.75:1 for 11px semibold
   text - the selected destination less legible than the four unselected ones
   beside it (8.46:1). --accent-text is the token derived for this job, and
   brand-theme.js names tab labels among its consumers: 4.78:1 on the dark
   pill, and darker than --accent in light, so the light figure only rises. */
.bottom-nav-item.is-selected { color: var(--accent-text); font-weight: 600; }
.bottom-nav-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }

/* -------------------------------------------------------- 4. page header -- */

/* The header is the one scroll-edge surface: transparent at rest (0 blurred
   elements at scroll top), a uniform glass bar with a hard 1px bottom edge
   once content scrolls beneath it (data-scrolled from the sentinel observer).
   It bleeds to the column edges so the bar spans the content like a toolbar.
   HIG Scroll views (8 June 2026): prefer the automatic scroll edge style, which
   is "a more opaque visual separation for top toolbars that contain a large
   number of controls" - hence --glass-fill-edge (.84 light / .80 dark) rather
   than the bars' .78/.72. Not a soft gradient: WWDC26/278 says the soft style
   no longer matches the system. One scroll edge per view, so the bottom edge
   stays a single hard line and takes no inner lowlight. */
.hdr-sentinel { position: absolute; top: 0; inset-inline-start: 0; width: 1px; height: 1px; pointer-events: none; }
.hdr {
  --hdr-collapse: 0px;
  position: sticky; top: 0; z-index: 90; border-bottom: 0;
  margin-inline: calc(-1 * var(--gutter)); padding-inline: var(--gutter);
}
/* The material is not a switch. The fill and the hard edge sit on a layer of
   their own whose opacity IS the scroll: --scroll-edge runs from 0 at the top
   of the page to 1 at 80px (written by the page on both bars), so the bar
   arrives with the content that passes under it instead of appearing at a
   threshold. The blur cannot fade and is not asked to: it turns on at the
   sentinel, under a fill still too thin to show it. */
.hdr::before, .library-mobile-bar::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: var(--glass-fill-edge);
  box-shadow: inset 0 1px 0 var(--glass-highlight), 0 1px 0 var(--glass-edge);
  opacity: var(--scroll-edge, 0);
}
.hdr.material { background: transparent; -webkit-backdrop-filter: none; backdrop-filter: none; box-shadow: none; }
.hdr[data-scrolled="true"] {
  -webkit-backdrop-filter: blur(24px) saturate(160%);
          backdrop-filter: blur(24px) saturate(160%);
}
.library-heading {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
  min-height: var(--hdr-h); padding-block: 10px; margin-bottom: var(--space-4);
}
.library-heading > div:first-child { flex: 1 1 auto; min-width: 0; }
.hdr h1 { font: var(--text-title-1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hdr h1 + p, .hdr .sub { display: flex; align-items: center; gap: 6px 8px; flex-wrap: wrap; margin-top: 2px; font: var(--text-footnote); color: var(--label-secondary); }
.hdr .stamp { font: var(--text-footnote); color: var(--label-secondary); white-space: nowrap; }
/* Compact (the page sets data-compact once the title has scrolled): the title steps down to the section size. */
.hdr[data-compact="true"] h1 { font: var(--text-title-2); }
.hdr[data-compact="true"] .sub, .hdr[data-compact="true"] h1 + p { display: none; }
.hdr .btn { flex: none; }
/* Bar items are monochrome: symbols share the actions group, text stays alone (HIG Toolbars); accent only where it means something. */
.library-actions { display: flex; align-items: center; gap: var(--space-2); flex: none; margin-inline-start: auto; }
.hdr #refIco { display: inline-block; }
.hdr #refreshBtn { position: relative; }
.hdr #refreshBtn::before { content: ""; position: absolute; inset: -4px; }   /* 44px hit area around the 36px symbol button */
.hdr .user-menu summary.btn.plain, .hdr #tenantsAdminLink { color: var(--label); }

/* Logo dimensions describe artwork, excluding the source image's margins. */
.client-logo-frame {
  position: relative; display: inline-block; flex: none; align-self: center; box-sizing: content-box;
  width: var(--client-logo-width, 72px); height: var(--client-logo-height, 34px);
  padding: 6px; overflow: hidden; background: #fff; border-radius: var(--radius-sm);
}
.client-logo-frame .hdr-logo {
  position: absolute; width: var(--client-logo-image-width); height: var(--client-logo-image-height);
  left: var(--client-logo-image-left); top: var(--client-logo-image-top); max-width: none;
  margin: 0; padding: 0; background: transparent; border-radius: 0; clip-path: var(--client-logo-clip, none); object-fit: contain;
}
.hdr .client-logo-frame { transition: scale var(--duration) var(--ease); }
.hdr[data-compact="true"] .client-logo-frame { scale: .8; }

.who { display: flex; align-items: center; gap: 8px; font: var(--text-control); color: var(--label); }
.user-menu { position: relative; z-index: 95; }
.user-menu summary { list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; }
.user-menu summary::-webkit-details-marker { display: none; }
.user-menu summary .glyph { width: 12px; height: 12px; color: var(--label-secondary); }
.user-menu summary .person { display: none; width: 22px; height: 22px; color: var(--label); }
.user-menu-items { position: absolute; inset-inline-end: 0; top: calc(100% + 6px); min-width: 225px; display: flex; flex-direction: column; z-index: 100; }
.user-menu-items .btn { text-align: start; width: 100%; padding: 6px 10px; }
.user-menu-items #themeBtn { border-bottom: var(--hairline) solid var(--separator); border-radius: var(--radius-sm) var(--radius-sm) 0 0; margin-bottom: 4px; padding-bottom: 8px; }
#logoutAllBtn { color: var(--label-secondary); }
#logoutAllBtn.danger { color: var(--red-text); background: var(--red-tint); }
/* A three-way appearance picker inside the account menu (auto / light / dark). */
.theme-picker { display: flex; flex-direction: column; gap: 4px; padding: 4px 10px 8px; }
/* The two accessibility switches under the appearance picker: settings rows,
   the same shape the admin console uses, inside the account menu. */
.reduce-picker { display: flex; flex-direction: column; padding: 0 10px 8px; }
.reduce-picker .group-row { min-height: var(--menu-row-h); padding: 0; gap: var(--space-3); cursor: pointer; }
.reduce-picker .group-label { font: var(--text-control); color: var(--label); }
.reduce-picker .group-footer { margin: 4px 0 0; }
.theme-picker > .group-title { margin: 0 0 4px; }
.theme-picker .segmented { width: 100%; height: var(--control-h-sm); }

/* Alerts: inline status rows, a tinted leading rule, text in --label. */
.alert {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-bottom: var(--space-3); padding: 10px 14px;
  border-radius: var(--radius-md); background: var(--bg-grouped-2); border: var(--card-border);
  border-inline-start: 3px solid var(--orange); color: var(--label); font: var(--text-subhead);
}
.alert-error { border-inline-start-color: var(--red); }
.alert-warn { border-inline-start-color: var(--orange); }
.alert .btn { margin-inline-start: auto; }

/* Client and account pickers - shown only when there is something to pick. */
.client-context { display: flex; flex-wrap: wrap; gap: 8px 12px; align-items: center; margin: 0; }
.client-context:not(:has(#clientPicker:not([hidden]), #accountPicker:not([hidden]), #accountCurrency:not([hidden]))) { display: none; }
.client-context .select-control { width: 100%; min-width: 180px; max-width: 320px; }
.context-field { margin: 0; min-width: 120px; }
#accountPicker { display: flex; }
#accountCurrency { align-self: center; }

/* ------------------------------------------------------- 4. toolbar --------*/

/* The filter toolbar is a row of content-layer controls on the page - not
   glass (nothing scrolls beneath it). Three groups at most: view filters,
   the period, and the client + search at the trailing side (HIG toolbars). */
.toolbar {
  --tc-h: var(--control-h);
  position: relative; z-index: 40; display: flex; align-items: center; flex-wrap: wrap;
  gap: var(--space-2) var(--space-3); margin: 0 0 var(--space-4);
}
.toolbar-group, .library-sort, .library-filters { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; min-width: 0; }
/* The trailing group takes what the first row leaves and never clips the
   client picker; the search ends the row, starting at 200px and growing to
   320px. (The phone block below lifts the cap so it spans the row.) */
.toolbar-group.trailing { margin-inline-start: auto; flex: 1 1 auto; min-width: 0; max-width: none; justify-content: flex-end; }
.toolbar-group.trailing .client-context { flex: 0 1 auto; min-width: 0; }
.toolbar-group.trailing .client-context .select-control { min-width: 160px; }
.toolbar-group.trailing .search-field { flex: 1 1 200px; max-width: 320px; }
/* The comparison's custom dates take a row of their own, present only while "מותאם" is chosen. */
.toolbar-row { flex-basis: 100%; }
.toolbar-row:not(:has(> .comparison-custom:not([hidden]))) { display: none; }
.toolbar .filter-field { flex-direction: row; align-items: center; gap: 8px; }
.toolbar .filter-field > .field-label { display: none; }
.toolbar .select-control { flex: 1 1 auto; min-width: 150px; }
.toolbar .select-trigger { width: auto; min-width: 150px; }
.toolbar #dateBtn { width: auto; min-width: 190px; }
/* HIG Toolbars: "Minimize the number of groups... In general, aim for a
   maximum of three." The bar carries the client, the period and the platform;
   status, lead source, channels and domain live behind one "מסננים" pull-down
   at EVERY width, so the row never wraps into a second one. */
.toolbar-more-btn { display: inline-flex; }
.toolbar-secondary { display: none; flex-basis: 100%; padding-top: var(--space-2); border-top: var(--hairline) solid var(--separator); }
.toolbar[data-more="true"] .toolbar-secondary { display: flex; }
.filters, .report-controls { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2) var(--space-3); margin: 0 0 var(--space-4); }
.report-controls .report-note { margin: 0; }
.comparison-custom { display: flex; align-items: flex-end; flex-wrap: wrap; gap: 10px; width: 100%; padding: var(--space-2) 0 2px; }
.comparison-custom label { display: grid; gap: 6px; font: var(--text-footnote); color: var(--label-secondary); }
.comparison-custom input { width: 150px; }
#compareError:not(:empty) { color: var(--red-text); }
.status-note { flex-basis: 100%; margin: 0; }
/* The admin link lives in the header on wide screens and in the user menu on phones. */
@media (min-width: 768px) {
  #tenantsAdminMenuLink { display: none; }
}

/* Domain tab bar: a pill segmented control with the same sliding thumb, and
   the same scrub - the owner asked for the drag on every bar that carries a
   selection. On a phone the strip scrolls, and there the finger scrolls it
   (app.js scrolls()); the pointer scrubs at every width. */
.tabs-row { display: flex; align-items: center; gap: var(--space-2); margin: 0 0 var(--space-4); }
.tabs-row > .tabs { margin: 0; min-width: 0; }
.tabs-row > .card-info { margin: 0; }
.tabs {
  position: relative; isolation: isolate; display: inline-flex; max-width: 100%; padding: var(--thumb-pad); gap: 0;
  background: var(--fill-3); border-radius: var(--radius-pill);
  overflow-x: auto; overflow-y: hidden; scrollbar-width: none; scroll-padding-inline: 8px;
  margin: 0 0 var(--space-4);
}
.tabs::-webkit-scrollbar { display: none; }
.tab {
  position: relative; z-index: 2; pointer-events: auto; flex: 0 0 auto; height: calc(var(--control-h) - 2 * var(--thumb-pad)); padding: 0 16px; border-radius: var(--radius-pill);
  font: var(--text-control); color: var(--label-secondary); white-space: nowrap;
  transition: color var(--duration-fast) var(--ease), background-color var(--duration-fast) var(--ease), box-shadow var(--duration-fast) var(--ease);
}
.tab::after { content: attr(data-label); font-weight: 600; visibility: hidden; height: 0; display: block; overflow: hidden; pointer-events: none; }
.tab:hover { background: var(--fill-4); color: var(--label); }
.tabs.has-thumb .tab:hover { background: transparent; color: var(--label); }
.tab:active:not(.on), .segmented > button:active:not([aria-checked="true"]):not([aria-pressed="true"]) { background: var(--fill-4); }
.tab.on { background: var(--segment-selected); font-weight: 600; color: var(--label); box-shadow: var(--shadow-thumb); }
.tabs.has-thumb .tab.on { background: transparent; box-shadow: none; }
.tabs.has-thumb .tab.on { color: var(--label); font-weight: 600; }
.tab:focus-visible { outline-offset: -2px; }
/* The tab strip fades where more tabs hide beyond its edge. */
.tabs[data-fade="both"] { -webkit-mask-image: linear-gradient(to left, transparent, #000 24px, #000 calc(100% - 24px), transparent); mask-image: linear-gradient(to left, transparent, #000 24px, #000 calc(100% - 24px), transparent); }
.tabs[data-fade="end"] { -webkit-mask-image: linear-gradient(to left, #000 calc(100% - 24px), transparent); mask-image: linear-gradient(to left, #000 calc(100% - 24px), transparent); }
.tabs[data-fade="start"] { -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent); mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent); }

/* A screen change (transitionView, index.html). The incoming view rises 6px
   into place as it fades in, over the ghost of the outgoing one fading out,
   so the two are never both on screen at full strength; a drill-down slides in
   from the trailing side and back out again, and the list it covered sinks
   under it. The toolbar's per-tab controls and the section title crossfade
   with the view rather than pop. Transform and opacity only, 320ms on the
   .smooth curve; under Reduce Motion every one of these is the plain
   crossfade (the blocks at the end of the sheet). */
.view-stage { position: relative; }
.view-ghost { position: absolute; inset: 0; z-index: 2; overflow: hidden; pointer-events: none; animation: view-out var(--duration) var(--ease) both; }
/* The copy keeps the spacing the live view's own rules give its sections. */
.view-ghost > .card, .view-ghost > .tbl-card, .view-ghost > .report-summary { margin-bottom: var(--space-4); }
main[data-active-tab] #view, main[data-active-tab] .settings-panel { animation: view-in var(--duration) var(--ease) both; }
main[data-active-tab] .toolbar, main[data-active-tab] .section-title { animation: fade-in var(--duration) var(--ease) both; }
main[data-active-tab] #view[data-move="drill-in"] { animation-name: drill-in; }
main[data-active-tab] #view[data-move="drill-back-in"] { animation-name: drill-back-in; }
.view-ghost[data-move="drill-out"] { animation-name: drill-out; }
.view-ghost[data-move="drill-under"] { animation-name: drill-under; }
@keyframes view-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes view-out { from { opacity: 1; } to { opacity: 0; } }
/* --dirx is -1 in this right-to-left page, so the trailing side is the left. */
@keyframes drill-in { from { opacity: 0; transform: translateX(calc(24px * var(--dirx))); } to { opacity: 1; transform: none; } }
@keyframes drill-out { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateX(calc(24px * var(--dirx))); } }
@keyframes drill-back-in { from { opacity: 0; transform: translateX(calc(-24px * var(--dirx))); } to { opacity: 1; transform: none; } }
@keyframes drill-under { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateX(calc(-16px * var(--dirx))); } }

/* ------------------------------------------------------------ 5. cards -- */

/* Content is opaque grouped cards: white on the grouped page, elevated
   (#2C2C2E on #1C1C1E) in dark, 12px radius, no hover lift, no glass. */
.card, .tbl-card, .settings-panel, .panel, .connection-panel {
  background: var(--bg-grouped-2);
  border: var(--card-border);
  border-radius: var(--radius-md);
  box-shadow: var(--card-shadow);
  min-width: 0;
}
.card, .settings-panel, .panel { padding: var(--space-5); }
.card-head { display: flex; align-items: flex-start; gap: var(--space-3); margin-bottom: var(--space-4); }
.card-head > div:first-child { flex: 1 1 auto; min-width: 0; }
.card h3, .tbl-bar .t, .settings-panel-head h2, .settings-panel-head h3, .panel h2, .summary-head h3 { font: var(--text-title-2); }
.card-sub { font: var(--text-footnote); color: var(--label-secondary); margin-top: 2px; }
.card-info {
  flex: none; width: 44px; height: 44px; margin-block: -12px; margin-inline-end: -14px;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--label-tertiary); border-radius: 50%;
  transition: color var(--duration-fast) var(--ease), background-color var(--duration-fast) var(--ease);
}
.card-info:hover, .card-info[aria-expanded="true"] { color: var(--accent-text); background: var(--fill-4); }
.card-info .glyph { width: 16px; height: 16px; }
/* The tile's name doubles as the glossary trigger: an inline label that keeps
   its own size and grows a 44px hit zone under a finger (HIG Accessibility). */
.metric-name { position: relative; text-align: start; }
button.metric-name { border-radius: var(--radius-xs); color: inherit; }
button.metric-name:hover, button.metric-name[aria-expanded="true"] { color: var(--label); }
@media (pointer: coarse) {
  button.metric-name::before { content: ""; position: absolute; inset-inline: -8px; inset-block: -13px; }
}

.card-head .mini-toggle, .card-head .card-info { margin-top: -12px; margin-bottom: -12px; }
.row { display: grid; gap: var(--space-4); margin-bottom: var(--space-4); align-items: start; }
.r-2 { grid-template-columns: 1fr; }   /* two up only at the wide tier, below */
#view > .card, #view > .tbl-card, #view > .report-summary { margin-bottom: var(--space-4); }
.empty { color: var(--label-secondary); font: var(--text-subhead); padding: var(--space-8) 0; text-align: center; }
.empty-state { display: grid; justify-items: center; gap: 6px; padding: var(--space-8) var(--space-4); text-align: center; }
.empty-state .glyph { width: 40px; height: 40px; color: var(--label-tertiary); }
.empty-state h4 { font: var(--text-headline); }
.empty-state p { font: var(--text-footnote); color: var(--label-secondary); }
.foot { font: var(--text-footnote); color: var(--label-secondary); margin-top: var(--space-4); text-align: start; }
.foot:empty { display: none; }

/* ------------------------------------------------------- 5. KPI tiles ---- */

/* Tiles fill the row: auto-fit collapses the track a missing tile would
   leave, and a row of exactly three or six takes explicit columns so six
   tiles never leave an orphan on a second row. */
.report-summary { margin: 0 0 var(--space-4); }
.report-summary .summary-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-3); }
.report-summary .summary-foot { margin: var(--space-3) 0 0; }
.meeting-metrics { display: grid; gap: var(--space-3); }
/* One grid, three fixed rows - name, value, comparison - so the numbers of
   every tile share a baseline. The Latin abbreviation (CTR, CVR, CPL) used to
   own a fourth row; it now reads inside the metric's own definition popover,
   where a reader who wants it can find it. */
.meeting-metric {
  margin: 0; min-width: 0; min-height: 112px; padding: 14px 16px;
  display: grid; grid-template-rows: auto auto 1fr; align-content: start; gap: 6px;
  background: var(--bg-grouped-2);
  border: var(--card-border);
  border-radius: var(--radius-md);
  box-shadow: var(--card-shadow);
}
.meeting-metric dt { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; font: var(--text-footnote); font-weight: 500; color: var(--label-secondary); }
.meeting-metric dt .card-info { margin-block: -12px; margin-inline-end: -14px; }
/* The glossary popover: the metric's name with its abbreviation, one sentence, then the small-print context. */
.metric-glossary .metric-glossary-short { font: var(--text-footnote); color: var(--label-secondary); direction: ltr; unicode-bidi: isolate; }
.metric-glossary .metric-glossary-context { margin-top: 6px; font: var(--text-caption-1); color: var(--label-secondary); }
.meeting-metric .metric-source { font-weight: 400; color: var(--label-secondary); }
.meeting-metric > dt { grid-row: 1; }
.meeting-metric > .metric-value { grid-row: 2; }
.meeting-metric > .metric-previous { grid-row: 3; align-self: end; }
.meeting-metric dd { margin: 0; }
.meeting-metric .metric-value {
  font: var(--text-title-1); color: var(--label); white-space: nowrap; unicode-bidi: isolate; margin: 4px 0 6px;
  font-variant-numeric: tabular-nums; font-feature-settings: "tnum";
}
.meeting-metric .metric-number { direction: ltr; unicode-bidi: isolate; }
/* A tile whose number changed with a load crossfades to the new figure
   (markChangedNumbers, index.html); a number that did not change stays still. */
.metric-number.is-changed { display: inline-block; animation: num-in var(--duration) var(--ease) both; }
@keyframes num-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
/* Text is never quieter than --label-secondary (4.5:1 in both palettes) - a
   placeholder is text, so --placeholder reads that token too; --label-tertiary
   is for glyphs alone. */
.meeting-metric .metric-value:has(> .metric-number:empty), .metric-missing { color: var(--label-secondary); }
.meeting-metric .metric-previous { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: auto; font: var(--text-footnote); color: var(--label-secondary); min-width: 0; overflow: visible; }
.meeting-metric .metric-previous .metric-caption { display: inline-flex; gap: 4px; align-items: baseline; }
.meeting-metric .metric-previous .metric-caption bdi { unicode-bidi: isolate; }
.meeting-metric .metric-previous .change-label { cursor: pointer; }
.report-summary > .report-note { margin: var(--space-3) 0 0; }
.report-note { font: var(--text-footnote); color: var(--label-secondary); margin: var(--space-2) 0; }
/* The campaign table's scope line: a caption, not a second KPI row. The row gap
   is the one thing in it that is not a caption measurement: every change chip
   grows an 11px hit zone above and below itself, so two wrapped lines need 22px
   between them or the lower line's zone lands on the upper line's chip and a tap
   near an edge opens a different metric's explanation. It costs nothing on a
   line that does not wrap. */
.scope-strip { display: flex; align-items: baseline; flex-wrap: wrap; gap: 22px var(--space-4); margin: 0 0 var(--space-3); font: var(--text-footnote); color: var(--label-secondary); }
.scope-item { display: inline-flex; align-items: baseline; gap: 6px; }
.scope-value { color: var(--label); font-weight: 600; font-variant-numeric: tabular-nums; unicode-bidi: isolate; }
.report-note:empty { display: none; }
.sum-empty {
  display: flex; flex-wrap: wrap; gap: 6px; align-items: baseline;
  margin-bottom: var(--space-3); padding: 10px 14px;
  background: var(--bg-grouped-2); border: var(--card-border); border-radius: var(--radius-md);
  border-inline-start: 3px solid var(--separator); font: var(--text-footnote); color: var(--label-secondary);
}
.sum-empty strong { color: var(--label); font-weight: 600; }
/* Explicit column counts so a row never ends in one orphan: three or six
   tiles take three columns from 768px (even rows of three) and six in one row
   from 1200px, where the column leaves each tile 140px or more; four tiles
   (costs hidden) sit two by two, then four in a row from 1024px; five take
   three then two, five in a row from 1200px. */
@media (min-width: 768px) {
  .meeting-metrics:has(> :nth-child(3):last-child), .meeting-metrics:has(> :nth-child(5):last-child), .meeting-metrics:has(> :nth-child(6):last-child) { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .meeting-metrics:has(> :nth-child(4):last-child) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1200px) {
  .meeting-metrics:has(> :nth-child(4):last-child) { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .meeting-metrics:has(> :nth-child(5):last-child) { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  .meeting-metrics:has(> :nth-child(6):last-child) { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .meeting-metrics:has(> :nth-child(8):last-child) { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* Text disclosures (the metric appendix, the formulas panel's help, a
   finding's details) share one summary: a plain accent-coloured control with
   a chevron ahead of the label. The chevron is a masked symbol, never a text
   glyph, because the bidi algorithm mirrors "‹" inside a Hebrew run and the
   rotation then lands on the wrong side. It points forward (left in RTL,
   right in LTR: --dirx) while closed and down once open, like the card
   disclosures' chevron. */
/* The label reads in --label and the triangle in --label-secondary: a disclosure
   is not a link, and the accent is reserved for primary actions and status. */
.metric-appendix > summary, #formulaPanel > details > summary, #analysisPanel .radar-disclosure > summary { width: fit-content; min-height: var(--control-h-sm); padding: 6px 8px; margin-inline-start: -8px; font: var(--text-control); color: var(--label); cursor: pointer; list-style: none; border-radius: var(--radius-sm); }
.metric-appendix > summary:hover, #formulaPanel > details > summary:hover, #analysisPanel .radar-disclosure > summary:hover { background: var(--fill-4); }
.metric-appendix > summary::-webkit-details-marker, #formulaPanel > details > summary::-webkit-details-marker, #analysisPanel .radar-disclosure > summary::-webkit-details-marker { display: none; }
.metric-appendix > summary::before, #formulaPanel > details > summary::before, #analysisPanel .radar-disclosure > summary::before {
  content: ""; display: inline-block; width: 12px; height: 12px; margin-inline-end: 6px; vertical-align: -1px;
  background: var(--label-secondary);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M3.5 6l4.5 4.5L12.5 6%27 fill=%27none%27 stroke=%27%23000%27 stroke-width=%271.8%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M3.5 6l4.5 4.5L12.5 6%27 fill=%27none%27 stroke=%27%23000%27 stroke-width=%271.8%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E") center / contain no-repeat;
  transform: rotate(calc(-90deg * var(--dirx))); transition: transform var(--duration-fast) var(--ease);
}
.metric-appendix[open] > summary::before, #formulaPanel > details[open] > summary::before, #analysisPanel .radar-disclosure[open] > summary::before { transform: rotate(0deg); }

/* The appendix under the headline grid: a disclosure with grouped rows per category. */
.metric-appendix { margin-top: var(--space-3); }
.metric-appendix-body { display: grid; gap: var(--space-4); margin-top: var(--space-2); }
.metric-list .metric-row { min-height: var(--row-h); font: var(--text-subhead); }
.metric-row .metric-label { flex: 1 1 auto; min-width: 0; color: var(--label); }
.metric-row .metric-source { color: var(--label-secondary); }
.metric-row .metric-row-short {
  display: inline-flex; align-items: center; font: 600 .6875rem/1.2 var(--font-sans); color: var(--label-secondary);
  background: var(--fill-3); padding: 1px 6px; border-radius: var(--radius-xs); direction: ltr; unicode-bidi: isolate;
}
.metric-row .metric-row-reason { flex-basis: 100%; font: var(--text-footnote); color: var(--label-secondary); }
.metric-row .metric-row-figures { display: flex; align-items: center; gap: var(--space-3); margin-inline-start: auto; flex: none; }
.metric-row .metric-row-value { min-width: 64px; text-align: end; font: var(--text-subhead); font-weight: 600; color: var(--label); font-variant-numeric: tabular-nums; direction: ltr; unicode-bidi: isolate; }
.metric-row .metric-row-value.metric-missing, .metric-row[data-available="false"] .metric-row-value { color: var(--label-secondary); font-weight: 400; }
.metric-row .metric-row-change { display: inline-flex; align-items: center; gap: 8px; min-width: 156px; font: var(--text-footnote); color: var(--label-secondary); }
.metric-row .metric-row-change .metric-caption { display: inline-flex; gap: 4px; align-items: baseline; font-variant-numeric: tabular-nums; }
.metric-row .metric-row-change .metric-caption bdi { unicode-bidi: isolate; }
/* The funnel card: a stage per row, its count, a bar for its share of the stage before, and that share in words. */
.funnel-card .funnel { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-4); }
.funnel-stage { display: grid; gap: 6px; }
.funnel-stage-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); }
.funnel-stage-label { font: var(--text-subhead); color: var(--label); }
.funnel-stage-value { font: var(--text-headline); color: var(--label); font-variant-numeric: tabular-nums; direction: ltr; unicode-bidi: isolate; }
.funnel-bar { height: 8px; border-radius: var(--radius-pill); background: var(--fill-4); overflow: hidden; }
.funnel-bar-fill { display: block; height: 100%; border-radius: inherit; background: var(--chart-1); }
.funnel-stage-rate { font: var(--text-footnote); color: var(--label-secondary); }
.funnel-stage-rate bdi, .funnel-foot bdi { font-variant-numeric: tabular-nums; unicode-bidi: isolate; }
.funnel-foot { margin: var(--space-4) 0 0; font: var(--text-footnote); color: var(--label-secondary); }

/* ---------------------------------------------------------- 5. charts ---- */

.chart-box { position: relative; direction: ltr; }
.chart-box svg { display: block; width: 100%; }
.chart-box svg text { font-family: var(--font-sans); font-weight: 400; font-variant-numeric: tabular-nums; }
.chart-box svg:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: var(--radius-sm); }
.legend { display: flex; gap: 6px; flex-wrap: wrap; margin-top: var(--space-3); direction: rtl; justify-content: flex-end; }
.chart-tools { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; margin-bottom: var(--space-3); }
.chart-tools .legend { margin: 0; margin-inline-start: auto; }
.chart-tools .chart-bucket { height: var(--control-h-sm); padding: 2px; }
.chart-tools .chart-bucket > button { min-width: 0; padding: 0 12px; font: 500 .8125rem/1.125rem var(--font-sans); }
.legend > span, .legend-pill {
  display: inline-flex; align-items: center; gap: 6px; height: 24px; padding: 0 10px;
  border-radius: var(--radius-sm); background: var(--fill-4);
  font: 500 .75rem/1rem var(--font-sans); color: var(--label-secondary); white-space: nowrap;
}
.legend-pill[aria-pressed="true"] { color: var(--label); }
/* An aria-pressed="false" pill is an active control, not a disabled one, so
   its label keeps the 4.5:1 floor. opacity: .5 dropped the 12px text to about
   2:1 and hid which series the reader had just turned off; the hollow dot the
   pill already draws carries the state. opacity stays for :disabled. */
.legend-pill[aria-pressed="false"] { color: var(--label-secondary); }
.legend .kline, .legend .krect { width: 8px; height: 8px; border-radius: 50%; border: 0; background: currentColor; }
.legend .kline { background: transparent; border-top: 8px solid; border-radius: 50%; }
.tt {
  position: fixed; pointer-events: none; z-index: 1300; display: none; direction: rtl; min-width: 150px;
  padding: 8px 12px; font: var(--text-footnote);
}
.tt .tt-t { font: var(--text-caption-2); color: var(--label-secondary); margin-bottom: 4px; }
.tt .tt-row { display: flex; align-items: center; gap: 12px; justify-content: space-between; line-height: 20px; }
.tt .tt-row b { font-weight: 600; font-variant-numeric: tabular-nums; }
.tt .kline { width: 10px; height: 0; border-radius: 50%; border-top: 10px solid; display: inline-block; vertical-align: -1px; }
.ctable { width: 100%; border-collapse: separate; border-spacing: 0; font: var(--text-subhead); }
.ctable th, .ctable td { height: var(--row-h); padding: 0 12px; border-bottom: var(--hairline) solid var(--separator); text-align: start; white-space: nowrap; }
.ctable th { height: 40px; font: 500 .75rem/1rem var(--font-sans); color: var(--label-secondary); }
.ctable td.num, .ctable th.num { text-align: right; direction: ltr; unicode-bidi: isolate; font-variant-numeric: tabular-nums; }
.ctable tr:hover td { background: var(--fill-4); }
.ctable tbody tr:last-child td, .ctable tr:last-child td { border-bottom: 0; }
.ctable-wrap { max-height: 250px; overflow: auto; display: none; }
.report-table { display: block; margin: var(--space-3) 0 0; overflow-x: auto; }
.report-table .ctable { width: 100%; }
.report-table th, .report-table td { white-space: nowrap; }
.tbl-scroll, .report-table, .ctable-wrap, .table-scroll { scrollbar-width: thin; scrollbar-color: var(--separator) transparent; overscroll-behavior-x: contain; }
.report-table[data-total-row="true"] tr:last-child td { font-weight: 600; border-top: 1px solid var(--separator); border-bottom: 0; }
.report-table[data-total-row="true"] tr:last-child td:first-child { font-weight: 600; }
/* A report table is the card's content, not a chart's alternate: full height, no nested vertical scroller. */
.ctable-wrap.report-table { max-height: none; }
/* A change chip grows its 44px zone 11px past a 22px chip, and the last row of
   a table sits on the bottom edge of a scroll container, which clips whatever
   hangs below it: that row's chips measured 67x40 under a finger while every
   row above them measured 44. The container carries those 11px as padding and
   hands them straight back as margin, so the overhang has room inside the
   scrollport and nothing on the page moves. Under a finger only, where 44px is
   the floor and the scrollbar is an overlay that the padding cannot push down
   onto whatever follows the table. */
@media (pointer: coarse) {
  .ctable-wrap, .report-table { padding-block-end: 11px; margin-block-end: -11px; }
}
.report-table[data-fade="both"] { -webkit-mask-image: linear-gradient(to left, transparent, #000 24px, #000 calc(100% - 24px), transparent); mask-image: linear-gradient(to left, transparent, #000 24px, #000 calc(100% - 24px), transparent); }
.report-table[data-fade="end"] { -webkit-mask-image: linear-gradient(to left, #000 calc(100% - 24px), transparent); mask-image: linear-gradient(to left, #000 calc(100% - 24px), transparent); }
.report-table[data-fade="start"] { -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent); mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent); }
/* The first column stays put while the rest scrolls, like the campaign table. */
.report-table .ctable th:first-child, .report-table .ctable td:first-child { position: sticky; inset-inline-start: 0; z-index: 2; background: var(--bg-grouped-2); box-shadow: -1px 0 0 var(--separator) inset; }
.report-table .ctable tr:hover td:first-child { background: var(--bg-grouped-3); }
/* A two-row header: a platform's name once over its three figures; an ungrouped
   column spans both rows and its text sits level with the second row. */
.ctable thead th.group { height: 30px; padding-bottom: 0; text-align: center; font: 600 .75rem/1rem var(--font-sans); color: var(--label); border-bottom: 0; }
.ctable thead th[rowspan] { vertical-align: bottom; padding-bottom: 11px; }
.ctable thead tr.sub-head th { height: 40px; }
/* Only the top-left cell of a grouped header is the sticky first column. */
.report-table .ctable thead tr.sub-head th:first-child { position: static; box-shadow: none; }

/* Analytics groups (perf card) */
.perf { display: flex; flex-direction: column; }
.perf .top { display: flex; align-items: center; gap: 9px; padding: 0 0 10px; }
.perf .top .dot { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; }
.perf .top h4 { font: var(--text-headline); flex: 1 1 auto; min-width: 0; }
.perf .top .card-info { margin-block: -12px; }
.perf .body { display: flex; flex-wrap: wrap; gap: var(--space-6); }
.perf .stat { flex: 0 1 180px; min-width: 0; }
.perf .stat .k { font: var(--text-footnote); color: var(--label-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.perf .stat .v { font: var(--text-title-2); margin-top: 2px; font-variant-numeric: tabular-nums; letter-spacing: normal; }
.perf .stat .d { font: var(--text-footnote); color: var(--label-secondary); margin-top: 2px; }

/* ------------------------------------------------------ 5. campaign table -- */

.tbl-card { overflow: hidden; }
.tbl-bar { display: flex; align-items: center; gap: 10px; padding: 14px 16px 12px; flex-wrap: wrap; border-bottom: var(--hairline) solid var(--separator); }
.tbl-bar .t { color: var(--label); }
.tbl-bar .count, .tbl-bar .t .count { font: var(--text-footnote); font-weight: 500; color: var(--label-secondary); margin-inline-start: 6px; direction: ltr; unicode-bidi: isolate; font-variant-numeric: tabular-nums; }
.tbl-scroll { overflow: auto; max-height: 640px; position: relative; }
.tbl-scroll[data-fade="both"] { -webkit-mask-image: linear-gradient(to left, transparent, #000 24px, #000 calc(100% - 24px), transparent); mask-image: linear-gradient(to left, transparent, #000 24px, #000 calc(100% - 24px), transparent); }
.tbl-scroll[data-fade="end"] { -webkit-mask-image: linear-gradient(to left, #000 calc(100% - 24px), transparent); mask-image: linear-gradient(to left, #000 calc(100% - 24px), transparent); }
.tbl-scroll[data-fade="start"] { -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent); mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent); }
table.main { border-collapse: separate; border-spacing: 0; width: 100%; min-width: 1040px; font: var(--text-subhead); }
/* The header row is a hard scroll edge: opaque, pinned, no glass. */
table.main th {
  position: sticky; top: 0; z-index: 20; height: 40px; padding: 0 12px;
  background: var(--bg-grouped-2); color: var(--label-secondary);
  font: 500 .75rem/1rem var(--font-sans); text-align: start; white-space: nowrap;
  border-bottom: 1px solid var(--separator); cursor: pointer; user-select: none;
}
table.main th.static { cursor: default; }
/* The header's label is a real button (keyboard, focus ring) filling the cell;
   the chevron shows on the sorted column. width:100% is the cell MINUS its two
   12px paddings, and the negative margins then slide that box to the leading
   edge - so the button covered 42px of a 66px "מטרה" header, under the 44px
   minimum, and left a dead strip at the trailing edge. calc adds the padding
   back, so the button IS the cell. */
table.main th .sort-btn {
  all: unset; box-sizing: border-box; display: inline-flex; align-items: center; gap: 4px;
  width: calc(100% + 24px); min-height: 40px; padding: 0 12px; margin: 0 -12px; cursor: pointer; font: inherit; color: inherit; white-space: nowrap;
}
/* Under a finger the header row is a 44px target like every other control. */
@media (pointer: coarse) {
  table.main th { height: var(--control-h); min-width: var(--control-h); }
  table.main th .sort-btn { min-height: var(--control-h); }
}
table.main th.num .sort-btn { flex-direction: row-reverse; justify-content: flex-start; }
table.main th .sort-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: var(--radius-sm); }
table.main th .arr { width: 10px; height: 10px; opacity: 0; color: var(--label-secondary); flex: none; }
table.main th.sorted .arr { opacity: 1; }
table.main th.sorted { color: var(--label); }
/* Inset grouped separators: ONE hairline per row that stops 12px short of the
   leading (right) edge, like an iOS inset list. Every cell draws a plain
   border; only the leading (sticky name) cell swaps it for a background image
   that starts 12px in - drawn as an image so that cell keeps its opaque fill
   under the same line. */
table.main td { height: var(--row-h); padding: 0 12px; border-bottom: var(--hairline) solid var(--separator-quiet); white-space: nowrap; font-variant-numeric: tabular-nums; vertical-align: middle; }
table.main td:first-child {
  border-bottom: 0;
  background-image: linear-gradient(var(--separator), var(--separator)); background-repeat: no-repeat;
  background-size: calc(100% - 12px) var(--hairline); background-position: left bottom;
}
table.main tbody tr:last-child td { border-bottom: 0; background-image: none; }
table.main td.num, table.main th.num { text-align: right; direction: ltr; unicode-bidi: isolate; }
/* Alternating rows in a wide multicolumn table (HIG Lists and tables, macOS).
   The fill is the quietest step, so it separates without reading as a state -
   hover and selection still win because they come after it. */
table.main tbody tr:nth-child(even) td, table.main tbody tr:nth-child(even) td.nm { background-color: var(--fill-4); }
table.main tbody tr:hover td { background-color: var(--fill-3); }
table.main tr[aria-selected="true"] td { background-color: var(--tint); }
table.main th.nm, table.main td.nm {
  position: sticky; inset-inline-start: 0; z-index: 10; background-color: var(--bg-grouped-2);
  min-width: 250px; max-width: 340px; white-space: normal;
  box-shadow: -1px 0 0 var(--separator) inset;
}
table.main th.nm { z-index: 25; }
table.main tbody tr:hover td.nm { background-color: var(--bg-grouped-3); }
/* A service line's own head row: the line and its three figures, one band the
   width of the table, so a long list reads as a table per service line rather
   than one wall (REQ-11). It stays under the sticky column header. */
table.main tbody tr.group-head th {
  position: sticky; inset-inline-start: 0; top: auto; z-index: 15; height: 36px; padding: 0 12px;
  background: var(--bg-grouped-3); color: var(--label); border-bottom: 1px solid var(--separator);
  font: var(--text-footnote); font-weight: 600; text-align: start; cursor: default;
}
.group-head-line { display: flex; align-items: baseline; gap: 4px var(--space-4); flex-wrap: wrap; }
.group-head-name { font-weight: 600; }
.group-head-figure { display: inline-flex; align-items: baseline; gap: 6px; font-weight: 400; color: var(--label-secondary); font-variant-numeric: tabular-nums; }
.group-head-figure .num { color: var(--label); font-weight: 600; direction: ltr; unicode-bidi: isolate; }
/* A proportional bar behind a measure: the share of the column's widest value,
   in the quietest fill, so a wall of digits has a shape (REQ-15). */
table.main td:has(> .cell-bar) { position: relative; }
table.main td > .cell-bar {
  --share: 0%;   /* the row's share of the column's widest value, set per cell */
  position: absolute; inset-block: 6px; inset-inline-start: 0; z-index: 0;
  width: var(--share); background: var(--fill-4); border-radius: var(--radius-xs); pointer-events: none;
}
table.main td > .cell-figure { position: relative; z-index: 1; }
table.main td[data-col="status"] { white-space: nowrap; }
td.nm .t { font-weight: 500; line-height: 20px; }
td.nm .m { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; font: var(--text-caption-1); color: var(--label-secondary); margin-top: 2px; }
td .sub { font: var(--text-caption-1); color: var(--label-secondary); }
/* Editing, the way System Settings reveals "Connect" on hover: the cell is
   the control, the pencil appears on hover, focus and always on touch. */
td.editable { cursor: default; }
/* An empty editable cell: the invitation reads as a placeholder, not a value. */
td.editable .cell-edit-text.is-placeholder { color: var(--label-secondary); }
td.editable:hover { box-shadow: none; }
td.editable .cell-edit { position: relative; display: flex; align-items: center; gap: 8px; width: calc(100% + 16px); max-width: none; height: var(--control-h-sm); min-height: var(--control-h-sm); margin: 0 -8px; padding: 0 8px; color: var(--label); font: inherit; font-weight: 400; text-align: start; border-radius: var(--radius-sm); }
td.editable .cell-edit::before { content: ""; position: absolute; inset: -4px 0; }   /* the 44px row is the hit area */
.cell-edit-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.cell-edit-glyph { width: 14px; height: 14px; flex: none; color: var(--label-tertiary); opacity: 0; transition: opacity var(--duration-fast) var(--ease); }
td.editable:hover .cell-edit-glyph, .cell-edit:focus-visible .cell-edit-glyph, .cell-edit-icon:focus-visible .cell-edit-glyph { opacity: 1; }
td.editable:hover .cell-edit { background: var(--fill-4); }
td.editable .cell-edit-icon { position: relative; width: 28px; height: 28px; min-height: 28px; padding: 0; margin: 0; margin-inline-start: 2px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; vertical-align: middle; color: var(--label-tertiary); }
.cell-edit-icon::before { content: ""; position: absolute; inset: -8px; }  /* 44x44 hit area around a 28px glyph button */
td.editable .cell-edit-icon:hover { background: var(--fill-4); color: var(--accent-text); }
@media (hover: none) { .cell-edit-glyph { opacity: 1; } }
.edit-input { width: 110px; height: var(--control-h-sm); min-height: var(--control-h-sm); padding: 0 8px; }
table.main .btn-sm { height: var(--control-h-sm); min-height: var(--control-h-sm); }
/* Pause/resume as a symbol with a title; the armed state is the one tinted thing in the row. */
.row-action { position: relative; width: var(--control-h-sm); height: var(--control-h-sm); min-height: var(--control-h-sm); padding: 0; border-radius: 50%; background: transparent; color: var(--label-secondary); }
.row-action::before { content: ""; position: absolute; inset: -4px; }
.row-action .glyph { width: 14px; height: 14px; }
tr:hover .row-action, .row-action:focus-visible, .row-action:hover:not(:disabled) { background: var(--fill-4); color: var(--label); }
.row-action.btn-confirm { width: auto; padding: 0 12px; border-radius: var(--radius-sm); color: var(--accent-text); background: var(--tint); font: 500 .8125rem/1.125rem var(--font-sans); }
.row-action.btn-confirm:hover:not(:disabled) { background: var(--tint-strong); color: var(--accent-text); }
table.main .campaign-open { display: block; max-width: 100%; color: var(--label); font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; line-height: 20px; padding: 0; min-height: 36px; text-align: start; }
table.main .campaign-open:hover { background: none; text-decoration: underline; text-underline-offset: 3px; }
table.main td.subject-cell { min-width: 140px; max-width: 280px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding-block: 0; }
table.main td.subject-cell > span { overflow: hidden; text-overflow: ellipsis; vertical-align: middle; }
.subject-edit, .budget-edit { display: inline-flex; margin-inline-start: 8px; color: var(--accent-text); font: var(--text-caption-1); vertical-align: middle; }
/* The subject is the button (a pencil beside it); the budget keeps a 28px glyph button after the value. */
.subject-edit.cell-edit { margin-inline-start: -8px; font: var(--text-subhead); }
.budget-edit.cell-edit-icon { margin-inline-start: 2px; }
.subject-cell input { display: block; width: 100%; min-width: 150px; height: var(--control-h-sm); min-height: var(--control-h-sm); margin-bottom: 6px; }
.subject-cell .btn, .subject-cell .text-button { margin-inline-end: 8px; }
.subject-cell [role="alert"] { display: block; color: var(--red-text); }
@keyframes col-flash { from { background-color: var(--tint-strong); } to { background-color: transparent; } }
table.main td.col-highlight, table.main th.col-highlight, .ctable .col-highlight { animation: col-flash 2s var(--ease) both; }
.campaign-report-heading { display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px 16px; margin: 0 0 var(--space-4); }
.campaign-report-heading h2 { font: var(--text-title-2); }
.campaign-report-heading .report-note { flex: 1 1 260px; margin: 0; overflow-wrap: anywhere; }
.report-history-entry { margin: 0 0 var(--space-4); }

/* ------------------------------------------------------- 5. settings ---- */

/* The formulas and Daniela panels are frameless: a section on the grouped
   page whose groups are the cards, not a card holding cards. */
.settings-panel { margin-bottom: var(--space-4); }
#formulaPanel, #analysisPanel { background: transparent; border: 0; box-shadow: none; border-radius: 0; padding: 8px 0 40px; margin: 0; max-width: 100%; }
.settings-panel-head { display: flex; align-items: center; flex-wrap: wrap; gap: 10px 16px; padding-bottom: 14px; margin-bottom: 18px; border-bottom: var(--hairline) solid var(--separator); }
.settings-panel-head > .settings-actions, .settings-panel-head > .btn:last-child { margin: 0; padding: 0; border: 0; margin-inline-start: auto; }
.settings-panel-head h2 { font: var(--text-title-2); }
.settings-panel-head .card-sub { font: var(--text-footnote); color: var(--label-secondary); margin: 2px 0 0; max-width: 610px; }
.settings-actions { display: flex; align-items: center; justify-content: flex-end; flex-wrap: wrap; gap: 8px; margin-top: var(--space-4); padding-top: var(--space-4); border-top: var(--hairline) solid var(--separator); }
.settings-actions .report-note { margin: 0; margin-inline-end: auto; }
.settings-actions .btn-primary { display: inline-flex; width: auto; min-width: 120px; }
.analysis-summary { max-width: 76ch; margin: 0 0 var(--space-4); font: var(--text-body); font-variant-numeric: tabular-nums; }
#formulaPanel > details { margin-top: var(--space-4); padding-top: var(--space-3); border-top: var(--hairline) solid var(--separator); }   /* its summary: the shared disclosure recipe (KPI tiles) */
.formula-completion { position: relative; width: 100%; min-width: 0; }
.formula-completion input { font-family: var(--font-mono); }
.formula-suggestions {
  position: absolute; z-index: 120; inset-inline: 0; top: calc(100% + 5px);
  max-height: min(300px, 45vh, var(--formula-menu-space, 300px)); overflow-y: auto; overscroll-behavior: contain;
  margin: 0; list-style: none; direction: rtl;
}
.formula-suggestion {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  width: 100%; min-height: var(--menu-row-h); padding: 6px 10px; border-radius: var(--radius-sm);
  text-align: start; cursor: pointer; font: var(--text-callout); color: var(--label);
}
.formula-suggestion:hover, .formula-suggestion[aria-selected="true"] { background: var(--fill-3); }
.formula-suggestion-label { min-width: 0; overflow-wrap: anywhere; }
.formula-suggestion-token { direction: ltr; unicode-bidi: isolate; color: var(--label-secondary); font: var(--text-caption-1); font-family: var(--font-mono); }
.formula-suggestions[data-placement="above"] { top: auto; bottom: calc(100% + 5px); }
/* The line above the table, present only while a filter is active: a tinted summary and "נקה", no card around them. */
#formulaFilter { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2) var(--space-3); margin: 0 0 var(--space-3); padding: 0; background: transparent; border: 0; }
#formulaFilter .select-control { flex: 0 1 230px; min-width: 0; }
#formulaFilter > input { width: 120px; }
#formulaFilter > .report-note { margin: 0; }

/* Channel picker (a details element) */
.report-channel-picker { position: relative; min-width: 0; }
.report-channel-trigger { display: flex; width: 100%; padding-inline-end: 34px; list-style: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; position: relative; }
.report-channel-trigger::-webkit-details-marker { display: none; }
.report-channel-trigger::after { content: ""; position: absolute; inset-inline-end: 12px; top: 50%; width: 12px; height: 12px; transform: translateY(-50%); background: var(--label-secondary); -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M4.5 6.2L8 2.7l3.5 3.5M4.5 9.8L8 13.3l3.5-3.5%27 fill=%27none%27 stroke=%27%23000%27 stroke-width=%271.8%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M4.5 6.2L8 2.7l3.5 3.5M4.5 9.8L8 13.3l3.5-3.5%27 fill=%27none%27 stroke=%27%23000%27 stroke-width=%271.8%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E") center / contain no-repeat; }
.report-channel-picker[open] > .report-channel-trigger { background: var(--bg-grouped-3); }
.report-channel-panel {
  position: absolute; z-index: 85; inset-inline-start: 0; top: calc(100% + 6px);
  /* The list is seven rows and an actions bar - 377px - so a 360px cap drew a
     scrollbar down the full edge of a panel that was 17px short of its own
     content. The cap clears it and still yields to a short window. */
  min-width: 245px; max-width: min(360px, calc(100vw - 32px)); max-height: min(24rem, calc(100dvh - 8rem)); overflow-y: auto; overscroll-behavior: contain;
}
.report-channel-option { min-height: var(--row-h); }
.report-channel-panel .grabber, .report-channel-panel .sheet-title { display: none; }
.report-channel-option input { flex: none; }
.report-channel-option:has(input:disabled) { opacity: .4; cursor: default; }
.report-channel-actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; padding: 10px 6px 4px; margin-top: 6px; border-top: var(--hairline) solid var(--separator); }

/* --------------------------------------------- 5. popover, sheet, toast --- */

/* Popovers, sheets and the toast: thick glass, the transient layer. */
.popover {
  position: fixed; z-index: 1200; max-width: 320px; padding: 12px 14px;
  background: var(--glass-fill-thick); color: var(--label); border-radius: var(--radius-menu);
  box-shadow: inset 0 1px 0 var(--glass-highlight), inset 0 -1px 0 var(--glass-lowlight), var(--glass-shadow-thick);
  font: var(--text-footnote); direction: rtl; text-align: start;
  transform-origin: top; animation: pop-in var(--duration-transient) var(--ease);
}
.popover:focus-visible { outline: none; }
/* The arrow points at the control that opened the popover (HIG popovers), so
   a box clamped to the viewport edge still reads as belonging to its source.
   placePopover (app.js) appends it and sets its left to the anchor's centre,
   kept 14px inside the corners; on a popover placed above it moves to the
   bottom edge. The rotated square is clipped to the half that protrudes, so
   the material never doubles over the box and the rim runs along both edges. */
.popover-arrow {
  position: absolute; top: -6px; left: var(--arrow-x, 50%); width: 12px; height: 12px; margin-left: -6px; pointer-events: none;
  background: inherit; box-shadow: -0.5px -0.5px 0 var(--glass-rim);
  transform: rotate(45deg); clip-path: polygon(-1px -1px, calc(100% + 1px) -1px, -1px calc(100% + 1px));
}
.popover[data-placement="above"] .popover-arrow {
  top: auto; bottom: -6px; box-shadow: 0.5px 0.5px 0 var(--glass-rim);
  clip-path: polygon(calc(100% + 1px) -1px, calc(100% + 1px) calc(100% + 1px), -1px calc(100% + 1px));
}
/* The chart tooltip shares the popover look but follows the pointer: no entrance animation. */
.tt.popover { padding: 8px 12px; z-index: 1300; animation: none; max-width: 320px; }
.popover-notes p, .popover-notes li { margin: 0; font: var(--text-subhead); line-height: 20px; }
.popover-notes .popover-title { display: flex; align-items: center; gap: 6px; margin-bottom: 4px; font: var(--text-headline); }
.popover-notes .popover-title .glyph { width: 14px; height: 14px; color: var(--orange); }
.popover-notes ul { margin: 0; padding-inline-start: 18px; display: grid; gap: 6px; }
.popover-notes bdi { unicode-bidi: isolate; }
.popover .grabber { display: none; }
/* The floor rises with the software keyboard here too: the period sheet's
   custom range is a pair of numeric fields on its own bottom bar, and the
   keyboard they raise covered the field being typed into. --kb is the strip
   the keyboard has taken (theme.js), and unset whenever none is up. */
.popover.as-sheet {
  inset-inline: 0; bottom: var(--kb, 0px); top: auto; max-width: none;
  max-height: min(70dvh, calc(100dvh - var(--kb, 0px) - max(12px, env(safe-area-inset-top)))); overflow: auto;
  padding: 8px 20px max(20px, env(safe-area-inset-bottom)); border-radius: var(--radius-sheet) var(--radius-sheet) 0 0;
  box-shadow: inset 0 1px 0 var(--glass-highlight), inset 0 -1px 0 var(--glass-lowlight), 0 0 0 0.5px var(--glass-rim), var(--shadow-lg); animation: rise var(--duration) var(--ease);
}
.popover.as-sheet .grabber, .sheet .grabber { display: block; width: 36px; height: 5px; margin: 0 auto 12px; border-radius: var(--radius-pill); background: var(--fill); }
/* A panel moved into a sheet stops being its own surface: the sheet is the
   surface, so the panel drops its overlay position, fill and shadow. The date
   form's bar keeps its floor, because eleven preset rows stand above it and a
   reader must not have to scroll to find "החל"; it turns OPAQUE to do so,
   since glass never samples glass (14.1). The negative margin hands it the
   sheet's own bottom padding, so the bar reaches the sheet's edge while its
   contents stay clear of the home indicator. The inline axis does the same with
   the sheet's 20px gutter: an opaque bar inset from both sides of a full-bleed
   sheet read as a misplaced card with a strip of sheet showing either side of
   it, and its own padding keeps the controls on the sheet's 20px grid. */
.popover.as-sheet .user-menu-items { position: static; background: transparent; box-shadow: none; }
.popover.as-sheet .dd-foot {
  bottom: calc(-1 * max(20px, env(safe-area-inset-bottom))); margin-bottom: calc(-1 * max(20px, env(safe-area-inset-bottom)));
  padding-bottom: max(20px, env(safe-area-inset-bottom));
  margin-inline: -20px; padding-inline: 20px;
  background: var(--bg-elevated);
  /* Opaque and on the floor, the bar ended the list rather than covering it:
     three of the eleven presets sit under it at first paint and a hairline is
     all that said so, with no scrollbar to see on iOS until a reader already
     scrolls. The soft edge above it is the same shading the glass surfaces use
     at a lower edge, so the list visibly passes under the bar. */
  box-shadow: 0 -8px 12px -8px var(--glass-lowlight);
}
@keyframes rise { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
/* Closing reverses the rise: the sheet sinks and fades while its scrim fades (is-closing, app.js). */
@keyframes sink { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateY(12px); } }
.popover.as-sheet.is-closing, .sheet.is-closing { animation: sink var(--duration-transient) var(--ease) both; pointer-events: none; }
.scrim { position: fixed; inset: 0; z-index: 1100; background: rgba(0,0,0,.28); animation: fade-in var(--duration-fast) var(--ease); }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }

/* The top edge stops below the status bar and the Dynamic Island: the page is
   viewport-fit=cover, so a tall sheet that reached 100dvh would put its
   grabber, its title and both of its actions under the island. The gap is the
   safe-area inset, and never less than 12px, which also leaves a strip of
   scrim to tap on a phone without one (HIG Sheets, March 2026).

   The floor rises with the software keyboard here too, as it does for the
   period sheet and the chat: this is the sheet the reader TYPES in - the
   formula editor's name field, its expression field and the selects under
   them all sat beneath a 336px keyboard. --kb is the strip the keyboard has
   taken (theme.js), unset whenever none is up, and the height gives back what
   the floor took so the top edge holds still. The >=768px block below
   re-centres the sheet, so the desktop dialog is untouched. */
.sheet {
  --sheet-top-gap: max(12px, env(safe-area-inset-top));
  position: fixed; z-index: 1150; inset-inline: 0; bottom: var(--kb, 0px); top: auto;
  display: flex; flex-direction: column; max-height: calc(100dvh - var(--sheet-top-gap) - var(--kb, 0px));
  background: var(--glass-fill-thick); color: var(--label); border-radius: var(--radius-sheet) var(--radius-sheet) 0 0;
  box-shadow: inset 0 1px 0 var(--glass-highlight), inset 0 -1px 0 var(--glass-lowlight), 0 0 0 0.5px var(--glass-rim), var(--shadow-lg);
  padding-top: 8px; animation: rise var(--duration) var(--ease);
}
.sheet .grabber { margin-bottom: 4px; }
/* Cancel leads, the confirming action trails (HIG sheets, March 2026). */
.sheet-head { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; min-height: 56px; padding: 0 12px; gap: 8px; }
.sheet-head > .btn:first-child { justify-self: start; }
.sheet-head > .btn:last-child { justify-self: end; }
.sheet-title { font: var(--text-headline); text-align: center; grid-column: 2; }
.sheet-body { padding: 0 20px 20px; overflow: auto; }
.sheet-body .group-title:first-child { margin-top: 8px; }
/* Pop-up menus portaled to <body> must sit above the sheet and its scrim. */
html.sheet-open .select-menu { z-index: 1200; }
@media (min-width: 768px) {
  .sheet {
    inset: 50% auto auto 50%; transform: translate(-50%, -50%); width: 560px; max-width: calc(100vw - 32px);
    max-height: min(85dvh, 760px); border-radius: var(--radius-sheet); padding-top: 0;
    animation: sheet-in var(--duration) var(--ease);
  }
  /* The centred dialog is held by its own translate, so its scale rides on it:
     it grows out of the control that opened it (openSheet sets the origin from
     that control's rect) and shrinks back into it. */
  .sheet.is-closing { animation: sheet-out var(--duration-transient) var(--ease) both; }
  .sheet.wide { width: 720px; }
  .sheet .grabber { display: none; }
  .sheet-head { border-bottom: var(--hairline) solid var(--separator); padding: 0 16px; }
  .sheet-body { padding: 20px; }
}

@keyframes sheet-in { from { opacity: 0; transform: translate(-50%, -50%) scale(.94); } to { opacity: 1; transform: translate(-50%, -50%); } }
@keyframes sheet-out { from { opacity: 1; transform: translate(-50%, -50%); } to { opacity: 0; transform: translate(-50%, -50%) scale(.94); } }

.toast {
  position: fixed; z-index: 1250; bottom: max(24px, env(safe-area-inset-bottom)); left: 50%;
  transform: translate(-50%, 12px); opacity: 0; pointer-events: none;
  max-width: min(480px, calc(100vw - 32px)); padding: 10px 16px;
  background: var(--glass-fill-thick); color: var(--label); border-radius: var(--radius-menu);
  box-shadow: inset 0 1px 0 var(--glass-highlight), inset 0 -1px 0 var(--glass-lowlight), var(--glass-shadow-thick);
  font: var(--text-footnote); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: opacity var(--duration) var(--ease), transform var(--duration) var(--ease);
}
.toast.on { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }

/* -------------------------------------------------------- 5. loading ----- */

/* The page is viewport-fit=cover, so top: 0 is under the status bar and the
   Dynamic Island: the whole 3px of the one moving sign that a refresh is
   running was drawn inside the island's strip and never seen. The physical
   insets go on the physical properties, so the direction never enters into it. */
.loadbar { position: fixed; top: env(safe-area-inset-top); left: env(safe-area-inset-left); right: env(safe-area-inset-right); height: 3px; z-index: 400; display: none; background: var(--fill-3); }
.loadbar::after { content: ""; position: absolute; top: 0; bottom: 0; width: 40%; border-radius: var(--radius-pill); background: var(--accent); animation: load 1.05s infinite linear; }
.loadbar.on { display: block; }
@keyframes load { 0% { left: 100%; } 100% { left: -40%; } }

.skeleton { display: grid; gap: var(--space-4); animation: sk-pulse 1.4s ease-in-out infinite; }
.sk-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: var(--space-3); }
.sk-tile, .sk-chart, .sk-row { background: var(--fill-4); border-radius: var(--radius-md); }
.sk-tile { min-height: 112px; }
.sk-chart { height: 300px; }
.sk-rows { display: grid; gap: 8px; }
.sk-row { height: var(--row-h); border-radius: var(--radius-sm); }
@keyframes sk-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .55; } }

.progress { height: 4px; border-radius: var(--radius-pill); background: var(--fill-3); overflow: hidden; }
.progress > i { display: block; height: 100%; border-radius: var(--radius-pill); background: var(--accent); transition: width var(--duration) var(--ease); }
.spinner { width: 16px; height: 16px; border-radius: 50%; border: 2px solid var(--fill); border-top-color: var(--label-secondary); animation: rot .8s linear infinite; }

/* ----------------------------------------------- 6. login (system blue) --- */

.login-wrap { min-height: 100dvh; display: grid; place-items: center; padding: var(--space-6) var(--gutter); }
.login-card {
  width: 100%; max-width: 400px; padding: var(--space-8);
  background: var(--bg-grouped-2); border: var(--card-border); border-radius: var(--radius-xl); box-shadow: var(--shadow-lg);
  display: grid; gap: var(--space-4);
}
.login-card h1 { font: var(--text-title-1); margin: 0 0 var(--space-2); }
.login-card .sub { color: var(--label-secondary); font: var(--text-subhead); }
.login-card .field { margin: 0; }
.login-card .field > input { height: 44px; min-height: 44px; font: 400 1.0625rem/1.375rem var(--font-sans); }
.login-card .alert { margin: 0; }
.login-logo { display: block; box-sizing: content-box; width: auto; height: 48px; margin: 0 0 var(--space-2); }
/* The agency logo is a JPEG with its own white background: give it a white
   plate in dark mode rather than inverting it - on the sign-in card and at
   the head of the rail, the two places it appears. The plate carries the
   wordmark at full strength, so the rail's resting dimming comes off. The
   padding is the plate's own: with the sheet's border-box the same 22px mark
   rendered a 16px glyph in dark and its 22px in light. */
:root[data-theme="dark"] .login-logo { background: #fff; padding: 6px 10px; border-radius: var(--radius-sm); }
:root[data-theme="dark"] .sidebar-brand img { box-sizing: content-box; background: #fff; padding: 3px 6px; border-radius: var(--radius-xs); opacity: 1; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .login-logo { background: #fff; padding: 6px 10px; border-radius: var(--radius-sm); }
  :root:not([data-theme="light"]) .sidebar-brand img { box-sizing: content-box; background: #fff; padding: 3px 6px; border-radius: var(--radius-xs); opacity: 1; }
}

/* ------------------------------------------------- 6. admin and check ---- */

.admin-wrap, .connection-wrap { max-width: var(--content-max); margin: 0 auto; padding: var(--space-4) var(--gutter) var(--space-12); }
.admin-header, .connection-header { display: flex; justify-content: space-between; align-items: center; gap: var(--space-4); flex-wrap: wrap; margin-bottom: var(--space-5); min-height: var(--control-h); }
.admin-header h1, .connection-header h1 { font: var(--text-title-1); }
.admin-header h2 { font: var(--text-title-2); }
.connection-header p { margin: 4px 0 0; color: var(--label-secondary); font: var(--text-footnote); }
.admin-nav { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.row2 { display: grid; gap: var(--space-6); }
.panel { padding: var(--space-5); }
.panel h2 { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin: 0 0 var(--space-4); }
.panel > .admin-header { margin-bottom: var(--space-4); }
.table-scroll { overflow: auto; max-height: 560px; }
#frmTitle { scroll-margin-top: 24px; }
.tlist { width: 100%; min-width: 1000px; border-collapse: separate; border-spacing: 0; font: var(--text-subhead); }
.tlist thead { position: sticky; top: 0; z-index: 1; background: var(--bg-grouped-2); }
.tlist th, .tlist td { text-align: start; height: var(--row-h); padding: 0 12px; border-bottom: var(--hairline) solid var(--separator-quiet); vertical-align: middle; white-space: nowrap; }
.tlist th { height: 40px; color: var(--label-secondary); font: 500 .75rem/1rem var(--font-sans); }
.tlist td:first-child { min-width: 180px; font-weight: 500; }
.tlist td:nth-child(2), .tlist td:nth-child(3), .tlist td:nth-child(4) { direction: ltr; text-align: left; font-variant-numeric: tabular-nums; }
.tlist td:last-child { min-width: 230px; }
.tlist tr:last-child td { border-bottom: 0; }
.tlist tbody tr:hover td { background: var(--fill-4); }
.tlist tbody tr.account-row td { background: var(--bg-grouped-3); }
.account-row td:first-child { padding-inline-start: 28px; font-weight: 400; }
.tlist .btn-sm { margin-inline-end: 4px; }

/* The client form: grouped inset lists, one group per topic. The groups sit
   inside a white panel, so the inset list takes the grouped-3 tone and its
   controls the card tone. */
.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-6); }
.form-section { min-width: 0; }
.form-section > h3 { font: var(--text-footnote); font-weight: 500; color: var(--label-secondary); margin: 0 16px 6px; }
.form-section > p.muted { margin: 0 16px var(--space-3); }
.frm .group { background: var(--bg-grouped-3); }
.frm .group input, .frm .group select, .frm .group .select-trigger { background: var(--bg-grouped-2); }
.frm .form-field { display: grid; grid-template-columns: minmax(120px, 160px) minmax(0, 1fr); align-items: center; gap: 4px 12px; min-height: var(--row-h); padding: 4px 16px; }
.frm .form-field + .form-field { border-top: var(--hairline) solid var(--separator); }
.frm .form-field > label { margin: 0; font: var(--text-subhead); color: var(--label); }
.frm .form-field > input, .frm .form-field > select, .frm .form-field > .select-control { grid-column: 2; }
.frm .form-field > .field-help { grid-column: 1 / -1; margin: 0 0 4px; }
.frm .form-field input, .frm .form-field select { height: var(--control-h); min-height: var(--control-h); font: var(--text-subhead); }
.frm .form-field .select-trigger { height: var(--control-h); min-height: var(--control-h); font: var(--text-subhead); background: var(--bg-grouped-2); box-shadow: inset 0 0 0 1px var(--separator); border-radius: var(--radius-control); }
/* Hairlines between rows run the full width, like .form-field + .form-field.
   Rows inside a generated container (CRM fields, CRM controls) always follow
   another row; the domain list comes first in its group, so only its second
   row onwards gets a line, and the "הוסף תחום" row only when the list has rows. */
.frm .group > .form-field + .group-row, .frm .group > .group-row + .form-field, .frm .group > .group-row + .group-row,
.frm .group > div > .form-field, .frm .group > div > .group-row, .frm .group > div > .domain-row + .domain-row,
.frm .group > div:not(:empty) + .group-row {
  border-top: var(--hairline) solid var(--separator); margin-inline-start: 0; padding-inline-start: 16px;
}
.frm .group > div:empty { display: none; }
.frm .group-row { padding: 6px 16px; flex-wrap: wrap; row-gap: 6px; }
.frm .group-row .actions { margin: 0; }
.frm .group-row > .group-label { font: var(--text-subhead); }
.frm .toggle-row { cursor: pointer; }
.toggle > input[type="checkbox"] { width: 100%; height: 100%; }
.frm .form-field > .field-inline { grid-column: 2; display: flex; align-items: center; gap: 8px; min-width: 0; flex-wrap: wrap; }
.field-inline > input { flex: 1 1 160px; min-width: 0; }
.frm .form-field > .field-inline > input[type="color"] { flex: 0 0 44px; width: 44px; height: var(--control-h-sm); padding: 3px; border-radius: var(--radius-control); cursor: pointer; }
.frm .form-field > .field-inline > input[type="color"]:disabled { opacity: .4; cursor: default; }
/* A descriptor that opens a group (the stage mapping under the connection
   fields) gets a footnote-weight title row, separated from the row above by
   the same hairline the rows use; the first row under it takes no line of its own. */
.frm .group .group-subtitle { margin: 0; padding: 12px 16px 4px; font: var(--text-footnote); color: var(--label-secondary); border-top: var(--hairline) solid var(--separator); }
.frm .group > div > .group-subtitle + .form-field,
.frm .group > div > .group-subtitle + .group-row { border-top: 0; }
.frm .group + .group-footer { margin-top: 6px; }
.brand-preview { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.brand-swatch {
  display: inline-flex; align-items: center; gap: 8px; height: 36px; padding: 0 10px; border-radius: var(--radius-control);
  box-shadow: inset 0 0 0 1px var(--separator); font: 600 .8125rem/1.125rem var(--font-sans); white-space: nowrap;
}
.brand-swatch i { width: 14px; height: 14px; border-radius: 50%; display: inline-block; flex: none; }
.brand-swatch .brand-btn { height: 24px; padding: 0 10px; border-radius: var(--radius-pill); font: 600 .75rem/1.5rem var(--font-sans); }
.domain-row { display: grid; grid-template-columns: minmax(120px, 1fr) minmax(160px, 2fr) auto; gap: 8px; align-items: center; padding: 6px 16px; }
.domain-row + .domain-row { border-top: var(--hairline) solid var(--separator); }
.domain-row input { height: var(--control-h-sm); min-height: var(--control-h-sm); font: var(--text-subhead); }
/* Domain rows are labelled twice and shown once: column titles above the list
   on a desktop, a label above each field on a phone. */
.domain-head { display: grid; grid-template-columns: minmax(120px, 1fr) minmax(160px, 2fr) auto; gap: 8px; padding: 8px 16px 4px; font: var(--text-footnote); color: var(--label-secondary); }
.domain-head > span:last-child { min-width: 50px; }
.domain-head:not([hidden]) + #domainList > .domain-row:first-child { border-top: var(--hairline) solid var(--separator); }
.domain-cell { display: grid; gap: 4px; min-width: 0; }
.frm .domain-cell > label { display: none; margin: 0; font: var(--text-footnote); color: var(--label-secondary); }
/* Admin status chips follow the dashboard's status rule: a small dot in one
   semantic colour beside plain text on a neutral fill, never a tinted capsule. */
.status-chip, .chip.stored, .tenant-chips .chip.on, .tenant-chips .chip.bad { gap: 6px; color: var(--label); background: var(--fill-4); }
.status-chip::before, .chip.stored::before, .tenant-chips .chip.on::before, .tenant-chips .chip.bad::before { content: ""; flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--gray); }
.chip.stored::before, .status-chip.on::before, .tenant-chips .chip.on::before { background: var(--green); }
.status-chip.bad::before, .tenant-chips .chip.bad::before { background: var(--red); }
.status-chip.bad { white-space: normal; height: auto; min-height: 24px; padding: 2px 10px; text-align: start; }
.tlist td.tenant-cell { height: auto; padding-top: 6px; padding-bottom: 6px; }
.tenant-chips { display: flex; gap: 4px; margin-top: 3px; }
.tenant-chips .chip { height: 20px; padding: 0 8px; font: 500 .6875rem/.875rem var(--font-sans); }
.tenant-chips .chip.on::before, .tenant-chips .chip.bad::before { width: 6px; height: 6px; }
.group-footer.ok { color: var(--green-text); }
.group-footer.err { color: var(--red-text); }
.actions { display: flex; gap: var(--space-2); margin-top: var(--space-4); flex-wrap: wrap; align-items: center; }
.form-message { margin-top: var(--space-3); font: var(--text-subhead); }
#msg:empty, #frmMsg:empty, #userMsg:empty { display: none; }
#msg:not(:empty) { margin-bottom: var(--space-4); }
#extraOps { margin-top: var(--space-6); padding-top: var(--space-6); border-top: var(--hairline) solid var(--separator); }
.keybox { direction: ltr; text-align: left; font-family: var(--font-mono); font-size: .875rem; background: var(--bg-grouped-3); border-radius: var(--radius-md); padding: 12px; margin: var(--space-4) 16px 0; overflow-wrap: anywhere; }
.ok { color: var(--green-text); } .err { color: var(--red-text); }
.userline { display: flex; justify-content: space-between; gap: 12px; align-items: center; flex-wrap: wrap; min-height: var(--row-h); padding: 4px 16px; border-bottom: var(--hairline) solid var(--separator); }
#userList:not(:empty) { margin: 0 0 var(--space-4); background: var(--bg-grouped-3); border-radius: var(--radius-md); overflow: hidden; }
#userList .userline:last-child { border-bottom: 0; }
#userList .userline.muted { border-bottom: 0; }

.connection-actions { display: flex; align-items: center; gap: var(--space-5); flex-wrap: wrap; padding: var(--space-4) var(--space-5); border-bottom: var(--hairline) solid var(--separator); }
#status { margin: 0; color: var(--label-secondary); font: var(--text-subhead); }
.connection-table { overflow-x: auto; }
.connection-table table { width: 100%; min-width: 620px; border-collapse: separate; border-spacing: 0; font: var(--text-subhead); }
.connection-table td, .connection-table th { height: var(--row-h); padding: 0 var(--space-5); border-bottom: var(--hairline) solid var(--separator); text-align: start; white-space: nowrap; }
.connection-table th { height: 40px; color: var(--label-secondary); font: 500 .75rem/1rem var(--font-sans); }
.connection-table tbody tr:last-child td { border-bottom: 0; }

/* ==== track F: formulas panel, builder sheet and filter row ==== */

/* Panel: a settings group with a heading, footnote and actions. */
.formula-head { align-items: flex-start; }
.formula-head > div:first-child { flex: 1 1 240px; min-width: 0; }
.formula-head-actions { margin: 0; padding: 0; border: 0; flex-wrap: nowrap; }
.formula-list { margin-top: var(--space-2); }
.formula-row { align-items: flex-start; flex-wrap: wrap; padding: 12px 16px; gap: 8px 16px; }
.formula-row + .formula-row { margin-inline-start: 16px; padding-inline-start: 0; }
.formula-main { flex: 1 1 240px; min-width: 0; display: grid; gap: 4px; }
.formula-name { font: var(--text-headline); overflow-wrap: anywhere; }
.formula-expr { font: var(--text-footnote); color: var(--label-secondary); overflow-wrap: anywhere; }
.formula-expr > code { font: .8125rem/1.125rem var(--font-mono); direction: ltr; unicode-bidi: isolate; }
.formula-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 2px; }
.formula-actions { display: flex; align-items: center; gap: 2px; margin-inline-start: auto; align-self: center; }
.formula-confirm { font: var(--text-footnote); color: var(--label-secondary); margin-inline-end: 4px; }
.formula-status:not(:empty) { margin-top: var(--space-3); color: var(--red-text); }
.formula-load-error { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2) var(--space-3); }
.formula-load-error .report-note { margin: 0; }
.formula-skeleton { padding: 4px 0; }
.formula-empty, #formulaPanel .empty-state { background: var(--bg-grouped-2); border: var(--card-border); border-radius: var(--radius-md); box-shadow: var(--card-shadow); padding: var(--space-10) var(--space-6); margin-top: var(--space-4); }
.formula-empty .glyph { width: 40px; height: 40px; }
.formula-empty .btn { margin-top: 6px; }

/* Builder sheet. */
.formula-builder { display: grid; gap: var(--space-5); }
/* The templates pop-up follows its label, so its menu opens inside the sheet rather than over the scrim. */
.formula-field-head { display: flex; align-items: center; justify-content: flex-start; gap: var(--space-3); flex-wrap: wrap; }
.formula-field-head > label { font: var(--text-control); color: var(--label); }
.formula-field-head .select-control { flex: 0 1 auto; }
.formula-field-head .select-trigger { width: auto; min-width: 0; }
.formula-chip-row { display: flex; flex-wrap: wrap; gap: 6px; }
.formula-chip {
  display: inline-flex; align-items: center; height: 28px; padding: 0 10px;
  border-radius: var(--radius-sm); background: var(--fill-3); color: var(--label);
  font: 500 .8125rem/1.125rem var(--font-sans); white-space: nowrap;
  transition: background-color var(--duration-fast) var(--ease);
}
.formula-chip:hover { background: var(--fill-2); }
.formula-chip:active { background: var(--fill); }
.formula-chip.op { min-width: 36px; justify-content: center; padding: 0 8px; font: 500 1rem/1.25rem var(--font-mono); }
.field .formula-completion { width: 100%; }
.field .formula-completion > input {
  width: 100%; min-width: 0; height: var(--control-h); min-height: var(--control-h); padding: 0 12px;
  font: 1rem/1.375rem var(--font-mono); color: var(--label);
  background: var(--bg-grouped-3); border: 0; border-radius: var(--radius-control); box-shadow: inset 0 0 0 1px var(--separator);
}
.field[data-invalid="true"] .formula-completion > input { box-shadow: inset 0 0 0 1px var(--red-text); }
.field .select-segmented { width: 100%; }
.field .select-segmented .segmented { width: 100%; }
.formula-preview { font: var(--text-footnote); color: var(--label-secondary); margin: 0; font-variant-numeric: tabular-nums; }
.formula-preview:empty { display: none; }
.formula-preview-name { color: var(--label); }
.formula-preview-value { color: var(--label); font-weight: 600; }
.formula-form-error { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 8px; font: var(--text-footnote); color: var(--red-text); }
.formula-form-error:empty { display: none; }
/* Discard prompt: an inline confirmation at the top of the form, the destructive choice never the default. */
.formula-discard { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 8px; padding: 8px 12px; border-radius: var(--radius-md); background: var(--bg-grouped-3); font: var(--text-subhead); color: var(--label); }
.formula-discard-actions { display: inline-flex; align-items: center; gap: 4px; margin-inline-start: auto; }

/* Filter: it stands above the campaign table it filters, so it opens the view
   and carries no rule of its own above it - #formulaFilter owns the box. */
.formula-filter-title { font: var(--text-footnote); color: var(--label-secondary); margin: 0 0 8px; }
.formula-filter-row { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2) var(--space-3); }
.formula-filter-row .select-control { flex: 0 1 230px; min-width: 0; }
.formula-filter-row > input {
  width: 120px; min-width: 0; height: var(--control-h); min-height: var(--control-h); padding: 0 12px;
  font: var(--text-body); color: var(--label); direction: ltr; text-align: left; font-variant-numeric: tabular-nums;
  background: var(--bg-grouped-3); border: 0; border-radius: var(--radius-control); box-shadow: inset 0 0 0 1px var(--separator);
}
.formula-filter .formula-filter-note { margin: 8px 0 0; }
.formula-filter .formula-filter-note:empty { display: none; }
/* The value's own error sits beside the box, so the sentence naming the active
   filter is never replaced by a complaint about what was typed. */
.formula-filter-error { margin: 0; }

/* The builder teaches: an intro, headed chip rows with a live meaning line, a
   preview over the client's own campaigns, and a help disclosure in the panel. */
.formula-intro { margin: 0; max-width: 60ch; font: var(--text-footnote); color: var(--label-secondary); }
.formula-chip-group { display: grid; gap: 6px; }
.formula-field-note { min-height: 16px; margin: 0; font: var(--text-footnote); color: var(--label-secondary); }
.formula-preview-rows { display: grid; gap: 2px; }
.formula-preview-row { display: flex; align-items: baseline; gap: 6px; }
.formula-preview-note { margin: 0; font: var(--text-footnote); color: var(--label-secondary); }
.formula-empty-example > code, .formula-help code { font: .8125rem/1.125rem var(--font-mono); direction: ltr; unicode-bidi: isolate; }
.formula-count { margin-top: 4px; }
.formula-undo { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 8px; margin-top: var(--space-3); }
.formula-undo:empty { display: none; }
.formula-help > h4 { margin-top: var(--space-4); font: var(--text-headline); }
.formula-help > p { margin-top: 4px; font: var(--text-footnote); color: var(--label-secondary); }
.formula-help-list { display: grid; grid-template-columns: max-content 1fr; gap: 4px var(--space-3); margin: 6px 0 0; font: var(--text-footnote); }
.formula-help-list dt { color: var(--label); }
.formula-help-list dd { margin: 0; color: var(--label-secondary); }
/* Operator and field chips are the only practical way to build a formula on a
   phone, so under a finger they take the full 44px target (HIG Accessibility).
   The 32px pill keeps its own look; the padding carries the rest. */
@media (pointer: coarse) {
  .formula-chip { height: 44px; }
  .formula-chip.op { min-width: 44px; }
}
/* ==== track I: Daniela panel ==== */
/* The Daniela panel reads like a settings screen: a header, a segmented view
   switch, grouped inset lists on the page, toggles that save on change and a
   sheet for the rule editor. The panel is frameless, so its groups are the
   white cards on the grouped page, like System Settings. */
#analysisPanel .radar-head { display: flex; align-items: flex-start; gap: var(--space-3) var(--space-4); margin-bottom: var(--space-4); }
#analysisPanel .radar-head .radar-title { flex: 1 1 auto; min-width: 0; }
#analysisPanel .radar-head h2 { margin: 0; font: var(--text-title-2); }
#analysisPanel .radar-subtitle { margin: 2px 0 0; font: var(--text-footnote); color: var(--label-secondary); }
#analysisPanel .radar-tabs { margin-bottom: var(--space-5); isolation: isolate; }
#analysisPanel .radar-tabs > button { position: relative; z-index: 2; pointer-events: auto; }
#analysisPanel .radar-tabs > button[aria-selected="true"] { background: var(--segment-selected); font-weight: 600; color: var(--label); box-shadow: var(--shadow-thumb); }
#analysisPanel .radar-tabs.has-thumb > button[aria-selected="true"] { background: transparent; box-shadow: none; }
#analysisPanel .radar-actions { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2) var(--space-3); margin: 0 0 var(--space-3); }
#analysisPanel .radar-jobline { display: inline-flex; align-items: center; min-height: 20px; font: var(--text-footnote); color: var(--label-secondary); }
#analysisPanel .radar-jobline:empty { display: none; }
#analysisPanel .radar-job { display: inline-flex; align-items: center; gap: 8px; }
#analysisPanel .radar-message { margin: 0 0 var(--space-3); }
#analysisPanel .radar-message:empty, #analysisPanel .radar-delivery:empty, #analysisPanel .radar-evaluation:empty { display: none; }
#analysisPanel .group-footer.is-error, .radar-sheet-error.is-error { color: var(--red-text); }
#analysisPanel .group { background: var(--bg-grouped-2); }
#analysisPanel .group-title { margin-top: var(--space-6); }
#analysisPanel .radar-view > .group-title:first-child, #analysisPanel .radar-result > .group-title:first-child { margin-top: 0; }
#analysisPanel .radar-result { margin-top: var(--space-5); }
#analysisPanel .radar-result:empty { display: none; }
#analysisPanel .group-row { background: transparent; }
#analysisPanel .group-row > .toggle { margin-inline-start: auto; }
#analysisPanel .radar-number {
  width: 84px; height: var(--control-h-sm); min-height: var(--control-h-sm); margin-inline-start: auto; padding: 0 10px; text-align: center;
  font: var(--text-body); font-variant-numeric: tabular-nums; color: var(--label);
  background: var(--bg-grouped-3); border: 0; border-radius: var(--radius-control); box-shadow: inset 0 0 0 1px var(--separator);
}
/* While a save is in flight the focused control is only marked busy (disabling
   it would drop keyboard focus); it looks the same as its disabled neighbours. */
#analysisPanel .btn[aria-disabled="true"] { opacity: .4; cursor: default; }
#analysisPanel .toggle:has(input:disabled), #analysisPanel .toggle:has(input[aria-disabled="true"]) { opacity: .5; }
#analysisPanel .toggle:has(input:disabled) input, #analysisPanel .toggle:has(input[aria-disabled="true"]) input { cursor: default; }
#analysisPanel .radar-number:disabled, #analysisPanel .radar-number[aria-disabled="true"] { opacity: .5; }
#analysisPanel .radar-jobline:focus, #analysisPanel .radar-message:focus { outline: none; }
#analysisPanel .radar-jobline:focus-visible, #analysisPanel .radar-message:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--radius-xs); }
/* Rule rows: name and sentence at the start, switch and two plain actions at the end. */
#analysisPanel .radar-rule { flex-wrap: wrap; padding: 8px 16px; gap: 8px 12px; }
#analysisPanel .radar-rule > .group-label { display: flex; flex-direction: column; gap: 2px; flex: 1 1 240px; padding: 6px 0; }
#analysisPanel .radar-rule-name { font: var(--text-headline); color: var(--label); overflow-wrap: anywhere; }
#analysisPanel .radar-rule-sentence { font: var(--text-subhead); color: var(--label-secondary); overflow-wrap: anywhere; }
/* A formula expression is Latin: monospaced, in its own direction (the dir
   attribute isolates it), hugging the row's leading edge like the Hebrew lines. */
.radar-rule-expression { font: .8125rem/1.125rem var(--font-mono); color: var(--label-secondary); overflow-wrap: anywhere; }
#analysisPanel .radar-rule > .group-label > .radar-rule-expression { align-self: flex-start; max-width: 100%; }
.radar-sheet .field > .radar-rule-expression { margin: 0; }
#analysisPanel .radar-rule-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 6px; margin-inline-start: auto; }
#analysisPanel .radar-rule-actions .toggle { margin-inline-end: 6px; }
#analysisPanel .radar-confirm { font: var(--text-subhead); color: var(--label); margin-inline-end: 4px; }
#analysisPanel .radar-activity .group-value { flex: none; font: var(--text-footnote); }
/* The last analysis: a summary row, findings as rows with a "פרטים" disclosure, footnotes under the group. */
#analysisPanel .radar-summary-row { padding: 12px 16px; }
#analysisPanel .radar-summary-row .analysis-summary { margin: 0; }
#analysisPanel .radar-finding { display: block; padding: 16px 20px; }
#analysisPanel .radar-finding-title { margin: 0; font: var(--text-headline); overflow-wrap: anywhere; }
#analysisPanel .radar-finding-action { margin: 4px 0 0; max-width: 76ch; font: var(--text-subhead); line-height: 20px; color: var(--label-secondary); overflow-wrap: anywhere; }
#analysisPanel .radar-finding-note, .radar-disclosure .radar-finding-note { margin: 4px 0 0; font: var(--text-footnote); color: var(--label-secondary); }
/* (The "פרטים" summary takes the shared disclosure recipe, with the KPI appendix.) */
#analysisPanel .radar-disclosure p, #analysisPanel .radar-disclosure li { max-width: 76ch; margin: 8px 0; font: var(--text-subhead); color: var(--label); line-height: 22px; overflow-wrap: anywhere; }
#analysisPanel .radar-disclosure h5 { margin: 10px 0 2px; font: var(--text-headline); color: var(--label); }
#analysisPanel .radar-disclosure ul { margin: 4px 0; padding-inline-start: 20px; }
#analysisPanel .radar-result > .radar-disclosure { margin-top: var(--space-2); }
#analysisPanel .radar-more > .group { margin-top: var(--space-2); }
#analysisPanel .radar-fact { display: flex; flex-direction: column; gap: 2px; }
#analysisPanel .radar-fact-title { font-weight: 500; }
#analysisPanel .radar-fact-values { font: var(--text-footnote); color: var(--label-secondary); font-variant-numeric: tabular-nums; }
#analysisPanel .radar-skeleton { margin-top: var(--space-4); }
/* The rule sheet: two columns on wide screens, the name across both. */
.radar-sheet { display: grid; gap: var(--space-4); }
.radar-sheet .field > .help:empty { display: none; }
.radar-sheet .field > input[dir="ltr"] { text-align: left; }
.radar-sheet-error { margin: 0; font: var(--text-footnote); color: var(--red-text); }
.radar-sheet-error:empty { display: none; }
/* "לבטל את השינויים?" sits at the top of the sheet body as an inset group; empty, it takes no room. */
.radar-discard { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; padding: 10px 16px; border-radius: var(--radius-md); background: var(--bg-grouped-3); }
.radar-discard:empty { display: none; }
.radar-discard > .radar-confirm { flex: 1 1 200px; margin: 0; font: var(--text-subhead); color: var(--label); }
/* The two answers stay together: one line beside the question, or a line of their own on a phone. */
.radar-discard > .radar-discard-actions { display: flex; flex: none; align-items: center; gap: 8px; margin-inline-start: auto; }
@media (min-width: 768px) {
  .radar-sheet { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .radar-sheet > .radar-sheet-wide, .radar-sheet > .radar-discard, .radar-sheet > .radar-sheet-error { grid-column: 1 / -1; }
}

/* ==== track T4: breakdowns and creative cards ==== */
/* Two collapsed cards under the domain table. The header is the disclosure:
   the whole row is one button (44px and more), the chevron at its inline end
   turns from forward to down when the body opens. Plain card material, no glass. */
.report-breakdowns { display: grid; gap: var(--space-4); margin-bottom: var(--space-4); }
.disclosure-card > .card-head { margin-bottom: 0; align-items: center; }
.disclosure-card > .card-head > .disclosure-head {
  flex: 1 1 auto; min-width: 0; min-height: 44px; margin: -12px 0; padding: 4px 0;
  display: flex; align-items: center; gap: var(--space-3); text-align: start;
  color: var(--label); background: transparent; border-radius: var(--radius-sm);
}
.disclosure-card > .card-head > .disclosure-head:hover .disclosure-chevron { color: var(--label-secondary); }
.disclosure-head .disclosure-text { flex: 1 1 auto; min-width: 0; }
.disclosure-head .disclosure-text h3 { font: var(--text-title-2); }
.disclosure-head .disclosure-text .card-sub { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.disclosure-head .disclosure-chevron {
  width: 16px; height: 16px; color: var(--label-tertiary);
  transform: rotate(90deg); transition: transform var(--duration) var(--ease), color var(--duration-fast) var(--ease);
}
html[dir="ltr"] .disclosure-head .disclosure-chevron { transform: rotate(-90deg); }
.disclosure-head[aria-expanded="true"] .disclosure-chevron, html[dir="ltr"] .disclosure-head[aria-expanded="true"] .disclosure-chevron { transform: rotate(0deg); }
.disclosure-card > .card-head > .card-info-slot { flex: none; display: flex; align-items: center; }
.disclosure-card > .card-head > .card-info-slot:empty { display: none; }
.disclosure-body { margin-top: var(--space-4); display: grid; gap: var(--space-4); }
/* The segment control scrolls rather than wraps when six Hebrew labels do not fit a phone. */
.breakdown-picker { max-width: 100%; overflow-x: auto; scrollbar-width: none; justify-self: start; }
.breakdown-picker::-webkit-scrollbar { display: none; }
.breakdown-picker > button { padding: 0 12px; }
.breakdown-content { display: grid; gap: var(--space-5); }
.breakdown-platform { display: grid; gap: var(--space-2); min-width: 0; }
.breakdown-platform > h4, .creative-head > h4 { font: var(--text-headline); color: var(--label); }
.breakdown-chart-sub { margin: 0; }
.breakdown-bars { min-height: 0; }
.breakdown-state, .creative-state { margin: 0; }
.breakdown-platform > .report-table, .creative-table { margin-top: 0; }
.breakdown-platform .report-note, .disclosure-body > .report-note { margin: 0; }
/* Creative: three runs, each a titled list. A row names the ad and, in the
   footnote style, its campaign; the figures keep the table's tabular columns. */
.creative-section { display: grid; gap: var(--space-2); min-width: 0; }
.creative-head { display: flex; align-items: baseline; gap: var(--space-2); flex-wrap: wrap; }
.creative-head > .card-sub { margin-top: 0; }
.ctable td.ad-cell { height: auto; min-height: var(--row-h); padding-top: 8px; padding-bottom: 8px; white-space: normal; }
.ad-cell .ad-name, .fatigue-text .ad-name { display: block; font: var(--text-control); color: var(--label); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 320px; }
.ad-cell .ad-campaign, .fatigue-text .ad-campaign { display: block; font: var(--text-footnote); color: var(--label-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 320px; }
.fatigue-list { list-style: none; margin: 0; padding: 0; }
.fatigue-row { min-height: var(--row-h); padding: 10px 16px; justify-content: space-between; flex-wrap: wrap; gap: 6px 16px; }
.fatigue-text { flex: 1 1 200px; min-width: 0; }
.fatigue-figures { display: flex; gap: 6px 16px; flex-wrap: wrap; }
.fatigue-pair { display: inline-flex; align-items: baseline; gap: 6px; font: var(--text-footnote); color: var(--label-secondary); white-space: nowrap; }
.fatigue-values { font: var(--text-control); color: var(--label); font-variant-numeric: tabular-nums; direction: ltr; unicode-bidi: isolate; }

/* ==== fixer dashboard (final recheck): KPI grid, domain table column groups ==== */
/* Tiles fill the row: auto-fit collapses the track a missing tile would have taken. */
.meeting-metrics { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }


/* ------------------------------------------------------- 7. responsive --- */

/* Two size classes and one wide tier, which is what the system defines (HIG
   Layout: "Determine layout based on size classes, not device type"): compact
   below 768, regular from 768, wide from 1200. The header carries one row and
   icon-only actions until the wide tier has room for the user's name; the
   two-up row and the paired sheet columns are wide-tier layouts too. */
.hdr .who { display: none; }
.hdr .user-menu summary { width: var(--control-h); padding: 0; justify-content: center; gap: 2px; }
/* Without room for the name the control says who it belongs to in initials;
   the person glyph is the fallback when a name gives none. */
.hdr .user-menu summary .initials { display: inline-flex; align-items: center; justify-content: center; min-width: 22px; font: 600 .75rem/1 var(--font-sans); letter-spacing: .02em; color: var(--label); }
.hdr .user-menu summary .initials:empty { display: none; }
.hdr .user-menu summary .initials:not(:empty) + .who ~ .person, .hdr .user-menu summary:has(.initials:not(:empty)) .person { display: none; }
.hdr .user-menu summary .person { display: inline-block; }
.hdr #tenantsAdminLink { padding: 0 8px; }
@media (min-width: 1200px) {
  .r-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hdr .who { display: flex; }
  .hdr .user-menu summary { width: auto; padding: 0 10px; justify-content: center; gap: 6px; }
  .hdr .user-menu summary .person, .hdr .user-menu summary .initials { display: none; }
  .hdr #tenantsAdminLink { padding: 0 10px; }
}
@media (max-width: 767px) {
  /* Tiles reflow to what the screen fits: 160px columns, two on a phone. The
     compact class runs to 767px, so the same rule also draws an iPad mini in
     portrait, where a bare auto-fit reached four columns and left six tiles as
     4+2 and five as 4+1. auto-fit counts its tracks from the MINIMUM track
     size, so the cap is a floor under that minimum - a third (or a half) of the
     row, once a third is wider than 160px - and the counts match the tier above
     without a fourth breakpoint. Contract 13.5: six tiles never leave an
     orphan, at any width. */
  .meeting-metrics { grid-template-columns: repeat(auto-fit, minmax(min(100%, 160px), 1fr)); gap: var(--space-2); }
  .meeting-metrics:has(> :nth-child(3):last-child),
  .meeting-metrics:has(> :nth-child(5):last-child),
  .meeting-metrics:has(> :nth-child(6):last-child) { grid-template-columns: repeat(auto-fit, minmax(min(100%, max(160px, (100% - 2 * var(--space-2)) / 3)), 1fr)); }
  .meeting-metrics:has(> :nth-child(4):last-child) { grid-template-columns: repeat(auto-fit, minmax(min(100%, max(160px, (100% - var(--space-2)) / 2)), 1fr)); }
  /* The shell stacks: the sidebar becomes a drawer, the floating tab bar carries navigation. */
  .document { padding-inline-start: 0; }
  .sidebar-scrim { display: none; position: fixed; inset: 0; z-index: 104; border: 0; padding: 0; margin: 0; background: rgba(0,0,0,.4); -webkit-tap-highlight-color: transparent; }
  .sidebar-scrim.is-open { display: block; animation: fade-in var(--duration-fast) var(--ease); }
  .shell > .sidebar { display: none; }
  .shell > .sidebar.mobile-open {
    display: flex; position: fixed; z-index: 105;
    /* The drawer's insets set its height, not the desktop's 100dvh. It is
       presented modally, and a modal surface takes the tab bar down with it
       (html.sheet-open, above), so there is no bar below to end above: the
       82px this once reserved was a strip of dimmed page under the panel. What
       the insets do owe is the safe area - a bare 8px put the panel's own close
       button under the status bar and the island. The inline offset takes the
       LARGER of the two side insets, like .bottom-nav: inset-inline-start is
       the right edge in this RTL document, so naming safe-area-inset-left
       alone read the inset of the side the drawer is not on. */
    inset-block: max(8px, env(safe-area-inset-top)) max(8px, env(safe-area-inset-bottom)); height: auto; max-height: none;
    inset-inline-start: max(8px, env(safe-area-inset-left), env(safe-area-inset-right)); width: min(280px, 86vw); padding: 14px 12px 18px;
    border-radius: var(--radius-sheet); border: var(--hairline) solid var(--separator);
    background: var(--bg-grouped-2); box-shadow: var(--shadow-lg);
    /* An opaque card over its own scrim: nothing behind it reaches the pixel,
       so the pane's 24px blur comes off the phone's compositor. */
    -webkit-backdrop-filter: none; backdrop-filter: none;
    overflow: hidden auto; overscroll-behavior: contain;
    animation: sidebar-drawer-in var(--duration) var(--ease);
  }
  .shell > .sidebar.mobile-open .sidebar-close { display: inline-flex; margin-inline-start: auto; }
  .library-mobile-bar { display: flex; }
  .bottom-nav { display: block; }
  .document { padding-bottom: calc(var(--bottom-nav-h) + 24px + env(safe-area-inset-bottom)); }
  /* Two bars float over this screen, so the scrollport reserves both edges: the
     phone bar above and the floating tab bar below. The document's padding pads
     the flow; only scroll-padding stops a keyboard-focused control being parked
     on an edge, behind glass (WCAG 2.2 SC 2.4.11). */
  html {
    scroll-padding-top: calc(var(--hdr-h) + var(--space-2) + env(safe-area-inset-top));
    scroll-padding-bottom: calc(var(--bottom-nav-h) + 24px + env(safe-area-inset-bottom));
  }
  /* The toast rises above the tab bar instead of landing on it. */
  .toast { bottom: calc(var(--bottom-nav-h) + 24px + env(safe-area-inset-bottom)); }
  /* The phone bar is the scroll edge here: the page header stays in the flow, no second sticky bar. */
  .hdr, .hdr[data-scrolled="true"] { position: static; margin-inline: 0; padding-inline: 0; background: transparent; -webkit-backdrop-filter: none; backdrop-filter: none; box-shadow: none; }
  /* Static, the header is no containing block: its fill layer would size itself to the shell. The bar's own layer is the edge here. */
  .hdr::before { display: none; }
  /* Static, so the header stopped holding its own layers: the account control's
     z-index escaped onto the page and drew the chip across the phone bar's
     glass while the freshness stamp beside it passed correctly beneath. The
     header keeps them to itself again, and content passes under the one edge. */
  .hdr { isolation: isolate; }
  .library-heading { min-height: 0; padding-block: 12px 8px; margin-bottom: var(--space-3); }
  .hdr h1 { font: var(--text-title-1); }
  .hdr[data-compact="true"] h1 { font: var(--text-title-1); }
  /* The phone bar already carries the client's name, Daniela and the refresh:
     the heading keeps the logo, the timestamp and the account menu, and the
     title stays in the outline for a screen reader only. */
  .hdr-lead h1 { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
  .hdr-lead .assistant-btn, .hdr #refreshBtn { display: none; }
  .hdr[data-compact="true"] .sub, .hdr[data-compact="true"] h1 + p { display: flex; }
  .hdr[data-compact="true"] .client-logo-frame { scale: 1; }
  /* One bar identifies the client. The phone bar carries its name, so the
     heading below it drops the logo and keeps only the freshness stamp and
     the account control - the page was spending a quarter of an 844px screen
     saying the same thing twice. The width cap stays for the tablet tier,
     where the logo is still drawn. */
  .hdr .client-logo-frame { display: none; }
  .client-logo-frame { --client-logo-max-width: 108px; }
  .hdr .sub { overflow: hidden; }
  .hdr #tenantsAdminLink { display: none; }
  .user-menu-items .btn, .select-option, .dd-row { min-height: 44px; }
  .theme-picker .segmented, .theme-picker .segmented > button { height: 44px; min-height: 44px; }
  .client-context { width: 100%; }
  /* No flex basis here: the picker's field is a column, where a basis would become a 140px height. */
  .client-context .select-control { min-width: 0; max-width: none; flex: 1 1 auto; }
  .context-field { flex: 1 1 140px; }
  .toolbar { gap: var(--space-2); }
  .toolbar-group, .library-sort, .library-filters { width: 100%; }
  .toolbar-group.trailing { margin-inline-start: 0; flex: none; max-width: none; }   /* the search spans the row like every other control */
  .toolbar-group.trailing .search-field { max-width: none; flex: 1 1 100%; }
  /* 3 segments in 358px = 116px each; "Google Ads" at 600 is 82px and fits with 10px inline padding. */
  .toolbar .select-segmented, .toolbar .segmented { width: 100%; }
  .toolbar .segmented { grid-auto-columns: minmax(0, 1fr); }
  .toolbar .segmented > button { min-width: 0; padding: 0 10px; }
  .toolbar .select-control, .toolbar .select-trigger, .toolbar #dateBtn, .toolbar .dd { width: 100%; min-width: 0; }
  .toolbar .filter-field { flex: 1 1 calc(50% - 4px); min-width: 0; }
  .toolbar .filter-field > .field-label { display: none; }
  .toolbar .dd-menu { min-width: 0; width: 100%; max-width: calc(100vw - 32px); }
  /* The same three groups a wide screen carries - client, period, platform -
     stacked instead of ranged: a phone reader filters as often as a desktop
     one, and a control nobody can see is a control nobody uses. Only the
     status, channel, lead-source and domain filters open with "מסננים", at
     every width (contract 14.1, and the base rule's own comment above). The
     period keeps the disclosure at its side, so the bar reads platform, then
     period, then client. */
  #dateField { flex: 1 1 190px; }
  /* The period pairs with its disclosure on one line: the range needs the full
     190px for its second line of dates, so the comparison takes the next line
     and "מסננים" rides beside it rather than spending a row of its own. From
     about 500px the three sit on one line together. */
  #compareField { flex: 1 1 200px; }
  /* The trailing group collapses only when it really holds nothing: the search
     is on the campaign tab alone, and a client with one account has no picker.
     An empty flex line would still spend a row gap above the content. */
  #toolbarTrailing:not(:has(#searchField:not([hidden]), #clientPicker:not([hidden]), #accountPicker:not([hidden]), #accountCurrency:not([hidden]))) { display: none; }
  .toolbar-secondary .filter-field { flex: 1 1 calc(50% - 4px); }
  /* A value alone ("CRM / גיליון, אם מחוברים") does not say what it controls: keep a caption above each secondary filter. */
  .toolbar-secondary .filter-field { flex-direction: column; align-items: stretch; gap: 4px; }
  .toolbar-secondary .filter-field > .field-label { display: block; font: var(--text-caption-1); color: var(--label-secondary); padding-inline-start: 12px; }
  .toolbar-secondary > select, .toolbar-secondary .select-control { width: 100%; }
  /* The channels control is a details/summary pair, so it matched neither
     selector above and stood as a short pill at the end of the row between two
     fields that span it. Same field, same width. */
  .toolbar-secondary > #reportChannelPicker { flex: 1 1 100%; }
  .toolbar-secondary .report-channel-picker { width: 100%; }
  .comparison-custom input { width: 100%; }
  .comparison-custom label { flex: 1 1 140px; }
  .meeting-metric { min-height: 100px; padding: 12px 14px; grid-template-rows: auto auto 1fr; }
  .meeting-metric .metric-value { font: var(--text-title-2); }
  /* Narrow tiles: the chip always sits above the caption, so neighbours share one anatomy. */
  .meeting-metric .metric-previous { flex-direction: column; align-items: flex-start; gap: 4px; }
  .row { gap: var(--space-3); margin-bottom: var(--space-3); }
  .card, .settings-panel, .panel { padding: var(--space-4); }
  .tbl-bar { padding: 12px 16px; }
  /* The pinned name column had measured 281px of a 358px scrollport, so no
     figure could ever be read in full beside it: the automatic table algorithm
     hands the surplus over the table's 1040px floor to the widest column and
     ignores a max-width on its own, while a definite width it does honour.
     45vw caps the column on a narrower phone, and the name ellipsises on one
     line the way every other cell in the table already does. */
  table.main th.nm, table.main td.nm {
    width: min(45vw, 170px); min-width: 0; max-width: min(45vw, 170px);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .settings-actions { justify-content: flex-start; }
  .settings-actions .report-note { flex-basis: 100%; }
  .form-grid { grid-template-columns: 1fr; gap: var(--space-5); }
  .frm .form-field { grid-template-columns: 1fr; padding: 8px 16px; }
  .frm .form-field > input, .frm .form-field > select, .frm .form-field > .select-control { grid-column: auto; }
  .frm .form-field > .field-inline { grid-column: auto; }
  /* iOS Safari zooms a focused field under 16px, so the floor is absolute; above it the reader's own size wins. */
  .frm .form-field input, .frm .form-field select, .field input, .search-field input, .filters input[type="search"], .comparison-custom input, .dd-foot .dd-date { font-size: max(1rem, 16px); }
  .report-channel-picker { position: static; }
  .report-channel-panel {
    position: fixed; z-index: 1150; inset-inline: 0; top: auto; bottom: 0; min-width: 0; max-width: none; max-height: 70dvh;
    padding: 8px 20px max(20px, env(safe-area-inset-bottom)); border-radius: var(--radius-sheet) var(--radius-sheet) 0 0;
    box-shadow: var(--shadow-lg); animation: rise var(--duration) var(--ease);
  }
  .report-channel-panel .grabber { display: block; width: 36px; height: 5px; margin: 0 auto 12px; border-radius: var(--radius-pill); background: var(--fill); }
  .report-channel-panel .sheet-title { display: block; font: var(--text-headline); text-align: center; min-height: 44px; line-height: 44px; }
  .report-channel-option input { width: 22px; height: 22px; }
  #formulaFilter { display: flex; align-items: flex-end; }
  #formulaFilter > .field-label, #formulaFilter > .report-note { flex-basis: 100%; }
  #formulaFilter .select-control { flex: 1 1 calc(50% - 10px); }
  #formulaFilter > input { flex: 1 1 160px; }
  .tabs { display: flex; }
  .tab { flex: 1 0 auto; text-align: center; }
  .tabs-row { align-items: flex-start; }
  .tabs-row > .tabs { flex: 1 1 auto; }
  .campaign-report-heading h2 { font: var(--text-headline); }
  #analysisPanel .radar-tabs { width: 100%; }
  #analysisPanel .radar-tabs > button { min-width: 0; }
  #analysisPanel .radar-actions > .btn.primary { flex: 1 1 100%; }
  #analysisPanel .radar-rule-actions { margin-inline-start: 0; flex-basis: 100%; }
  .domain-row { grid-template-columns: 1fr; }
  .domain-row .btn { justify-self: start; }
  .domain-head { display: none; }
  .frm .domain-cell > label { display: block; }
  .disclosure-card > .card-head > .disclosure-head { margin: -8px 0; }
  .breakdown-picker > button { padding: 0 10px; }
  .ad-cell .ad-name, .ad-cell .ad-campaign, .fatigue-text .ad-name, .fatigue-text .ad-campaign { max-width: 200px; }
  .fatigue-row { padding: 10px 12px; }
  .metric-list .metric-row { flex-wrap: wrap; row-gap: 4px; }
  .metric-row .metric-row-figures { margin-inline-start: 0; width: 100%; justify-content: space-between; }
  .metric-row .metric-row-change { min-width: 0; }
  .sheet-body { padding-bottom: max(20px, env(safe-area-inset-bottom)); }
  .toolbar .filter-field, .toolbar-secondary .filter-field { flex-basis: 100%; }
  /* The formula sheet's action rows and filter line wrap to their own lines. */
  .formula-head-actions { flex-basis: 100%; justify-content: flex-start; }
  .formula-actions { margin-inline-start: 0; flex-basis: 100%; }
  .formula-filter-row .select-control { flex: 1 1 100%; }
  .formula-filter-row > input { flex: 1 1 100px; }
}
@keyframes sidebar-drawer-in {
  from { transform: translateX(calc(20px * var(--dirx))); opacity: 0; }
  to { transform: none; opacity: 1; }
}

/* ==== shell: page header, section title, toolbar rows, source chips, Daniela's teaser ==== */
/* ---- page header: the client leads, the assistant trigger follows, actions trail ---- */
.hdr-lead { display: flex; align-items: center; gap: var(--space-3); flex: 1 1 auto; min-width: 0; }
.hdr-title { min-width: 0; flex: 0 1 auto; }
.hdr-lead .assistant-btn { flex: none; }
.hdr .btn-label { display: none; }

/* ---- the section title: the tab's name under the client's ---- */
.section-title { font: var(--text-title-2); color: var(--label); margin: 0 0 var(--space-3); }

/* ---- the source chips, one row on the overview ---- */
.src-row { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 8px; margin: 0 0 var(--space-4); }

/* ---- "עוד": the destinations the phone bar folded, as rows in a sheet (openMoreSheet) ----
   Rows on glass take the cool glass fills, like every other menu row; the
   glyph is the bar's own, in the accent like the rail's. */
.more-list { display: flex; flex-direction: column; gap: 2px; padding: 4px 0 8px; }
.more-item {
  display: flex; align-items: center; gap: 12px; width: 100%; min-height: 44px; padding: 6px 10px;
  border-radius: var(--radius-sm); background: transparent; color: var(--label); font: var(--text-control); text-align: start;
  transition: background-color var(--duration-fast) var(--ease);
}
.more-item svg { width: 22px; height: 22px; flex: none; color: var(--accent); }
.more-item:hover { background: var(--glass-hover); }
.more-item:active { background: var(--glass-press); }
.more-item[aria-current="page"] { color: var(--accent-text); font-weight: 600; }

/* ---- Daniela's teaser card on the overview ---- */
.daniela-teaser .teaser-summary { font: var(--text-subhead); color: var(--label); margin: 0 0 var(--space-3); }
.daniela-teaser .btn { align-self: flex-start; }

/* ---- the one link from a domain to its campaigns ---- */
.domain-campaigns { display: flex; margin: 0 0 var(--space-4); }
.domain-campaigns .btn { text-decoration: none; }

/* ---- the skip link: invisible until a keyboard reaches it, then a small elevated plate ----
   The first thing a keyboard or VoiceOver reaches owes the safe area: a flat
   16px put the plate inside the status bar and the island. The inline offset
   takes the larger of the two side insets, like .bottom-nav, so it clears a
   landscape notch on either side without an RTL branch. */
.skip-link:focus-visible { position: fixed; inset-inline-start: calc(var(--space-4) + max(env(safe-area-inset-left), env(safe-area-inset-right))); top: calc(var(--space-4) + env(safe-area-inset-top)); z-index: 2000; width: auto; height: auto; margin: 0; padding: 8px 12px; clip: auto; white-space: nowrap; background: var(--bg-elevated); color: var(--accent-text); border-radius: var(--radius-sm); box-shadow: var(--shadow-lg); }

/* ---- the head: the mark leads it, the controls hold its trailing end ----
   The mark's own auto margin does the work, so nothing here has to pick a
   side; the rule stays only for a head that has lost its mark (the collapsed
   rail, where the column centres its glyphs instead). */
.sidebar-head { justify-content: flex-end; }

/* ---- the formula filter line sits directly above the campaign table ---- */
#view > #formulaFilter { margin-bottom: var(--space-3); }

@media (max-width: 767px) {
  .hdr-lead { gap: var(--space-2); }
}

/* ==== דניאלה chat: the trigger capsule, the desktop panel, the chat and the phone sheet ====
   Tokens only, no hard-coded colour. The panel is OPAQUE on purpose: glass
   belongs to the navigation and transient layer (the blur allow-list above is
   pinned by tools/ui-design-system-test.mjs); on phones the chat rides inside
   .sheet, which already blurs. Reduce Motion is the global block below. */
/* ---- trigger: a tinted capsule, icon-only on phones ---- */
.assistant-btn {
  display: inline-flex; align-items: center; gap: 6px;
  height: 36px; min-height: 36px; padding: 0 14px 0 12px;
  border: 0; border-radius: var(--radius-control); cursor: pointer;
  background: var(--tint); color: var(--accent-text);
  font: 500 .9375rem/1.25rem var(--font-sans); white-space: nowrap;
  transition: background var(--duration-fast) var(--ease), transform var(--duration-fast) var(--ease);
}
/* Stroked like the six glyphs beside it, at the one stroke geometry: 20 units
   at 18px is 1.5px, the same optical weight as the header's other marks. */
.assistant-btn .glyph { width: 18px; height: 18px; fill: none; stroke-width: 1.667; }
.assistant-btn:hover { background: var(--tint-strong); }
.assistant-btn:active { transform: scale(.97); }
/* Open it becomes the screen's one filled action, and only then takes the
   capsule: closed it is a tinted trigger and an 8px rectangle like every other
   control in the bar (three geometries in one toolbar row was two too many).
   --accent-fill is the one accent
   shade verified under --on-accent (4.5:1 in both palettes); --accent itself
   is tuned to read on the dark surface and lands near 3:1 under white. */
.assistant-btn[aria-expanded="true"] { background: var(--accent-fill); color: var(--on-accent); border-radius: var(--radius-pill); }
.assistant-btn[aria-expanded="true"]:hover { background: var(--accent-hover); }
/* The phone bar's marks are stroked and monochrome (section 14.3): a filled
   accent bubble beside a stroked hamburger and refresh wore the TAB bar's
   weights in the wrong bar. The open state keeps its tint below. */
#mobileAssistantBtn { width: 44px; height: 44px; }
#mobileAssistantBtn .glyph { width: 22px; height: 22px; }
#mobileAssistantBtn[aria-expanded="true"] { background: var(--tint); }
/* ---- desktop panel: a popover-style panel under the trigger ---- */
.assistant-panel {
  position: fixed; z-index: 1000;
  width: 380px; max-width: calc(100vw - 16px); max-height: min(640px, 80vh);
  display: flex; flex-direction: column;
  background: var(--bg-elevated); color: var(--label);
  border: var(--hairline) solid var(--separator); border-radius: var(--radius-menu);
  box-shadow: var(--shadow-lg);
  opacity: 0; transform: translateY(-6px); pointer-events: none;
  transition: opacity 320ms var(--ease), transform 320ms var(--ease);
  overflow: hidden;
}
.assistant-panel.is-open { opacity: 1; transform: none; pointer-events: auto; }
.assistant-panel[hidden] { display: none; }
.assistant-panel .assistant-chat { flex: 1; min-height: 0; }

/* ---- the chat ---- */
.assistant-chat { position: relative; display: flex; flex-direction: column; min-height: 0; height: 100%; }
.assistant-head {
  display: flex; align-items: center; gap: 8px; min-height: 48px; padding: 6px 12px 6px 8px;
  border-bottom: var(--hairline) solid var(--separator);
}
.assistant-title { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: 2px; overflow: hidden; }
.assistant-name { font: 600 .9375rem/1.25rem var(--font-sans); }
.assistant-tenant { font: var(--text-footnote); color: var(--label-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.assistant-clear { height: 32px; min-height: 32px; padding: 0 10px; font: 500 .8125rem/1.125rem var(--font-sans); }
.assistant-close {
  width: 32px; height: 32px; display: grid; place-items: center; border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--label-secondary); cursor: pointer;
}
.assistant-close:hover { background: var(--fill-4); color: var(--label); }
.assistant-close .glyph { width: 18px; height: 18px; }
.assistant-chat[data-mode="sheet"] .assistant-close { display: none; }
.assistant-chat[data-mode="sheet"] .assistant-head { border-bottom: 0; min-height: 40px; }

.assistant-log {
  flex: 1; min-height: 160px; overflow-y: auto; overscroll-behavior: contain;
  display: flex; flex-direction: column; gap: 10px; padding: 14px 12px;
  scroll-behavior: smooth;
}
.assistant-empty { display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 20px 8px 8px; text-align: center; }
.assistant-empty[hidden] { display: none; }
.assistant-hero { display: grid; place-items: center; width: 48px; height: 48px; border-radius: var(--radius-pill); background: var(--tint); color: var(--accent-text); }
.assistant-hero .glyph { width: 26px; height: 26px; fill: currentColor; }
.assistant-empty-text { margin: 0; font: var(--text-footnote); color: var(--label-secondary); }
.assistant-suggestions { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
.assistant-chip { height: 32px; padding: 0 12px; font: 500 .8125rem/1.125rem var(--font-sans); color: var(--accent-text); background: var(--tint); border: 0; cursor: pointer; }
.assistant-chip:hover { background: var(--tint-strong); }

/* Messages sit like iOS Messages: what the user sent at the trailing edge
   (inline-end: the left in RTL), Daniela's answers at the leading edge, each
   bubble's tail on the corner nearest its edge. The sent bubble is a filled
   surface, so it takes --accent-fill under --on-accent, the verified pair. */
.assistant-msg { display: flex; flex-direction: column; gap: 4px; max-width: 85%; animation: assistant-fade 120ms var(--ease); }
.assistant-msg-user { align-self: flex-end; }
.assistant-msg-assistant { align-self: flex-start; }
.assistant-msg-body {
  padding: 9px 12px; border-radius: var(--radius-lg); font: var(--text-subhead); line-height: 1.45;
  unicode-bidi: plaintext; overflow-wrap: anywhere; word-break: break-word;
}
.assistant-msg-user .assistant-msg-body { background: var(--accent-fill); color: var(--on-accent); border-end-end-radius: var(--radius-xs); }
.assistant-msg-assistant .assistant-msg-body { background: var(--fill-3); color: var(--label); border-end-start-radius: var(--radius-xs); }
.assistant-msg-body p { margin: 0; }
.assistant-msg-body p + p, .assistant-md > * + * { margin-top: 6px; }
.assistant-md ul, .assistant-md ol { margin: 0; padding-inline-start: 18px; }
.assistant-md li + li { margin-top: 2px; }
.assistant-table-scroll { overflow-x: auto; max-width: 100%; }
.assistant-table { border-collapse: collapse; font: .8125rem/1.125rem var(--font-sans); font-variant-numeric: tabular-nums; min-width: 100%; }
.assistant-table th, .assistant-table td { padding: 4px 8px; text-align: start; border-bottom: var(--hairline) solid var(--separator); white-space: nowrap; }
.assistant-table th { font-weight: 600; color: var(--label-secondary); }
.assistant-msg-status { font: var(--text-footnote); color: var(--label-secondary); padding: 0 6px; font-variant-numeric: tabular-nums; }
.assistant-msg-status[hidden] { display: none; }

.assistant-caret { display: inline-block; width: 1px; height: 1em; margin-inline-start: 1px; background: currentColor; vertical-align: -2px; animation: assistant-blink 1s steps(1) infinite; }
.assistant-typing { display: inline-flex; gap: 4px; align-items: center; height: 18px; }
.assistant-typing i { width: 6px; height: 6px; border-radius: 50%; background: var(--label-secondary); opacity: .4; animation: assistant-dots 1.2s infinite; }
.assistant-typing i:nth-child(2) { animation-delay: .2s; }
.assistant-typing i:nth-child(3) { animation-delay: .4s; }
.assistant-note { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; font: var(--text-footnote); color: var(--label-secondary); padding: 0 6px; }
.assistant-note.assistant-degraded { padding: 0 6px; }
.assistant-retry { height: 28px; min-height: 28px; padding: 0 8px; font: 500 .8125rem/1.125rem var(--font-sans); }
/* Centred by auto margins, which read the same in either direction. */
.assistant-jump {
  position: absolute; inset-inline: 0; margin-inline: auto; bottom: 96px;
  width: 32px; height: 32px; border-radius: 50%; border: var(--hairline) solid var(--separator);
  background: var(--bg-elevated); color: var(--label); box-shadow: var(--shadow-md); cursor: pointer; font: 500 .9375rem/1.25rem var(--font-sans);
}
.assistant-jump[hidden] { display: none; }

.assistant-composer {
  display: flex; align-items: flex-end; gap: 8px; padding: 8px 12px 6px; margin: 0;
  border-top: var(--hairline) solid var(--separator); position: relative;
}
.assistant-composer[hidden] { display: none; }
.assistant-input {
  flex: 1; min-height: 38px; max-height: 126px; resize: none; padding: 8px 12px;
  border: var(--hairline) solid var(--separator); border-radius: var(--radius-pill);
  background: var(--fill-4); color: var(--label); font: var(--text-subhead); line-height: 22px;
}
/* No outline: none here - it cancelled the shared accent ring, and the
   40%-alpha shadow that stood in for it measured about 2.15:1 on the panel. */
.assistant-input:focus-visible { border-color: var(--accent); }
.assistant-input::placeholder { color: var(--label-secondary); }
.assistant-count { position: absolute; inset-inline-start: 16px; top: -18px; font: var(--text-caption-1); color: var(--label-secondary); font-variant-numeric: tabular-nums; }
.assistant-count[hidden] { display: none; }
.assistant-send {
  flex: none; width: 36px; height: 36px; border-radius: 50%; border: 0; cursor: pointer;
  display: grid; place-items: center; background: var(--accent-fill); color: var(--on-accent);
  transition: opacity var(--duration-fast) var(--ease), transform var(--duration-fast) var(--ease);
}
.assistant-send .glyph { width: 18px; height: 18px; }
.assistant-send:disabled { opacity: .35; cursor: default; }
.assistant-send:not(:disabled):active { transform: scale(.94); }
.assistant-send.assistant-stop { background: var(--fill-3); color: var(--label); }
.assistant-send.assistant-stop .glyph { fill: currentColor; }
.assistant-unconfigured { padding: 14px 16px; border-top: var(--hairline) solid var(--separator); font: var(--text-subhead); color: var(--label); }
.assistant-unconfigured[hidden] { display: none; }
.assistant-unconfigured p { margin: 0; }
.assistant-foot-note { margin-top: 4px; font: var(--text-caption-1); color: var(--label-secondary); direction: ltr; text-align: end; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.assistant-foot { margin: 0; padding: 0 16px 10px; font: var(--text-caption-1); color: var(--label-secondary); }
.assistant-foot[hidden] { display: none; }
.assistant-hint[hidden] { display: none; }

/* ---- phone: the chat inside the bottom sheet, stretched to the keyboard ----
   The sheet fills the screen below the safe-area inset, and --kb is how much
   of the bottom the software keyboard has taken: theme.js measures it from
   window.visualViewport and keeps it on <html>, unset whenever no keyboard is
   up. The floor rises by that much and the height gives the same back, so the
   top edge holds still and the composer sits ON the keyboard instead of under
   it. Neither dvh nor the layout viewport shrinks for the keyboard on iOS
   Safari or on Chrome Android's resizes-visual, so nothing else can do this. */
.sheet.sheet-assistant {
  bottom: var(--kb, 0px);
  height: calc(100dvh - var(--sheet-top-gap) - var(--kb, 0px));
  max-height: calc(100dvh - var(--sheet-top-gap));
}
/* One header, not two. The generic sheet chrome would repeat the title the
   chat already carries and spend 112px of a 844px screen on it, so the chat's
   own header IS the sheet's header here: the title and the tenant lead, "נקה
   שיחה" and the close symbol trail it (HIG sheets: one header, one title).
   The grabber sits outside .sheet-head, so drag-to-dismiss is untouched, and
   the dialog keeps its aria-label, so hiding the heading costs it no name. */
.sheet.sheet-assistant > .sheet-head { display: none; }
.sheet.sheet-assistant .assistant-chat[data-mode="sheet"] .assistant-head {
  min-height: 56px; padding: 6px 8px 6px 16px; border-bottom: var(--hairline) solid var(--separator);
}
.sheet.sheet-assistant .assistant-chat[data-mode="sheet"] .assistant-name { font: var(--text-headline); }
.sheet.sheet-assistant .assistant-chat[data-mode="sheet"] .assistant-close { display: grid; width: 44px; height: 44px; }
.sheet.sheet-assistant .sheet-body { flex: 1; min-height: 0; display: flex; flex-direction: column; padding: 0 0 env(safe-area-inset-bottom); }
.sheet.sheet-assistant .assistant-chat { flex: 1; min-height: 0; }
.sheet.sheet-assistant .assistant-log { padding-inline: 16px; }
.sheet.sheet-assistant .assistant-composer { padding-inline: 16px; }
.sheet.sheet-assistant .assistant-input { min-height: 44px; }
.sheet.sheet-assistant .assistant-send { width: 44px; height: 44px; }
@media (min-width: 768px) {
  /* The centred dialog is held by `inset: 50% auto auto 50%`, so the phone's
     keyboard floor has to be handed back or the box would stretch downward. */
  .sheet.sheet-assistant { height: auto; bottom: auto; }
}
@media (max-width: 767px) {
  /* The same absolute floor keeps iOS Safari from zooming the sheet when the composer takes focus. */
  .assistant-input { font-size: max(1rem, 16px); }
}
/* Under a finger the suggestion chips and "נקה שיחה" are 44px targets like the composer. */
@media (pointer: coarse) {
  .assistant-chip { height: var(--control-h); min-height: var(--control-h); padding: 0 16px; }
  .assistant-clear { height: var(--control-h); min-height: var(--control-h); }
}

@keyframes assistant-fade { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
@keyframes assistant-blink { 50% { opacity: 0; } }
@keyframes assistant-dots { 0%, 80%, 100% { opacity: .4; transform: translateY(0); } 40% { opacity: 1; transform: translateY(-2px); } }
.assistant-static .assistant-typing i, .assistant-static .assistant-caret { animation: none; }

/* ------------------------------------------------------- 8. a11y media --- */

/* Reduce Motion: crossfades only. Every duration collapses to a frame, then
   the surfaces that enter (menus, popovers, sheets, the drawer, a tab's
   content) get a short fade instead of their slide or scale, and nothing
   springs, lifts or swells. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 1ms !important; animation-iteration-count: 1 !important; transition-duration: 1ms !important; scroll-behavior: auto !important; }
  .select-menu, .dd-menu, .user-menu-items, .report-channel-panel, .formula-suggestions, .popover, .popover.as-sheet, .sheet, .shell > .sidebar.mobile-open,
  main[data-active-tab] #view, main[data-active-tab] .settings-panel, main[data-active-tab] .toolbar, main[data-active-tab] .section-title, .metric-number.is-changed { animation-name: fade-in !important; animation-duration: 160ms !important; }
  /* What leaves fades out the same way: the ghost of a screen, a closing menu, popover, sheet or scrim. */
  .view-ghost, .popover.is-closing, .select-menu.is-closing, .dd.is-closing .dd-menu, .scrim.is-closing, .sheet.is-closing { animation-name: fade-out !important; animation-duration: 160ms !important; }
  .toast { transition-property: opacity !important; transition-duration: 160ms !important; transform: translate(-50%, 0); }
  .dim { transition-duration: 160ms !important; }
  .skeleton, .loadbar::after, .spin, .spinner, .bottom-nav.is-catching::after { animation: none !important; }
  .segmented-thumb, .tabs-thumb, .bottom-nav-indicator, .sidebar-indicator { transition: none !important; scale: 1 !important; }
  .segmented-thumb::after, .tabs-thumb::after, .bottom-nav-indicator::after, .sidebar-indicator::after { transition: none !important; }
  .segmented.is-dragging > .segmented-thumb { scale: 1 !important; }
  .bottom-nav-item:active, .btn:active:not(:disabled) { transform: none; }
  .hdr .client-logo-frame, .hdr[data-compact="true"] .client-logo-frame { scale: 1; }
}
/* ...and the same, switched in the app. Both reference products ship a Reduce
   Motion and a Reduce Transparency row in their own settings beside Appearance;
   this is the stylesheet half, driven by theme.js on <html>. The switch and the
   system preference must reach the SAME surfaces - the phone bar is the only
   glass a 390px screen carries at the top - and ui-design-system-test.mjs pins
   the two selector lists as one set so they cannot drift apart again. */
html[data-reduce-motion="true"] *, html[data-reduce-motion="true"] *::before, html[data-reduce-motion="true"] *::after { animation-duration: 1ms !important; animation-iteration-count: 1 !important; transition-duration: 1ms !important; scroll-behavior: auto !important;}
html[data-reduce-motion="true"] .select-menu, html[data-reduce-motion="true"] .dd-menu, html[data-reduce-motion="true"] .user-menu-items, html[data-reduce-motion="true"] .report-channel-panel, html[data-reduce-motion="true"] .formula-suggestions, html[data-reduce-motion="true"] .popover, html[data-reduce-motion="true"] .popover.as-sheet, html[data-reduce-motion="true"] .sheet, html[data-reduce-motion="true"] .shell > .sidebar.mobile-open, html[data-reduce-motion="true"] main[data-active-tab] #view, html[data-reduce-motion="true"] main[data-active-tab] .settings-panel, html[data-reduce-motion="true"] main[data-active-tab] .toolbar, html[data-reduce-motion="true"] main[data-active-tab] .section-title, html[data-reduce-motion="true"] .metric-number.is-changed { animation-name: fade-in !important; animation-duration: 160ms !important;}
html[data-reduce-motion="true"] .view-ghost, html[data-reduce-motion="true"] .popover.is-closing, html[data-reduce-motion="true"] .select-menu.is-closing, html[data-reduce-motion="true"] .dd.is-closing .dd-menu, html[data-reduce-motion="true"] .scrim.is-closing, html[data-reduce-motion="true"] .sheet.is-closing { animation-name: fade-out !important; animation-duration: 160ms !important;}
html[data-reduce-motion="true"] .toast { transition-property: opacity !important; transition-duration: 160ms !important; transform: translate(-50%, 0);}
html[data-reduce-motion="true"] .dim { transition-duration: 160ms !important;}
html[data-reduce-motion="true"] .skeleton, html[data-reduce-motion="true"] .loadbar::after, html[data-reduce-motion="true"] .spin, html[data-reduce-motion="true"] .spinner, html[data-reduce-motion="true"] .bottom-nav.is-catching::after { animation: none !important;}
html[data-reduce-motion="true"] .segmented-thumb, html[data-reduce-motion="true"] .tabs-thumb, html[data-reduce-motion="true"] .bottom-nav-indicator, html[data-reduce-motion="true"] .sidebar-indicator { transition: none !important; scale: 1 !important;}
html[data-reduce-motion="true"] .segmented-thumb::after, html[data-reduce-motion="true"] .tabs-thumb::after, html[data-reduce-motion="true"] .bottom-nav-indicator::after, html[data-reduce-motion="true"] .sidebar-indicator::after { transition: none !important;}
html[data-reduce-motion="true"] .segmented.is-dragging > .segmented-thumb { scale: 1 !important;}
html[data-reduce-motion="true"] .bottom-nav-item:active, html[data-reduce-motion="true"] .btn:active:not(:disabled) { transform: none;}
html[data-reduce-motion="true"] .hdr .client-logo-frame, html[data-reduce-motion="true"] .hdr[data-compact="true"] .client-logo-frame { scale: 1;}
/* No backdrop-filter at all: every glass surface is simply opaque. */
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .material, .glass, .hdr[data-scrolled="true"], .document:has(.hdr[data-scrolled="true"]) .library-mobile-bar, .bottom-nav, .select-menu, .dd-menu, .user-menu-items, .report-channel-panel, .popover, .sheet, .toast, .dd-foot { background: var(--glass-fallback); }
  .sidebar { background: var(--bg-sidebar); }
}
/* Reduce Transparency (Chrome/Edge 118+; Safari's path is Increase Contrast below): frosted becomes solid. */
@media (prefers-reduced-transparency: reduce) {
  .material, .glass, .hdr[data-scrolled="true"], .document:has(.hdr[data-scrolled="true"]) .library-mobile-bar, .bottom-nav, .select-menu, .dd-menu, .user-menu-items, .report-channel-panel, .popover, .sheet, .toast, .dd-foot {
    -webkit-backdrop-filter: none; backdrop-filter: none; background: var(--glass-fallback);
  }
  .hdr.material { background: transparent; }
  .hdr[data-scrolled="true"] { background: var(--glass-fallback); }
  .sidebar { -webkit-backdrop-filter: none; backdrop-filter: none; background: var(--bg-sidebar); }
  .bottom-nav-indicator { background: var(--fill-3); }
  /* (.tabs and .segmented are --fill-3 tracks, not glass: they keep their grey so the opaque thumb stays visible.) */
}
html[data-reduce-transparency="true"] .material, html[data-reduce-transparency="true"] .glass, html[data-reduce-transparency="true"] .hdr[data-scrolled="true"], html[data-reduce-transparency="true"] .document:has(.hdr[data-scrolled="true"]) .library-mobile-bar, html[data-reduce-transparency="true"] .bottom-nav, html[data-reduce-transparency="true"] .select-menu, html[data-reduce-transparency="true"] .dd-menu, html[data-reduce-transparency="true"] .user-menu-items, html[data-reduce-transparency="true"] .report-channel-panel, html[data-reduce-transparency="true"] .popover, html[data-reduce-transparency="true"] .sheet, html[data-reduce-transparency="true"] .toast, html[data-reduce-transparency="true"] .dd-foot {
    -webkit-backdrop-filter: none; backdrop-filter: none; background: var(--glass-fallback);}
html[data-reduce-transparency="true"] .hdr.material { background: transparent;}
html[data-reduce-transparency="true"] .hdr[data-scrolled="true"] { background: var(--glass-fallback);}
html[data-reduce-transparency="true"] .sidebar { -webkit-backdrop-filter: none; backdrop-filter: none; background: var(--bg-sidebar);}
html[data-reduce-transparency="true"] .bottom-nav-indicator { background: var(--fill-3);}
/* Increase Contrast: predominantly black or white with a contrasting border. */
@media (prefers-contrast: more) {
  :root {
    --separator: rgba(60,60,67,.55); --separator-opaque: #6E6E73; --separator-strong: rgba(60,60,67,.70);
    --label-secondary: rgba(60,60,67,.90); --label-tertiary: rgba(60,60,67,.75); --chart-grid: rgba(60,60,67,.30);
    --bg-grouped: #FFFFFF; --bg-grouped-3: #FFFFFF; --bg-sidebar: #FFFFFF; --sidebar-selected: #D6D6DB;
    --glass-fill: #FFFFFF; --glass-fill-thick: #FFFFFF; --glass-fill-edge: #FFFFFF; --glass-sidebar: #FFFFFF; --nav-indicator: #E5E5EA; --nav-indicator-rim: #000000;
  }
  :root[data-theme="dark"] {
    --separator: rgba(235,235,245,.50); --separator-opaque: #8E8E93; --separator-strong: rgba(235,235,245,.70);
    --label-secondary: rgba(235,235,245,.85); --label-tertiary: rgba(235,235,245,.70); --chart-grid: rgba(235,235,245,.24);
    --bg-grouped: #000000; --bg-grouped-2: #000000; --bg-grouped-3: #000000; --bg-elevated: #000000; --bg-sidebar: #000000; --sidebar-selected: #3A3A3C;
    --glass-fill: #000000; --glass-fill-thick: #000000; --glass-fill-edge: #000000; --glass-sidebar: #000000; --nav-indicator: #3A3A3C; --nav-indicator-rim: #FFFFFF;
  }
  .card, .tbl-card, .settings-panel, .panel, .meeting-metric, .group, .select-menu, .dd-menu, .user-menu-items, .popover, .sheet, .toast, .report-channel-panel, .formula-suggestions, .sidebar, .bottom-nav, .hdr[data-scrolled="true"], .library-mobile-bar, .login-card, .alert {
    border: 1px solid var(--label); box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none;
  }
  .sidebar { background: var(--bg-sidebar); }
  .btn, .select-trigger, .popup, .segmented, .tabs, .search-field input, .field > input, .form-field input, .frm input, .frm select, .toggle { box-shadow: inset 0 0 0 1px var(--label); }
  .segmented-thumb, .tabs-thumb, .bottom-nav-indicator, .sidebar-indicator { box-shadow: 0 0 0 1px var(--label); }
  .change-label { box-shadow: 0 0 0 1px var(--label); }
  .popover-arrow { box-shadow: -1px -1px 0 var(--label); }
  .popover[data-placement="above"] .popover-arrow { box-shadow: 1px 1px 0 var(--label); }
}
@media (prefers-contrast: more) and (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --separator: rgba(235,235,245,.50); --separator-opaque: #8E8E93; --separator-strong: rgba(235,235,245,.70);
    --label-secondary: rgba(235,235,245,.85); --label-tertiary: rgba(235,235,245,.70); --chart-grid: rgba(235,235,245,.24);
    --bg-grouped: #000000; --bg-grouped-2: #000000; --bg-grouped-3: #000000; --bg-elevated: #000000; --bg-sidebar: #000000; --sidebar-selected: #3A3A3C;
    --glass-fill: #000000; --glass-fill-thick: #000000; --glass-fill-edge: #000000; --glass-sidebar: #000000; --nav-indicator: #3A3A3C; --nav-indicator-rim: #FFFFFF;
  }
}
@media (forced-colors: active) {
  .card, .tbl-card, .settings-panel, .panel, .meeting-metric, .group, .select-menu, .dd-menu, .user-menu-items, .popover, .sheet, .toast, .report-channel-panel, .formula-suggestions, .sidebar, .bottom-nav, .library-mobile-bar, .login-card, .alert {
    background: Canvas; color: CanvasText; border: 1px solid CanvasText; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none;
  }
  .btn, .select-trigger, .popup, .segmented > button, .tab, .bottom-nav-item, .sidebar-item { background: ButtonFace; color: ButtonText; border: 1px solid ButtonText; box-shadow: none; }
  .btn.primary, .btn-primary, .tab.on, .segmented > button[aria-checked="true"], .sidebar-item.is-selected, .sidebar-item[aria-current="page"], .bottom-nav-item.is-selected { background: Highlight; color: HighlightText; }
  .material, .hdr[data-scrolled="true"] { background: Canvas; }
  .segmented-thumb, .tabs-thumb, .bottom-nav-indicator, .sidebar-indicator { background: Highlight; border: 1px solid CanvasText; box-shadow: none; }
  .segmented.has-thumb > button[aria-checked="true"], .tabs.has-thumb .tab.on { background: transparent; color: HighlightText; border-color: transparent; }
  .sidebar-nav.has-indicator > .sidebar-item.is-selected, .sidebar-nav.has-indicator > .sidebar-item[aria-current="page"] { background: transparent; color: HighlightText; border-color: transparent; }
  .status-dot { border: 1px solid CanvasText; }
  .pill.status.hollow .status-dot { background: transparent; box-shadow: none; }
  .change-label { border: 1px solid CanvasText; forced-color-adjust: none; }
  .funnel-bar-fill { background: CanvasText; }
  .popover-arrow { display: none; }   /* forced colours drop the rim; a bare notch would break the border */
  :focus-visible { outline-color: Highlight; }
}

/* ------------------------------------------------- 9. leads tab ------ */

/* The CRM records table (leads-ui.js). Everything the table needs beyond
   table.main's own grammar lives here and nowhere else. */
.leads-bar { gap: var(--space-3) var(--space-4); }
.leads-bar .t { flex: 0 0 auto; }
.leads-bar .leads-search { flex: 1 1 240px; max-width: 380px; margin-inline-start: auto; }
.leads-segmented { height: var(--control-h); }
.leads-table { min-width: 960px; }
.leads-table th.nm, .leads-table td.nm { min-width: 180px; max-width: 280px; }
.leads-table td[data-col="phone"], .leads-table td[data-col="email"] { text-align: right; }
.leads-table td[data-col="email"] { max-width: 280px; overflow: hidden; text-overflow: ellipsis; }
.leads-table td[data-col="stage"] .leads-verdict { margin-inline-start: 8px; vertical-align: middle; }
.leads-table td[data-col="url"], .leads-table th[data-col="url"] { width: 56px; text-align: center; }
.leads-link { position: relative; display: inline-flex; width: 28px; height: 28px; align-items: center; justify-content: center; border-radius: 50%; color: var(--label-secondary); vertical-align: middle; }
.leads-link::before { content: ""; position: absolute; inset: -8px; }   /* 44x44 hit area around a 28px glyph */
.leads-link:hover { background: var(--fill-4); color: var(--accent-text); }
.leads-link .glyph { width: 16px; height: 16px; }
.leads-skeleton { padding: var(--space-4); }
.leads-body > .empty, .leads-body > .empty-state { padding-block: var(--space-8); }
.leads-error .btn { margin-top: var(--space-2); }
.leads-foot { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--space-3) var(--space-4); padding: 12px 16px; border-top: var(--hairline) solid var(--separator); }
.leads-foot-lines { display: grid; gap: 4px; font: var(--text-footnote); color: var(--label-secondary); }
.leads-foot-lines .leads-count { font: var(--text-subhead); font-weight: 500; color: var(--label); }
.leads-foot-lines .leads-note { color: var(--orange-text); }
.leads-actions { display: flex; gap: var(--space-2); flex: 0 0 auto; }
@media (max-width: 767px) {
  .leads-bar .leads-search { flex-basis: 100%; max-width: none; margin-inline-start: 0; }
  .leads-foot { flex-direction: column; align-items: stretch; }
  .leads-actions { justify-content: flex-end; }
}

/* ----------------------------------------------- 9. reports tab ------ */

/* The monthly client report (reports-ui.js). Two columns from the wide
   tier: the report's pages, and a controls column on the trailing side.
   Below it the controls come first and a page takes the width. The pages
   are white on every theme, because they are the PDF and the PDF is paper:
   their ink is their own, only the accent is the client's. Nothing in this
   block animates, and nothing here is glass. */
#reportsPanel { background: transparent; border: 0; box-shadow: none; border-radius: 0; padding: 8px 0 40px; margin: 0; max-width: 100%; }
.reports { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-6); align-items: start; }
.reports-preview { min-width: 0; }
.reports-controls { display: grid; gap: var(--space-4); align-content: start; order: -1; }
@media (min-width: 1200px) {
  .reports { grid-template-columns: minmax(0, 1fr) 300px; }
  /* Pinned under the header, and never taller than what is left of the window:
     the month picker, the switches, the actions and the drafts together run
     past 900px, and a column pinned past the fold put "הורד PDF" and the
     saved drafts out of reach until the whole report had been scrolled. The
     column scrolls within itself instead; its menus are fixed to the body, so
     nothing inside it is clipped by that scroller. */
  .reports-controls { order: 0; position: sticky; top: calc(var(--hdr-h) + var(--space-4)); max-height: calc(100dvh - var(--hdr-h) - var(--space-4) * 2); overflow-y: auto; overscroll-behavior: contain; }
}
.reports-controls .settings-panel-head { margin-bottom: 0; }
.report-control-group { display: grid; gap: var(--space-2); }
.report-action-row { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.report-custom-range { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.report-custom-range input { height: var(--control-h); padding: 0 12px; border: 0; border-radius: var(--radius-control); background: var(--fill-3); color: var(--label); font: var(--text-control); }
.report-switches .group-row.is-unavailable .group-label { color: var(--label-secondary); }
.report-drafts .report-draft-open { flex: 1 1 auto; justify-content: flex-start; text-align: start; }
.report-drafts .report-draft-open[aria-current="true"] { font-weight: 600; }
/* A glyph button, sized by the control tier it sits in: 36px beside a pointer, the full 44px under a finger, like the row it closes. */
.report-drafts .btn.report-draft-delete { flex: none; width: var(--control-h-sm); height: var(--control-h-sm); min-height: var(--control-h-sm); padding: 0; color: var(--label-secondary); }
.report-save-status, .report-job-status { display: inline-flex; align-items: center; gap: 8px; min-height: 1rem; }
/* The pages. A4 at the CSS inch: 210mm by 297mm, 14mm margins, a head and a
   foot on every page. The ink is fixed so the page reads the same on the
   dark theme and in print. */
.report-pages { display: grid; gap: var(--space-6); justify-items: center; }
.report-page {
  --report-ink: #1d1d1f; --report-ink-2: #6e6e73; --report-rule: #d2d2d7; --report-fill: #f5f5f7; --report-up: #1f7a3a; --report-down: #b3261e; --report-accent: var(--accent);
  /* The page owns its ink, so the shared pieces drawn inside it read the
     page's colours and not the theme's: on the dark theme the chart's axis
     labels and grid came out near-white on white on the screen while the very
     same DOM printed dark, and the preview is meant to be the PDF. */
  --label: var(--report-ink); --label-secondary: var(--report-ink-2); --label-tertiary: var(--report-ink-2);
  --chart-axis-text: var(--report-ink-2); --chart-grid: rgba(0,0,0,.10); --chart-compare: #8e8e93;
  position: relative; box-sizing: border-box; width: min(210mm, 100%); min-height: 297mm; padding: 14mm 16mm 12mm;
  display: flex; flex-direction: column; gap: var(--space-4);
  background: #fff; color: var(--report-ink); border-radius: var(--radius-xs); box-shadow: 0 0 0 0.5px rgba(0,0,0,.10), 0 8px 24px rgba(0,0,0,.08);
  font: var(--text-callout);
}
.report-page-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); padding-bottom: var(--space-3); border-bottom: 1px solid var(--report-rule); }
.report-brand { display: flex; align-items: center; gap: var(--space-3); min-width: 0; }
.report-client-logo { height: 40px; width: auto; max-width: 140px; object-fit: contain; }
.report-client-name { font: var(--text-headline); color: var(--report-ink); }
.report-period { margin-top: 2px; font: var(--text-footnote); color: var(--report-ink-2); }
.report-page-body { flex: 1 1 auto; display: grid; gap: var(--space-6); align-content: start; }
.report-page-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding-top: var(--space-3); border-top: 1px solid var(--report-rule); font: var(--text-caption-1); color: var(--report-ink-2); }
.report-mark { height: 18px; width: auto; opacity: .85; }
.report-section { display: grid; gap: var(--space-3); }
.report-section-head { display: flex; align-items: center; gap: var(--space-2); }
/* Every written thing is a field styled as the printed text: a heading, a
   line, the notes. Hover shows the paper it sits on; focus takes the ring. */
.report-heading, .report-line, .report-notes { display: block; width: 100%; box-sizing: border-box; margin: 0; padding: 4px 6px; border: 0; border-radius: var(--radius-xs); background: transparent; color: inherit; font: inherit; resize: none; overflow: hidden; }
.report-heading { font: var(--text-title-2); color: var(--report-ink); }
.report-heading:hover, .report-line:hover, .report-notes:hover { background: var(--report-fill); }
.report-heading:focus-visible, .report-line:focus-visible, .report-notes:focus-visible { outline: 2px solid var(--report-accent); outline-offset: 0; background: #fff; }
.report-line, .report-notes { font: var(--text-callout); line-height: 1.5; min-height: 1.5rem; field-sizing: content; }
.report-line-static { margin: 0; font: var(--text-footnote); color: var(--report-ink-2); }
.report-num { direction: ltr; unicode-bidi: isolate; font-variant-numeric: tabular-nums; font-feature-settings: "tnum"; }
.report-change { font-weight: 600; direction: ltr; unicode-bidi: isolate; font-variant-numeric: tabular-nums; }
.report-change.up { color: var(--report-up); }
.report-change.down { color: var(--report-down); }
.report-change.flat, .report-change.no-direction { color: var(--report-ink-2); }
.report-tiles { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-3); margin: 0; }
.report-tile { display: grid; gap: 4px; min-width: 0; padding: 10px 12px; border-radius: var(--radius-sm); background: var(--report-fill); }
.report-tile-name { font: var(--text-caption-1); color: var(--report-ink-2); }
.report-tile-value { margin: 0; font: var(--text-title-2); color: var(--report-ink); font-variant-numeric: tabular-nums; }
.report-tile-previous { margin: 0; display: flex; flex-wrap: wrap; gap: 4px; align-items: baseline; font: var(--text-caption-1); color: var(--report-ink-2); }
.report-summary-lines { display: grid; gap: 4px; }
.report-channel-cards { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); }
.report-channel-card { padding: 12px 14px; border-radius: var(--radius-sm); background: var(--report-fill); }
.report-channel-name { margin: 0 0 8px; font: var(--text-headline); }
.report-channel-figures { display: grid; grid-template-columns: auto 1fr; gap: 4px 12px; margin: 0; font: var(--text-footnote); }
.report-channel-figures dt { color: var(--report-ink-2); }
.report-channel-figures dd { margin: 0; text-align: end; font-variant-numeric: tabular-nums; }
.report-site-figures { grid-template-columns: repeat(3, auto 1fr); }
.report-subsection { display: grid; gap: var(--space-2); }
.report-subheading { margin: 0; font: var(--text-headline); }
.report-tbl-wrap { overflow: hidden; }
.report-tbl { width: 100%; border-collapse: collapse; font: var(--text-footnote); }
.report-tbl th { padding: 6px 8px; text-align: start; font: var(--text-caption-1); font-weight: 600; color: var(--report-ink-2); border-bottom: 1px solid var(--report-rule); white-space: nowrap; }
.report-tbl td { padding: 6px 8px; border-bottom: var(--hairline) solid var(--report-rule); vertical-align: top; min-width: 0; }
.report-tbl td:first-child { font-weight: 500; max-width: 200px; overflow-wrap: anywhere; }
.report-tbl th.num, .report-tbl td.num { text-align: right; direction: ltr; unicode-bidi: isolate; font-variant-numeric: tabular-nums; white-space: nowrap; }
.report-tbl tbody tr:nth-child(even) td { background: var(--report-fill); }
.report-lines { display: grid; gap: 6px; margin: 0; padding: 0; padding-inline-start: 20px; }
.report-line-row { display: flex; align-items: flex-start; gap: 4px; }
.report-line-row .report-line { flex: 1 1 auto; }
.report-line-row .btn.report-line-remove { position: relative; flex: none; width: 28px; height: 28px; min-height: 28px; padding: 0; color: var(--report-ink-2); opacity: 0; }
.report-line-row:hover .btn.report-line-remove, .report-line-row .btn.report-line-remove:focus-visible, .report-line-row .report-line:focus-visible + .btn.report-line-remove { opacity: 1; }
/* Under a finger the glyph stays 28px beside its line - the drawn size is the
   paper's - and a transparent zone around it carries the missing 16px. */
@media (hover: none) {
  .report-line-row .btn.report-line-remove { opacity: 1; }
  .report-line-row .btn.report-line-remove::before { content: ""; position: absolute; inset: -8px; }
}
.report-chart { min-width: 0; }
.report-chart svg { display: block; width: 100%; height: auto; }
.report-chart-legend { display: flex; gap: 8px; }
.report-legend-now::before, .report-legend-before::before { content: ""; display: inline-block; width: 10px; height: 10px; margin-inline-end: 6px; border-radius: 50%; vertical-align: middle; }
.report-legend-now::before { background: var(--report-accent); }
.report-legend-before::before { background: var(--chart-compare); }
.report-page.is-skeleton, .report-page.report-error { min-height: 60vh; justify-content: center; }
.report-skeleton-bar { height: 14px; border-radius: var(--radius-xs); background: var(--report-fill); }
.report-error { align-items: center; text-align: center; gap: var(--space-3); }
/* A hidden page of the real width, where the blocks are measured before they are dealt onto pages. */
.report-measure { position: absolute; top: 0; inset-inline-start: -200vw; visibility: hidden; pointer-events: none; }
/* Screen only: the print engine lays the page out at the sheet's width, never the phone's. */
@media screen and (max-width: 767px) {
  .report-page { min-height: 0; padding: 24px 16px; }
  .report-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .report-channel-cards { grid-template-columns: minmax(0, 1fr); }
  .report-site-figures { grid-template-columns: auto 1fr; }
  .report-tbl-wrap { overflow-x: auto; }
}
/* Print: the pages and nothing else. Each page is one A4 sheet with the
   client's head and the Web3D foot on it, tables repeat their header row when
   a block is taller than a sheet, and the editing affordances and the
   controls go. Colours are kept as drawn. */
@media print {
  @page { size: A4 portrait; margin: 0; }
  /* The light theme, forced: the sheet outside the page boxes is paper too. */
  html:has(#reportsPanel:not([hidden])), body:has(#reportsPanel:not([hidden])), body:has(#reportsPanel:not([hidden])) .shell, body:has(#reportsPanel:not([hidden])) .document { background: #fff; }
  body:has(#reportsPanel:not([hidden])) .sidebar, body:has(#reportsPanel:not([hidden])) .sidebar-scrim, body:has(#reportsPanel:not([hidden])) .hdr, body:has(#reportsPanel:not([hidden])) .hdr-sentinel, body:has(#reportsPanel:not([hidden])) .toolbar, body:has(#reportsPanel:not([hidden])) .bottom-nav, body:has(#reportsPanel:not([hidden])) .library-mobile-bar, body:has(#reportsPanel:not([hidden])) .tabs-row, body:has(#reportsPanel:not([hidden])) #view, body:has(#reportsPanel:not([hidden])) #sectionTitle, body:has(#reportsPanel:not([hidden])) .toast, body:has(#reportsPanel:not([hidden])) .sheet, body:has(#reportsPanel:not([hidden])) .scrim, body:has(#reportsPanel:not([hidden])) .popover, body:has(#reportsPanel:not([hidden])) .select-menu, body:has(#reportsPanel:not([hidden])) #assistantHost, body:has(#reportsPanel:not([hidden])) .reports-controls { display: none; }
  body:has(#reportsPanel:not([hidden])) .shell, body:has(#reportsPanel:not([hidden])) .document, body:has(#reportsPanel:not([hidden])) main, body:has(#reportsPanel:not([hidden])) .library-content, body:has(#reportsPanel:not([hidden])) .wrap { display: block; width: auto; max-width: none; min-height: 0; margin: 0; padding: 0; }
  #reportsPanel { padding: 0; }
  .reports, .report-pages { display: block; }
  .report-page { width: 210mm; min-height: 297mm; margin: 0; border-radius: 0; box-shadow: none; }
  /* A sheet break only between printed pages: the trailing empty pages are not drawn, so a break after the last printed one would add a blank sheet. */
  .report-page:has(~ .report-page:not(.is-print-empty)) { break-after: page; page-break-after: always; }
  .report-page, .report-page * { print-color-adjust: exact; -webkit-print-color-adjust: exact; }
  .report-tbl thead { display: table-header-group; }
  .report-tbl tr, .report-tile, .report-channel-card, .report-line-row, .report-section-head, .report-chart { break-inside: avoid; page-break-inside: avoid; }
  .report-section-head, .report-subheading { break-after: avoid; page-break-after: avoid; }
  .report-page.is-print-empty, .report-section.is-empty, .report-line-row .btn.report-line-remove, .report-add-line, .report-measure { display: none; }
  .report-heading, .report-line, .report-notes { background: transparent; }
  .report-heading::placeholder, .report-line::placeholder, .report-notes::placeholder { color: transparent; }
}
/* ------------------------------------------ end of the reports tab -- */

/* The hidden attribute always wins; this stays the last rule of the sheet. */
[hidden] { display: none !important; }
