/* ===================================================================
   NAVO FOUNDATIONS v1 — DESIGN SYSTEM DOCUMENTATION
   Font wiring reproduced verbatim from the verified Figma Make source
   (src/index.css): Switzer = product/functional, Ranade = display/brand.
   JetBrains Mono is code only — <code>, the .mono utility and .code-card.
   Every other surface, identifiers and codes included, is Switzer with
   tabular numerals.
=================================================================== */
@font-face{ font-family:'Switzer'; src:url('/fonts/Switzer-Variable.woff2') format('woff2'); font-weight:100 900; font-style:normal; font-display:swap; }
@font-face{ font-family:'Switzer'; src:url('/fonts/Switzer-VariableItalic.woff2') format('woff2'); font-weight:100 900; font-style:italic; font-display:swap; }
@font-face{ font-family:'JetBrains Mono'; src:url('/fonts/JetBrainsMono-Variable.woff2') format('woff2'); font-weight:100 800; font-style:normal; font-display:swap; } /* Code only — <code>, .mono, .code-card */
@font-face{ font-family:'Ranade'; src:url('/fonts/Ranade-Variable.woff2') format('woff2'); font-weight:100 900; font-style:normal; font-display:swap; }
@font-face{ font-family:'Ranade'; src:url('/fonts/Ranade-VariableItalic.woff2') format('woff2'); font-weight:100 900; font-style:italic; font-display:swap; }

:root{
  /* ---- Neutral scale — verified, src/data/colors.ts::neutralScale ---- */
  --n-0:#FFFFFF; --n-25:#FCFCFD; --n-50:#F8F9FB; --n-100:#F1F3F6; --n-200:#E3E6EB;
  --n-300:#CDD2DA; --n-400:#9DA5B1; --n-500:#707986; --n-600:#505866; --n-700:#363D48;
  --n-800:#252A32; --n-900:#181B20; --n-950:#0B0D10; --n-1000:#000000;

  /* ---- Brand blue scale — verified, src/data/colors.ts::blueScale ---- */
  --blue-50:#F0F5FF; --blue-100:#E0EAFF; --blue-200:#C2D5FF; --blue-300:#91B4FF;
  --blue-400:#5C8DFA; --blue-500:#3567EF; --blue-600:#1F50E1; --blue-700:#113EC9; --blue-800:#1235A3;
  --blue-900:#102F81; --blue-950:#031A61;
  /* ---- Secondary palette primitives — v1.33 doc/code sync. Foundations → Color has documented
     these six scales as real tokens; until v1.33 they existed only on that page. Values copied
     verbatim from it. Same rule as --blue-*: never consumed directly by components. ---- */
  --coral-50:#FFF2F1; --coral-100:#FFE1DE; --coral-200:#FFC8C3; --coral-300:#FFA29A; --coral-400:#FA6D62; --coral-500:#F04438;
  --coral-600:#D63027; --coral-700:#BC1C15; --coral-800:#991B16; --coral-900:#7F1D19; --coral-950:#450A08;
  --rust-50:#FFF7ED; --rust-100:#FFEBD5; --rust-200:#FFD4AA; --rust-300:#FFB66F; --rust-400:#F89951; --rust-500:#F17B34;
  --rust-600:#EA5E16; --rust-700:#C2470C; --rust-800:#9A3912; --rust-900:#7C3112; --rust-950:#431506;
  --aqua-50:#EDFCFC; --aqua-100:#D2F7F6; --aqua-200:#A9EEEC; --aqua-300:#72DEDD; --aqua-400:#3BC9C9; --aqua-500:#18B6B8;
  --aqua-600:#0E969B; --aqua-700:#10777C; --aqua-800:#125F64; --aqua-900:#134F53; --aqua-950:#052E32;
  --violet-50:#F7F3FF; --violet-100:#EEE7FF; --violet-200:#DED1FF; --violet-300:#C8AEFF; --violet-400:#AA82FF; --violet-500:#8B5CF6;
  --violet-600:#7044EC; --violet-700:#5B32D6; --violet-800:#4928AE; --violet-900:#3D248A; --violet-950:#241451;
  --gold-50:#FFFBEB; --gold-100:#FEF3C7; --gold-200:#FDE68A; --gold-300:#FCD34D; --gold-400:#FBBF24; --gold-500:#F59E0B;
  --gold-600:#D97706; --gold-700:#B45309; --gold-800:#92400E; --gold-900:#78350F; --gold-950:#451A03;
  --lime-50:#F8FEE7; --lime-100:#EEFCCB; --lime-200:#DDF99C; --lime-300:#C6F35F; --lime-400:#A8E936; --lime-500:#86D31C;
  --lime-600:#66AA12; --lime-700:#4F8113; --lime-800:#416616; --lime-900:#385618; --lime-950:#1B3007;

  /* ---- Brand ring colors — verified from approved SVG source ---- */
  --brand-red:#E2231A; --brand-orange:#FF8135;

  /* ---- Destructive — the semantic Interactive / Destructive role (Color → Color roles: Error/600, hover Error/700), identical in both themes. v1.34: was var(--brand-red) — NAVO Red is never Error ---- */
  --destructive:#D92D20; --destructive-hover:#B42318; --destructive-active:#B51B14;

  /* ---- Semantic surface/text roles — light (default & primary mode), verified FoundAppearance pairs ---- */
  --bg-canvas:var(--n-0); --bg-base:var(--n-0); --bg-raised:var(--n-0); --bg-sunken:var(--n-100);
  /* Track fill for meters/charts — idle segments that must stay visible on ANY surface.
     --bg-sunken cannot serve this: in dark it resolves to the same n-950 as --bg-canvas,
     so a sunken track on a canvas-coloured parent renders black on black. */
  --bg-track:var(--n-100);
  --nav-hover-bg:var(--n-100);
  --border-default:var(--n-200); --border-strong:var(--n-300); --divider:var(--n-100);
  --text-primary:var(--n-950); --text-secondary:var(--n-600); --text-tertiary:var(--n-500); --text-disabled:var(--n-400);
  --text-inverse:var(--n-0); --link:var(--blue-700);
  --accent:var(--blue-700); --accent-hover:var(--blue-800); --accent-wash:var(--blue-50); --accent-wash-border:var(--blue-100);
  --border-subtle-line:rgba(16,24,40,.07); --ambient-wash:none; /* retired — page/content surfaces stay neutral per Foundations → Color; no blue/violet page-background tint */
  --scrollbar-thumb:var(--n-300);
  --selection-bg:var(--blue-100);

  /* ---- Status / semantic tint tokens — light values, unchanged from the original literals ---- */
  --status-verified-bg:#E8F6EE; --status-verified-text:#0F7A42;
  --status-derived-bg:#EFF3FF; --status-derived-text:#2547B8;
  --status-proposed-bg:#FFF3E4; --status-proposed-text:#B4590A;
  --status-approval-bg:#FDEBEC; --status-approval-text:#B4231A;
  --status-legacy-bg:var(--n-100); --status-legacy-text:var(--text-tertiary);
  --badge-success-bg:#ECFDF3; --badge-success-text:#027A48;
  --badge-warning-bg:#FFFAEB; --badge-warning-text:#B54708;
  --badge-error-bg:#FEF3F2; --badge-error-text:#B42318;
  --badge-info-bg:#EFF8FF; --badge-info-text:#175CD3;
  --badge-neutral-bg:var(--n-100); --badge-neutral-text:var(--text-secondary);
  --badge-live-bg:#F8FEE7; --badge-live-border:#DDF99C; --badge-live-text:#385618; --badge-live-mono:#66AA12; --badge-live-dot:#C6F35F;
  --dodont-do-bg:#F3FAF6; --dodont-do-border:#D6ECDF; --dodont-do-text:var(--badge-success-text);
  --dodont-dont-bg:#FFF2F1; --dodont-dont-border:#FFC8C3; --dodont-dont-text:#BC1C15; --dodont-dont-mono:#BC1C15;
  --dodont-do-banner:#86D31C; --dodont-dont-banner:#F04438;
  --codeblock-bg:var(--n-800);
  --state-hover-bg:var(--n-100); --state-pressed-bg:var(--n-200);

  /* ==== RADIUS — normalized to an even-number grid (Foundation Normalization pass).
     Supersedes the prior "Human-specified" 11/18/12/16/18/20/24 scale documented in
     Foundations → Radius; see that page for the superseding decision record. ==== */
  --radius-0:0px; --radius-2:2px; --radius-4:4px; --radius-6:6px; --radius-8:8px;
  --radius-12:12px; --radius-16:16px; --radius-20:20px; --radius-24:24px; --radius-32:32px; --radius-999:999px;

  /* ---- Aura update: controls/fields/buttons move to fully pill, cards to 24px —
     see Foundations → Radius decision record. r-float/r-panel/r-modal/r-expressive
     already matched the Aura reference and are unchanged. ---- */
  --r-control:var(--radius-999); --r-control-sm:var(--radius-999);
  --r-float:var(--radius-12); --r-card:var(--radius-24);
  --r-button:var(--radius-999); --r-button-sm:var(--radius-999); --r-button-lg:var(--radius-999);
  --r-panel:var(--radius-20); --r-modal:var(--radius-20);
  --r-expressive:var(--radius-24); --r-chip:var(--radius-4); --r-pill:var(--radius-999);
  --ease-lift:cubic-bezier(.22,1,.36,1);
  --ease-spring:cubic-bezier(.34,1.32,.48,1); /* Aura update: native spring/overshoot for control press-release */

  /* ---- Spacing — 2px base grid, verified FoundSpacing (comment corrected: this scale
     is 2px-based, not 4px — --sp-1 is 2px). Unchanged core scale plus three layout-specific
     additions (--sp-56/-60/-130) preserving the live, already-approved page/section rhythm. ---- */
  --sp-0:0px; --sp-1:2px; --sp-2:4px; --sp-3:6px; --sp-4:8px; --sp-5:12px; --sp-6:16px; --sp-7:20px;
  --sp-8:24px; --sp-9:32px; --sp-10:40px; --sp-11:48px; --sp-12:64px; --sp-13:80px; --sp-14:96px;
  --sp-56:56px; --sp-60:60px; --sp-130:130px;

  /* ---- Spacing semantic roles — Foundation Normalization role audit (438 raw instances
     traced to real selectors and grouped by function; see decision record). ---- */
  --space-chrome-gap:var(--sp-4); --space-control-inset-sm:var(--sp-4); --space-row-inset-sm:var(--sp-4);
  --space-label-gap:var(--sp-5); --space-card-stack:var(--sp-5); --space-inline-gap:var(--sp-5);
  --space-menu-row-inset:var(--sp-5); --space-control-inset:var(--sp-5); --space-surface-inset-sm:var(--sp-5);
  --space-diagram-label-inset:var(--sp-5); --space-empty-state-cta-gap:var(--sp-5); --space-dense-cell-inset:var(--sp-5);
  --space-block-gap:var(--sp-6); --space-surface-inset:var(--sp-6); --space-stack-gap:var(--sp-6);
  --space-surface-inset-lg:var(--sp-7); --space-section-break:var(--sp-7);
  --space-card-inset:var(--sp-8); --space-header-inset:var(--sp-8); --space-doc-section-gap:var(--sp-8);
  --space-empty-state-inset:var(--sp-9); --space-demo-stack-gap:var(--sp-9);
  --space-input-affix-clearance:var(--sp-10); --space-page-intro-gap:var(--sp-11);

  /* ---- Layout — page/section rhythm. Live rendered values preserved exactly
     (Foundation Normalization Decision 5) — tokenized only, zero visual change. ---- */
  --space-page-gutter-top:var(--sp-56); --space-page-gutter-x:var(--sp-60);
  --hero-navw:var(--shell-nav-w); --hero-gutter:var(--space-page-gutter-x); --hero-gutter-top:var(--space-page-gutter-top);
  --space-page-gutter-bottom:var(--sp-56); --space-section-gap:var(--sp-60);

  /* ---- Elevation — verified, FoundElevation §01.10 ---- */
  --shadow-0:none;
  /* ---- Aura update: warm ink undertone (#0B0D10) instead of pure black — light mode only ---- */
  --shadow-1:0 1px 3px rgba(11,13,16,.08);
  --shadow-2:0 4px 12px rgba(11,13,16,.10);
  --shadow-3:0 8px 24px rgba(11,13,16,.12);
  --shadow-4:0 16px 40px rgba(11,13,16,.16);
  --shadow-ovl:0 24px 60px rgba(11,13,16,.24);

  /* ---- Motion — verified, FoundMotion ---- */
  --dur-fast:100ms; --dur-moderate:150ms; --dur-default:200ms; --dur-slow:300ms;
  --ease-out:cubic-bezier(.16,1,.3,1); --ease-in:cubic-bezier(.7,0,.84,0);

  /* ==== DATA VISUALIZATION — v1.33. Foundations → Data Visualization in code, mirroring the
     Figma NAVO/Data Visualization collection. Every colour is a one-level alias to a primitive.
     Chart colours are never brand anchors: --brand-red / --brand-orange are not data colours. ==== */
  /* Categorical — seven hues, in this order. There is no 8th hue: the 8th group is "Other" in
     --data-viz-context, and a series beyond that is aggregated or split into small multiples.
     Order and bindings are PROVISIONAL — from the 2026-09-03 Figma audit, not re-verified in v1.33.
     Figma's slot 06 (green-550, the Success-500 value) is retired, not replaced. */
  --data-viz-categorical-01:var(--blue-600); --data-viz-categorical-02:var(--aqua-500);
  --data-viz-categorical-03:var(--violet-600); --data-viz-categorical-04:var(--gold-500);
  --data-viz-categorical-05:var(--coral-600); --data-viz-categorical-06:var(--lime-500);
  --data-viz-categorical-07:var(--rust-500);
  /* Sequential — intensity, volume, density. Never for categorical distinctions. */
  --data-viz-sequential-blue-01:var(--blue-100); --data-viz-sequential-blue-02:var(--blue-200); --data-viz-sequential-blue-03:var(--blue-300); --data-viz-sequential-blue-04:var(--blue-400); --data-viz-sequential-blue-05:var(--blue-500); --data-viz-sequential-blue-06:var(--blue-600); --data-viz-sequential-blue-07:var(--blue-700); --data-viz-sequential-blue-08:var(--blue-800); --data-viz-sequential-blue-09:var(--blue-900);
  --data-viz-sequential-aqua-01:var(--aqua-100); --data-viz-sequential-aqua-02:var(--aqua-200); --data-viz-sequential-aqua-03:var(--aqua-300); --data-viz-sequential-aqua-04:var(--aqua-400); --data-viz-sequential-aqua-05:var(--aqua-500); --data-viz-sequential-aqua-06:var(--aqua-600); --data-viz-sequential-aqua-07:var(--aqua-700); --data-viz-sequential-aqua-08:var(--aqua-800); --data-viz-sequential-aqua-09:var(--aqua-900);
  --data-viz-sequential-violet-01:var(--violet-100); --data-viz-sequential-violet-02:var(--violet-200); --data-viz-sequential-violet-03:var(--violet-300); --data-viz-sequential-violet-04:var(--violet-400); --data-viz-sequential-violet-05:var(--violet-500); --data-viz-sequential-violet-06:var(--violet-600); --data-viz-sequential-violet-07:var(--violet-700); --data-viz-sequential-violet-08:var(--violet-800); --data-viz-sequential-violet-09:var(--violet-900);
  /* Diverging — blue ↔ coral around a neutral midpoint. Cool = early / ahead / under,
     warm = late / behind / over. No new colour family. */
  --data-viz-diverging-cool-3:var(--blue-700); --data-viz-diverging-cool-2:var(--blue-500); --data-viz-diverging-cool-1:var(--blue-200);
  --data-viz-diverging-mid:var(--n-200);
  --data-viz-diverging-warm-1:var(--coral-200); --data-viz-diverging-warm-2:var(--coral-400); --data-viz-diverging-warm-3:var(--coral-600);
  /* Structure — the quiet ink every visualization is drawn on. */
  --data-viz-grid:var(--n-100); --data-viz-axis:var(--n-300); --data-viz-baseline:var(--n-400);
  --data-viz-label:var(--n-500); --data-viz-context:var(--n-300); --data-viz-annotation:var(--n-700);
  --data-viz-target:var(--n-800); --data-viz-highlight:var(--blue-700);
  --data-viz-stroke-grid:1px; --data-viz-stroke-line:2px;
  --data-viz-point-r:var(--sp-2); --data-viz-bar-radius:var(--radius-2);
  /* Logistics map roles (approved 2026-09-23). No brand anchors: Destination is coral, Hub is violet.
     Delayed / Completed reuse the Status vocabulary (a Route never invents its own states), so they
     alias the existing badge tokens and follow the theme through them. Colour is never the only cue:
     line treatment, marker shape and labels carry the meaning too. */
  --data-viz-route-default:var(--n-400); --data-viz-route-selected:var(--blue-700);
  --data-viz-route-alternative:var(--aqua-500); --data-viz-route-inactive:var(--n-200);
  --data-viz-route-delayed:var(--badge-warning-text); --data-viz-route-completed:var(--badge-success-text);
  --data-viz-origin:var(--blue-800); --data-viz-destination:var(--coral-600); --data-viz-hub:var(--violet-600);
  --data-viz-state-live:var(--lime-300);
  /* Data motion — "data should move, not the UI". No spring, no overshoot. */
  --dur-data:400ms; --dur-draw:600ms; --stagger-data:40ms;
  --ease-data:cubic-bezier(.4,0,.2,1);

  /* ---- Glass — labeled in reference screenshots ---- */
  --glass-fill:.62; --glass-fill-strong:.82;
  --glass-fill-subtle:.40; /* v1.34 — Glass 1, the subtle nested surface (Elevation & Surfaces → Glass) */
  --glass-blur:24px; --glass-blur-lg:40px; /* Aura update: standard vs. large blur tier — matches this file's own Glass Material Contract note (Elevation) and NAVO/Glass/Blur — Large in Figma */
  --grad-neutral:radial-gradient(circle at 30% 25%, #70798633, transparent 60%), radial-gradient(circle at 75% 40%, #7079861a, transparent 55%), radial-gradient(circle at 45% 85%, #70798633, transparent 60%), #F1F3F6;
  --grad-blue:radial-gradient(circle at 25% 30%, #18b6b81a, transparent 55%), radial-gradient(circle at 65% 25%, #3567ef1a, transparent 55%), radial-gradient(circle at 50% 80%, #1f50e11a, transparent 60%), #F5F6F8;
  --grad-brand:radial-gradient(circle at 30% 25%, #b1a0e84d, transparent 55%), radial-gradient(circle at 70% 35%, #3bc9c933, transparent 55%), radial-gradient(circle at 50% 85%, #113ec933, transparent 60%), #F0EDF2;
  --grad-warm:radial-gradient(circle at 25% 30%, #f59e0b33, transparent 55%), radial-gradient(circle at 70% 30%, #bc1c151a, transparent 50%), radial-gradient(circle at 50% 85%, #fbbf2433, transparent 60%), #F5F6F8;
  --grad-accent:linear-gradient(135deg, #a8e93633, transparent 60%), radial-gradient(circle at 65% 30%, #a16ee833, transparent 55%), radial-gradient(circle at 40% 80%, #f17b3433, #fcd34d00 60%), #F5F6F8;
  --glass-card-bg:rgba(255,255,255,var(--glass-fill));
  --glass-card-bg-strong:rgba(255,255,255,var(--glass-fill-strong));
  --glass-card-bg-subtle:rgba(255,255,255,var(--glass-fill-subtle)); /* v1.34 — Glass 1 */
  --glass-card-border:rgba(255,255,255,.8);

  --font-sans:'Switzer', system-ui, sans-serif;
  --font-display:'Ranade', serif;
  --font-mono:'JetBrains Mono', ui-monospace, monospace;

  /* ==== TYPOGRAPHY — even-number-only primitives (Foundation Normalization pass).
     Collapses the prior 11/11.5/12/12.5/13/13.5/14px micro-scale onto --fs-1/--fs-2;
     13px specifically was split by semantic role, not rounded (see decision record). ==== */
  --fs-1:12px; --fs-2:14px; --fs-3:16px; --fs-4:18px; --fs-5:20px; --fs-6:24px; --fs-7:26px;
  --fs-8:32px; --fs-9:38px; --fs-10:40px; --fs-11:44px; --fs-12:48px; --fs-13:64px;
  --fs-14:80px; --fs-15:96px; /* Aura update: full-bleed marketing steps above Hero */
  --lh-1:1.15; --lh-2:1.4; --lh-3:1.5; --lh-4:1.6; --lh-5:1.7;
  --ls-1:-.02em; --ls-2:-.015em; --ls-3:-.01em; --ls-4:0; --ls-5:.01em; --ls-6:.03em; --ls-7:.04em; --ls-8:.08em;
  --fw-regular:400; --fw-medium:500; --fw-semibold:600; --fw-bold:700;

  --text-heading-xs:var(--fs-4); --text-heading-s:var(--fs-5); --text-heading-m:var(--fs-6);
  --text-heading-l:var(--fs-7); --text-heading-xl:var(--fs-8);
  --text-page-title:var(--fs-9); --text-kpi-hero:var(--fs-10);

  /* ---- Icon sizing — normalized 3-tier scale, replaces 11/13/14/15/16px spread ---- */
  --size-icon-sm:12px; --size-icon-md:14px; --size-icon-lg:16px;

  --shell-nav-w:280px; --shell-top-h:60px;

  /* ---- Shell height & sidebar insets. A sidebar is chrome, not content: it owns the
     viewport's height and never grows with the page, so every shell height is measured
     from one token instead of each surface writing its own 100vh.

     --shell-vh is the SMALL viewport (svh) wherever the browser has it: the height measured
     with a mobile browser's toolbars SHOWN. dvh is exact to the pixel but re-lays out the
     whole shell every time that bar collapses, dragging the nav list and its scroll
     position with it; svh is stable, and can only ever be too short by the bar's height —
     which the sidebar's own inset absorbs. Plain vh stays the fallback for browsers
     without the 2022 units, where it is the only thing that ever was.

     --shell-side-inset is the gap a floating sidebar keeps from the viewport edges, and
     --shell-side-h is the height that inset leaves it. Both are read, never re-derived. ---- */
  --shell-vh:100vh;
  --shell-side-inset:var(--sp-5);
  --shell-side-h:calc(var(--shell-vh) - var(--shell-side-inset) * 2);

  /* ---- Surface depth & canvas texture — visual differentiation pass 2.
     Additive only: no primitive or semantic token VALUES above this point
     are changed. These are new supplementary tokens for presentation-layer
     refinement (shadows, sheens, canvas texture, focus ring, active rail). ---- */
  --canvas-grid:radial-gradient(circle at 1px 1px, rgba(16,24,40,.05) 1px, transparent 0);
  --shadow-surface-rest:0 1px 1px rgba(16,24,40,.02), 0 2px 6px rgba(16,24,40,.04), 0 14px 28px -16px rgba(16,24,40,.12);
  --sticky-edge-shadow:rgba(16,24,40,.12);
  --shadow-surface-hover:0 1px 1px rgba(16,24,40,.03), 0 6px 16px rgba(16,24,40,.07), 0 24px 44px -18px rgba(16,24,40,.18);
  --surface-sheen:inset 0 1px 0 rgba(255,255,255,.85);
  --ring-focus:0 0 0 3px var(--blue-100);
  --shadow-accent-hover:0 12px 28px rgba(17,62,201,.24); /* Aura update: colored lift glow, was 0 2px 8px .20 */
  --shadow-destructive-hover:0 12px 28px rgba(217,45,32,.26); /* Aura update, scaled to match */

  /* ==== WORKSPACE BLOCKS — v1.35. Patterns → Workspace Blocks. Lifted from the TrackingMCP workspace
     (owner-approved 2026-10-02). Every value is an alias to a primitive; nothing new in the palette. ==== */
  /* Ground and block layers: the higher a layer, the lighter it is. */
  --bg-ground:var(--n-200); /* v1.35 — the workspace page ground, two neutral steps under its blocks */
  --block-frame-bg:var(--glass-card-bg-subtle); /* v1.35 — a block's frame (Glass 1), also the controls tray */
  --block-card-bg:var(--n-0); /* v1.35 — the one card inside a block */
  --block-tile-bg:var(--n-100); /* v1.35 — a quiet tile on the card */
  --block-track:var(--n-200); /* v1.35 — a bar's empty track on a tile */
  --layer-hover:color-mix(in srgb, var(--text-primary) 4%, transparent); /* v1.35 — hover wash laid over any layer */
  /* Selected: one mark, the brand blue. */
  --selected-mark:var(--accent); /* v1.35 — a chosen chip's fill and a chosen card's 2px ring */
  --selected-mark-ink:var(--n-0); /* v1.35 — ink on the chosen chip */
  /* Status badges: solid 300 fills with dark ink (the .step-pill recipe). Alerts, banners and status
     text keep the --badge-*-bg / --badge-*-text pairs. */
  --badge-solid-success-bg:var(--lime-300); --badge-solid-success-text:var(--n-950); /* v1.35 */
  --badge-solid-warning-bg:var(--gold-300); --badge-solid-warning-text:var(--n-950); /* v1.35 */
  --badge-solid-info-bg:var(--blue-700); --badge-solid-info-text:var(--n-0); /* v1.35 — on the move is blue */
  --badge-solid-error-bg:var(--badge-error-text); --badge-solid-error-text:var(--bg-base); /* v1.35 — semantic error, never brand red */
  --badge-solid-neutral-bg:var(--n-200); --badge-solid-neutral-text:var(--n-800); /* v1.35 */
  /* The journey: done is blue, the leg into now runs blue to lime, now is a lime point that pulses. */
  --journey-done:var(--blue-500); /* v1.35 */
  --journey-now:var(--lime-300); /* v1.35 */
  --journey-leg-x:linear-gradient(to right in oklch, var(--journey-done), var(--journey-now)); /* v1.35 */
  --journey-leg-y:linear-gradient(to bottom in oklch, var(--journey-done), var(--journey-now)); /* v1.35 */
  /* Shipment stages, one hue each, the same on every chart, column and dot. */
  --stage-pre:var(--n-300); /* v1.35 — before the voyage */
  --stage-sea:var(--blue-400); /* v1.35 — at sea */
  --stage-ts:var(--blue-300); /* v1.35 — transshipment */
  --stage-arr:var(--aqua-300); /* v1.35 — arriving */
  --stage-port:var(--violet-300); /* v1.35 — at the destination port */
  --stage-done:var(--lime-300); /* v1.35 — delivered */
  /* People: initials on one of six palette hues, picked from the person, dark ink. */
  --avatar-hue-0:var(--lime-300); --avatar-hue-1:var(--violet-300); --avatar-hue-2:var(--aqua-300); /* v1.35 */
  --avatar-hue-3:var(--gold-300); --avatar-hue-4:var(--coral-300); --avatar-hue-5:var(--blue-300); /* v1.35 */
  /* Calendars are about arriving: the chosen day an aqua fill, today an aqua ring. */
  --cal-fill:var(--aqua-700); --cal-ink:var(--aqua-700); /* v1.35 */
}

/* ---- Dark theme — semantic surface tokens only, per FoundAppearance's verified
   Light/Dark pairs (Background/Canvas, Background/Default, Surface/Raised,
   Text/Primary, Text/Secondary, Border/Default, Interactive/Primary/Default) plus
   consistent extensions for the remaining semantic roles. Primitives (neutral,
   blue, brand, semantic hue scales) never change — only which primitive a
   semantic token resolves to. No filter/invert is used anywhere. ---- */
:root[data-theme="dark"]{
  --bg-canvas:var(--n-950); --bg-base:var(--n-900); --bg-raised:var(--n-800); --bg-sunken:var(--n-950);
  --bg-track:var(--n-800);   /* distinct from BOTH canvas (n-950) and base (n-900) */
  --nav-hover-bg:var(--n-800);
  --border-default:var(--n-700); --border-strong:var(--n-600); --divider:var(--n-800);
  --text-primary:var(--n-50); --text-secondary:var(--n-300); --text-tertiary:var(--n-400); --text-disabled:var(--n-600);
  --text-inverse:var(--n-950); --link:var(--blue-500);
  --accent:var(--blue-500); --accent-hover:var(--blue-400); --accent-wash:rgba(53,103,239,.16); --accent-wash-border:rgba(53,103,239,.4);
  --border-subtle-line:rgba(255,255,255,.08); --ambient-wash:none; /* retired — page/content surfaces stay neutral per Foundations → Color; no blue/violet page-background tint */
  --scrollbar-thumb:var(--n-700);
  --selection-bg:var(--blue-800);

  /* ---- Data visualization — dark values (v1.33). Categorical and sequential do not change. ---- */
  --data-viz-diverging-cool-3:var(--blue-300); --data-viz-diverging-cool-1:var(--blue-800);
  --data-viz-diverging-mid:var(--n-700);
  --data-viz-diverging-warm-1:var(--coral-800); --data-viz-diverging-warm-3:var(--coral-300);
  --data-viz-grid:var(--n-800); --data-viz-axis:var(--n-700); --data-viz-baseline:var(--n-600);
  --data-viz-label:var(--n-400); --data-viz-context:var(--n-700); --data-viz-annotation:var(--n-200);
  --data-viz-target:var(--n-100); --data-viz-highlight:var(--blue-500);
  --data-viz-route-default:var(--n-600); --data-viz-route-selected:var(--blue-500);
  --data-viz-route-alternative:var(--aqua-400); --data-viz-route-inactive:var(--n-700);
  --data-viz-origin:var(--blue-400); --data-viz-destination:var(--coral-400); --data-viz-hub:var(--violet-400);

  --shadow-1:0 1px 3px rgba(0,0,0,.5);
  --shadow-2:0 4px 14px rgba(0,0,0,.55);
  --shadow-3:0 10px 28px rgba(0,0,0,.6);
  --shadow-4:0 18px 44px rgba(0,0,0,.65);
  --shadow-ovl:0 26px 64px rgba(0,0,0,.7);

  --status-verified-bg:#0B2E1D; --status-verified-text:#6CE9A6;
  --status-derived-bg:#0F1E42; --status-derived-text:#84ADFF;
  --status-proposed-bg:#3A2408; --status-proposed-text:#FEC84B;
  --status-approval-bg:#3A1210; --status-approval-text:#FDA29B;
  --status-legacy-bg:var(--n-800); --status-legacy-text:var(--n-400);
  --badge-success-bg:#022C1C; --badge-success-text:#6CE9A6;
  --badge-warning-bg:#4E1D09; --badge-warning-text:#FEC84B;
  --badge-error-bg:#55160C; --badge-error-text:#FDA29B;
  --badge-info-bg:#102A56; --badge-info-text:#84CAFF;
  --badge-neutral-bg:var(--n-800); --badge-neutral-text:var(--n-300);
  --badge-live-bg:rgba(198,243,95,.14); --badge-live-border:rgba(198,243,95,.3); --badge-live-text:#C6F35F; --badge-live-mono:rgba(198,243,95,.75); --badge-live-dot:#C6F35F;
  --dodont-do-bg:#0B2E1D; --dodont-do-border:#1B4A32; --dodont-do-text:var(--badge-success-text);
  --dodont-dont-bg:rgba(240,68,56,.14); --dodont-dont-border:rgba(240,68,56,.3); --dodont-dont-text:#FFA29A; --dodont-dont-mono:rgba(240,68,56,.75);
  --codeblock-bg:var(--n-800);
  --state-hover-bg:var(--n-800); --state-pressed-bg:var(--n-700);

  --grad-neutral:radial-gradient(circle at 30% 25%, #70798640, transparent 60%), radial-gradient(circle at 75% 40%, #70798626, transparent 55%), radial-gradient(circle at 45% 85%, #70798640, transparent 60%), #181B20;
  --grad-blue:radial-gradient(circle at 25% 30%, #18b6b833, transparent 55%), radial-gradient(circle at 65% 25%, #3567ef33, transparent 55%), radial-gradient(circle at 50% 80%, #1f50e133, transparent 60%), #181B20;
  --grad-brand:radial-gradient(circle at 30% 25%, #b1a0e866, transparent 55%), radial-gradient(circle at 70% 35%, #3bc9c94d, transparent 55%), radial-gradient(circle at 50% 85%, #113ec94d, transparent 60%), #181B20;
  --grad-warm:radial-gradient(circle at 25% 30%, #f59e0b4d, transparent 55%), radial-gradient(circle at 70% 30%, #bc1c1533, transparent 50%), radial-gradient(circle at 50% 85%, #fbbf244d, transparent 60%), #181B20;
  --grad-accent:linear-gradient(135deg, #a8e9364d, transparent 60%), radial-gradient(circle at 65% 30%, #a16ee84d, transparent 55%), radial-gradient(circle at 40% 80%, #f17b344d, #fcd34d00 60%), #181B20;
  --glass-card-bg:rgba(24,27,32,var(--glass-fill));
  --glass-card-bg-strong:rgba(24,27,32,var(--glass-fill-strong));
  --glass-card-bg-subtle:rgba(24,27,32,var(--glass-fill-subtle)); /* v1.34 — Glass 1 */
  --glass-card-border:rgba(255,255,255,.14);

  --canvas-grid:radial-gradient(circle at 1px 1px, rgba(255,255,255,.055) 1px, transparent 0);
  --shadow-surface-rest:0 1px 1px rgba(0,0,0,.35), 0 2px 8px rgba(0,0,0,.4), 0 16px 32px -16px rgba(0,0,0,.55);
  --sticky-edge-shadow:rgba(0,0,0,.5);
  --shadow-surface-hover:0 1px 1px rgba(0,0,0,.4), 0 10px 22px rgba(0,0,0,.5), 0 28px 52px -18px rgba(0,0,0,.65);
  --surface-sheen:inset 0 1px 0 rgba(255,255,255,.05);
  --ring-focus:0 0 0 3px rgba(53,103,239,.35);
  --shadow-accent-hover:0 12px 28px rgba(53,103,239,.35); /* Aura update, was 0 2px 10px */
  --shadow-destructive-hover:0 12px 28px rgba(217,45,32,.38); /* Aura update, was 0 2px 10px */

  /* ==== WORKSPACE BLOCKS — v1.35, dark. Half steps up from a flat n-950 ground. ==== */
  --bg-ground:var(--n-950); /* v1.35 */
  --block-frame-bg:var(--n-900); /* v1.35 */
  --block-card-bg:var(--n-800); /* v1.35 */
  --block-tile-bg:color-mix(in srgb, var(--n-700) 55%, var(--n-800)); /* v1.35 — half a step above the card */
  --block-track:var(--n-700); /* v1.35 */
  --badge-solid-neutral-bg:var(--n-700); --badge-solid-neutral-text:var(--n-100); /* v1.35 */
  --stage-pre:var(--n-600); /* v1.35 */
  --cal-ink:var(--aqua-300); /* v1.35 */
}

*{box-sizing:border-box;}
html,body{margin:var(--sp-0);padding:var(--sp-0);}
h1,h2,h3,h4,h5,h6{margin:var(--sp-0);}
/* Ranade carries every heading level — h1 through h4 — system-wide, per
   the updated Typography rule — see Foundations → Typography → "The
   Ranade usage test". Dense component/pattern micro-labels (anatomy rows,
   spec captions, table headers) never use h1-h4 in this file — they're
   plain divs/spans with their own classes — so this rule only ever reaches
   genuine titles: card headlines, question headings, section titles. h5/h6
   stay on Switzer (truly dense micro-labels do use those). */
h1,h2,h3,h4{ font-family:var(--font-display); }
body{
  background:var(--bg-canvas); color:var(--text-primary); font-family:var(--font-sans);
  font-size:var(--fs-2); line-height:var(--lh-3); -webkit-font-smoothing:antialiased;
}
h1,h2,h3,h4{margin:var(--sp-0); font-weight:var(--fw-bold); color:var(--text-primary);} /* font-family set on line 250 */
p{margin:var(--sp-0);}
a{color:var(--link); text-decoration:none;}
a:hover{text-decoration:underline;}
button{font-family:inherit;}
::selection{background:var(--selection-bg);}
code, .mono{ font-family:var(--font-mono); font-variant-numeric:tabular-nums; letter-spacing:var(--ls-5); } /* The only mono surfaces in the system, with .code-card */
::-webkit-scrollbar{width:10px; height:10px;}
::-webkit-scrollbar-thumb{background:var(--scrollbar-thumb); border-radius:var(--r-pill); border:2px solid var(--bg-canvas);}
::-webkit-scrollbar-track{background:transparent;}

@media (prefers-reduced-motion: reduce){
  *{animation-duration:.001ms !important; transition-duration:.001ms !important;}
}

/* The small-viewport unit where it exists. Written as an upgrade rather than inline in
   :root so the vh fallback above stays the value in browsers that never learned svh. */
@supports (height:100svh){ :root{ --shell-vh:100svh; } }

/* ============================= SHELL ============================= */
.shell{ display:grid; grid-template-columns:var(--shell-nav-w) 1fr; grid-template-rows:var(--shell-top-h) 1fr; height:var(--shell-vh); }

.topbar{
  grid-column:1/-1; grid-row:1; display:flex; align-items:center; gap:var(--space-stack-gap);
  padding:var(--sp-0) var(--sp-8); background:var(--bg-base); border-bottom:1px solid var(--border-subtle-line); z-index:30;
}
.topbar .brand{ display:flex; align-items:center; gap:var(--space-chrome-gap); font-weight:600; font-size:var(--fs-2); letter-spacing:var(--ls-3); }
.topbar .brand svg{ height:24px; width:auto; display:block; }
#brand-logo-landing svg{ height:22px; width:auto; display:block; }
#brand-logo-ovintro svg{ height:24px; width:auto; display:block; }
.busy-bg-wordmark{ fill:#0B0D10; }
:root[data-theme="dark"] .busy-bg-wordmark{ fill:#fff; }
.busy-bg-black-gradient{ background:linear-gradient(135deg, var(--n-800), var(--n-700)); }
:root[data-theme="dark"] .busy-bg-black-gradient{ background:linear-gradient(135deg, var(--n-1000), var(--n-950)); }
.topbar .divider-v{ width:1px; height:20px; background:linear-gradient(180deg, transparent, var(--border-default) 30%, var(--border-default) 70%, transparent); }
.topbar .crumbs{ font-size:var(--fs-1); }
.topbar .crumb{ max-width:none; overflow:visible; text-overflow:clip; white-space:nowrap; }
.topbar-spacer{flex:1;}
.searchbox{
  display:flex; align-items:center; gap:var(--sp-4); width:280px; padding:var(--sp-4) var(--sp-5); border-radius:var(--r-control);
  background:var(--bg-base); border:1px solid var(--border-default); color:var(--text-tertiary); font-size:var(--fs-2);
  box-shadow:inset 0 1px 2px rgba(16,24,40,.03); cursor:pointer;
  transition:border-color var(--dur-default) var(--ease-out), box-shadow var(--dur-default) var(--ease-out), background var(--dur-default) var(--ease-out);
}
.searchbox:hover{ background:var(--bg-canvas); border-color:var(--border-strong); }
.searchbox .field-icon{ position:static; transform:none; flex-shrink:0; }
.searchbox-label{ flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.searchbox .field-kbd{ position:static; margin-left:auto; flex-shrink:0; }
/* ---- Live command-palette search (Cmd/Ctrl+K or click the searchbox) —
   reuses the .cmdk-demo visual pattern already documented on the Command
   Palette specimen, so the live search looks identical to what's shown
   as a component example elsewhere in the system. ---- */
.cmdk-overlay{ position:fixed; inset:0; z-index:1000; display:none; align-items:flex-start; justify-content:center; padding-top:12vh; background:rgba(11,13,16,.5); }
.cmdk-overlay.open{ display:flex; }
.cmdk-demo.cmdk-live{ width:560px; max-width:90vw; max-height:70vh; display:flex; flex-direction:column; }
.cmdk-demo.cmdk-live .cmdk-input{ flex-shrink:0; }
.cmdk-demo.cmdk-live .cmdk-input input{ flex:1; border:none; outline:none; background:none; font-size:var(--fs-2); color:var(--text-primary); font-family:var(--font-sans); }
.cmdk-demo.cmdk-live .cmdk-input input::placeholder{ color:var(--text-tertiary); }
.cmdk-demo.cmdk-live .cmdk-results{ overflow-y:auto; max-height:none; flex:1; }
#nav-toggle.nav-toggle{ display:none; }
.mobile-nav-scrim{ display:none; }
.theme-toggle .icon-moon{ display:none; }
:root[data-theme="dark"] .theme-toggle .icon-sun{ display:none; }
:root[data-theme="dark"] .theme-toggle .icon-moon{ display:block; }
.sidenav{
  grid-column:1; grid-row:2; overflow-y:auto; background:var(--bg-base); border-right:1px solid var(--border-subtle-line);
  padding:var(--sp-7) var(--sp-5) var(--sp-10); box-shadow:1px 0 0 rgba(16,24,40,.015);
  /* min-height:0 is what lets a grid row shorter than its content actually scroll, instead
     of stretching the row and pushing the shell past the bottom of the viewport;
     overscroll-behavior stops a flick at the end of the list carrying on into the page. */
  min-height:0; overscroll-behavior:contain;
}
.nav-group{ margin-bottom:var(--sp-1); }
.nav-group-label{
  display:flex; align-items:center; gap:var(--sp-4); padding:var(--sp-4) var(--space-label-gap); border-radius:var(--radius-24); cursor:pointer;
  font-size:var(--fs-2); font-weight:600; color:var(--text-primary); user-select:none;
  transition:background var(--dur-moderate) var(--ease-out);
}
.nav-group-label:hover{ background:var(--nav-hover-bg); }
.nav-group-label .chev{ margin-left:auto; width:14px; height:14px; color:var(--text-tertiary); transform:rotate(90deg); transition:transform var(--dur-default) var(--ease-lift); } /* the shared chev asset points right; a collapsed group reads as "down = there is more below", open flips it up */
.nav-group.open .chev{ transform:rotate(-90deg); }
.nav-group-label .count{ font-size:var(--fs-1); color:var(--text-tertiary); font-weight:500; }
.nav-items{ display:none; padding-left:var(--space-surface-inset); margin:var(--sp-1) var(--sp-0) var(--space-label-gap); border-left:1px solid var(--border-subtle-line); margin-left:var(--sp-7); }
.nav-group.open .nav-items{ display:block; }
.nav-item{
  display:block; padding:var(--sp-4) var(--sp-5); border-radius:var(--radius-24); margin:1px var(--sp-0);
  font-size:var(--fs-2); color:var(--text-secondary); cursor:pointer; white-space:nowrap; position:relative;
  transition:color var(--dur-moderate) var(--ease-out), background var(--dur-moderate) var(--ease-out), transform var(--dur-moderate) var(--ease-lift);
}
.nav-item:hover{ color:var(--text-primary); background:var(--nav-hover-bg); transform:translateX(1px); }
.nav-item.active{ color:var(--accent); background:var(--accent-wash); font-weight:500; box-shadow:inset 0 0 0 1px var(--accent-wash-border); }
.nav-item .n{ display:inline-block; width:18px; color:var(--text-disabled); font-size:var(--fs-1); }
.nav-root-item{
  display:flex; align-items:center; gap:var(--sp-4); padding:var(--sp-4) var(--space-label-gap); border-radius:var(--radius-24); font-size:var(--fs-2); font-weight:600;
  color:var(--text-primary); cursor:pointer; transition:background var(--dur-moderate) var(--ease-out);
}
.nav-root-item:hover{ background:var(--nav-hover-bg); }
.nav-root-item.active{ color:var(--accent); background:var(--accent-wash); }
.nav-sep{ height:1px; background:linear-gradient(90deg, transparent, var(--border-default) 15%, var(--border-default) 85%, transparent); margin:var(--space-label-gap) var(--sp-3); }
.nav-scope-note{ padding:var(--space-label-gap) var(--sp-5); font-size:var(--fs-1); color:var(--text-tertiary); line-height:var(--lh-3); }

.workspace{ grid-column:2; grid-row:2; overflow-y:auto; }
.page{ display:none; max-width:1200px; margin:var(--sp-0) auto; padding:var(--space-page-gutter-top) var(--space-page-gutter-x) var(--space-page-gutter-bottom); }
.page.active{ display:block; animation:page-in 260ms var(--ease-lift); }
@keyframes page-in{ from{ opacity:0; transform:translateY(4px); } to{ opacity:1; transform:translateY(0); } }
@media (prefers-reduced-motion: reduce){ .page.active{ animation:none; } }

/* ============================= PAGE CHROME ============================= */
.gs-row{ display:flex; align-items:center; justify-content:space-between; gap:var(--sp-5); padding:var(--sp-5) var(--sp-6); border-radius:var(--radius-32); background:var(--bg-sunken); margin-bottom:var(--sp-3); }
.gs-row.clickable{ cursor:pointer; transition:background var(--dur-moderate) var(--ease-out), transform var(--dur-moderate) var(--ease-lift); }
.gs-row.clickable:hover{ background:var(--accent-wash); transform:translateX(2px); }
.gs-row .gs-row-text h4{ font-size:var(--fs-2); font-weight:600; color:var(--text-primary); margin:var(--sp-0) var(--sp-0) var(--sp-1); }
.gs-row .gs-row-text p{ font-size:var(--fs-1); color:var(--text-tertiary); margin:var(--sp-0); }
.gs-row .gs-row-icon{ flex-shrink:0; width:16px; height:16px; color:var(--text-tertiary); }
.gs-row .gs-row-thumb{ position:relative; overflow:hidden; border-radius:var(--radius-16); width:56px; height:56px; flex-shrink:0; }
.gs-row .gs-row-thumb svg{ position:absolute; inset:0; width:100%; height:100%; }
.gs-row-text{ flex:1; min-width:0; }
.hero-fullbleed{ position:relative; width:calc(100vw - var(--hero-navw) - 16px); margin-left:calc(-1 * (max(0px,(100vw - var(--hero-navw) - 1200px)/2) + var(--hero-gutter)) + 8px); margin-right:0; margin-top:calc(-1 * (var(--hero-gutter-top) - 8px)); border-radius:32px; }

/* ---- Overview landing pages (Components/Patterns/Templates/etc.) — a two-tile
   intro hero + a grid of category cards, each with a small generated brand-color
   blob illustration, styled after the Material Design 3 "Styles overview" page. ---- */
.ov-hero{ display:grid; grid-template-columns:1fr 1fr; gap:var(--sp-6); margin-bottom:var(--sp-8); align-items:stretch; }
.ov-hero-text{ background:var(--bg-sunken); border-radius:var(--radius-32); padding:var(--sp-9); display:flex; flex-direction:column; justify-content:center; overflow-wrap:break-word; min-width:0; }
:root[data-theme="dark"] .ov-hero-text{ background:var(--bg-base); }
.ov-hero-art.mono-brand{ background:var(--bg-sunken); }
:root[data-theme="dark"] .ov-hero-art.mono-brand{ background:var(--bg-base); }
:root[data-theme="dark"] .gs-row{ background:var(--bg-base); }
.ov-hero-text .page-title{ margin:var(--sp-0) var(--sp-0) var(--sp-4); }
.ov-hero-text .page-purpose{ margin:var(--sp-0); }
.ov-hero-art{ position:relative; overflow:hidden; border-radius:var(--radius-32); min-height:220px; }
.ov-hero-art svg{ position:absolute; inset:0; width:100%; height:100%; }
.ov-card-grid{ display:grid; grid-template-columns:1fr 1fr; gap:var(--sp-6); margin-top:var(--sp-6); }
.ov-card{ border-radius:var(--radius-32); overflow:hidden; background:var(--bg-base); border:1px solid var(--border-default); cursor:pointer; transition:transform var(--dur-moderate) var(--ease-lift), box-shadow var(--dur-moderate) var(--ease-out); }
.ov-card:hover{ transform:translateY(-2px); box-shadow:var(--shadow-2); }
.ov-card-art{ position:relative; overflow:hidden; aspect-ratio:16/10; }
.ov-card-art svg{ position:absolute; inset:0; width:100%; height:100%; }
.ov-card-body{ padding:var(--sp-6) var(--sp-6); }
.ov-card-body h3{ font-size:var(--fs-3); font-weight:700; color:var(--text-primary); margin:var(--sp-0) var(--sp-0) var(--sp-2); }
.ov-card-body p{ font-size:var(--fs-1); color:var(--text-secondary); line-height:var(--lh-4); margin:var(--sp-0); }
.gs-hero-nav{ display:grid; grid-template-columns:1fr 1fr; gap:var(--sp-4); }
.gs-hero-nav-item{ display:flex; align-items:center; justify-content:space-between; gap:var(--sp-5); padding:var(--sp-6) var(--sp-7); border-radius:var(--r-panel); background:var(--accent-wash); border:1px solid transparent; cursor:pointer; transition:background var(--dur-moderate) var(--ease-lift), box-shadow var(--dur-moderate) var(--ease-out), transform var(--dur-moderate) var(--ease-lift); text-align:left; }
.gs-hero-nav-item:hover{ transform:translateY(-2px); background:var(--accent-wash-border); box-shadow:var(--shadow-1); }
.gs-hero-nav-text{ min-width:0; }
.gs-hero-nav-icon-wrap{ display:flex; align-items:center; justify-content:center; width:44px; height:44px; border-radius:var(--radius-16); background:var(--bg-base); box-shadow:var(--shadow-surface-rest); flex-shrink:0; }
.gs-hero-nav-icon{ display:block; width:22px; height:22px; color:var(--accent); }
.gs-hero-nav-item h5{ font-size:var(--fs-2); font-weight:700; color:var(--text-primary); margin:var(--sp-0) var(--sp-0) var(--sp-1); }
.gs-hero-nav-item p{ font-size:11.5px; color:var(--text-secondary); margin:var(--sp-0); line-height:var(--lh-3); }
.gs-divider{ display:block; width:60px; height:16px; margin:var(--sp-9) auto; }
.status-chip{ font-size:var(--fs-1); font-weight:600; letter-spacing:var(--ls-6); text-transform:uppercase; padding:var(--sp-2) var(--sp-4); border-radius:var(--r-pill); }
.status-verified{ background:var(--status-verified-bg); color:var(--status-verified-text); }
.status-derived{ background:var(--status-derived-bg); color:var(--status-derived-text); }
.status-proposed{ background:var(--status-proposed-bg); color:var(--status-proposed-text); }
.status-approval{ background:var(--status-approval-bg); color:var(--status-approval-text); }
.status-legacy{ background:var(--status-legacy-bg); color:var(--status-legacy-text); }
/* ---- deprecation lifecycle states — distinct from product/component Status (c-status)
   and from the page-confidence chips above; reuses badge tokens only, no new colors ---- */
.dep-state{ display:inline-flex; align-items:center; gap:var(--sp-3); font-size:var(--fs-1); font-weight:600; letter-spacing:var(--ls-6); text-transform:uppercase; padding:var(--sp-2) var(--sp-4); border-radius:var(--r-pill); flex-shrink:0; }
.dep-state.deprecated{ background:var(--badge-info-bg); color:var(--badge-info-text); }
.dep-state.legacy{ background:var(--badge-neutral-bg); color:var(--badge-neutral-text); }
.dep-state.migration{ background:var(--badge-warning-bg); color:var(--badge-warning-text); }
.dep-state.removal{ background:var(--badge-error-bg); color:var(--badge-error-text); }
.dep-state.removed{ background:var(--status-legacy-bg); color:var(--status-legacy-text); }
/* label-only, not a lifecycle state: marks the "After" side of a Migration specimen */
.dep-state.current{ background:var(--badge-success-bg); color:var(--badge-success-text); }
.page-title{ font-family:var(--font-display); font-size:var(--text-page-title); line-height:var(--lh-1); font-weight:var(--fw-semibold); letter-spacing:var(--ls-2); margin-bottom:var(--sp-5); }
.page-purpose{ font-size:var(--fs-3); color:var(--text-secondary); max-width:640px; line-height:var(--lh-4); margin-bottom:var(--space-page-intro-gap); }
.section-head{ display:flex; align-items:baseline; justify-content:space-between; margin-bottom:var(--sp-6); gap:var(--sp-6); }
.section-title{ font-family:var(--font-display); font-size:var(--fs-6); font-weight:var(--fw-semibold); line-height:var(--lh-1); color:var(--text-primary); }
.section-sub{ font-size:var(--fs-2); color:var(--text-secondary); margin-top:-6px; margin-bottom:var(--sp-6); max-width:620px; }

/* ---- Bulk Actions page — vertical rhythm fix, scoped to this page only ---- */
#page-p-bulk .section-head{ margin-bottom:var(--sp-8); }

/* ---- Import/Export page — vertical rhythm fix, scoped to this page only ---- */
#page-p-importexport .section-head{ margin-bottom:var(--sp-8); }

/* ---- Loading page — vertical rhythm fix, scoped to this page only ---- */
#page-p-loading .section-head{ margin-bottom:var(--sp-8); }

/* ---- Errors page — vertical rhythm fix, scoped to this page only ---- */
#page-p-errors .section-head{ margin-bottom:var(--sp-8); }

/* ---- Permissions page — vertical rhythm fix, scoped to this page only ---- */
#page-p-permissions .section-head{ margin-bottom:var(--sp-8); }

/* ---- AI page — vertical rhythm fix, scoped to this page only ---- */
#page-p-ai .section-head{ margin-bottom:var(--sp-8); }

/* ---- Dashboard template page — vertical rhythm fix, scoped to this page only ---- */
#page-t-dashboard{ max-width:1600px; }
#page-t-dashboard .section-head{ margin-bottom:var(--sp-8); }
#page-t-dashboard .spec-frame{ --spec-grid-line:color-mix(in srgb, var(--border-subtle-line) 40%, transparent); background:var(--bg-canvas); }
#page-t-list .spec-frame{ --spec-grid-line:color-mix(in srgb, var(--border-subtle-line) 40%, transparent); background:var(--bg-canvas); }
#page-t-dashboard .dt-table thead th{ background:var(--bg-sunken); border-bottom:1px solid var(--border-strong); }
#page-t-dashboard .dash-ship-table td, #page-t-dashboard .dash-ship-table th{ padding:var(--sp-4) var(--sp-6); }
#page-t-dashboard .dash-ship-table thead th{ font-size:var(--fs-1); }
#page-t-dashboard .dash-attn-row{ transition:background var(--dur-default) var(--ease-out); }
#page-t-dashboard .dash-attn-row:hover{ background:var(--bg-canvas); }
#page-t-dashboard .dash-updates-box{ border:1px solid var(--border-default); border-radius:var(--r-card); padding:2px var(--sp-6); }
#page-t-dashboard .dash-updates-timeline .tl-content{ padding-bottom:var(--sp-5); gap:1px; }
#page-t-dashboard .dash-updates-timeline .tl-item:last-child .tl-content{ padding-bottom:var(--sp-0); }
#page-t-dashboard .dash-updates-timeline .tl-content .t{ font-size:var(--fs-1); font-weight:500; }
#page-t-dashboard .dash-updates-timeline .tl-content .ts{ font-size:10.5px; }
#page-t-dashboard .dash-updates-timeline .tl-content .m{ font-size:10.5px; color:var(--text-disabled); }
#page-t-dashboard .dash-updates-timeline .tl-dot{ width:7px; height:7px; margin-top:var(--sp-2); }
#page-t-dashboard .dash-updates-timeline .tl-line{ min-height:10px; }
/* The KPI strip's own base. It existed only as a narrow-viewport override scoped to
   #page-t-dashboard, so at desktop width the class carried nothing and every specimen
   re-declared these three lines inline. */
.dash-kpi-strip{ display:flex; border-bottom:1px solid var(--border-default); margin-bottom:var(--sp-6); }
@media (max-width:639px){
  #page-t-dashboard .dash-split{ grid-template-columns:minmax(0,1fr)!important; }
  #page-t-dashboard .dash-kpi-strip{ display:grid!important; grid-template-columns:minmax(0,1fr) minmax(0,1fr); }
  #page-t-dashboard .dash-kpi-strip > div{ min-width:0; }
  #page-t-dashboard .dash-kpi-strip > div > div{ flex-wrap:wrap; min-width:0; }
  #page-t-dashboard .dash-kpi-strip > div{ border-right:1px solid var(--divider); border-bottom:none; }
  #page-t-dashboard .dash-kpi-strip > div:nth-child(2n){ border-right:none; }
  #page-t-dashboard .dash-kpi-strip > div:nth-child(-n+2){ border-bottom:1px solid var(--divider); }
  #page-t-dashboard .dash-surface{ padding:var(--sp-8) 18px!important; }
  #page-t-dashboard .dash-attn-row{ flex-direction:column; align-items:flex-start!important; gap:var(--sp-3)!important; }
  #page-t-dashboard .zone-row{ flex-direction:column; }
}

/* ---- App Shell template page — live specimen frame, composed from existing
   primitives (.brand, .nd-item/.nd-group-label, .dt-wrap/.dt-table, .mini-avatar,
   .searchbox) rather than a one-off illustration. Only existing tokens are
   referenced below — no new color/spacing/radius values. ---- */
#page-t-appshell{ max-width:1600px; }
#page-t-appshell .section-head{ margin-bottom:var(--sp-7); }
#page-t-appshell .dt-table thead th{ background:var(--bg-sunken); border-bottom:1px solid var(--border-strong); }
#page-t-appshell .dash-ship-table td, #page-t-appshell .dash-ship-table th{ padding:var(--sp-4) var(--sp-6); }
#page-t-appshell .dash-ship-table thead th{ font-size:var(--fs-1); }
#page-t-appshell .dash-attn-row{ transition:background var(--dur-default) var(--ease-out); }
#page-t-appshell .dash-attn-row:hover{ background:var(--bg-canvas); }
#page-t-appshell .dash-updates-box{ border:1px solid var(--border-default); border-radius:var(--r-card); padding:2px var(--sp-6); }
#page-t-appshell .dash-updates-timeline .tl-content{ padding-bottom:var(--sp-5); gap:1px; }
#page-t-appshell .dash-updates-timeline .tl-item:last-child .tl-content{ padding-bottom:var(--sp-0); }

#page-t-appshell .dash-updates-timeline .tl-content .ts{ font-size:10.5px; }
#page-t-appshell .dash-updates-timeline .tl-content .m{ font-size:10.5px; color:var(--text-disabled); }
#page-t-appshell .dash-updates-timeline .tl-dot{ width:7px; height:7px; margin-top:var(--sp-2); }
#page-t-appshell .dash-updates-timeline .tl-line{ min-height:10px; }
/* ---- The App Shell specimen is a miniature VIEWPORT onto the real app, not
   a responsive redesign of it: top bar + sidebar + content are all left at
   real production sizing (same sidebar width, same nav item scale, same
   Dashboard reference width as the standalone page), then the ENTIRE
   composition is scaled down together with one zoom factor — so every
   proportion (sidebar-to-content ratio, KPI layout, table columns,
   typography hierarchy) matches the real product exactly, just smaller. ---- */
#page-t-appshell .ash-app-scale{ width:1337px; zoom:0.822; }
/* ---- The Live specimen is a fixed desktop composition at every viewport —
   it must never pick up the real site's own narrow-viewport adaptations
   (sidebar collapsing to 170px, search hiding). Higher specificity than the
   unscoped @media rules below beats them regardless of viewport width, so
   no !important is needed. The zoom value above is a static fallback; JS
   (fitAppShellSpecimen) overrides it live to exactly fill the frame at
   every size — see the script block. ---- */
#page-t-appshell .ash-frame:not(.ash-mini) .ash-side{ width:220px; }
#page-t-appshell .ash-frame:not(.ash-mini) .searchbox{ display:flex; }
.ash-frame{ border:1px solid var(--border-default); border-radius:var(--r-panel); overflow:hidden; background:var(--bg-base); width:100%; }
.ash-topbar{ display:flex; align-items:center; gap:var(--sp-6); padding:var(--sp-4) var(--sp-7); border-bottom:1px solid var(--border-subtle-line); background:var(--bg-base); }
.ash-topbar .brand{ display:flex; align-items:center; flex-shrink:0; }
.ash-topbar .brand svg{ height:22px; width:auto; display:block; }
.ash-crumb{ font-size:var(--fs-1); color:var(--text-tertiary); white-space:nowrap; }
.ash-crumb b{ color:var(--text-primary); font-weight:500; }
.ash-spacer{ flex:1; }
.ash-body{ display:flex; }
.ash-side{ width:220px; flex-shrink:0; border-right:1px solid var(--border-subtle-line); padding:var(--sp-4); background:var(--bg-base); overflow:hidden; }
.ash-content{ flex:1; min-width:0; padding:var(--sp-6) var(--sp-7); background:var(--bg-canvas); }
.ash-panel{ width:220px; flex-shrink:0; border-left:1px solid var(--border-subtle-line); padding:var(--sp-5) var(--sp-6); background:var(--bg-base); }
.ash-panel-row{ display:flex; flex-direction:column; gap:var(--sp-1); padding:var(--sp-3) 0; border-bottom:1px solid var(--divider); }
.ash-panel-row:last-child{ border-bottom:none; }
.ash-frame.ash-mini .ash-body{ min-height:0; }
.ash-frame.ash-mini .ash-topbar{ padding:var(--sp-3) var(--sp-5); gap:var(--sp-4); }
.ash-frame.ash-mini .ash-side{ width:120px; padding:var(--sp-4) var(--sp-3) var(--sp-4) var(--sp-7); }
.ash-frame.ash-mini .ash-content{ padding:var(--sp-5) var(--sp-6); }
.ash-frame.ash-mini .ash-panel{ width:150px; padding:var(--sp-4) var(--sp-5); }
.ash-frame.ash-mini .nd-item{ padding:var(--sp-3) var(--sp-4); font-size:var(--fs-1); }
.ash-frame.ash-mini .nd-item.active::before{ left:-10px; }

/* ---- Aura glass tier for the shell — opt-in via .ash-frame.ash-glass ----
   The bloom sits INSIDE the frame and every surface stacked on it is translucent,
   so this is the sanctioned "wash behind glass" case, not the retired
   --ambient-wash page tint (page-level surfaces stay neutral per Foundations -> Color).
   Structure, widths, paddings and border geometry are inherited unchanged — this
   modifier only repoints surfaces onto the existing --glass-* tokens. ---- */
/* v1.33: no decorative backdrop. The glass frame sits on the canonical canvas — the aura washes
   that used to sit behind it are removed with the no-decorative-gradient rule. */
.ash-frame.ash-glass{ background:var(--bg-canvas);
  border-color:var(--glass-card-border); box-shadow:var(--shadow-4); }
.ash-frame.ash-glass .ash-topbar{ background:transparent; border-bottom-color:var(--glass-card-border); }
/* Sidebar-first composition: the menu owns the full height of the frame and the top bar
   rides above the content column only, rather than spanning edge to edge. .ash-main is the
   column those two share. Scoped to the glass tier — the Admin shell below keeps the
   full-width top bar the Anatomy section documents. */
.ash-main{ flex:1; min-width:0; display:flex; flex-direction:column; }
/* ---- Navigation layout variant. The same three groups, presented either down the side
   (default) or across the top with a menu each. Nothing is duplicated: the top bar is
   built from the sidebar's own groups at switch time, so the sidebar stays the source. ---- */
.ash-navbar{ display:none; align-items:center; gap:var(--sp-7); flex-wrap:wrap; }
.ash-frame.ash-nav-top .ash-navbar{ display:flex; }
/* Horizontal: the menu becomes the same three-part bar the App Shell pill is — brand, the
   nav, then account and theme at the far end. Only the vertical stack of groups goes; the
   identity row and the account row keep their jobs, they just sit in a row now. */
/* The horizontal variant of a BARE menu (no shell frame around it). Currently unreachable:
   after the Side Navigation specimen became a real .ash-frame, the only .navlist-demo left are
   .compact and .rail, and neither carries the handle-bottom that is the gesture into this
   layout. Kept because it is a real documented variant and the JS still supports it, not
   because anything exercises it — so treat it as unverified until a specimen does.
   flex-direction is stated rather than inherited: it relied on the default `row` until
   .nav-col (the three-part column the height contract needs) began setting `column` on the
   same element, which stacked brand, menus and account on three lines. .ash-nav-top is
   (0,2,0) against .nav-col's (0,1,0), so it wins wherever the two meet. */
.navlist-demo.ash-nav-top{ display:flex; flex-direction:row; align-items:center; gap:var(--sp-6); width:100%; border-radius:var(--r-pill); }  /* pill, matching the shape App Shell's own nav-top bar takes (.ash-frame.ash-nav-top .ash-topbar) — the card radius belongs to the vertical menu, a horizontal bar of this height reads as a pill. Measured height was already 60px, the same as that bar. */
/* The right edge governs sidebar WIDTH, and in the top layout there is no sidebar to widen —
   App Shell sidesteps this by hiding .ash-side outright, which a bare menu cannot do since it
   IS the bar. So the width grip goes instead. Without this the handle stays draggable, writes
   style.width back onto a full-width row, and re-pins it (the 380px this specimen was stuck
   at). The bottom grip stays: that is the gesture back to the side. */
.navlist-demo.ash-nav-top .menu-handle:not(.handle-bottom){ display:none; }
/* DOM order is brand, groups, account, navbar — the row wants brand, navbar, account,
   so flex order arranges it instead of moving the markup for one of two layouts. */
.navlist-demo.ash-nav-top .nav-brand{ order:1; }
.navlist-demo.ash-nav-top .ash-navbar{ order:2; }
.navlist-demo.ash-nav-top .nav-account{ order:3; }
.navlist-demo.ash-nav-top .ash-navbar{ display:flex; flex-wrap:wrap; }
.navlist-demo.ash-nav-top .nav-group,
.navlist-demo.ash-nav-top .nav-scroll{ display:none; }  /* the groups now sit inside .nav-scroll, so the old child combinator stopped matching — the same correction the nine bento rules took in v1.24. The scroller goes with them: an empty flex:1 box would otherwise hold the row open. */
.navlist-demo.ash-nav-top .nav-brand{ padding:var(--sp-0); flex-shrink:0; }
.navlist-demo.ash-nav-top .nav-account{ margin:var(--sp-0) var(--sp-0) var(--sp-0) auto; padding:var(--sp-0); flex-shrink:0; }
.ash-frame.ash-nav-top .ash-side,
.ash-frame.ash-glass.ash-nav-top .ash-side{ display:none; }  /* the glass tier sets display:flex further down the file at equal specificity, so the
   variant has to carry both classes to win on weight rather than on source order */

.ash-navbar .lp-navdrop-panel{ min-width:240px; padding:var(--sp-4); text-align:left; }
.ash-navbar .lp-navdrop-panel .nav-item{ white-space:nowrap; }
.ash-navbar .lp-navdrop-panel .nav-item.active::before{ display:none; }

/* Centred greeting above the content. --text-page-title is the system's largest documented
   heading step and already resolves to Ranade, the display face — which is what a greeting
   is: a display moment, not product chrome. Everything below it stays Switzer. */
.ash-greet{ text-align:center; padding:var(--sp-8) var(--sp-6) var(--sp-9); }
.ash-greet .ash-greet-kicker{ font-size:var(--fs-2); color:var(--text-secondary); margin-bottom:var(--sp-4); }
.ash-greet .page-title{ margin-bottom:var(--sp-0); max-width:18ch; margin-inline:auto; }
.ash-main .ash-content{ flex:1; }

/* The menu becomes a floating glass panel, exactly the material Side Navigation's
   .navlist-demo carries on its own wash: same fill, same blur + saturate, same border
   and overlay shadow. It stops being a flush region with a divider, so the divider
   border is replaced by a full edge and the panel is inset from the frame. */
.ash-frame.ash-glass .ash-side{
  background:var(--glass-card-bg);
  backdrop-filter:blur(var(--glass-blur)) saturate(1.4);
  -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(1.4);
  border:1px solid var(--glass-card-border);
  border-radius:var(--r-card);
  margin:var(--sp-5);
  display:flex; flex-direction:column; }
.ash-frame.ash-glass .ash-content{ background:transparent;
  /* The gap to the menu was the menu's 12px margin PLUS the content's 20px inset = 32px,
     against 12px between the cards themselves. Zero the left inset so the single margin
     is the whole gap, and match the other three sides to it. */
  padding:var(--sp-5) var(--sp-5) var(--sp-5) var(--sp-0); }
/* With no sidebar there is nothing to the left for the menu's margin to supply, so the
   content re-takes its own left inset and the frame is even on both sides again. */
.ash-frame.ash-nav-top .ash-content,
.ash-frame.ash-glass.ash-nav-top .ash-content{ padding-left:var(--sp-5); }
/* In the top layout the header stops being a flat band with a hairline and becomes the
   landing page's floating Glass pill — .lp-topnav's exact material, so the two surfaces
   in the system that carry horizontal navigation are the same object. */
.ash-frame.ash-nav-top .ash-topbar,
.ash-frame.ash-glass.ash-nav-top .ash-topbar{
  height:60px; box-sizing:border-box;
  /* auto side margins would switch off the cross-axis stretch and shrink the pill to its
     content; explicit margins keep it spanning .ash-main, flush with the cards below. */
  margin:var(--sp-5) var(--sp-5) var(--sp-0);
  padding:var(--sp-0) var(--sp-6);
  gap:var(--sp-6); justify-content:space-between;
  border:1px solid var(--glass-card-border);
  border-radius:var(--r-pill);
  background:var(--glass-card-bg);
  backdrop-filter:blur(var(--glass-blur)) saturate(1.4);
  -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(1.4); }
/* backdrop-filter on the pill makes it its own stacking context, so the dropdown's z-index:40
   only ranks it INSIDE the pill. The content cards below blur too and come later in the DOM,
   so they were painting over the open menu. Rank the pill itself above the content. */
.ash-frame.ash-nav-top .ash-topbar,
.ash-frame.ash-glass.ash-nav-top .ash-topbar{ position:relative; z-index:30; }
/* Sidebar-first, side layout: this top bar carries nothing. Identity, theme and account all
   live in the menu — that is the whole point of the composition — so every one of its content
   children is display:none here and the only thing left inside is the grip you drag UP to move
   the navigation into the top bar. Where you are is named by each view's own eyebrow instead,
   down in the content area beside the title it belongs to — the same pairing the Admin shell
   already uses ("Operations" over "Dashboard"). So the band is deliberately empty, and carries
   no divider either: the glass sidebar floats as its own panel,
   nothing is flush against anything, and the hairline read as a stray white line across the
   top of the content column. The 16px lane stays — it is the drag target's home.
   Weight: (0,4,0) with .ash-nav-top inside :not(), so it outranks the glass tier's
   border-bottom-color at (0,3,0) and cannot touch the nav-top pill, which needs its full
   border. The Admin shell below keeps its hairline — its regions really are flush. */
.ash-frame.ash-glass:not(.ash-nav-top) .ash-topbar{ border-bottom:none; }

/* ---- Destination views. The content area renders exactly one at a time and the sidebar
   chooses which — this is the shell's own navigation, the thing the frame is FOR.
   Named .ash-view and deliberately not .ash-pane: .ash-panel is already the contextual right
   panel, and two names that close would read as the same region.
   Reuses the page-in keyframe this document's own pages use, not a second one that means the
   same thing. ---- */
.ash-view{ display:none; }
.ash-view.active{ display:block; animation:page-in 220ms var(--ease-lift); }
@media (prefers-reduced-motion: reduce){ .ash-view.active{ animation:none; } }
/* A view's own header, and with the top bar empty the only thing naming where you are: a
   .type-eyebrow carrying the group, then the destination as the title. Page-level content,
   which Region hierarchy puts in the content area rather than in the chrome. */
.ash-view-head{ padding:var(--sp-7) var(--sp-2) var(--sp-6); }
.ash-view-title{ font-size:var(--text-heading-m); font-weight:var(--fw-semibold); color:var(--text-primary); margin-bottom:var(--sp-2); }
.ash-view-desc{ font-size:var(--fs-2); color:var(--text-secondary); max-width:62ch; }
/* identity, theme and account belong to whichever surface is carrying the navigation */
.ash-frame:not(.ash-nav-top) .ash-top-only{ display:none !important; }  /* .lp-topnav-actions has no base display of its own, but the landing's mobile rules force one */
.ash-topbar .lp-topnav-actions{ display:flex; align-items:center; gap:var(--sp-4); }
.ash-topbar .ash-top-only.brand svg{ height:22px; width:auto; display:block; }
.ash-frame.ash-nav-top .ash-topbar .ash-top-only.brand{ display:flex; align-items:center; }
.ash-frame.ash-glass .ash-panel{ background:transparent; border-left-color:var(--glass-card-border); }

/* ======================= SIDEBAR HEIGHT, INSETS & SCROLL =======================
   The rule: a sidebar is chrome, so it is measured against the VIEWPORT, never against
   the page. It stays put while the content scrolls, keeps its identity row and its
   account row permanently visible, and scrolls only its own list of destinations. A menu
   that grows with the page is the bug this section closes — the account row ends up below
   the fold, and on a short screen the bottom of the menu is eaten by the edge of the
   display, which is not a padding problem and cannot be fixed with one.

   Three additive classes carry it, and none of them invents a value:

     .nav-scroll  wraps the groups — the ONE region inside a menu allowed to scroll. It is
                  unconditional: flex:1 and min-height:0 are inert in a parent that is not
                  a bounded flex column, and overflow-y:auto never scrolls a box with no
                  height limit. So it is safe on every menu in the system, and only comes
                  alive where a height is actually being enforced.
     .nav-col     makes a menu the three-part column that contract needs — identity pinned
                  at the top, .nav-scroll taking the slack, account pinned at the bottom.
                  Use it wherever a menu already has a definite height of its own.
     .nav-sticky  .nav-col plus the height and the stick: --shell-side-h, held
                  --shell-side-inset from the top. Sticky, not fixed — a sticky menu keeps
                  its column in the layout, so the content beside it needs no compensating
                  margin and nothing can slide underneath it.

   On a shell, .ash-viewport on the FRAME does all of it at once: the frame becomes the
   viewport, the sidebar takes its full height automatically (cross-axis stretch already
   sizes a flex item to the row minus its own margins), and the content column gets the
   scroll the shell has just taken away from the document. ---- */
.nav-scroll{ flex:1 1 auto; min-height:0; overflow-y:auto; overscroll-behavior:contain; scrollbar-gutter:stable; }
/* The bar itself is the system's existing .scroll-region recipe — .nav-scroll is added to
   those selectors rather than given a second 5px overlay scrollbar of its own. The stable
   gutter is reserved even when the list fits, so expanding a group cannot nudge every
   label sideways by the width of a scrollbar that just appeared. */
.nav-col, .nav-sticky{ display:flex; flex-direction:column; min-height:0; }
.nav-sticky{ position:sticky; top:var(--shell-side-inset); align-self:flex-start; height:var(--shell-side-h); }
/* The pinned rows are the reason the middle can scroll: neither may be allowed to shrink,
   or a long nav list would squeeze the account row instead of scrolling underneath it. */
.nav-col > .nav-brand, .nav-col > .nav-account,
.nav-sticky > .nav-brand, .nav-sticky > .nav-account,
.ash-frame.ash-viewport .ash-side > .nav-brand,
.ash-frame.ash-viewport .ash-side > .nav-account{ flex-shrink:0; }

/* The shell in its production geometry. Every link in the flex chain needs min-height:0 —
   one missing and the tallest child wins the sizing argument, the shell grows past the
   viewport, and the scroll is handed straight back to the document. */
.ash-frame.ash-viewport{ height:var(--shell-vh); max-height:var(--shell-vh); overflow:hidden; }
.ash-frame.ash-viewport .ash-body{ height:100%; min-height:0; }
.ash-frame.ash-viewport .ash-main{ min-height:0; }
.ash-frame.ash-viewport .ash-content{ overflow-y:auto; min-height:0; }
.ash-frame.ash-viewport .ash-side{ display:flex; flex-direction:column; min-height:0; overflow:hidden; }
/* Inset and padding. The floating (glass) menu already keeps --sp-5 of margin from the
   frame; in the full-height geometry that margin IS --shell-side-inset, so the two are the
   same number by definition rather than by coincidence. The panel's own padding rises to
   match, so a nav pill never sits 8px inside a rounded 12px-inset edge — that gap is what
   reads as tight, not the height. */
.ash-frame.ash-viewport .ash-side{ padding:var(--shell-side-inset); }
.ash-frame.ash-glass.ash-viewport .ash-side{ margin:var(--shell-side-inset); }
/* A bottom pad on the scroller, so the last destination clears the account row instead of
   stopping flush against it. */
.ash-frame.ash-viewport .ash-side .nav-scroll{ padding-bottom:var(--sp-3); }

/* ---- Documentation specimens. A shell in full production geometry IS the viewport, which
   a specimen halfway down a documentation page cannot be — so the two specimens below are
   pinned to a demo height and inherit every other rule above unchanged. That is the whole
   point of measuring against a token: only the number differs. ---- */
#page-t-appshell #appshell-live.ash-viewport{ height:min(680px, 78vh); max-height:none; }
#page-t-appshell .ash-frame.ash-viewport .ash-app-scale{ height:100%; min-height:0; }
/* Side Navigation's own specimen, so the three-part column is visible there too: eighteen
   destinations do not fit in 420px, which is exactly the case the scroller exists for. */
/* Navigation's Side Navigation specimen IS the App Shell sidebar now — same markup, same
   frame, same behaviour — so it takes a demo height the same way the App Shell one does
   rather than having a bespoke one of its own. 480px shows the scroll: three open groups are
   ~839px of list. No .ash-app-scale here, so .ash-body gets the height straight from the frame. */
#page-c-navigation #navlist-shell.ash-viewport{ height:480px; max-height:none; }
/* The shell's content sheet. These exact values are written inline on seven template
   specimens; named here so a variant can retheme it instead of fighting an inline style. */
.ash-sheet{ width:100%; background:var(--bg-base); border:1px solid var(--border-subtle-line); border-radius:var(--r-card); box-shadow:var(--shadow-surface-rest), var(--surface-sheen); padding:var(--sp-7) var(--sp-8); }
.ash-frame.ash-glass .ash-sheet,
.ash-frame.ash-glass .card,
.ash-frame.ash-glass .searchbox{ background:var(--glass-card-bg); border-color:var(--glass-card-border); backdrop-filter:blur(var(--glass-blur)); -webkit-backdrop-filter:blur(var(--glass-blur)); }
.ash-frame.ash-glass .ash-sheet{ box-shadow:none; }  /* flat: the border carries the edge, not a drop shadow */
/* A block that already drew its own bordered box now sits inside a card that draws one.
   The card keeps the edge; the inner box gives its up. */
#page-t-appshell .ash-sheet .dash-updates-box{ border:none; border-radius:var(--sp-0); padding:var(--sp-0); }  /* the box is set by #page-t-appshell .dash-updates-box (0,1,1) — a classes-only reset loses to it, so this one carries the same id rather than reaching for !important */
/* Bento composition for a shell's content area: one four-track grid, cards claim
   width by span rather than by nesting another row container. Named the way this file
   already names its grids (.two-col, .three-col), and it carries no surface of its own
   — the cards are .ash-sheet exactly as before. */
.ash-bento{ display:grid; grid-template-columns:repeat(4, minmax(0,1fr)); gap:var(--sp-5); align-items:stretch; }  /* stretch, not start: cards in a row match height even when one carries an extra line */
.ash-bento .bento-2{ grid-column:span 2; }
.ash-bento .bento-3{ grid-column:span 3; }
.ash-bento .bento-tall{ grid-row:span 2; }
@media (max-width:900px){
  .ash-bento{ grid-template-columns:repeat(2, minmax(0,1fr)); }
  .ash-bento .bento-3, .ash-bento .bento-2{ grid-column:span 2; }
  .ash-bento .bento-tall{ grid-row:auto; }
}
/* A card's head: title (plus any badge) left, the card's single action right.
   .section-head already states this at page scale; this is the same idea at card scale. */
.ash-sheet .sheet-head{ display:flex; align-items:center; justify-content:space-between; gap:var(--sp-4); margin-bottom:var(--sp-5); }
.ash-sheet .sheet-head .sheet-head-title{ display:flex; align-items:center; gap:var(--sp-4); min-width:0; }
/* A card's title. Foundations has a page title (.type-display-product, --fs-6) and a
   micro-label (.type-section-heading, --fs-1 caps) with nothing between them, and a card
   head needs that missing step: sentence case, one size down, same weight. Composed from
   existing tokens rather than added as a new Foundations role — Foundations is locked. */
/* The account sits at the foot of the menu, the way the production shell has it —
   not in the top bar. margin-top:auto is what pins it there however tall the menu is. */
.nav-account{ margin-top:auto; display:flex; align-items:center; gap:var(--sp-4); padding:var(--sp-5) var(--space-label-gap); }
/* The menu's foot carries the same pair the top pill does: account, then the theme control
   pushed to the far edge. Collapsed to the 64px rail only the avatar survives — the rail
   has room for one round control, and identity outranks a preference. */
.nav-account .nav-account-who{ display:flex; flex-direction:column; min-width:0; }
.nav-account .nav-account-name{ font-size:var(--fs-1); font-weight:var(--fw-medium); color:var(--text-primary); line-height:var(--lh-2); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.nav-account .nav-account-role{ font-size:var(--fs-1); color:var(--text-tertiary); line-height:var(--lh-2); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
/* it goes with the labels: a 64px rail has room for the avatar and nothing beside it */
.navlist-demo.collapsed .nav-account-who,
.ash-frame.side-collapsed .ash-side .nav-account-who{ display:none; }
.nav-account .theme-toggle{ margin-left:auto; flex-shrink:0; }
.navlist-demo.collapsed .nav-account .theme-toggle,
.ash-frame.side-collapsed .ash-side .nav-account .theme-toggle{ display:none; }
.navlist-demo.collapsed .nav-account, .ash-frame.side-collapsed .ash-side .nav-account{ justify-content:center; padding-left:var(--sp-0); padding-right:var(--sp-0); }
.ash-sheet .sheet-title{ font-family:var(--font-sans); font-size:var(--fs-4); font-weight:var(--fw-regular); letter-spacing:var(--ls-2); line-height:var(--lh-2); color:var(--text-primary); }
/* A figure and the delta that qualifies it sit on one baseline, not on two lines. */
.stat-block .stat-figure{ display:flex; align-items:baseline; gap:var(--sp-4); }
/* On a KPI card the figure is the card's subject, so it outsizes the title that names it.
   --fs-6 is the page-title step and reads level with an --fs-4 card title; one step up
   restores the hierarchy the references show. The role itself is untouched — it has 52
   other uses in this document. */
.ash-bento .stat-figure .type-numeric-hero{ font-size:var(--fs-8); letter-spacing:var(--ls-1); }
/* Inside a card the table carries no surface of its own — the card is the surface. Both
   the wrapper's white box and the head's sunken fill would otherwise read as a second
   card stacked on the first. Scoped to .ash-sheet so the DataTable component keeps its
   own framing everywhere else. */
.ash-sheet .dt-wrap{ background:transparent; border:none; border-radius:var(--sp-0); }
/* A whisper of the accent under the head band, not the opaque --bg-sunken grey that
   was there before. --accent-wash is the system's own light-accent surface but it is
   opaque in light and translucent in dark, so it would behave differently per theme;
   mixing --accent down keeps one declaration honest in both and lets the glass through. */
#page-t-appshell .ash-sheet .dt-table thead th{ background:color-mix(in srgb, var(--accent) 6%, transparent); }
/* Every hoverable row inside a card shares one highlight. --bg-canvas was opaque white and
   punched through the glass; a translucent tint sits on it instead. Both selectors carry the
   page id because the rules they override do — a classes-only reset loses to them. */
.ash-sheet .dt-table tbody tr:hover td,
#page-t-appshell .ash-sheet .dash-attn-row:hover{ background:color-mix(in srgb, var(--text-primary) 4%, transparent); }
/* A KPI reads as its own card here, so the figure sets the card's rhythm. */
.ash-bento .ash-sheet .stat-block{ padding:var(--sp-0); }

@media (max-width:900px){
  .ash-panel{ display:none; }
  .ash-side{ width:170px; }
}

.principles{ display:grid; grid-template-columns:repeat(2,1fr); gap:var(--sp-5); }
.principle-card{ padding:var(--sp-7) var(--sp-7); border:none; border-radius:var(--radius-32); background:var(--glass-card-bg); backdrop-filter:blur(var(--glass-blur));
  box-shadow:var(--shadow-4);
  transition:border-color var(--dur-default) var(--ease-lift), box-shadow var(--dur-default) var(--ease-lift), transform var(--dur-default) var(--ease-lift); }
.principle-card:hover{ border-color:var(--border-strong); box-shadow:var(--shadow-2); transform:translateY(-2px); }
.principle-card h4{ font-size:var(--fs-2); margin-bottom:var(--sp-3); }
.principle-card p{ font-size:var(--fs-1); color:var(--text-secondary); line-height:var(--lh-3); }

.card{ border:1px solid var(--border-subtle-line); border-radius:var(--r-card); background:var(--bg-base); padding:var(--sp-8);
  transition:border-color var(--dur-default) var(--ease-lift), box-shadow var(--dur-default) var(--ease-lift); }
/* Vertical card lists opt in with .card-stack on the container. Card itself ships
   no stacking margin: grid and flex rows space siblings with `gap`, and a default
   margin-top leaked into every one of them — the first card sat flush while each
   sibling after it dropped 12px, drifting the row's tops out of alignment. */
.card-stack > .card + .card{ margin-top:var(--space-card-stack); }
/* Glass frame — a glass band (--glass-card-bg, solid --glass-card-border) around an opaque backing layer. v1.33: the gradient border-box stroke is removed.
   Documented in full on Foundations → Elevation → "Glass frame — gradient accent border". Default sizing matches --r-card content
   cards (8px ring, inner radius = r-card); size to a specific specimen (e.g. a pill search bar) via inline padding/border-radius. */
.glass-frame{ padding:8px; border:1px solid var(--glass-card-border); border-radius:calc(var(--r-card) + 8px); background:var(--glass-card-bg); backdrop-filter:blur(var(--glass-blur-lg)) saturate(1.4); -webkit-backdrop-filter:blur(var(--glass-blur-lg)) saturate(1.4); box-shadow:var(--shadow-4); }
.glass-frame-inner{ background:var(--bg-base); border-radius:var(--r-card); padding:var(--sp-8); }
.card.compact{ padding:var(--space-surface-inset-sm); }
.card.spacious{ padding:var(--sp-9); }
.card.clickable{ cursor:pointer; border-color:var(--border-default); }
.card.clickable:hover{ transform:translateY(-1px); border-color:var(--border-strong); box-shadow:var(--shadow-2); }
.card.selected{ border-color:var(--accent); background:var(--accent-wash); }
.card.disabled{ background:var(--bg-sunken); opacity:.55; pointer-events:none; }

/* ---- panel: same surface language as Card, one radius step up (--r-panel)
   for a larger structural region rather than a repeated grid unit ---- */
.panel{ border:1px solid var(--border-subtle-line); border-radius:var(--r-panel); background:var(--bg-base);
  box-shadow:var(--shadow-surface-rest), var(--surface-sheen); padding:var(--sp-9); }

/* ---- section container: grouping WITHOUT a card — spacing/tone/border only,
   one signal per boundary, never a shadow stacked on top ---- */
.section-tonal{ background:var(--bg-sunken); border-radius:var(--r-card); padding:var(--sp-6) var(--sp-7); }
.section-bordered{ border:1px solid var(--border-default); border-radius:var(--r-card); padding:var(--sp-6) var(--sp-7); }

/* ---- group / stack container ---- */
.stack-v{ display:flex; flex-direction:column; gap:var(--sp-5); }
.stack-h{ display:flex; flex-direction:row; gap:var(--sp-5); flex-wrap:wrap; }
.group-shared{ border:1px solid var(--border-default); border-radius:var(--r-card); overflow:hidden; background:var(--bg-base); }
.group-shared > *{ padding:var(--sp-5) var(--sp-6); border-bottom:1px solid var(--divider); }
.group-shared > *:last-child{ border-bottom:none; }
.group-shared.horizontal{ display:flex; }
.group-shared.horizontal > *{ border-bottom:none; border-right:1px solid var(--divider); flex:1; }
.group-shared.horizontal > *:last-child{ border-right:none; }
/* stacked content item — a grouped object, not a form control */
.stack-row{ display:flex; align-items:center; gap:var(--sp-4); padding:var(--sp-4) var(--sp-1); font-size:var(--fs-1); color:var(--text-primary); border-bottom:1px solid var(--divider); }
.stack-row:last-child{ border-bottom:none; }
.stack-row::before{ content:''; width:4px; height:4px; border-radius:50%; background:var(--text-disabled); flex-shrink:0; }
/* small role tag beside a specimen sub-label, ties back to the surface-hierarchy rule */
.spec-role{ font-size:10px; font-weight:500; color:var(--text-disabled); text-transform:none; letter-spacing:var(--ls-4); margin-left:var(--sp-3); }

/* ---- well / sunken container: recessed, for embedded regions that should
   read as "inside" the surface above them, not another card floating on it ---- */
.well{ background:var(--bg-sunken); border:1px solid var(--border-default); border-radius:var(--r-card); padding:var(--space-surface-inset) var(--sp-6); }

/* ---- split container: master/detail shell ---- */
.split-2{ display:grid; grid-template-columns:220px 1fr; border:1px solid var(--border-default); border-radius:var(--r-card); overflow:hidden; background:var(--bg-base); }
.split-2 > .pane-a{ border-right:1px solid var(--divider); background:var(--bg-canvas); padding:var(--space-surface-inset) var(--sp-6); }
.split-2 > .pane-b{ padding:var(--space-surface-inset) var(--sp-6); }

/* ---- scroll container: the identical overlay-scrollbar recipe already
   approved for Tables' .dt-scroll, applied to vertical content ---- */
.scroll-region, .nav-scroll{ overflow-y:auto; scrollbar-width:thin; scrollbar-color:color-mix(in srgb, var(--text-tertiary) 22%, transparent) transparent; }
.scroll-region:hover, .nav-scroll:hover{ scrollbar-color:color-mix(in srgb, var(--text-tertiary) 42%, transparent) transparent; }
.scroll-region::-webkit-scrollbar, .nav-scroll::-webkit-scrollbar{ width:5px; }
.scroll-region::-webkit-scrollbar-track, .nav-scroll::-webkit-scrollbar-track{ background:transparent; }
.scroll-region::-webkit-scrollbar-thumb, .nav-scroll::-webkit-scrollbar-thumb{ background-color:color-mix(in srgb, var(--text-tertiary) 22%, transparent); border-radius:var(--r-pill); border:1px solid transparent; background-clip:padding-box; transition:background-color var(--dur-moderate) var(--ease-out); }
.scroll-region:hover::-webkit-scrollbar-thumb, .scroll-region::-webkit-scrollbar-thumb:hover,
.nav-scroll:hover::-webkit-scrollbar-thumb, .nav-scroll::-webkit-scrollbar-thumb:hover{ background-color:color-mix(in srgb, var(--text-tertiary) 42%, transparent); }

/* =========================================================
   UTILITIES — small, reusable helpers only. Every rule below
   consumes an existing Foundations token; none define a new
   color, radius, or type value of their own.
========================================================= */

/* documentation-only placeholder box for neutral, content-agnostic layout demos — not itself a utility */
.demo-box{ height:30px; padding:var(--sp-0) var(--space-control-inset-sm); border:1px dashed var(--border-default); border-radius:var(--radius-6); background:var(--bg-base); display:flex; align-items:center; justify-content:center; font-size:var(--fs-1); color:var(--text-tertiary); flex-shrink:0; }

/* layout */
.u-stack{ display:flex; flex-direction:column; }
.u-inline{ display:flex; flex-direction:row; align-items:center; }
.u-cluster{ display:flex; flex-direction:row; flex-wrap:wrap; align-items:center; }
.u-gap-xs{ gap:var(--sp-2); } .u-gap-sm{ gap:var(--sp-4); } .u-gap-md{ gap:var(--sp-6); } .u-gap-lg{ gap:var(--sp-8); } .u-gap-xl{ gap:var(--sp-9); }
.u-spacer{ flex:1 1 auto; }
.u-divider{ height:1px; width:100%; background:var(--divider); border:none; }
.u-divider-v{ width:1px; align-self:stretch; background:var(--divider); border:none; }

/* responsive show/hide — keyed to the SM breakpoint boundary, see Breakpoints (f-breakpoints) */
.u-hide-sm{}
.u-show-sm{ display:none!important; }
@media (max-width:639px){
  .u-hide-sm{ display:none!important; }
  .u-show-sm{ display:block!important; }
  .topbar .crumbs{ display:none; }
  .topbar{ position:relative; }
  .topbar .brand{ position:absolute; left:50%; top:50%; transform:translate(-50%,-50%); }
  .topbar .divider-v{ display:none; }
  .lp-topnav{ position:relative; flex-wrap:nowrap; }
  .lp-topnav .brand{ position:absolute; left:50%; top:50%; transform:translate(-50%,-50%); }
  .lp-topnav-toggle{ display:flex !important; order:1; }
  .lp-topnav-links{ display:none !important; position:absolute; top:calc(100% + var(--sp-3)); left:0; right:0; flex-direction:column; align-items:stretch; gap:var(--sp-2); background:var(--glass-card-bg); backdrop-filter:blur(var(--glass-blur)) saturate(1.4); -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(1.4); border:1px solid var(--glass-card-border); border-radius:var(--r-panel); padding:var(--sp-4); box-shadow:var(--shadow-ovl); z-index:20; }
  .lp-topnav.lp-topnav-mobile-open .lp-topnav-links{ display:flex !important; }
  .lp-topnav-actions{ order:2; }
  .lp-topnav-actions .mini-btn:not(.icon-only){ display:none !important; }
  .lp-topnav .lp-navdrop{ width:100%; }
  .lp-topnav .lp-navdrop-trigger{ width:100%; justify-content:space-between; }
  .lp-topnav .lp-navdrop-panel{ position:static; left:auto; transform:none; width:100% !important; box-shadow:none; margin-top:var(--sp-2); }
  .lp-footer-grid{ grid-template-columns:1fr !important; gap:var(--sp-6) !important; }
  .lp-footer-cols{ grid-template-columns:1fr !important; }
  .lp-navdrop-panel{ max-width:calc(100vw - 48px); }
  .lp-navdrop-cols{ grid-template-columns:1fr !important; }
  .route-search-pill{ flex-direction:column !important; align-items:stretch !important; overflow-x:visible; }
  .route-search-pill .field{ width:100% !important; }
  .route-search-pill .icon-btn{ align-self:center; transform:rotate(0deg) !important; }
  .route-search-pill .mini-btn{ margin-left:0 !important; width:100%; }
}

/* overflow — shares the one neutral scrollbar recipe, formalized below under Scrollbar */
.u-overflow-auto{ overflow:auto; }
.u-overflow-x-auto{ overflow-x:auto; overflow-y:hidden; }
.u-overflow-y-auto{ overflow-y:auto; overflow-x:hidden; }
.u-overflow-hidden{ overflow:hidden; }
.u-overflow-auto, .u-overflow-x-auto, .u-overflow-y-auto{ scrollbar-width:thin; scrollbar-color:color-mix(in srgb, var(--text-tertiary) 22%, transparent) transparent; }
.u-overflow-auto:hover, .u-overflow-x-auto:hover, .u-overflow-y-auto:hover{ scrollbar-color:color-mix(in srgb, var(--text-tertiary) 42%, transparent) transparent; }
.u-overflow-auto::-webkit-scrollbar, .u-overflow-x-auto::-webkit-scrollbar, .u-overflow-y-auto::-webkit-scrollbar{ width:5px; height:5px; }
.u-overflow-auto::-webkit-scrollbar-track, .u-overflow-x-auto::-webkit-scrollbar-track, .u-overflow-y-auto::-webkit-scrollbar-track{ background:transparent; }
.u-overflow-auto::-webkit-scrollbar-thumb, .u-overflow-x-auto::-webkit-scrollbar-thumb, .u-overflow-y-auto::-webkit-scrollbar-thumb{ background-color:color-mix(in srgb, var(--text-tertiary) 22%, transparent); border-radius:var(--r-pill); border:1px solid transparent; background-clip:padding-box; transition:background-color var(--dur-moderate) var(--ease-out); }
.u-overflow-auto:hover::-webkit-scrollbar-thumb, .u-overflow-x-auto:hover::-webkit-scrollbar-thumb, .u-overflow-y-auto:hover::-webkit-scrollbar-thumb{ background-color:color-mix(in srgb, var(--text-tertiary) 42%, transparent); }

/* alignment */
.u-items-start{ align-items:flex-start; } .u-items-center{ align-items:center; } .u-items-end{ align-items:flex-end; } .u-items-stretch{ align-items:stretch; }
.u-justify-start{ justify-content:flex-start; } .u-justify-center{ justify-content:center; } .u-justify-end{ justify-content:flex-end; } .u-justify-between{ justify-content:space-between; }

/* width / sizing — no arbitrary pixel helpers; intrinsic keywords and min-width:0 only */
.u-w-full{ width:100%; }
.u-w-fit{ width:fit-content; }
.u-w-min{ width:min-content; }
.u-w-max{ width:max-content; }
.u-min-w-0{ min-width:0; }

/* text */
.u-truncate{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0; }
.u-clamp-2{ display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.u-clamp-3{ display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden; }
.u-nowrap{ white-space:nowrap; }
.u-tabular-nums{ font-variant-numeric:tabular-nums; }
.u-numeric{ font-variant-numeric:tabular-nums; text-align:right; }

/* interaction */
.u-focus-ring:focus-visible{ outline:none; box-shadow:var(--ring-focus); }
.u-hit-area{ position:relative; }
.u-hit-area::after{ content:''; position:absolute; inset:-8px; }
.u-cursor-pointer{ cursor:pointer; } .u-cursor-default{ cursor:default; } .u-cursor-not-allowed{ cursor:not-allowed; }
.u-cursor-grab{ cursor:grab; } .u-cursor-grabbing{ cursor:grabbing; } .u-cursor-resize-col{ cursor:col-resize; }
.u-no-pointer-events{ pointer-events:none; }
.u-scroll-lock{ overflow:hidden!important; }

/* state / accessibility */
.u-hidden{ display:none!important; }
.u-sr-only{ position:absolute; width:1px; height:1px; padding:var(--sp-0); margin:-1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0; }
.skip-link{ position:absolute; left:16px; top:-48px; z-index:80; padding:var(--space-label-gap) var(--sp-6); border-radius:var(--r-control); background:var(--bg-base); color:var(--text-primary); font-size:var(--fs-1); font-weight:500; box-shadow:var(--shadow-2); border:1px solid var(--border-default); transition:top var(--dur-default) var(--ease-out); }
.skip-link:focus{ top:16px; outline:none; box-shadow:var(--ring-focus), var(--shadow-2); }
@media (prefers-reduced-motion: reduce){ .skip-link{ transition:none; } }

/* surface helpers — reference existing tokens only, never a new fill or shadow */
.u-surface-subtle-border{ border:1px solid var(--border-subtle-line); }
.u-surface-raised{ background:var(--bg-raised); box-shadow:var(--shadow-surface-rest); }
.u-surface-sunken{ background:var(--bg-sunken); }
.u-surface-selected{ border-color:var(--accent); background:var(--accent-wash); }

/* ---- AI surface — opt-in only, never applied to neutral/core UI ---- */
.ai-surface{
  position:relative; border-radius:var(--radius-32); padding:var(--sp-7); overflow:hidden;
  border:1px solid var(--accent-wash-border);
  background-color:var(--glass-card-bg);
  backdrop-filter:blur(var(--glass-blur));
}
/* v1.33: no wash, no sheen, no tinted shadow. AI content uses the existing glass surface, border,
   typography and loading indicators — it does not get a visual language of its own. */

/* swatches */
.swatch-grid{ display:grid; grid-template-columns:repeat(7,1fr); gap:var(--space-inline-gap); }
.swatch{ border-radius:var(--r-float); overflow:hidden; border:1px solid var(--border-default); }
.swatch-fill{ height:56px; }
.swatch-label{ padding:var(--sp-4) var(--sp-4); background:var(--bg-base); }
.swatch-label .step{ font-size:var(--fs-1); font-weight:600; }
.swatch-label .hex{ font-size:10.5px; color:var(--text-tertiary); font-variant-numeric:tabular-nums; letter-spacing:var(--ls-5); }
.brand-swatch-grid{ display:grid; grid-template-columns:1.6fr repeat(6,1fr); grid-template-rows:repeat(2,140px); gap:2px; border-radius:var(--radius-32); overflow:hidden; }
.brand-swatch{ display:flex; flex-direction:column; justify-content:space-between; padding:var(--sp-5); font-family:var(--font-sans); }
.brand-swatch.hero{ grid-row:span 2; }
.brand-swatch-name{ font-size:var(--fs-1); font-weight:700; letter-spacing:var(--ls-6); text-transform:uppercase; }
.brand-swatch.hero .brand-swatch-name{ font-size:var(--fs-3); }
.brand-swatch-info{ font-family:var(--font-sans); font-size:10px; line-height:1.6; opacity:.9; font-variant-numeric:tabular-nums; }
.brand-swatch.hero .brand-swatch-info{ font-size:11px; }

/* type specimen */
.type-row{ display:flex; align-items:baseline; gap:var(--sp-8); padding:var(--sp-6) var(--sp-0); border-bottom:1px solid var(--divider); overflow:hidden; }
.type-row:last-child{ border-bottom:none; }
.type-row .meta{ width:170px; flex-shrink:0; }
.type-row .meta .name{ font-size:var(--fs-1); font-weight:600; }
.type-row .meta .spec{ font-size:var(--fs-1); color:var(--text-tertiary); font-variant-numeric:tabular-nums; }
.type-row .sample{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; flex:1; min-width:0; }

/* usage / mapping table — same global cleanup as the Tables component:
   safe internal horizontal scroll (never the page), a matching subtle
   overlay scrollbar, and slightly more breathing room in the header. */
/* ---- doctable-wrap: rounded OUTER container only. border-radius on a
   border-collapse:collapse <table> does not render reliably across
   browsers, so the radius+clip lives on this plain-div wrapper instead —
   the table itself keeps border-collapse:collapse with straight internal
   row dividers, unaffected by (and unaware of) the rounded corner. ---- */
.doctable-wrap{ border-radius:var(--radius-32); overflow-x:auto; overflow-y:hidden; border:1px solid var(--border-default); background:var(--bg-base); }
table.doctable{ width:100%; table-layout:auto; border-collapse:collapse; font-size:var(--fs-1); display:table; }
table.doctable th{ text-align:left; font-size:var(--fs-1); text-transform:uppercase; letter-spacing:var(--ls-7); color:var(--text-tertiary); font-weight:600; padding:var(--sp-5) var(--sp-5) var(--space-dense-cell-inset); border-bottom:1px solid var(--border-default); white-space:nowrap; }
table.doctable td{ padding:var(--sp-5) var(--sp-5); border-bottom:1px solid var(--divider); vertical-align:top; color:var(--text-secondary); }
table.doctable tr:last-child td{ border-bottom:none; }
table.doctable td.k{ font-family:var(--font-display); color:var(--text-primary); font-weight:500; white-space:nowrap; }
table.doctable{ background:var(--bg-base); }
table.doctable th:first-child, table.doctable td:first-child{ padding-left:var(--sp-6); }
table.doctable{ scrollbar-width:thin; scrollbar-color:color-mix(in srgb, var(--text-tertiary) 22%, transparent) transparent; }
table.doctable:hover{ scrollbar-color:color-mix(in srgb, var(--text-tertiary) 42%, transparent) transparent; }
table.doctable::-webkit-scrollbar{ height:5px; }
table.doctable::-webkit-scrollbar-track{ background:transparent; }
table.doctable::-webkit-scrollbar-thumb{ background-color:color-mix(in srgb, var(--text-tertiary) 22%, transparent); border-radius:var(--r-pill); border:1px solid transparent; background-clip:padding-box; transition:background-color var(--dur-moderate) var(--ease-out); }
table.doctable:hover::-webkit-scrollbar-thumb, table.doctable::-webkit-scrollbar-thumb:hover{ background-color:color-mix(in srgb, var(--text-tertiary) 42%, transparent); }

/* do / dont */
.dodont{ position:relative; display:grid; grid-template-columns:1fr 1fr; gap:var(--sp-8); align-items:start; }
.dodont .col{ padding:var(--sp-0); }
.dodont h5{ margin:var(--sp-0) var(--sp-0) var(--sp-5); font-size:var(--fs-3); font-weight:600; }
.dodont .do h5{ color:var(--dodont-do-text); }
.dodont .dont h5{ color:var(--dodont-dont-text); }
.dodont ul{ margin:var(--sp-0); padding:var(--sp-0); list-style:none; display:flex; flex-direction:column; gap:var(--sp-4); }
.dodont li{ font-size:var(--fs-2); color:var(--text-secondary); line-height:var(--lh-2); padding-left:var(--sp-6); position:relative; }
.dodont li:before{ position:absolute; left:0; top:1px; font-size:var(--fs-1); }
.dodont .do li:before{ content:"✓"; color:var(--badge-live-mono); }
.dodont .dont li:before{ content:"✕"; color:var(--dodont-dont-mono); }

/* generic light/dark-only inline toggle — for embedding the approved brand mark's two variants directly (no JS swap) */
.u-light-only{ display:inline; }
.u-dark-only{ display:none; }
:root[data-theme="dark"] .u-light-only{ display:none; }
:root[data-theme="dark"] .u-dark-only{ display:inline; }

/* chip / pill */
/* Tonal pills carry no outline — the fill is the shape. The 1px border is kept transparent
   rather than removed so the box still measures the same and a pill does not shift 2px
   against a neighbour that has one.
   The fill moves --bg-sunken -> --bg-track for the reason that keeps recurring: sunken
   resolves to the same #0B0D10 as the canvas in dark, so once the border goes a sunken pill
   is invisible there. Track is one step off the canvas in both themes (#F1F3F6 / #252A32). */
.chip, .flow-step, .state-pill{ display:inline-flex; align-items:center; gap:var(--sp-3); padding:var(--sp-3) var(--sp-5); border-radius:var(--r-pill); font-size:var(--fs-1); font-weight:500; background:var(--bg-track); border:1px solid transparent; color:var(--text-secondary); max-width:100%; overflow-wrap:break-word; }
.chip-row{ display:flex; gap:var(--sp-4); flex-wrap:wrap; }

/* code block */
.codeblock{ background:var(--codeblock-bg); color:#D7DEE8; font-family:var(--font-mono); border-radius:var(--r-card); padding:var(--sp-6) var(--sp-7); font-size:var(--fs-1); overflow-x:auto; line-height:var(--lh-5); }
.codeblock .tok-key{ color:#8FB8FF; } .codeblock .tok-val{ color:#9FE6B0; } .codeblock .tok-cm{ color:#6B7280; }

.two-col{ display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:var(--sp-6); align-items:start; }
.three-col{ display:grid; grid-template-columns:1fr 1fr 1fr; gap:var(--sp-5); align-items:start; }
.two-col > *, .three-col > *{ min-width:0; }
/* ---- A single unified card split into internal columns by hairline
   dividers — used for step-by-step pipelines where each step needs more
   room than a .flow-row chip allows, without breaking into separate cards. ---- */
.pipeline-cols{ display:grid; }
.pipeline-col{ padding:var(--sp-7); border-left:1px solid var(--border-default); }
.pipeline-col:first-child{ border-left:none; }
.access-note{ padding:var(--space-surface-inset) var(--sp-6); margin-top:var(--space-block-gap); border-radius:var(--r-card); background:var(--accent-wash); border:1px solid var(--accent-wash-border); font-size:var(--fs-1); color:var(--text-secondary); }
.lp-jump-nav{ display:flex; flex-wrap:wrap; gap:var(--sp-3); border:1px solid var(--border-subtle-line); border-radius:var(--radius-32); background:var(--bg-base); padding:var(--sp-8); }
.lp-jump-pill{ transition:background var(--dur-default) var(--ease-out), border-color var(--dur-default) var(--ease-out); }
.lp-jump-pill:hover{ background:var(--bg-raised); border-color:var(--accent); color:var(--text-primary); }
.lp-jump-count{ font-family:var(--font-sans); font-variant-numeric:tabular-nums; color:var(--text-tertiary); }
.lp-group-divider{ display:flex; align-items:flex-end; justify-content:space-between; flex-wrap:wrap; gap:var(--sp-4); padding-top:var(--sp-8); border-top:1px solid var(--border-default); }
.lp-group-title{ font-family:var(--font-display); font-size:var(--fs-8); font-weight:var(--fw-semibold); line-height:var(--lh-1); color:var(--text-primary); margin-bottom:var(--sp-2); }
.lp-group-desc{ font-size:var(--fs-2); color:var(--text-secondary); margin:var(--sp-0); }
.lp-group-count{ font-size:var(--fs-1); color:var(--text-tertiary); white-space:nowrap; }
/* ---- canonical section-description paragraph — replaces a 130-instance hand-typed
   inline style (Foundation Normalization pass) ---- */
.section-desc{ font-size:var(--fs-2); color:var(--text-secondary); max-width:680px; line-height:var(--lh-4); margin-bottom:var(--space-block-gap); }
.access-note b{ color:var(--text-primary); }

.footer-nav{ display:flex; justify-content:space-between; margin-top:var(--sp-12); padding-top:var(--sp-8); border-top:1px solid var(--border-default); font-size:var(--fs-2); color:var(--text-tertiary); }

/* index / stub pages for un-built libraries */
.stub-banner{ display:flex; gap:var(--space-inline-gap); align-items:flex-start; padding:var(--sp-7) var(--sp-7); border-radius:var(--r-panel); background:var(--bg-sunken); border:1px solid var(--border-default); margin-bottom:var(--sp-9); }
.stub-banner p{ font-size:var(--fs-2); color:var(--text-secondary); line-height:var(--lh-3); }
.stub-list{ display:grid; grid-template-columns:1fr 1fr; gap:var(--sp-4); }
.gs-row-text h4 .n{ color:var(--text-tertiary); font-weight:400; margin-right:var(--sp-2); }

@media (max-width:900px){
  :root{ --hero-navw:0px; --hero-gutter:var(--sp-7); --hero-gutter-top:var(--sp-9); }
  .shell{ grid-template-columns:1fr; }
  .sidenav{ display:none; }
  .workspace{ grid-column:1; }
  #nav-toggle.nav-toggle{ display:flex; }
  .page{ padding:var(--sp-9) var(--sp-7); }
  .principles, .dodont, .two-col, .three-col, .ov-hero, .ov-card-grid{ grid-template-columns:1fr !important; }
  .dodont:before{ display:none; }
  .swatch-grid{ grid-template-columns:repeat(3,1fr); }
  .icon-grid{ grid-template-columns:repeat(3,1fr) !important; }
  .illus-grid{ grid-template-columns:repeat(2,1fr) !important; }
  .stub-list{ grid-template-columns:1fr !important; }
  .lp-footer-grid{ grid-template-columns:1fr !important; }
  .lp-footer-cols{ grid-template-columns:1fr 1fr !important; }
  .spacing-scale-grid{ grid-auto-flow:row !important; grid-template-columns:1fr !important; }
  .bw-versions-grid{ grid-template-columns:1fr !important; }
  .bw-versions-grid svg{ max-width:100%; height:auto; }
  .lp-bento-4up{ flex-direction:column !important; min-height:0 !important; }
  .lp-bento-4up > div{ flex:none !important; min-height:180px; }
  .lp-bento-grid{ display:flex !important; flex-direction:column !important; min-height:0 !important; }
  .lp-bento-grid > div{ grid-column:auto !important; grid-row:auto !important; min-height:180px; }
  .route-search-pill{ overflow-x:auto; width:100%; }
  .route-search-pill > *{ flex-shrink:0; }
  .spec-frame{ overflow-x:auto; max-width:100%; }
  .spec-frame > *{ flex-shrink:0; }
  .tab-pillbar{ max-width:100%; overflow-x:auto; }
  .tab-pillbar .tab-pill{ flex-shrink:0; }
  .stat-grid-3col{ grid-template-columns:1fr !important; }
  .stat-grid-3col .stat-block{ border-right:none !important; }
  .pair-row{ gap:var(--sp-2); }
  .pair-row .hx{ width:44px; }
  .pair-row .tk{ min-width:28px; }
  .product-row .name{ width:auto !important; }
  .product-row .tagline{ flex-basis:100% !important; }
  .pipeline-cols{ grid-template-columns:1fr !important; }
  .pipeline-col{ border-left:none; border-top:1px solid var(--border-default); }
  .pipeline-col:first-child{ border-top:none; }
  .searchbox{ display:none; }

  /* ---- mobile nav: sidebar hides behind the hamburger (--nav-toggle),
     reopens as a fixed-position overlay above content, closes on scrim
     click, outside click, Escape, or navigating to a page. ---- */
  #shell.mobile-nav-open .sidenav{
    display:block; position:fixed; top:var(--shell-top-h); left:0; bottom:0; width:280px; max-width:85vw;
    z-index:40; box-shadow:var(--shadow-4);
  }
  #shell.mobile-nav-open .mobile-nav-scrim{
    display:block; position:fixed; inset:var(--shell-top-h) 0 0 0; background:rgba(11,13,16,.4); z-index:35;
  }
}

/* ---- scale strip (compact multi-step palette row) ---- */
.scale-row{ display:flex; align-items:center; gap:var(--space-inline-gap); padding:var(--sp-4) var(--sp-0); }
.scale-row .name{ width:96px; flex-shrink:0; }
.scale-row .name b{ font-size:var(--fs-1); display:block; }
.scale-row .name span{ font-size:var(--fs-1); color:var(--text-tertiary); }
.scale-strip{ display:flex; flex:1; border-radius:var(--r-chip); overflow:hidden; height:30px; border:1px solid var(--border-default); }
.scale-strip .step{ flex:1; position:relative; }
.scale-strip .step.anchor{ box-shadow:inset 0 0 0 2px rgba(255,255,255,.7), inset 0 0 0 3px rgba(0,0,0,.15); }

/* ---- token pair rows (light/dark, borders, etc) ---- */
.pair-row{ display:flex; align-items:center; gap:var(--sp-4); padding:var(--sp-4) var(--sp-0); border-bottom:1px solid var(--divider); font-size:var(--fs-1); min-width:0; }
.pair-row:last-child{ border-bottom:none; }
.pair-row .tk{ flex:0 1 120px; min-width:40px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--text-primary); font-weight:500; }
.pair-row .sw{ width:20px; height:20px; border-radius:var(--r-chip); border:1px solid var(--border-default); flex-shrink:0; }
.pair-row .hx{ width:56px; color:var(--text-tertiary); font-size:var(--fs-1); flex-shrink:0; }
.pair-row .lbl{ color:var(--text-secondary); font-size:var(--fs-1); min-width:0; overflow-wrap:break-word; }

/* ---- click-to-copy swatches (Color foundation) ---- */
.copy-swatch{ cursor:pointer; -webkit-tap-highlight-color:transparent; }
.copy-swatch:hover{ filter:brightness(1.06); }
.copy-swatch:focus-visible{ outline:2px solid var(--accent); outline-offset:1px; }

/* ---- attention hierarchy strip ---- */
.attn-row{ display:flex; align-items:center; gap:var(--sp-5); padding:var(--sp-4) var(--sp-0); }
.attn-swatch{ width:52px; height:26px; border-radius:var(--r-chip); flex-shrink:0; display:flex; align-items:center; justify-content:center; font-size:10px; font-weight:600; }
.attn-label{ font-size:var(--fs-1); color:var(--text-secondary); }

/* ---- icon grid ---- */
.icon-grid{ display:grid; grid-template-columns:repeat(6,1fr); gap:var(--space-chrome-gap); }
.icon-tile{ display:flex; flex-direction:column; align-items:center; gap:var(--sp-4); padding:var(--sp-6) var(--sp-4); border:1px solid var(--border-default); border-radius:var(--r-card); background:var(--bg-base); }
.icon-tile-glyph{ width:40px; height:40px; display:flex; align-items:center; justify-content:center; flex-shrink:0; }
.icon-tile svg{ color:var(--text-secondary); }
.illus-grid{ display:grid; grid-template-columns:repeat(5,1fr); gap:var(--space-chrome-gap); }
.illus-tile{ display:flex; flex-direction:column; align-items:center; gap:var(--sp-4); padding:var(--sp-6) var(--sp-4); border:1px solid var(--border-default); border-radius:var(--r-card); background:var(--bg-base); }
.illus-tile svg{ width:64px; height:64px; }
.illus-tile .lbl{ font-size:10.5px; color:var(--text-tertiary); text-align:center; line-height:var(--lh-3); }
.icon-tile .lbl{ font-size:var(--fs-1); color:var(--text-tertiary); }

/* ---- motion demo ---- */
.motion-row{ display:flex; align-items:center; gap:var(--sp-6); padding:var(--sp-5) var(--sp-0); border-bottom:1px solid var(--divider); }
.motion-row:last-child{ border-bottom:none; }
.motion-row .meta{ width:220px; flex-shrink:0; font-size:var(--fs-1); }
.motion-row .meta b{ font-size:var(--fs-1); display:block; }
.motion-row .meta span{ color:var(--text-tertiary); font-size:var(--fs-1); }
.motion-demo{ width:120px; height:32px; position:relative; background:var(--bg-sunken); border-radius:var(--radius-8); overflow:hidden; }
.motion-demo .dot{ position:absolute; top:6px; left:6px; width:20px; height:20px; border-radius:var(--radius-6); background:var(--accent); }
.motion-row:hover .dot{ transform:translateX(80px); }
.motion-fast .dot{ transition:transform 100ms cubic-bezier(.2,0,0,1); }
.motion-mod .dot{ transition:transform 150ms cubic-bezier(.2,0,0,1); }
.motion-def .dot{ transition:transform 200ms cubic-bezier(0,0,.2,1); }
.motion-slow .dot{ transition:transform 300ms cubic-bezier(.2,0,0,1.4); }
.motion-spring .dot{ transition:transform 400ms var(--ease-spring); } /* Aura update: native spring/overshoot */

/* ---- opacity scale ---- */
.opacity-row{ display:flex; align-items:center; gap:var(--sp-6); padding:var(--sp-4) var(--sp-0); }
.opacity-row .box{ width:56px; height:36px; border-radius:var(--radius-8); background:var(--n-950); flex-shrink:0; }
.opacity-row .lbl{ font-size:var(--fs-1); color:var(--text-secondary); width:150px; }
.opacity-row .val{ font-size:var(--fs-1); color:var(--text-tertiary); }

/* ---- density demo ---- */
.density-block{ border:1px solid var(--border-default); border-radius:var(--r-card); overflow:hidden; }
.density-block .row{ display:flex; align-items:center; padding:var(--sp-0) var(--space-surface-inset); border-bottom:1px solid var(--divider); font-size:var(--fs-1); color:var(--text-secondary); border-top:3px solid transparent; }
.density-block .row:last-child{ border-bottom:none; }

/* ---- glass demo ---- */
.glass-demo{ position:relative; height:150px; border-radius:var(--r-panel); overflow:hidden; background:var(--bg-sunken); }
.glass-card{ position:absolute; top:24px; left:24px; right:24px; bottom:24px; border-radius:var(--r-card); background:var(--glass-card-bg); border:1px solid var(--glass-card-border); backdrop-filter:blur(var(--glass-blur)); box-shadow:var(--shadow-3); display:flex; align-items:center; justify-content:center; font-size:var(--fs-1); color:var(--text-secondary); }
.glass-card.blur-lg{ backdrop-filter:blur(var(--glass-blur-lg)); } /* Aura update: large/hero tier for full Modal/Drawer Glass moments */
/* ==== GLASS SURFACES — v1.34. Foundations → Elevation & Surfaces → Glass.
   Surface = material × elevation. Glass is a MATERIAL beside Solid, not a second height scale:
   each level borrows an existing elevation step. Glass is transparency and controlled layering; blur is
   reserved for surfaces floating over meaningful content (Glass 3–4). No gradient, glow, neon edge, tint
   or animated blur, and no glass for semantic status states.
   A utility carries the material only (fill, edge, highlight, shadow, blur) — never radius, padding or
   layout — so an existing component keeps its own shape and simply takes the treatment.
   Each rule is also stated at the App Shell glass tier's weight (.ash-frame.ash-glass …, 0,3,0), which
   otherwise out-ranks a single-class utility; stated after it, the level wins by source order. ==== */
.u-glass-0,
.ash-frame.ash-glass .u-glass-0{ background:transparent; border-color:transparent; box-shadow:none; -webkit-backdrop-filter:none; backdrop-filter:none; }
.u-glass-1,
.ash-frame.ash-glass .u-glass-1{ background:var(--glass-card-bg-subtle); border:1px solid transparent; box-shadow:var(--shadow-0); -webkit-backdrop-filter:none; backdrop-filter:none; }
.u-glass-2,
.ash-frame.ash-glass .u-glass-2{ background:var(--glass-card-bg); border:1px solid transparent; box-shadow:var(--surface-sheen), var(--shadow-1); -webkit-backdrop-filter:none; backdrop-filter:none; }
.u-glass-3,
.ash-frame.ash-glass .u-glass-3{ background:var(--glass-card-bg-strong); border:1px solid var(--glass-card-border); box-shadow:var(--surface-sheen), var(--shadow-3); -webkit-backdrop-filter:blur(var(--glass-blur)); backdrop-filter:blur(var(--glass-blur)); }
.u-glass-4,
.ash-frame.ash-glass .u-glass-4{ background:var(--glass-card-bg-strong); border:1px solid var(--glass-card-border); box-shadow:var(--surface-sheen), var(--shadow-4); -webkit-backdrop-filter:blur(var(--glass-blur-lg)); backdrop-filter:blur(var(--glass-blur-lg)); }
/* Motion: only the elevation change (edge + shadow). Fill and blur never transition, never animate. */
.u-glass-1, .u-glass-2, .u-glass-3, .u-glass-4{ transition:box-shadow var(--dur-default) var(--ease-lift), border-color var(--dur-default) var(--ease-lift); }
/* Interaction: an interactive glass surface lifts one elevation step — the shadow carries the state,
   never the transparency alone, and no darker outline is drawn (v1.34: no grey outlines). .is-hover / .is-focus are documentation states. */
:is(.u-glass-1, .u-glass-2):is(a, button, [role="button"], [role="link"], .clickable):hover,
:is(.u-glass-1, .u-glass-2).is-hover,
.ash-frame.ash-glass :is(.u-glass-1, .u-glass-2):is(a, button, [role="button"], [role="link"], .clickable):hover{ box-shadow:var(--surface-sheen), var(--shadow-2); }
:is(.u-glass-3, .u-glass-4):is(a, button, [role="button"], [role="link"], .clickable):hover,
:is(.u-glass-3, .u-glass-4).is-hover,
.ash-frame.ash-glass :is(.u-glass-3, .u-glass-4):is(a, button, [role="button"], [role="link"], .clickable):hover{ box-shadow:var(--surface-sheen), var(--shadow-4); }
:is(.u-glass-1, .u-glass-2, .u-glass-3, .u-glass-4):focus-visible,
:is(.u-glass-1, .u-glass-2, .u-glass-3, .u-glass-4).is-focus,
.ash-frame.ash-glass :is(.u-glass-1, .u-glass-2, .u-glass-3, .u-glass-4):focus-visible{ outline:none; box-shadow:var(--ring-focus), var(--shadow-1); }
/* Solid fallback — one rule set, three triggers: no backdrop-filter support (Glass 3–4 only, the levels
   that depend on blur), the user asking for less transparency, and the documentation toggle. */
@supports not ((-webkit-backdrop-filter:blur(1px)) or (backdrop-filter:blur(1px))){
  .u-glass-3, .u-glass-4,
  .ash-frame.ash-glass .u-glass-3, .ash-frame.ash-glass .u-glass-4{ background:var(--bg-base); }
}
@media (prefers-reduced-transparency: reduce){
  .u-glass-1, .ash-frame.ash-glass .u-glass-1{ background:var(--bg-sunken); }
  .u-glass-2, .u-glass-3, .u-glass-4,
  .ash-frame.ash-glass .u-glass-2, .ash-frame.ash-glass .u-glass-3, .ash-frame.ash-glass .u-glass-4{ background:var(--bg-base); -webkit-backdrop-filter:none; backdrop-filter:none; }
}
.glass-rt .u-glass-1{ background:var(--bg-sunken); }
.glass-rt :is(.u-glass-2, .u-glass-3, .u-glass-4){ background:var(--bg-base); -webkit-backdrop-filter:none; backdrop-filter:none; }
/* More contrast: opaque, and the default border instead of the subtle hairline or the white edge. */
@media (prefers-contrast: more){
  .u-glass-1, .ash-frame.ash-glass .u-glass-1{ background:var(--bg-sunken); border-color:var(--border-default); }
  .u-glass-2, .u-glass-3, .u-glass-4,
  .ash-frame.ash-glass .u-glass-2, .ash-frame.ash-glass .u-glass-3, .ash-frame.ash-glass .u-glass-4{ background:var(--bg-base); border-color:var(--border-default); -webkit-backdrop-filter:none; backdrop-filter:none; }
}
/* Forced colours: the system draws the surface; the edge is the only thing that must survive. */
@media (forced-colors: active){
  .u-glass-1, .u-glass-2, .u-glass-3, .u-glass-4{ background:Canvas; border:1px solid CanvasText; box-shadow:none; -webkit-backdrop-filter:none; backdrop-filter:none; }
}

/* ---- Glass specimens (documentation only). The atmosphere below is the TrackingMCP product shell's
   page wash, reproduced ONLY so the specimens can show glass in the context it is designed for. It is
   specimen-only and deliberately NOT a DS token: canonical has no page-background wash. ---- */
.glass-spec-atmos{ position:relative; overflow:hidden; border-radius:var(--r-panel); padding:var(--sp-8);
  background:
    linear-gradient(color-mix(in srgb, var(--bg-canvas) 62%, transparent), color-mix(in srgb, var(--bg-canvas) 62%, transparent)),
    radial-gradient(circle at 30% 30%, color-mix(in srgb, var(--blue-700) 22%, transparent), transparent 65%),
    radial-gradient(circle at 70% 30%, color-mix(in srgb, var(--aqua-500) 24%, transparent), transparent 65%),
    radial-gradient(circle at 30% 70%, color-mix(in srgb, var(--violet-600) 20%, transparent), transparent 65%),
    var(--bg-canvas); }
.glass-spec-tag{ display:inline-block; margin-bottom:var(--sp-5); font-size:var(--fs-1); color:var(--text-tertiary); }
.glass-spec-grid{ display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); gap:var(--space-block-gap); }
@media (max-width:900px){ .glass-spec-grid{ grid-template-columns:minmax(0, 1fr); } }
.glass-spec-cap{ margin-top:var(--sp-4); font-size:var(--fs-1); color:var(--text-tertiary); line-height:var(--lh-4); }
.glass-spec-cap b{ color:var(--text-secondary); font-weight:var(--fw-semibold); }
.glass-spec-title{ display:block; font-size:var(--fs-4); font-weight:var(--fw-semibold); color:var(--text-primary); }
/* Content behind a floating surface: dense rows, so the blur of Glass 3–4 has something to act on. */
.glass-spec-rows{ display:flex; flex-direction:column; gap:var(--sp-3); }
.glass-spec-rows > div{ display:flex; justify-content:space-between; gap:var(--sp-4); padding:var(--sp-3) var(--sp-4); border-radius:var(--r-float); background:var(--bg-base); font-size:var(--fs-1); color:var(--text-secondary); }
.glass-spec-rows > div b{ color:var(--text-primary); font-weight:var(--fw-semibold); font-variant-numeric:tabular-nums; }
.glass-spec-states{ display:grid; grid-template-columns:repeat(4, minmax(0, 1fr)); gap:var(--sp-5); }
@media (max-width:900px){ .glass-spec-states{ grid-template-columns:repeat(2, minmax(0, 1fr)); } }
.glass-spec-state{ min-height:96px; padding:var(--sp-5); border-radius:var(--r-panel); font-size:var(--fs-1); color:var(--text-secondary); display:flex; flex-direction:column; justify-content:space-between; gap:var(--sp-3); }
.glass-spec-state b{ color:var(--text-primary); font-size:var(--fs-2); font-weight:var(--fw-semibold); }

/* ---- overlay anatomy shared by Modal + Drawer: header / body / footer ---- */
.ovl-head{ display:flex; align-items:flex-start; justify-content:space-between; gap:var(--space-chrome-gap); padding:var(--sp-6) var(--sp-7); border-bottom:1px solid var(--divider); flex-shrink:0; }
.ovl-head .t{ font-size:15px; font-weight:600; color:var(--text-primary); }
.ovl-head .d{ font-size:var(--fs-1); color:var(--text-tertiary); margin-top:var(--sp-1); }
.ovl-close{ display:flex; flex-shrink:0; padding:var(--sp-2); border-radius:var(--radius-8); color:var(--text-tertiary); cursor:pointer; background:none; border:none; }
.ovl-close:hover{ background:var(--bg-sunken); color:var(--text-primary); }
.ovl-close svg{ width:var(--size-icon-lg); height:var(--size-icon-lg); }
.ovl-body{ padding:var(--sp-7) var(--sp-7); font-size:var(--fs-1); color:var(--text-secondary); line-height:var(--lh-4); flex:1; min-height:0; }
.ovl-body.scrollable{ overflow-y:auto; }
.ovl-foot{ display:flex; justify-content:flex-end; gap:var(--space-chrome-gap); padding:var(--space-surface-inset) var(--sp-7); border-top:1px solid var(--divider); background:var(--bg-canvas); flex-shrink:0; }

/* ---- modal / dialog ---- */
.modal-demo{ display:flex; flex-direction:column; background:var(--bg-base); border:1px solid var(--border-default); box-shadow:var(--shadow-4); overflow:hidden; border-radius:var(--r-modal); max-height:320px; }
.modal-demo.compact{ width:280px; }
.modal-demo.standard{ width:400px; }
.modal-demo.large{ width:540px; }

/* ---- drawer / side panel: rounded on the leading (left) edge only ---- */
.drawer-demo{ display:flex; flex-direction:column; background:var(--bg-base); border:1px solid var(--border-default); box-shadow:var(--shadow-4); overflow:hidden; border-radius:var(--r-panel) 0 0 var(--r-panel); height:300px; margin-left:auto; }
.drawer-demo.narrow{ width:220px; }
.drawer-demo.standard{ width:300px; }
.drawer-demo.wide{ width:400px; }

/* ---- popover: bordered floating surface with a directional arrow ---- */
.popover-demo{ display:inline-flex; flex-direction:column; align-items:flex-start; }
.popover-demo .surface{ position:relative; background:var(--bg-base); border:1px solid var(--border-default); border-radius:var(--radius-24); box-shadow:var(--shadow-3); padding:var(--space-surface-inset) var(--sp-6); font-size:var(--fs-1); color:var(--text-primary); min-width:170px; }
.popover-demo .surface::after{ content:''; position:absolute; width:9px; height:9px; background:var(--bg-base); border:1px solid var(--border-default); }
.popover-demo.top .surface::after{ bottom:-5px; left:22px; border-top:none; border-left:none; transform:rotate(45deg); }
.popover-demo.bottom .surface::after{ top:-5px; left:22px; border-bottom:none; border-right:none; transform:rotate(45deg); }

/* ---- command palette: the one surface that uses real Glass — floats over the
   specimen's own ambient wash, exactly the "bloom behind an opaque card" rule ---- */
.cmdk-demo{ width:400px; border-radius:var(--r-modal); overflow:hidden; background:var(--glass-card-bg-strong); border:1px solid var(--glass-card-border); backdrop-filter:blur(6px); box-shadow:var(--shadow-ovl); }
.cmdk-demo .cmdk-input{ display:flex; align-items:center; gap:var(--space-chrome-gap); padding:var(--space-surface-inset) var(--sp-6); border-bottom:1px solid var(--divider); font-size:var(--fs-2); color:var(--text-tertiary); }
.cmdk-demo .cmdk-input svg{ width:16px; height:16px; flex-shrink:0; }
.cmdk-demo .cmdk-results{ padding:var(--sp-4); max-height:200px; overflow-y:auto; }
.cmdk-demo .cmdk-group{ padding:var(--sp-4) var(--space-label-gap) var(--sp-2); font-size:10.5px; text-transform:uppercase; letter-spacing:var(--ls-7); color:var(--text-disabled); font-weight:600; }
.cmdk-demo .cmdk-item{ display:flex; align-items:center; gap:var(--space-chrome-gap); padding:var(--sp-4) var(--space-label-gap); border-radius:var(--radius-24); font-size:var(--fs-1); color:var(--text-secondary); cursor:pointer; }
.cmdk-demo .cmdk-item svg{ width:var(--size-icon-lg); height:var(--size-icon-lg); flex-shrink:0; color:var(--text-tertiary); }
.cmdk-demo .cmdk-item:hover{ background:var(--bg-sunken); color:var(--text-primary); }
.cmdk-demo .cmdk-item.active{ background:var(--accent-wash); color:var(--accent); }
.cmdk-demo .cmdk-item.active svg{ color:var(--accent); }
.cmdk-demo .cmdk-item .kbd{ margin-left:auto; font-size:10.5px; padding:var(--sp-1) var(--sp-3); border-radius:var(--radius-6); background:var(--bg-sunken); border:1px solid var(--border-default); color:var(--text-tertiary); flex-shrink:0; }
.cmdk-demo .cmdk-empty{ padding:var(--sp-9) var(--sp-7); text-align:center; color:var(--text-tertiary); font-size:var(--fs-1); }

/* ---- backdrop / scrim ---- */
.scrim-demo{ position:relative; width:220px; height:130px; flex-shrink:0; border-radius:var(--r-card); overflow:hidden; border:1px solid var(--border-default); background:var(--bg-canvas); }
.scrim-demo .bg-content{ position:absolute; inset:0; padding:var(--space-surface-inset-sm); font-size:var(--fs-1); color:var(--text-tertiary); display:flex; flex-direction:column; gap:var(--sp-3); }
.scrim-demo .scrim{ position:absolute; inset:0; background:rgba(16,24,40,.4); display:flex; align-items:center; justify-content:center; }
.scrim-demo .scrim.strong{ background:rgba(16,24,40,.68); }
.scrim-demo .scrim-label{ background:var(--bg-base); padding:var(--sp-3) var(--sp-5); border-radius:var(--radius-8); font-size:var(--fs-1); color:var(--text-primary); box-shadow:var(--shadow-2); }

/* ---- brand svg tiles ---- */
.brand-tile-grid{ display:grid; grid-template-columns:repeat(4,1fr); gap:var(--sp-5); }
.brand-tile{ display:flex; flex-direction:column; align-items:center; gap:var(--space-inline-gap); padding:var(--sp-7) var(--space-label-gap); border:1px solid var(--border-default); border-radius:var(--r-card); background:var(--bg-base); }
.brand-tile .lbl{ font-size:var(--fs-1); color:var(--text-tertiary); text-align:center; }

/* ---- product theme row ---- */
.product-row{ display:flex; align-items:center; flex-wrap:wrap; gap:var(--sp-2) var(--space-inline-gap); padding:var(--space-surface-inset) var(--sp-6); border:1px solid var(--border-default); border-radius:var(--r-card); background:var(--bg-base);
  transition:border-color var(--dur-default) var(--ease-lift), box-shadow var(--dur-default) var(--ease-lift), transform var(--dur-default) var(--ease-lift); }
.product-row:hover{ border-color:var(--border-strong); box-shadow:var(--shadow-1); transform:translateY(-1px); }
.product-row + .product-row{ margin-top:var(--space-label-gap); }
.access-note + .product-row{ margin-top:var(--space-block-gap); }
.product-dot4{ display:flex; }
.product-dot4 i{ width:16px; height:16px; border-radius:50%; margin-left:-5px; border:2px solid var(--bg-base); }
.product-dot4 i:first-child{ margin-left:var(--sp-0); }
.product-row .name{ font-weight:600; font-size:var(--fs-2); width:150px; flex-shrink:0; }
.product-row .tagline{ font-size:var(--fs-1); color:var(--text-tertiary); flex:1; min-width:0; }

/* ---- state matrix ---- */
.state-pill-row{ display:flex; flex-wrap:wrap; gap:var(--sp-4); }

/* ---- specimen frame (live mini-component previews) ---- */
.spec-frame{ border:1px solid var(--border-subtle-line); border-radius:var(--r-panel); position:relative; background:
    repeating-linear-gradient(0deg, transparent, transparent 23px, var(--spec-grid-line, var(--border-subtle-line)) 23px, var(--spec-grid-line, var(--border-subtle-line)) 24px),
    repeating-linear-gradient(90deg, transparent, transparent 23px, var(--spec-grid-line, var(--border-subtle-line)) 23px, var(--spec-grid-line, var(--border-subtle-line)) 24px),
    var(--bg-canvas);
  padding:var(--sp-9); display:flex; gap:var(--space-inline-gap); align-items:center; justify-content:center; flex-wrap:wrap;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.6), inset 0 0 0 1px rgba(16,24,40,.02), 0 1px 2px rgba(16,24,40,.03); }
.spec-frame::before{ content:'SPECIMEN'; position:absolute; top:10px; right:14px; font-size:9.5px; font-weight:600; letter-spacing:var(--ls-8); color:var(--text-disabled); }
/* quieter technical grid for Containers specifically — component stays the visual focus */
#page-c-containers .spec-frame{ --spec-grid-line:color-mix(in srgb, var(--border-subtle-line) 55%, transparent); }
.spec-label{ font-size:var(--fs-1); color:var(--text-tertiary); margin-top:var(--sp-4); }

/* ---- mini live components, built from Foundations tokens only ---- */
.mini-btn{ display:inline-flex; align-items:center; justify-content:center; gap:var(--sp-3); height:40px; padding:var(--sp-0) var(--sp-7); border-radius:var(--r-button); background:var(--accent); color:#fff; font-size:var(--fs-2); font-weight:500; border:1px solid transparent; cursor:pointer; font-family:var(--font-sans); line-height:1;
  transition:background var(--dur-default) var(--ease-out), border-color var(--dur-default) var(--ease-out), box-shadow var(--dur-default) var(--ease-lift), opacity var(--dur-default) var(--ease-out); }
.mini-btn:hover{ background:var(--accent-hover); box-shadow:var(--shadow-accent-hover); }
.mini-btn:active{ box-shadow:none; }
/* Secondary carries no outline. The 1px border is KEPT as transparent (inherited from
   .mini-btn) rather than set to none, so the box measures identically to Primary and a
   Secondary beside it in a row does not sit 2px shorter.
   What holds the edge instead is --shadow-surface-rest, which this tier already had. That
   matters most in LIGHT, where --bg-base and --bg-canvas are both --n-0: the fill gives no
   contrast at all there and the shadow is the whole affordance. In dark the button is --n-900
   on an --n-950 canvas, so fill contrast does part of the work and the shadow the rest. */
.mini-btn.secondary{ background:var(--bg-base); color:var(--text-primary); border-color:transparent; box-shadow:var(--shadow-surface-rest); }
/* A sample row is a row of chip-like buttons and deliberately drops the shadow — a dozen
   lifted pills read as clutter. With the outline gone as well there would be nothing left at
   all, so here (and only here) a tonal fill stands in for both. */
.sample-row .mini-btn.secondary{ box-shadow:none; background:var(--bg-track); }  /* --bg-track, NOT --bg-sunken: sunken resolves to the same #0B0D10 as the canvas in dark, so a shadowless borderless pill painted with it vanishes. Track is one step off the canvas in both themes (#F1F3F6 / #252A32) — the reason it exists. */
.mini-btn.secondary:hover{ background:var(--bg-canvas); box-shadow:var(--shadow-surface-hover); }  /* no border to darken any more, so the shadow step rest -> hover is the whole hover signal: .04/.12 alpha up to .07/.18 */
.mini-btn.tertiary{ background:var(--bg-sunken); color:var(--text-primary); border-color:transparent; }
.mini-btn.tertiary:hover{ background:var(--border-subtle-line); box-shadow:none; }
.mini-btn.destructive{ background:var(--destructive); color:#fff; }
.mini-btn.destructive:hover{ background:var(--destructive-hover); box-shadow:var(--shadow-destructive-hover); }
.mini-btn.destructive:active{ background:var(--destructive-active); }
.mini-btn.ghost{ background:transparent; color:var(--accent); border-color:transparent; }
.mini-btn.ghost:hover{ background:var(--accent-wash); box-shadow:none; transform:none; }
.mini-btn.white{ position:relative; isolation:isolate; background:var(--glass-card-bg); backdrop-filter:blur(var(--glass-blur)); -webkit-backdrop-filter:blur(var(--glass-blur)); color:var(--text-primary); border:1px solid var(--glass-card-border); box-shadow:var(--shadow-surface-rest), inset 0 1px 0 rgba(255,255,255,.12), inset 0 -8px 12px -8px rgba(0,0,0,.3); transition:box-shadow var(--dur-default) var(--ease-out), transform var(--dur-default) var(--ease-lift); }
.mfx-sparkle{ transform-origin:center; transform-box:fill-box; animation:mfx-sparkle-twinkle 1.6s ease-in-out infinite; }
.mfx-sparkle.s2{ animation-delay:.3s; }
.mfx-sparkle.s3{ animation-delay:.6s; }
.mfx-sparkle.s4{ animation-delay:.9s; }
@keyframes mfx-sparkle-twinkle{ 0%,100%{ opacity:.15; transform:scale(.6); } 50%{ opacity:1; transform:scale(1.15); } }
.mini-btn.white:hover{ box-shadow:var(--shadow-surface-hover); }
.mini-btn[disabled]{ opacity:.4; cursor:not-allowed; pointer-events:none; }
.mini-btn.loading{ color:transparent; pointer-events:none; position:relative; }
.mini-btn.loading::after{ content:''; position:absolute; width:14px; height:14px; border-radius:50%; border:2px solid rgba(255,255,255,.4); border-top-color:#fff; animation:spin .7s linear infinite; }
.mini-btn.secondary.loading::after, .mini-btn.tertiary.loading::after, .mini-btn.ghost.loading::after{ border-color:var(--border-strong); border-top-color:var(--accent); }
.mini-btn.sm{ height:32px; padding:var(--sp-0) var(--sp-5); font-size:var(--fs-1); gap:var(--sp-3); border-radius:var(--r-button-sm); }
.mini-btn.lg{ height:48px; padding:var(--sp-0) var(--sp-8); font-size:14.5px; gap:var(--sp-4); border-radius:var(--r-button-lg); }
.mini-btn svg{ width:var(--size-icon-lg); height:var(--size-icon-lg); flex-shrink:0; }
.mini-btn.sm svg{ width:var(--size-icon-md); height:var(--size-icon-md); }
/* icon-only mini-btn is always square (width = height) — full circle, same family language as Icon Button below */
.mini-btn.icon-only{ width:40px; padding:var(--sp-0); border-radius:50%; }
.mini-btn.icon-only.sm{ width:32px; }
.mini-btn.icon-only.lg{ width:48px; }

/* ---- Icon Button — standalone, square, four surface variants — full circle, same family language as mini-btn.icon-only ---- */
.icon-btn{
  display:inline-flex; align-items:center; justify-content:center; width:36px; height:36px; border-radius:50%;
  background:transparent; border:1px solid transparent; color:var(--text-secondary); cursor:pointer;
  transition:background var(--dur-default) var(--ease-out), border-color var(--dur-default) var(--ease-out), color var(--dur-default) var(--ease-out);
}
.icon-btn svg{ width:17px; height:17px; }
.icon-btn:hover{ background:var(--bg-sunken); color:var(--text-primary); }
.icon-btn.subtle{ background:var(--bg-sunken); }
.icon-btn.subtle:hover{ background:var(--border-subtle-line); }
.icon-btn.emphasized{ background:var(--accent-wash); color:var(--accent); }
.icon-btn.emphasized:hover{ background:var(--accent); color:#fff; }
.icon-btn.destructive:hover{ background:var(--badge-error-bg); color:var(--destructive); }
.icon-btn[disabled]{ opacity:.35; cursor:not-allowed; pointer-events:none; }

/* ---- Button Group — visually joined, one shared edge ---- */
.btn-group{ display:inline-flex; }
.btn-group .mini-btn{ border-radius:var(--radius-0); margin-left:-1px; }
.btn-group .mini-btn:first-child{ border-top-left-radius:var(--r-button); border-bottom-left-radius:var(--r-button); margin-left:var(--sp-0); }
.btn-group .mini-btn:last-child{ border-top-right-radius:var(--r-button); border-bottom-right-radius:var(--r-button); }
.btn-group .mini-btn.secondary{ position:relative; }
/* Group members overlap by -1px so two borders collapse into one seam. With both sides now
   transparent the seam vanished, so the later sibling draws it — one line between two
   segments, and none on the outside of the group. It is the one grey hairline that stays,
   because without it a segmented control reads as a single wide blob. */
.btn-group .mini-btn.secondary + .mini-btn.secondary{ border-left-color:var(--border-default); }
.btn-group .mini-btn.secondary:hover{ z-index:1; }

/* ---- Split Button — action + attached disclosure ---- */
.split-btn{ display:inline-flex; }
.split-btn .mini-btn:first-child{ border-top-right-radius:var(--radius-0); border-bottom-right-radius:var(--radius-0); }
.split-btn .divider{ width:1px; align-self:stretch; background:rgba(255,255,255,.28); }
.split-btn .mini-btn.secondary + .divider{ background:var(--border-default); }  /* stays --border-default: this hairline is structure, and --divider at #F1F3F6 on a white button is invisible */
.split-btn .caret{ display:inline-flex; align-items:center; justify-content:center; width:32px; border:none; cursor:pointer; background:var(--accent); color:#fff; border-top-right-radius:var(--r-button); border-bottom-right-radius:var(--r-button);
  transition:background var(--dur-default) var(--ease-out); }
.split-btn .caret:hover{ background:var(--accent-hover); }
/* The caret keeps exactly one border — the seam against the button it belongs to — and
   transparent on the other three. box-sizing:border-box is global, so its 32px is unchanged. */
.split-btn.secondary .caret{ background:var(--bg-base); color:var(--text-secondary); border:1px solid transparent; border-left:1px solid var(--border-default); }
.split-btn.secondary .caret:hover{ background:var(--bg-canvas); }

/* ---- Link / inline action ---- */
.nv-link{ color:var(--link); font-size:var(--fs-2); font-weight:500; cursor:pointer; text-underline-offset:3px; text-decoration-thickness:1px; transition:color var(--dur-moderate) var(--ease-out); }
.nv-link:hover{ text-decoration:underline; color:var(--accent-hover); }
.nv-link.subtle{ color:var(--text-secondary); text-decoration:underline; text-decoration-color:var(--border-strong); }
.nv-link.subtle:hover{ color:var(--text-primary); text-decoration-color:var(--text-secondary); }
.nv-link.external{ display:inline-flex; align-items:center; gap:var(--sp-2); }
.nv-link.external svg{ width:12px; height:12px; }
.mini-input{ height:40px; padding:var(--sp-0) var(--sp-5); border-radius:var(--r-control); border:1px solid var(--border-default); background:var(--bg-base); font-size:var(--fs-2); color:var(--text-primary); font-family:var(--font-sans);
  transition:border-color var(--dur-default) var(--ease-out), box-shadow var(--dur-default) var(--ease-out), background var(--dur-default) var(--ease-out); }
.mini-input::placeholder{ color:var(--text-disabled); }
.mini-input:hover{ border-color:var(--border-strong); }
.mini-input:focus{ outline:none; border-color:var(--blue-500); box-shadow:var(--ring-focus); }
.mini-input.err{ border-color:#FDA29B; }
.mini-input.err:focus{ box-shadow:0 0 0 3px rgba(217,45,32,.16); }
.mini-input.success{ border-color:#6CE9A6; }
.mini-input.filled{ background:var(--bg-sunken); border-color:transparent; }
.mini-input[readonly]{ background:var(--bg-sunken); color:var(--text-secondary); cursor:default; }
.mini-input[readonly]:hover{ border-color:var(--border-default); }
.mini-input:disabled, .mini-input[disabled]{ background:var(--bg-sunken); color:var(--text-disabled); cursor:not-allowed; opacity:.65; }
.mini-input.sm{ height:32px; padding:var(--sp-0) var(--space-control-inset-sm); font-size:var(--fs-1); }
.mini-input.lg{ height:48px; padding:var(--sp-0) var(--sp-6); font-size:var(--fs-2); }

/* ---- field wrapper: label, helper/error text, icon slots ---- */
.field{ display:flex; flex-direction:column; gap:var(--sp-3); width:100%; }
.field-label{ font-size:var(--fs-1); font-weight:500; color:var(--text-primary); display:flex; align-items:center; gap:var(--sp-3); }
.field-label .opt{ font-weight:400; color:var(--text-tertiary); }
.field-help{ font-size:var(--fs-1); color:var(--text-tertiary); }
.field-help.err{ color:var(--badge-error-text); }
.field-help.ok{ color:#039855; }
.field-help.warning{ color:var(--badge-warning-text); }

/* ---- inline alert / callout ---- */
.alert{ display:flex; align-items:flex-start; gap:var(--space-inline-gap); padding:var(--sp-5) var(--space-surface-inset); border-radius:var(--r-card); border:1px solid var(--border-default); font-size:var(--fs-1); line-height:var(--lh-3); background:var(--bg-sunken); color:var(--text-primary); }
.alert svg{ width:16px; height:16px; flex-shrink:0; margin-top:1px; }
.alert .body{ flex:1; min-width:0; }
.alert .title{ font-weight:600; margin-bottom:var(--sp-1); }
.alert .actions{ display:flex; gap:var(--space-inline-gap); margin-top:var(--sp-4); }
.alert .actions a{ font-size:var(--fs-1); font-weight:600; cursor:pointer; color:inherit; text-decoration:underline; text-underline-offset:2px; }
.alert .dismiss{ display:flex; flex-shrink:0; padding:var(--sp-2); border-radius:var(--radius-6); color:inherit; opacity:.55; cursor:pointer; background:none; border:none; margin:-2px -2px -2px var(--sp-0); }
.alert .dismiss:hover{ opacity:1; background:rgba(0,0,0,.08); }
.alert .dismiss svg{ width:var(--size-icon-md); height:var(--size-icon-md); margin:var(--sp-0); }
.alert.info{ background:var(--badge-info-bg); border-color:#84CAFF; color:var(--badge-info-text); }
.alert.success{ background:var(--badge-success-bg); border-color:#6CE9A6; color:var(--badge-success-text); }
.alert.warning{ background:var(--badge-warning-bg); border-color:#FEC84B; color:var(--badge-warning-text); }
.alert.error{ background:var(--badge-error-bg); border-color:#FDA29B; color:var(--badge-error-text); }

/* ---- banner: page-level, edge-to-edge, calmer than a saturated block ---- */
.banner{ display:flex; align-items:center; gap:var(--space-inline-gap); padding:var(--sp-5) var(--sp-7); border-bottom:1px solid var(--border-default); font-size:var(--fs-2); background:var(--bg-sunken); color:var(--text-primary); }
.banner svg{ width:17px; height:17px; flex-shrink:0; }
.banner .body{ flex:1; min-width:0; }
.banner .actions{ display:flex; align-items:center; gap:var(--space-inline-gap); flex-shrink:0; }
.banner.info{ background:var(--badge-info-bg); color:var(--badge-info-text); border-bottom-color:#84CAFF; }
.banner.warning{ background:var(--badge-warning-bg); color:var(--badge-warning-text); border-bottom-color:#FEC84B; }
.banner .dismiss{ display:flex; flex-shrink:0; padding:var(--sp-2); border-radius:var(--radius-6); color:inherit; opacity:.55; cursor:pointer; background:none; border:none; }
.banner .dismiss:hover{ opacity:1; background:rgba(0,0,0,.08); }
.banner .dismiss svg{ width:14px; height:14px; }

/* ---- toast / notification ---- */
.toast{ display:flex; align-items:flex-start; gap:var(--space-inline-gap); width:300px; max-width:100%; box-sizing:border-box; padding:var(--sp-5) var(--space-surface-inset-sm); border-radius:var(--r-float); background:var(--bg-base); border:1px solid var(--border-default); box-shadow:var(--shadow-surface-hover); font-size:var(--fs-1); color:var(--text-primary); }
.toast .icon{ flex-shrink:0; width:17px; height:17px; margin-top:1px; }
.toast.success .icon{ color:var(--badge-success-text); }
.toast.info .icon{ color:var(--badge-info-text); }
.toast.warning .icon{ color:var(--badge-warning-text); }
.toast.error .icon{ color:var(--badge-error-text); }
.toast .body{ flex:1; min-width:0; }
.toast .title{ font-weight:600; }
.toast .desc{ color:var(--text-secondary); font-size:var(--fs-1); margin-top:var(--sp-1); line-height:var(--lh-3); }
.toast .actions{ margin-top:var(--sp-4); display:flex; gap:var(--space-inline-gap); }
.toast .actions a{ font-size:var(--fs-1); font-weight:600; cursor:pointer; color:var(--accent); }
.toast .dismiss{ display:flex; flex-shrink:0; padding:var(--sp-2); border-radius:var(--radius-6); color:var(--text-tertiary); opacity:.7; cursor:pointer; background:none; border:none; margin:-3px -3px var(--sp-0) var(--sp-0); }
.toast .dismiss:hover{ opacity:1; background:var(--bg-sunken); }
.toast .dismiss svg{ width:var(--size-icon-md); height:var(--size-icon-md); }
.toast-stack{ display:flex; flex-direction:column; position:relative; }
.toast-stack .toast{ position:relative; }
.toast-stack .toast:not(:first-child){ margin-top:-38px; }
.toast-stack .toast:nth-child(1){ z-index:3; }
.toast-stack .toast:nth-child(2){ transform:scale(.97) translateY(-4px); opacity:.7; z-index:2; }
.toast-stack .toast:nth-child(3){ transform:scale(.94) translateY(-8px); opacity:.4; z-index:1; }

/* ---- tooltip: arrowed bubble, direction-aware ---- */
.tooltip-demo{ display:inline-flex; flex-direction:column; align-items:center; }
.tooltip-demo .bubble{ background:var(--n-950); color:#fff; box-shadow:0 0 0 1px rgba(255,255,255,.14), var(--shadow-surface-rest); font-size:var(--fs-1); padding:var(--sp-3) var(--space-control-inset-sm); border-radius:var(--radius-16); white-space:nowrap; position:relative; }
.tooltip-demo .bubble::after{ content:''; position:absolute; width:7px; height:7px; background:var(--n-950); transform:rotate(45deg); }
.tooltip-demo.top .bubble::after{ bottom:-3px; left:50%; margin-left:-3.5px; }
.tooltip-demo.bottom .bubble::after{ top:-3px; left:50%; margin-left:-3.5px; }
.tooltip-demo.left .bubble::after{ right:-3px; top:50%; margin-top:-3.5px; }
.tooltip-demo.right .bubble::after{ left:-3px; top:50%; margin-top:-3.5px; }

/* The working tooltip behind the specimen above. One shared node on position:fixed —
   an absolutely-positioned child would be clipped by .ash-side's overflow:hidden,
   and is unusable once that rail collapses to 64px. Behaviour follows this page's
   own contract: ~400ms hover delay, immediate on keyboard focus, dismissed by
   Escape, blur or mouse-leave. */
#tip{ position:fixed; z-index:200; top:0; left:0; display:flex; flex-direction:column; align-items:flex-start; gap:1px;
  background:var(--n-950); color:#fff; font-size:var(--fs-1); line-height:1.35;
  padding:var(--sp-3) var(--space-control-inset-sm); border-radius:var(--radius-16);
  white-space:nowrap; pointer-events:none; opacity:0; transform:translateY(-3px);
  /* the bubble is --n-950; in dark that sits on --bg-base (--n-900) at 1.13:1, so it needs
     its own edge to separate from the surface behind it. */
  box-shadow:0 0 0 1px rgba(255,255,255,.14), var(--shadow-surface-rest);
  transition:opacity var(--dur-moderate) var(--ease-out), transform var(--dur-moderate) var(--ease-out); }
#tip[data-show]{ opacity:1; transform:translateY(0); }
#tip .row{ display:flex; align-items:center; gap:var(--sp-4); }
#tip .kbd{ font-size:10.5px; font-weight:500; padding:1px var(--sp-3); border-radius:var(--radius-6);
  background:rgba(255,255,255,.16); color:#fff; border:none; }
#tip .sub{ font-size:10.5px; color:var(--n-400); }

/* ---- empty state: full, page-level version — see Data Display for the inline/per-cell version ---- */
.empty-state{ display:flex; flex-direction:column; align-items:center; text-align:center; padding:var(--sp-10) var(--sp-8); gap:var(--sp-2); }
.empty-state .icon{ width:38px; height:38px; color:var(--text-disabled); margin-bottom:var(--space-label-gap); }
.empty-state .title{ font-size:var(--fs-2); font-weight:600; color:var(--text-primary); }
.empty-state .desc{ font-size:var(--fs-1); color:var(--text-tertiary); max-width:300px; line-height:var(--lh-3); }
.empty-state .actions{ display:flex; gap:var(--space-inline-gap); margin-top:var(--sp-6); }
.field-shell{ position:relative; display:flex; align-items:center; }
/* Hero SearchField stroke — v1.33: a solid 1px --border-default stroke; on focus the stroke takes the field focus colour and the
   standard --ring-focus, exactly as every other input. No gradient, no flowing animation. */
.hero-search-wrap{ background:var(--border-default); transition:background var(--dur-default) var(--ease-out), box-shadow var(--dur-default) var(--ease-out); }
.hero-search-wrap:focus-within{ padding:1px; background:var(--blue-500); box-shadow:var(--ring-focus); }
.hero-search-wrap:focus-within .mini-input:focus{ box-shadow:none; }
/* AI Search — Dark: the same solid stroke, in the dark-surface neutral it sits on. */
.hero-search-wrap.ai-search-wrap{ background:var(--n-700); }
.field-shell .mini-input{ width:100%; }
.field-shell.has-leading .mini-input{ padding-left:var(--space-input-affix-clearance); }
.field-shell.has-trailing .mini-input{ padding-right:var(--space-input-affix-clearance); }
.field-icon{ position:absolute; top:50%; transform:translateY(-50%); display:flex; align-items:center; justify-content:center; width:16px; height:16px; color:var(--text-tertiary); pointer-events:none; }
.field-icon.leading{ left:12px; }
.field-icon.trailing{ right:12px; }
.field-icon-btn{ position:absolute; right:6px; width:26px; height:26px; border-radius:var(--radius-8); border:none; background:transparent; color:var(--text-tertiary); display:flex; align-items:center; justify-content:center; cursor:pointer; transition:background var(--dur-moderate) var(--ease-out), color var(--dur-moderate) var(--ease-out); }
.field-icon-btn:hover{ background:var(--bg-sunken); color:var(--text-primary); }
.field-icon-btn svg{ width:14px; height:14px; }
.field-kbd{ position:absolute; right:9px; font-size:10.5px; padding:var(--sp-1) var(--sp-3); border-radius:var(--radius-6); background:var(--bg-sunken); border:1px solid var(--border-default); color:var(--text-tertiary); pointer-events:none; }

/* ---- textarea ---- */
.mini-textarea{ min-height:88px; padding:var(--space-label-gap) var(--sp-5); border-radius:var(--r-card); border:1px solid var(--border-default); background:var(--bg-base); font-size:var(--fs-2); color:var(--text-primary); font-family:var(--font-sans); resize:vertical; line-height:var(--lh-3);
  transition:border-color var(--dur-default) var(--ease-out), box-shadow var(--dur-default) var(--ease-out); }
.mini-textarea:hover{ border-color:var(--border-strong); }
.mini-textarea:focus{ outline:none; border-color:var(--blue-500); box-shadow:var(--ring-focus); }
.char-count{ align-self:flex-end; font-size:var(--fs-1); color:var(--text-tertiary); font-variant-numeric:tabular-nums; }
.char-count.warn{ color:#B54708; }

/* ---- number stepper ---- */
.field-shell.stepper .mini-input{ padding-right:var(--sp-56); text-align:left; font-variant-numeric:tabular-nums; }
.stepper-ctrl{ position:absolute; right:1px; top:1px; bottom:1px; display:flex; flex-direction:column; width:26px; border-left:1px solid var(--border-default); border-radius:var(--radius-0) var(--r-control-sm) var(--r-control-sm) 0; overflow:hidden; }
.stepper-ctrl button{ flex:1; border:none; background:var(--bg-sunken); color:var(--text-secondary); cursor:pointer; display:flex; align-items:center; justify-content:center; transition:background var(--dur-moderate) var(--ease-out); }
.stepper-ctrl button:hover{ background:var(--border-subtle-line); color:var(--text-primary); }
.stepper-ctrl button:first-child{ border-bottom:1px solid var(--border-default); }
.stepper-ctrl svg{ width:9px; height:9px; }
.field-suffix{ position:absolute; right:12px; font-size:var(--fs-1); color:var(--text-tertiary); pointer-events:none; }

/* ---- select / combobox ---- */
.mini-select{ display:flex; align-items:center; justify-content:space-between; gap:var(--sp-4); height:40px; padding:var(--sp-0) var(--sp-5); border-radius:var(--r-control); border:1px solid var(--border-default); background:var(--bg-base); font-size:var(--fs-2); color:var(--text-primary); cursor:pointer;
  transition:border-color var(--dur-default) var(--ease-out), box-shadow var(--dur-default) var(--ease-out); }
.mini-select:hover{ border-color:var(--border-strong); }
.mini-select.open, .mini-select:focus{ outline:none; border-color:var(--blue-500); box-shadow:var(--ring-focus); }
.mini-select.placeholder{ color:var(--text-disabled); }
.mini-select .chev{ width:14px; height:14px; color:var(--text-tertiary); flex-shrink:0; }
.select-menu{ border:1px solid transparent; border-radius:var(--radius-24); background:var(--bg-base); box-shadow:var(--shadow-surface-hover); padding:var(--sp-3); margin-top:var(--sp-3); }  /* an overlay already lifted by --shadow-surface-hover, the strongest surface shadow in the set — that is the edge. In dark it also has real fill contrast (--bg-base n-900 over an n-950 canvas), so nothing depends on the hairline. */
.select-menu .opt{ display:flex; align-items:center; justify-content:space-between; padding:var(--sp-4) var(--space-menu-row-inset); border-radius:var(--radius-24); font-size:var(--fs-1); color:var(--text-secondary); cursor:pointer; }
.select-menu .opt:hover{ background:var(--bg-sunken); color:var(--text-primary); }
.select-menu .opt.selected{ background:var(--accent-wash); color:var(--accent); font-weight:500; }
.select-menu .opt.selected svg{ width:14px; height:14px; }
.select-menu .opt.disabled{ color:var(--text-disabled); cursor:not-allowed; }
.select-multi-tag{ display:inline-flex; align-items:center; gap:var(--sp-2); padding:var(--sp-1) var(--sp-2) var(--sp-1) var(--sp-4); border-radius:var(--r-chip); background:var(--accent-wash); color:var(--accent); font-size:var(--fs-1); }
.select-multi-tag button{ border:none; background:transparent; color:inherit; cursor:pointer; display:flex; padding:var(--sp-1); }

/* ---- file / upload ---- */
.dropzone{ border:1.5px dashed var(--border-strong); border-radius:var(--r-panel); background:var(--bg-canvas); padding:var(--sp-9); display:flex; flex-direction:column; align-items:center; gap:var(--sp-4); text-align:center; cursor:pointer;
  transition:border-color var(--dur-default) var(--ease-out), background var(--dur-default) var(--ease-out); }
.dropzone:hover{ border-color:var(--accent); background:var(--accent-wash); }
.dropzone.dragover{ border-color:var(--accent); background:var(--accent-wash); border-style:solid; }
.dropzone.err{ border-color:#FDA29B; background:#FEF3F2; }
.dropzone svg{ width:22px; height:22px; color:var(--text-tertiary); }
.upload-row{ display:flex; align-items:center; flex-wrap:wrap; gap:var(--space-inline-gap); padding:var(--space-label-gap) var(--sp-5); border:1px solid var(--border-default); border-radius:var(--r-control); background:var(--bg-base); }
.upload-row .bar{ flex:1; height:6px; border-radius:var(--r-pill); background:var(--bg-sunken); overflow:hidden; }
.upload-row .bar > span{ display:block; height:100%; background:var(--accent); border-radius:inherit; }
/* ---- checkbox ---- */
.mini-check{ appearance:none; -webkit-appearance:none; margin:var(--sp-0); width:18px; height:18px; border-radius:var(--r-chip); border:1.5px solid var(--border-strong); background:var(--bg-base); display:inline-flex; align-items:center; justify-content:center; cursor:pointer; flex-shrink:0;
  transition:background var(--dur-default) var(--ease-out), border-color var(--dur-default) var(--ease-out), transform var(--dur-fast) var(--ease-out); }
.mini-check svg{ width:var(--size-icon-sm); height:var(--size-icon-sm); color:#fff; opacity:0; transform:scale(.6); transition:opacity var(--dur-moderate) var(--ease-out), transform var(--dur-moderate) var(--ease-lift); }
.mini-check:hover{ border-color:var(--text-tertiary); background:var(--bg-sunken); }
.mini-check:active{ transform:scale(.9); }
.mini-check.on{ background:var(--accent); border-color:var(--accent); }
.mini-check.on svg{ opacity:1; transform:scale(1); }
.mini-check.indeterminate{ background:var(--accent); border-color:var(--accent); }
.mini-check.indeterminate svg{ display:none; }
.mini-check.indeterminate:after{ content:''; width:9px; height:1.5px; border-radius:1px; background:#fff; }
.mini-check.err{ border-color:#FDA29B; }
.mini-check.disabled{ opacity:.5; cursor:not-allowed; pointer-events:none; }
.mini-check.on.disabled{ opacity:.42; }

/* ---- radio ---- */
.mini-radio{ width:18px; height:18px; border-radius:50%; border:1.5px solid var(--border-strong); background:var(--bg-base); display:inline-flex; align-items:center; justify-content:center; cursor:pointer; flex-shrink:0;
  transition:border-color var(--dur-default) var(--ease-out), transform var(--dur-fast) var(--ease-out); }
.mini-radio:hover{ border-color:var(--text-tertiary); }
.mini-radio:active{ transform:scale(.9); }
.mini-radio.on{ border-color:var(--accent); }
.mini-radio.on:after{ content:''; width:8px; height:8px; border-radius:50%; background:var(--accent); transition:transform var(--dur-moderate) var(--ease-lift); }
.mini-radio.err{ border-color:#FDA29B; }
.mini-radio.disabled{ opacity:.5; cursor:not-allowed; pointer-events:none; }
.mini-radio.on.disabled{ opacity:.42; }

/* ---- switch ---- */
.mini-switch{ width:34px; height:20px; border-radius:var(--r-pill); background:var(--border-strong); position:relative; display:inline-block; cursor:pointer; flex-shrink:0;
  transition:background var(--dur-default) var(--ease-out); }
.mini-switch:hover{ background:var(--text-disabled); }
.mini-switch .knob{ width:16px; height:16px; border-radius:50%; background:#fff; position:absolute; top:2px; left:2px; transition:left var(--dur-default) var(--ease-lift), width var(--dur-moderate) var(--ease-out); box-shadow:0 1px 2px rgba(0,0,0,.18); }
.mini-switch:active .knob{ width:19px; }
.mini-switch.on{ background:var(--accent); }
.mini-switch.on .knob{ left:16px; }
.mini-switch.on:active .knob{ left:13px; }
.mini-switch.disabled{ opacity:.5; cursor:not-allowed; pointer-events:none; }
.mini-switch.on.disabled{ opacity:.42; }

/* ---- segmented control ---- */
/* The track is a surface, not a well: --bg-base, so it is white in light instead of the grey
   --bg-sunken it used to be. This also fixes dark by accident — sunken resolves to the same
   #0B0D10 as the canvas there, so the track had been invisible except for its border; --bg-base
   is #181B20, a real step above the canvas.
   The border STAYS here, unlike the pills and tags: a white track on a white page has no other
   boundary, and the control's extent is exactly what a segmented control has to show — where
   the unselected options end. It is load-bearing, not decoration. */
.seg-control{ position:relative; display:inline-flex; padding:var(--sp-2); border-radius:var(--r-control); background:var(--bg-base); border:1px solid var(--border-default); gap:var(--sp-1); }
.seg-control.compact{ padding:var(--sp-1); gap:1px; } /* radius deliberately NOT restated: the base rule already carries --r-control/-sm, which Radius defines as 999px pill for dense chrome since the Aura update. */
.seg-option{ position:relative; z-index:1; display:flex; align-items:center; gap:var(--sp-3); padding:var(--sp-0) var(--space-surface-inset); height:30px; border-radius:var(--r-control-sm); font-size:var(--fs-1); font-weight:500; color:var(--text-secondary); cursor:pointer; white-space:nowrap; background:none; border:none; font-family:var(--font-sans);
  transition:color var(--dur-default) var(--ease-out), background var(--dur-default) var(--ease-out); }
.seg-control.compact .seg-option{ height:24px; padding:var(--sp-0) var(--space-control-inset-sm); font-size:var(--fs-1); }
.seg-option svg{ width:14px; height:14px; flex-shrink:0; }
.seg-option:hover{ color:var(--text-primary); background:var(--border-default); }
.seg-option.active{ color:#fff; }
.seg-option.active:hover{ background:none; }
.seg-option.disabled{ color:var(--text-disabled); cursor:not-allowed; }
.seg-option.disabled:hover{ background:none; }
.seg-thumb{ position:absolute; top:3px; bottom:3px; border-radius:var(--r-control-sm); background:var(--accent); box-shadow:var(--shadow-surface-rest);
  transition:left var(--dur-moderate) var(--ease-lift), width var(--dur-moderate) var(--ease-lift); }
.seg-control.compact .seg-thumb{ top:2px; bottom:2px; }
@media (prefers-reduced-motion: reduce){ .seg-thumb{ transition:none; } }

/* ---- chips ---- */
.chip-opt{ display:inline-flex; align-items:center; gap:var(--sp-3); padding:var(--sp-3) var(--sp-5); border-radius:var(--r-pill); font-size:var(--fs-1); font-weight:500; border:1px solid var(--border-default); background:var(--bg-base); color:var(--text-secondary); cursor:pointer;
  transition:background var(--dur-default) var(--ease-out), border-color var(--dur-default) var(--ease-out), color var(--dur-default) var(--ease-out); }
.chip-opt svg{ width:var(--size-icon-md); height:var(--size-icon-md); flex-shrink:0; }
.chip-opt:hover{ border-color:var(--border-strong); background:var(--bg-sunken); }
.chip-opt.selected{ background:var(--accent-wash); border-color:var(--accent); color:var(--accent); }
.chip-opt.disabled{ opacity:.5; cursor:not-allowed; pointer-events:none; }
.chip-opt .rm{ display:flex; align-items:center; justify-content:center; margin:-2px -4px -2px var(--sp-1); padding:var(--sp-1); border:none; background:none; border-radius:50%; color:inherit; opacity:.65; cursor:pointer; -webkit-appearance:none; appearance:none; }
.chip-opt .rm:hover{ opacity:1; background:color-mix(in srgb, var(--text-primary) 8%, transparent); }
.mini-badge{ display:inline-flex; align-items:center; gap:var(--sp-3); padding:var(--sp-2) var(--sp-4); border-radius:var(--r-pill); font-size:var(--fs-1); font-weight:500; }
.mini-badge.success{ background:var(--badge-success-bg); color:var(--badge-success-text); } .mini-badge.warning{ background:var(--badge-warning-bg); color:var(--badge-warning-text); }
.mini-badge.error{ background:var(--badge-error-bg); color:var(--badge-error-text); } .mini-badge.info{ background:var(--badge-info-bg); color:var(--badge-info-text); }
.mini-badge.neutral{ background:var(--badge-neutral-bg); color:var(--badge-neutral-text); }
.mini-avatar{ width:32px; height:32px; border-radius:50%; background:var(--n-800); color:#fff; display:inline-flex; align-items:center; justify-content:center; font-size:var(--fs-1); font-weight:600; }
.mini-tag{ display:inline-flex; align-items:center; padding:var(--sp-2) var(--space-control-inset-sm); border-radius:var(--r-pill); font-size:var(--fs-1); background:var(--bg-track); color:var(--text-secondary); border:1px solid transparent; }  /* same as the pills above: fill carries it, border kept transparent for geometry, --bg-track so it survives dark */
.mini-card{ border:1px solid var(--border-default); border-radius:var(--r-card); background:var(--bg-base); padding:var(--sp-6); width:200px; }
.mini-tooltip{ background:var(--n-950); color:#fff; font-size:var(--fs-1); padding:var(--sp-3) var(--space-control-inset-sm); border-radius:var(--radius-8); }

/* ---- badge extensions ---- */
.mini-badge.sm{ padding:var(--sp-1) var(--sp-4); font-size:10.5px; }
.mini-badge .bdot{ width:6px; height:6px; border-radius:50%; background:currentColor; flex-shrink:0; }
.mini-badge.live{ background:#F8FEE7; color:#385618; }
.mini-badge.live .bdot{ background:#C6F35F; }
:root[data-theme="dark"] .mini-badge.live{ background:rgba(198,243,95,.14); color:#C6F35F; }
.mini-badge.muted{ opacity:.55; }

/* ---- status family: dot, label row, and text-only, all reading off the same
   verified semantic roles as Badge — never a new color, just a lighter-weight
   presentation for denser contexts than a full pill affords. ---- */
.status-dot{ display:inline-block; width:7px; height:7px; border-radius:50%; flex-shrink:0; }
.status-dot.neutral{ background:var(--text-disabled); }
.status-dot.info{ background:var(--badge-info-text); }
.status-dot.success{ background:var(--badge-success-text); }
.status-dot.warning{ background:var(--badge-warning-text); }
.status-dot.error{ background:var(--badge-error-text); }
.status-dot.live{ background:#C6F35F; position:relative; }
/* ---- Aura update: live-pulse ring — the system's only "process running now" affordance ---- */
.status-dot.live::after{ content:''; position:absolute; inset:-6px; border-radius:50%; background:#C6F35F; animation:navo-live-pulse 2s cubic-bezier(.22,.61,.36,1) infinite; }
@keyframes navo-live-pulse{ 0%{ transform:scale(1); opacity:.55; } 70%{ transform:scale(2.6); opacity:0; } 100%{ transform:scale(2.6); opacity:0; } }
@media (prefers-reduced-motion: reduce){ .status-dot.live::after{ animation:none; opacity:.3; } }
.status-row{ display:inline-flex; align-items:center; gap:var(--sp-3); font-size:var(--fs-1); font-weight:500; color:var(--text-primary); }
.status-row.sm{ font-size:var(--fs-1); gap:var(--sp-3); }
.status-row.sm .status-dot{ width:6px; height:6px; }
.status-row.muted{ opacity:.55; }
.status-text{ font-size:var(--fs-1); font-weight:500; }
.status-text.neutral{ color:var(--text-tertiary); }
.status-text.info{ color:var(--badge-info-text); }
.status-text.success{ color:var(--badge-success-text); }
.status-text.warning{ color:var(--badge-warning-text); }
.status-text.error{ color:var(--badge-error-text); }
.status-meta{ color:var(--text-tertiary); font-weight:400; }
.status-meta::before{ content:'·'; margin:var(--sp-0) var(--sp-3); color:var(--text-disabled); font-weight:400; }

/* ---- tag extensions ---- */
.mini-tag.dismissible{ padding-right:var(--sp-2); gap:var(--sp-3); }
.mini-tag .rm{ display:flex; align-items:center; justify-content:center; padding:var(--sp-1); border:none; background:none; border-radius:50%; color:inherit; opacity:.6; cursor:pointer; -webkit-appearance:none; appearance:none; }
.mini-tag .rm:hover{ opacity:1; background:color-mix(in srgb, var(--text-primary) 8%, transparent); }
.mini-tag.metadata{ background:transparent; border-style:dashed; border-color:var(--border-default); color:var(--text-tertiary); font-variant-numeric:tabular-nums; }  /* the ONE mini-tag that keeps a visible border: a dashed edge on no fill is this variant's whole identity, and the base colour is transparent now, so it has to say its own */
.mini-tag.status-adjacent{ display:inline-flex; align-items:center; gap:var(--sp-3); }
.mini-tag.status-adjacent .tdot{ width:6px; height:6px; border-radius:50%; flex-shrink:0; }
.mini-tag.truncate{ max-width:110px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; display:inline-block; }
.mini-tag.live{ display:inline-flex; align-items:center; gap:var(--sp-4); padding:var(--sp-5) var(--sp-7); border-radius:var(--r-pill); font-size:var(--fs-2); font-weight:600; color:var(--text-primary); border:1px solid var(--badge-live-border);
  background:var(--badge-live-bg);
  box-shadow:var(--shadow-2); }
.mini-tag.live .status-dot{ width:10px; height:10px; }

/* ---- avatar / entity marker ---- */
.mini-avatar.icon{ background:var(--bg-sunken); color:var(--text-secondary); }
.mini-avatar.icon svg{ width:var(--size-icon-lg); height:var(--size-icon-lg); }
.mini-avatar.image{ background-size:cover; background-position:center; color:transparent; }
.mini-avatar.fallback{ background:var(--n-200); color:var(--text-tertiary); border:1px dashed var(--border-strong); }
.avatar-stack{ display:flex; }
.avatar-stack .mini-avatar{ width:28px; height:28px; font-size:var(--fs-1); border:2px solid var(--bg-base); margin-left:-8px; }
.avatar-stack .mini-avatar:first-child{ margin-left:var(--sp-0); }
.avatar-stack .mini-avatar.more{ background:var(--bg-sunken); color:var(--text-tertiary); }

/* ---- KPI / metric ---- */
.kpi{ display:flex; flex-direction:column; gap:var(--sp-3); }
.kpi .lbl{ font-size:var(--fs-1); color:var(--text-tertiary); font-weight:500; }
.kpi .val{ font-family:var(--font-display); font-size:var(--fs-7); font-weight:600; font-variant-numeric:tabular-nums; color:var(--text-primary); letter-spacing:var(--ls-3); }
.kpi.compact .val{ font-size:var(--fs-4); }
.kpi.hero .val{ font-size:var(--fs-10); }
.kpi .delta{ display:inline-flex; align-items:center; gap:var(--sp-2); font-size:var(--fs-1); font-weight:500; font-variant-numeric:tabular-nums; }
.kpi .delta svg{ width:12px; height:12px; }
.kpi .delta.up{ color:var(--badge-success-text); }
.kpi .delta.down{ color:var(--badge-error-text); }
/* v1.33 — sentiment is the judgement, separate from the arrow's direction: "−3 delayed shipments"
   is direction down, sentiment good. With a sentiment class it wins over the legacy up/down colour. */
.kpi .delta.good{ color:var(--badge-success-text); }
.kpi .delta.bad{ color:var(--badge-error-text); }
.kpi .delta.neutral{ color:var(--text-secondary); }
.kpi .meta{ font-size:var(--fs-1); color:var(--text-tertiary); }

/* ---- key-value / description list ---- */
.kv-list{ display:flex; flex-direction:column; }
.kv-row{ display:flex; align-items:baseline; gap:var(--sp-6); padding:var(--sp-4) var(--sp-0); border-bottom:1px solid var(--border-default); }
.kv-row:last-child{ border-bottom:none; }
.kv-row .k{ flex:0 0 140px; font-size:var(--fs-1); color:var(--text-tertiary); }
.kv-row .v{ flex:1; font-size:var(--fs-1); color:var(--text-primary); font-variant-numeric:tabular-nums; }
.kv-list.stacked .kv-row{ flex-direction:column; gap:var(--sp-2); }
.kv-list.stacked .kv-row .k{ flex:none; }
.kv-list.compact .kv-row{ padding:var(--sp-3) var(--sp-0); }
.kv-list.compact .kv-row .k{ flex-basis:100px; font-size:var(--fs-1); }
.kv-list.compact .kv-row .v{ font-size:var(--fs-1); }

/* ---- timeline / event item ---- */
.timeline{ display:flex; flex-direction:column; }
.tl-item{ display:flex; gap:var(--sp-5); }
.tl-rail{ display:flex; flex-direction:column; align-items:center; }
.tl-dot{ width:10px; height:10px; border-radius:50%; background:var(--border-strong); flex-shrink:0; margin-top:var(--sp-2); }
.tl-item.completed .tl-dot{ background:var(--accent); }
.tl-item.current .tl-dot{ background:var(--accent); box-shadow:0 0 0 3px var(--accent-wash); }
.tl-item.delayed .tl-dot{ background:var(--badge-warning-text); }
.tl-line{ width:1.5px; flex:1; background:var(--border-default); min-height:24px; margin-top:var(--sp-1); }
.tl-item.completed .tl-line{ background:var(--accent); }
.tl-content{ padding-bottom:var(--sp-7); display:flex; flex-direction:column; gap:var(--sp-1); }
.tl-item:last-child .tl-content{ padding-bottom:var(--sp-0); }
.tl-content .t{ font-size:var(--fs-2); font-weight:500; color:var(--text-primary); }
.tl-item.upcoming .tl-content .t{ color:var(--text-tertiary); font-weight:400; }
.tl-content .ts{ font-size:var(--fs-1); color:var(--text-tertiary); font-variant-numeric:tabular-nums; }
.tl-content .m{ font-size:var(--fs-1); color:var(--text-secondary); }
.tl-item.delayed .tl-content .m{ color:var(--badge-warning-text); }

/* ---- progress ---- */
.prog-linear{ height:6px; border-radius:var(--r-pill); background:var(--bg-track); box-shadow:inset 0 0 0 1px var(--border-default); overflow:hidden; }
.prog-linear > span{ display:block; height:100%; border-radius:inherit; background:var(--accent); transition:width var(--dur-slow) var(--ease-out); }
.prog-linear.success > span{ background:var(--badge-success-text); }
.prog-linear.warning > span{ background:var(--badge-warning-text); }
.prog-linear.error > span{ background:var(--badge-error-text); }
.prog-linear.indeterminate > span{ width:35%!important; animation:prog-indeterminate 1.4s ease-in-out infinite; }
@keyframes prog-indeterminate{ 0%{ margin-left:-35%; } 100%{ margin-left:100%; } }
@media (prefers-reduced-motion: reduce){ .prog-linear.indeterminate > span{ animation:none; margin-left:var(--sp-0); width:35%!important; } }
.prog-circle{ transform:rotate(-90deg); }
.prog-circle .track{ fill:none; stroke:var(--bg-track); }
.prog-circle .fill{ fill:none; stroke:var(--accent); stroke-linecap:round; }
.prog-circle-wrap{ position:relative; display:inline-flex; align-items:center; justify-content:center; }
.prog-circle-wrap .val{ position:absolute; font-size:var(--fs-1); font-weight:600; font-variant-numeric:tabular-nums; color:var(--text-primary); }
.bar-chart{ display:flex; align-items:flex-end; gap:var(--sp-3); height:64px; }
.bar-chart-col{ flex:1; min-width:12px; border-radius:var(--radius-6) var(--radius-6) 0 0; background:var(--bg-track); }
.bar-chart-col.active{ background:var(--accent); }
.radar-chart{ position:relative; width:140px; height:140px; border-radius:50%; background:var(--bg-sunken); overflow:hidden; }
.radar-chart svg{ width:100%; height:100%; }
.radar-chart .ring{ fill:none; stroke:var(--border-default); }
.radar-chart .grid{ stroke:var(--border-subtle-line); }
.radar-chart .sweep{ transform-origin:50% 50%; animation:spin 4s linear infinite; }
.radar-chart .sweep path{ filter:blur(1.5px); opacity:.25; }
.radar-chart .center-dot{ fill:var(--text-primary); filter:drop-shadow(0 0 3px var(--text-primary)); }
.radar-chart .blip{ animation:navo-blip-pulse 2.4s ease-in-out infinite; }
@keyframes navo-blip-pulse{ 0%,100%{ opacity:.4; } 50%{ opacity:1; } }
.radar-chart .blip-ping{ transform-box:fill-box; transform-origin:50% 50%; animation:navo-blip-ping 2.6s ease-out infinite; }
@keyframes navo-blip-ping{ 0%{ transform:scale(.5); opacity:.7; } 100%{ transform:scale(2.8); opacity:0; } }
.radar-card:hover .radar-chart .sweep{ animation-duration:1.3s; }
.radar-card:hover .radar-chart .blip{ animation-duration:1.2s; }
:root[data-theme="dark"] .radar-chart .sweep path{ opacity:.45; }
@media (prefers-reduced-motion: reduce){ .radar-chart .sweep{ animation:none; } .radar-chart .blip{ animation:none; } .radar-chart .blip-ping{ animation:none; opacity:0; } }
.util-grid{ display:grid; grid-template-columns:repeat(6,1fr); gap:var(--sp-2); }
.util-grid .cell{ aspect-ratio:1; border-radius:var(--radius-6); background:var(--bg-track); }
.util-grid .cell.filled{ background:var(--accent); }
.util-grid .cell.partial{ background:var(--accent-wash); }
.iso-stack{ width:100%; height:auto; overflow:visible; }
.iso-cube{ transform-box:fill-box; transform-origin:50% 100%; transition:transform .18s var(--ease-lift), filter .18s var(--ease-lift); cursor:pointer; }
.iso-cube:hover{ transform:translateY(-5px); filter:brightness(1.3); }
.iso-cube-drop{ animation:iso-load .3s var(--ease-lift) both; transform-box:fill-box; transform-origin:50% 100%; }
.pack-card:hover .iso-cube-drop{ animation:iso-load-repack .25s var(--ease-lift) backwards; }
@keyframes iso-load{ 0%{ opacity:0; transform:translateY(-14px); } 100%{ opacity:1; transform:translateY(0); } }
@keyframes iso-load-repack{ 0%{ opacity:0; transform:translateY(-14px); } 100%{ opacity:1; transform:translateY(0); } }
@media (prefers-reduced-motion: reduce){ .iso-cube{ transition:none; } .iso-cube:hover{ transform:none; filter:none; } .iso-cube-drop{ animation:none; } .pack-card:hover .iso-cube-drop{ animation:none; } }

/* ---- Dashboard widgets: illustrated cards (ship / crane / mcp-connect / radar-detail) ---- */
.dash-ship{ animation:navo-ship-bob 4.5s ease-in-out infinite; }
@keyframes navo-ship-bob{ 0%,100%{ transform:translateY(0); } 50%{ transform:translateY(-2.5px); } }
.dash-wake{ animation:navo-wake-pulse 2.4s ease-in-out infinite; }
@keyframes navo-wake-pulse{ 0%,100%{ opacity:.3; } 50%{ opacity:.85; } }
.dash-route-flow{ stroke-dasharray:7 220; animation:navo-route-sail 3.2s linear infinite; }
@keyframes navo-route-sail{ 0%{ stroke-dashoffset:227; } 100%{ stroke-dashoffset:0; } }

.mcp-connect-card .mcp-client-box{ transition:stroke var(--dur-default) var(--ease-out); }
.mcp-connect-card:hover .mcp-client-box{ animation:navo-client-glow 1.6s ease-in-out infinite; }
@keyframes navo-client-glow{ 0%,100%{ stroke:var(--border-default); } 50%{ stroke:var(--blue-400); } }
.mcp-flow{ stroke-dasharray:6 184; animation:navo-mcp-flow 2.2s linear infinite; }
@keyframes navo-mcp-flow{ 0%{ stroke-dashoffset:190; } 100%{ stroke-dashoffset:0; } }
.mcp-connect-card:hover .mcp-flow{ animation-duration:1s; }
.mcp-orb{ animation:navo-orb-pulse 3s ease-in-out infinite; }
@keyframes navo-orb-pulse{ 0%,100%{ stroke-opacity:.6; } 50%{ stroke-opacity:1; } }

.accordion-trigger{ width:100%; background:none; border:none; display:flex; align-items:center; justify-content:space-between; gap:var(--sp-5); cursor:pointer; text-align:left; color:inherit; font:inherit; }
.accordion-icon{ flex-shrink:0; transition:transform var(--dur-default) var(--ease-out); }
.accordion-item.open .accordion-icon{ transform:rotate(45deg); }
.accordion-panel{ max-height:0; overflow:hidden; transition:max-height var(--dur-default) var(--ease-out); }
@media (prefers-reduced-motion: reduce){ .accordion-icon{ transition:none; } .accordion-panel{ transition:none; } }

/* Port congestion crane: a continuous 7s discharge/load cycle — trolley travels to the pier and
   back, hoist + cable lower and raise twice per cycle (once for the 40ft discharge, once for the
   20ft backhaul), and the four cargo pieces (40ft, 20ft, pier chassis, vessel slot) step in and out
   of view on the same timeline rather than tweening — a crane doesn't fade a container in, it's
   either on the hook, on the ground, or not there yet. */
.crane-card .dc-trolley{ animation:navo-dc-trolley 7s ease-in-out infinite; }
.crane-card .dc-hoist{ animation:navo-dc-hoist 7s ease-in-out infinite; }
.crane-card .dc-cable{ transform-box:fill-box; transform-origin:50% 0%; animation:navo-dc-cable 7s ease-in-out infinite; }
.crane-card .dc-load40{ animation:navo-dc-load40 7s step-end infinite; }
.crane-card .dc-load20{ animation:navo-dc-load20 7s step-end infinite; }
.crane-card .dc-pierexport{ animation:navo-dc-pierexport 7s step-end infinite; }
.crane-card .dc-shipplaced{ animation:navo-dc-shipplaced 7s step-end infinite; }
@keyframes navo-dc-trolley{ 0%,10%{ transform:translateX(0); } 38%,58%{ transform:translateX(-80px); } 86%,100%{ transform:translateX(0); } }
@keyframes navo-dc-hoist{ 0%{ transform:translateY(23px); } 9%,38%{ transform:translateY(0); } 46%,54%{ transform:translateY(23px); } 62%,86%{ transform:translateY(0); } 94%,100%{ transform:translateY(23px); } }
@keyframes navo-dc-cable{ 0%{ transform:scaleY(1); } 9%,38%{ transform:scaleY(.32); } 46%,54%{ transform:scaleY(1); } 62%,86%{ transform:scaleY(.32); } 94%,100%{ transform:scaleY(1); } }
@keyframes navo-dc-load40{ 0%{ opacity:1; } 49%{ opacity:0; } 96%{ opacity:1; } }
@keyframes navo-dc-load20{ 0%{ opacity:0; } 53%{ opacity:1; } 90%{ opacity:0; } }
@keyframes navo-dc-pierexport{ 0%{ opacity:0; } 50%{ opacity:1; } 53%{ opacity:0; } }
@keyframes navo-dc-shipplaced{ 0%{ opacity:1; } 6%{ opacity:0; } 90%{ opacity:1; } }

/* Widget kicker header — a category dot + mono uppercase "domain · surface" label, optionally an
   status-row on the right, bled flush to the card edges via negative margin (keyed off the card's
   own --sp-8 padding so it stays aligned if that padding ever changes) with a hairline separating it
   from the card body below. */
.widget-kicker-row{ display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:var(--sp-2) var(--sp-4); margin:calc(var(--sp-8) * -1) calc(var(--sp-8) * -1) var(--sp-6); padding:var(--sp-4) var(--sp-8); border-bottom:1px solid var(--border-subtle-line); }
.widget-kicker{ display:inline-flex; align-items:center; gap:var(--sp-3); font-family:var(--font-sans); font-size:var(--fs-1); font-weight:600; letter-spacing:.08em; text-transform:uppercase; color:var(--text-tertiary); white-space:nowrap; }
.widget-kicker-dot{ width:8px; height:8px; border-radius:50%; flex-shrink:0; }
.widget-kicker-status{ font-family:var(--font-sans); text-transform:uppercase; letter-spacing:.06em; }

@media (prefers-reduced-motion: reduce){
  .dash-ship,.dash-wake,.dash-route-flow,.mcp-flow,.mcp-orb{ animation:none; }
  .mcp-connect-card:hover .mcp-client-box{ animation:none; }
  .crane-card .dc-trolley,.crane-card .dc-hoist,.crane-card .dc-cable,.crane-card .dc-load40,.crane-card .dc-load20,.crane-card .dc-pierexport,.crane-card .dc-shipplaced{ animation:none; }
  .crane-card .dc-hoist{ transform:translateY(0); }
  .crane-card .dc-cable{ transform:scaleY(.32); }
  .crane-card .dc-load20,.crane-card .dc-pierexport{ opacity:0; }
}
.code-card{ background:#0B0D10; border:1px solid rgba(255,255,255,.1); box-shadow:0 1px 2px rgba(0,0,0,.24); border-radius:var(--r-card); padding:var(--sp-6) var(--sp-7); font-family:var(--font-mono); font-size:var(--fs-1); line-height:var(--lh-4); color:#9DA5B1; }
.code-card > div{ min-height:1.4em; }
.code-card .k{ color:#5C8DFA; }
.code-card .s{ color:#C6F35F; }
.code-card .c{ color:#505866; }
.code-card .ok{ color:#6CE9A6; }

/* ---- rating / score / confidence ---- */
.confidence-meter{ display:flex; align-items:center; gap:var(--sp-4); }
.confidence-meter .segs{ display:flex; gap:var(--sp-1); }
.confidence-meter .segs i{ width:14px; height:6px; border-radius:var(--radius-2); background:var(--bg-track); display:block; }
.confidence-meter .segs i.on{ background:var(--accent); }
.confidence-meter .num{ font-size:var(--fs-1); font-weight:500; font-variant-numeric:tabular-nums; color:var(--text-primary); }
.score-value{ display:flex; align-items:baseline; gap:var(--sp-2); font-variant-numeric:tabular-nums; }
.score-value .n{ font-size:var(--fs-5); font-weight:600; color:var(--text-primary); }
.score-value .d{ font-size:var(--fs-1); color:var(--text-tertiary); }

/* ---- empty / placeholder data state ---- */
.data-empty{ color:var(--text-disabled); font-size:var(--fs-1); font-variant-numeric:tabular-nums; }
.data-restricted{ display:inline-flex; align-items:center; gap:var(--sp-3); color:var(--text-tertiary); font-size:var(--fs-1); font-style:italic; }
.data-restricted svg{ width:var(--size-icon-md); height:var(--size-icon-md); }

/* ---- data table ---- */
.dt-wrap{ border:1px solid transparent; border-radius:var(--r-card); background:var(--bg-base); overflow:hidden; box-shadow:var(--shadow-surface-rest), var(--surface-sheen); } /* v1.34: no grey outline on surfaces */
.dt-scroll{ overflow-x:auto; overflow-y:hidden; padding-bottom:var(--space-surface-inset);
  scrollbar-width:thin; scrollbar-color:color-mix(in srgb, var(--text-tertiary) 22%, transparent) transparent; }
.dt-scroll:hover{ scrollbar-color:color-mix(in srgb, var(--text-tertiary) 42%, transparent) transparent; }
.dt-scroll::-webkit-scrollbar{ height:5px; }
.dt-scroll::-webkit-scrollbar-track{ background:transparent; }
.dt-scroll::-webkit-scrollbar-thumb{
  background-color:color-mix(in srgb, var(--text-tertiary) 22%, transparent);
  border-radius:var(--r-pill); border:1px solid transparent; background-clip:padding-box;
  transition:background-color var(--dur-moderate) var(--ease-out);
}
.dt-scroll:hover::-webkit-scrollbar-thumb, .dt-scroll::-webkit-scrollbar-thumb:hover{
  background-color:color-mix(in srgb, var(--text-tertiary) 42%, transparent);
}
.dt-table{ width:100%; border-collapse:collapse; font-size:var(--fs-1); }
.dt-table thead th{ position:sticky; top:0; z-index:2; text-align:left; font-size:var(--fs-1); text-transform:uppercase; letter-spacing:var(--ls-7); color:var(--text-tertiary); font-weight:600;
  background:var(--bg-base); border-bottom:1px solid var(--border-default); padding:var(--space-label-gap) var(--sp-5); white-space:nowrap; user-select:none; }
.dt-table thead th > .th-cell{ position:relative; display:flex; align-items:center; gap:var(--sp-3); padding-right:var(--sp-4); }
.dt-table thead th.sortable{ cursor:pointer; }
.dt-table thead th.sortable:hover{ color:var(--text-primary); }
.dt-table thead th .sort-ico{ width:12px; height:12px; color:var(--text-disabled); flex-shrink:0; }
.dt-table thead th.sorted-asc .sort-ico, .dt-table thead th.sorted-desc .sort-ico{ color:var(--accent); }
.dt-table thead th .sort-rank{ font-size:9px; font-weight:700; color:var(--accent); background:var(--accent-wash); border-radius:var(--radius-4); width:var(--size-icon-md); height:var(--size-icon-md); display:inline-flex; align-items:center; justify-content:center; flex-shrink:0; }
.dt-table thead th .filter-ico{ width:var(--size-icon-sm); height:var(--size-icon-sm); color:var(--text-disabled); margin-left:var(--sp-1); }
.dt-table thead th.filter-active .filter-ico{ color:var(--accent); }
/* resize handle: hit area stays generous (8px) for real usability, but the VISIBLE
   line is a thin 1.5px neutral hairline at rest — it should read as "this edge can be
   dragged," never compete with row/selection color. Stronger blue appears only when
   hinting an active drag (via the header's own hover, or the static .active demo
   class below) — pointer-events stay off so this purely-illustrative handle can never
   trap a scroll/trackpad gesture meant for the table underneath it. */
.dt-table thead th .col-resizer{ position:absolute; right:-6px; top:-10px; bottom:-10px; width:8px; cursor:col-resize; pointer-events:none; }
.dt-table thead th .col-resizer::before{ content:''; position:absolute; left:50%; top:10px; bottom:10px; width:1.5px; transform:translateX(-50%);
  background:var(--border-strong); transition:background var(--dur-moderate) var(--ease-out), width var(--dur-moderate) var(--ease-out); }
.dt-table thead th:hover .col-resizer::before{ background:var(--accent); }
.dt-table thead th .col-resizer.active::before{ background:var(--accent); width:2px; }
.dt-table td{ padding:var(--space-dense-cell-inset) var(--sp-5); border-bottom:1px solid var(--divider); vertical-align:middle; color:var(--text-secondary); white-space:nowrap; }
.dt-table tbody tr:last-child > td{ border-bottom:none; }
/* v1.34: row states follow the side menu. Hover is the menu's grey (--nav-hover-bg — opaque in both
   themes; --bg-canvas was --n-0 in light, i.e. the table's own white, so a hovered row was invisible and
   only the sticky column's edge seemed to react). It covers every cell, sticky ones included. */
.dt-table tbody tr.hover-demo td, .dt-table tbody tr:hover td{ background:var(--nav-hover-bg); }
/* selected-row background: one solid, pre-mixed color shared by every cell in the row —
   sticky and scrolling alike — so the row reads as one continuous surface. A plain
   var(--accent-wash) can't be reused here because it's translucent in dark theme, which
   would let scrolled-behind content show through the opaque sticky cells; color-mix
   gives an equivalent solid tint that's identical whether a cell happens to be sticky.
   v1.34: the tint is now exactly the side menu's selected wash (--accent-wash, light blue-50), laid as one
   flat layer over --bg-base so the cell stays opaque in dark too — a single colour, not a gradient. The
   16% accent mix it replaces read as a saturated blue next to the menu's near-transparent one. A selected
   row keeps its wash on hover, sticky cells included. */
.dt-table tbody tr.selected td,
.dt-table tbody tr.selected:hover td,
.dt-table tbody tr.selected:hover td.sticky-col,
.dt-table tbody tr.selected:hover td.checkbox-col{ background:linear-gradient(var(--accent-wash), var(--accent-wash)), var(--bg-base); }
.dt-table tbody tr.clickable{ cursor:pointer; }
.dt-table tbody tr.disabled td{ color:var(--text-disabled); cursor:not-allowed; }
.dt-table tbody tr.disabled:hover td{ background:transparent; }
/* v1.34: the focused row is ringed on its cells, not on the <tr> — an outline on the row was painted
   under the opaque sticky cells and showed only in broken segments. */
.dt-table tbody tr.row-focus td{ box-shadow:inset 0 2px 0 var(--blue-500), inset 0 -2px 0 var(--blue-500); }
.dt-table tbody tr.row-focus td:first-child{ box-shadow:inset 2px 0 0 var(--blue-500), inset 0 2px 0 var(--blue-500), inset 0 -2px 0 var(--blue-500); }
.dt-table tbody tr.row-focus td:last-child{ box-shadow:inset -2px 0 0 var(--blue-500), inset 0 2px 0 var(--blue-500), inset 0 -2px 0 var(--blue-500); }
.dt-table td.k{ color:var(--text-primary); font-weight:500; }
.dt-table td.num{ text-align:right; font-variant-numeric:tabular-nums; }
.dt-table td.mono{ font-variant-numeric:tabular-nums; color:var(--text-primary); font-weight:500; }
.dt-table td.truncate{ max-width:170px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.dt-table td.wrap{ white-space:normal; line-height:var(--lh-2); max-width:220px; }
/* sticky pinned region: selection checkbox (36px) + primary identifier column (240px) —
   both given generous fixed widths so header labels and IDs can never be squeezed by
   table auto-layout, regardless of font metrics or overall table width. */
.dt-table th.sticky-col, .dt-table td.sticky-col{ position:sticky; left:36px; z-index:1; width:240px; min-width:240px; max-width:240px; background:var(--bg-base); box-shadow:1px 0 0 var(--border-default), 8px 0 12px -8px var(--sticky-edge-shadow); }
.dt-table tbody tr:hover td.sticky-col{ background:var(--nav-hover-bg); }
.dt-table th.checkbox-col, .dt-table td.checkbox-col{ width:36px; min-width:36px; max-width:36px; padding-left:var(--space-surface-inset); padding-right:var(--sp-0); position:sticky; left:0; z-index:2; background:var(--bg-base); }
.dt-table tbody tr:hover td.checkbox-col{ background:var(--nav-hover-bg); }
.dt-table tbody tr.disabled:hover td.sticky-col, .dt-table tbody tr.disabled:hover td.checkbox-col{ background:var(--bg-base); } /* v1.34: a disabled row never reacts to hover, sticky cells included */
.dt-table tbody tr.selected td.checkbox-col{ box-shadow:inset 2px 0 0 var(--accent); }
.dt-table td.actions-col, .dt-table th.actions-col{ width:40px; text-align:right; padding-right:var(--space-dense-cell-inset); }
/* expanded row detail: a single cell spanning every column, made sticky at the same
   left:0 anchor as the pinned region — this keeps the ENTIRE detail panel (not just a
   spacer) glued to the visible viewport, so labels/values never travel under the
   scrolling columns or lose their beginning when the table is scrolled horizontally. */
.dt-table .row-detail td{ background:var(--bg-canvas); padding:var(--sp-0); color:var(--text-secondary); font-size:var(--fs-1); border-bottom:1px solid var(--divider); white-space:normal; vertical-align:top; }
/* the TD itself scrolls normally with the row (so its bg-canvas background always
   fills whatever part of the row is currently visible); the DETAIL CONTENT is a plain
   block wrapped in its own sticky div — position:sticky on a full-width colspan cell
   does not reliably stick in table layout, but a normal block element positioned
   sticky relative to .dt-scroll works exactly like the pinned checkbox/id columns. */
.dt-table .row-detail-sticky{ position:sticky; left:0; z-index:1; width:max-content; padding:var(--space-surface-inset) var(--sp-6) var(--space-surface-inset) 58px; }
.dt-table .expand-btn{ display:inline-flex; align-items:center; justify-content:center; width:20px; height:20px; border-radius:var(--radius-6); color:var(--text-tertiary); cursor:pointer; background:none; border:none; margin-right:var(--sp-3); flex-shrink:0;
  transition:transform var(--dur-default) var(--ease-lift), background var(--dur-moderate) var(--ease-out); }
.dt-table .expand-btn:hover{ background:var(--state-hover-bg); color:var(--text-primary); }
.dt-table .expand-btn.open{ transform:rotate(90deg); }
/* v1.34: the disclosure control was a 20px box with a 14px tertiary chevron and the browser's own
   button padding — easy to miss. It is now a 28px target with the 16px icon step in the secondary ink. */
.dt-table .expand-btn{ width:28px; height:28px; padding:var(--sp-0); color:var(--text-secondary); border-radius:var(--radius-8); transition:transform var(--dur-default) var(--ease-lift), background var(--dur-default) var(--ease-lift); }
/* v1.34: every control in a row sits on the row's centre, not on the text baseline. A cell that holds
   the 28px disclosure button takes the button's height as its line, so the button fills it and the
   identifier is centred in it by half-leading; the checkbox cell drops its line box so the box centres
   on the row. Measured: checkbox, chevron, identifier and the plain columns share one centre line. */
.dt-table td:has(> .expand-btn){ line-height:28px; }
.dt-table td > .expand-btn{ vertical-align:top; }
.dt-table td.checkbox-col, .dt-table th.checkbox-col{ line-height:0; }
.dt-table .checkbox-col .mini-check{ vertical-align:middle; }
.dt-table .expand-btn:disabled{ color:var(--text-disabled); cursor:not-allowed; background:none; }
.dt-table .expand-btn svg{ width:var(--size-icon-lg); height:var(--size-icon-lg); }
.dt-table.density-compact td, .dt-table.density-compact th{ padding-top:var(--sp-3); padding-bottom:var(--sp-3); }
.dt-table.density-comfortable td, .dt-table.density-comfortable th{ padding-top:var(--sp-6); padding-bottom:var(--sp-6); }
.dt-toolbar{ display:flex; align-items:center; gap:var(--space-chrome-gap); padding:var(--sp-5) var(--space-surface-inset); border-bottom:1px solid var(--border-default); flex-wrap:wrap; }
.dt-toolbar .spacer{ flex:1; }
.dt-bulkbar{ display:flex; align-items:center; gap:var(--sp-5); padding:var(--space-dense-cell-inset) var(--space-surface-inset); background:var(--accent-wash); border-bottom:1px solid var(--accent-wash-border); font-size:var(--fs-1); color:var(--accent); font-weight:500; }
.dt-bulkbar .spacer{ flex:1; }
.dt-empty{ padding:var(--sp-10) var(--sp-7); text-align:center; color:var(--text-tertiary); font-size:var(--fs-1); }
.dt-empty svg{ width:26px; height:26px; color:var(--text-disabled); margin-bottom:var(--sp-4); }
.dt-error{ padding:var(--sp-9) var(--sp-7); text-align:center; color:var(--badge-error-text); font-size:var(--fs-1); }
.dt-error svg{ width:22px; height:22px; margin-bottom:var(--sp-3); }
/* ---- tabs: underline ---- */
.tab-row{ position:relative; display:flex; gap:var(--sp-2); border-bottom:1px solid var(--border-default); }
.tab-row.scroll{ overflow-x:auto; scrollbar-width:none; mask-image:linear-gradient(90deg, #000 calc(100% - 24px), transparent); }
.tab-row.scroll::-webkit-scrollbar{ display:none; }
.mini-tab{ display:flex; align-items:center; gap:var(--sp-3); padding:var(--sp-4) var(--sp-2); font-size:var(--fs-1); color:var(--text-tertiary); border-bottom:2px solid transparent; margin-bottom:-1px; cursor:pointer; white-space:nowrap; background:none; border-left:none; border-right:none; border-top:none;
  transition:color var(--dur-default) var(--ease-out), border-color var(--dur-default) var(--ease-out); }
.mini-tab svg{ width:14px; height:14px; }
.mini-tab + .mini-tab{ margin-left:var(--space-block-gap); }
.mini-tab:hover{ color:var(--text-primary); }
.mini-tab.active{ color:var(--accent); border-bottom-color:var(--accent); font-weight:500; }
.mini-tab.disabled{ color:var(--text-disabled); cursor:not-allowed; }
.mini-tab.compact{ padding:var(--sp-3) var(--sp-1); font-size:var(--fs-1); }

/* ---- tabs: pill / contained ---- */
.tab-pillbar{ display:inline-flex; gap:var(--sp-2); padding:var(--sp-2); border-radius:var(--r-control); background:var(--bg-sunken); }
.tab-pillbar.compact{ padding:var(--sp-1); }
.tab-pill{ display:flex; align-items:center; gap:var(--sp-3); padding:var(--sp-0) var(--sp-6); height:32px; border-radius:var(--r-control-sm); font-size:var(--fs-2); font-weight:500; color:var(--text-secondary); cursor:pointer; white-space:nowrap; background:none; border:none;
  transition:color var(--dur-default) var(--ease-out), background var(--dur-default) var(--ease-out); }
.tab-pillbar.compact .tab-pill{ height:24px; padding:var(--sp-0) var(--space-control-inset-sm); font-size:var(--fs-1); }
.tab-pill svg{ width:14px; height:14px; }
.tab-pill:hover{ color:var(--text-primary); background:var(--border-default); }
.tab-pill.active{ background:var(--bg-base); color:var(--text-primary); box-shadow:var(--shadow-surface-rest); }
.tab-pill.active:hover{ background:var(--bg-base); }
.tab-pill.disabled{ color:var(--text-disabled); cursor:not-allowed; }
.tab-pill.disabled:hover{ background:none; }

/* ---- breadcrumbs ---- */
.crumbs{ display:flex; align-items:center; gap:var(--sp-3); font-size:var(--fs-1); color:var(--text-tertiary); flex-wrap:wrap; }
.crumb{ color:var(--text-tertiary); cursor:pointer; transition:color var(--dur-moderate) var(--ease-out); max-width:160px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.crumb:hover{ color:var(--text-primary); }
.crumb.current{ color:var(--text-primary); font-weight:500; cursor:default; }
.crumb.home{ display:flex; align-items:center; }
.crumb.home svg{ width:14px; height:14px; }
.crumb-sep{ color:var(--text-disabled); font-size:var(--fs-1); }
.crumb-overflow{ display:flex; align-items:center; justify-content:center; width:22px; height:22px; border-radius:var(--radius-6); color:var(--text-tertiary); cursor:pointer; }
.crumb-overflow:hover{ background:var(--bg-sunken); color:var(--text-primary); }

/* ---- side nav specimen: visually identical to this document's own sidebar,
   but under its own class names — the real .nav-item/.nav-root-item classes
   are targeted by goTo()'s global "clear active state" step, which would
   otherwise strip .active off these static documentation specimens too ---- */
.navlist-demo{ position:relative; width:220px; padding:var(--sp-5); border-radius:var(--r-card); border:1px solid var(--border-subtle-line); background:var(--bg-base); overflow:hidden; } /* mirrors .sidenav, the live implementation this page points at: the soft --border-subtle-line    hairline the real sidebar and .card both use, NOT the heavy --border-default box this had    (the edge cannot simply be dropped — in light --bg-base and --bg-canvas are both #FFFFFF,    so the card would vanish). Padding is symmetric now; the old 24px/8px left/right was a    workaround for the active rail rather than real spacing. */
.nd-item{ display:block; padding:var(--sp-4) var(--sp-5); border-radius:var(--radius-24); margin:1px var(--sp-0); font-size:var(--fs-1); color:var(--text-secondary); cursor:pointer; white-space:nowrap; position:relative;
  transition:color var(--dur-moderate) var(--ease-out), background var(--dur-moderate) var(--ease-out); }
.nd-item:hover{ color:var(--text-primary); background:var(--bg-canvas); }
.nd-item.active{ color:var(--accent); background:var(--accent-wash); font-weight:500; }
.nd-item.active::before{ content:''; position:absolute; left:-15px; top:4px; bottom:4px; width:3px; border-radius:var(--radius-4); background:var(--accent); }
.nd-item.disabled{ opacity:.45; cursor:not-allowed; }
.navlist-demo.compact .nav-item{ padding:var(--sp-3) var(--sp-5); } /* was .nd-item, a selector matching nothing. Density per Foundations → Density: "three modes, one    spacing multiplier … never forked copies" — Compact is a 33px row vs Default 37px (measured; this comment previously said 32 vs 40), a SPACING change    only. The dead rule also carried font-size:var(--fs-1); reviving that forked the type scale and made    the two variants read as different components, so only the vertical padding tightens here. */
.navlist-demo.compact .nav-item.active::before{ left:-6px; } /* the grouped variant gets the rail's room from .nav-items (20px margin + 16px padding);    compact has no guide line, so the rail is pulled in to sit inside the padding edge. */

/* ---- Side nav: leading icon slot + the collapsible rail the product ships ----
   The rail is NOT a permanently icon-only nav (still forbidden): it is the
   user-toggled collapsed state of a labelled nav, and every collapsed item keeps
   a Tooltip and an accessible name. ---- */
.nav-item.has-ico, .nav-root-item.has-ico{ display:flex; align-items:center; gap:var(--sp-4); }
/* The Admin rows carry no leading glyph and no reserved slot either — both the Error-red dot
   and the empty 18px box that replaced it were taken out as unnecessary. Their labels sit at
   the row's own padding edge, 26px left of the labels in the two iconed groups above; that is
   the accepted result, not an oversight. They are plain .nav-item rows now, so there is no
   class left to describe them. */
.nav-item .ico, .nav-root-item .ico{ width:18px; height:18px; flex-shrink:0; }
.nav-item .count{ margin-left:auto; font-size:var(--fs-1); color:var(--text-tertiary); font-weight:500; }

/* The rail is the SAME container as .navlist-demo with one added capability, not a
   second copy of its recipe — width/padding/border/radius/background all inherit. */
.navlist-demo{ transition:width var(--dur-default) var(--ease-lift); }

/* ---- Glass tier for the nav specimens — the landing top bar's recipe, not a new one.
   .lp-topnav is a glass pill sitting on a .lp-block (v1.33: --bg-sunken, no bloom);
   both halves come across together. Same
   material: --glass-card-bg, --glass-card-border, blur + saturate(1.4), --shadow-ovl. ---- */
.spec-frame.spec-glass{ background:var(--bg-sunken); }
.spec-frame.spec-glass .navlist-demo{
  border-color:var(--glass-card-border);
  background:var(--glass-card-bg);
  backdrop-filter:blur(var(--glass-blur)) saturate(1.4);
  -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(1.4);
  box-shadow:var(--shadow-ovl); }

/* ---- The menu's own brand row. Expanded it carries the full lockup (rendered by
   renderBrandLogo(), so it follows the theme); collapsed the lockup is replaced by the
   NAVO mark alone — larger than a product mark, because it is the master brand. ---- */
/* ---- NAVO logo: both themes ship together and CSS picks one, so the mark never
   flashes the wrong artwork on first paint and follows a theme change with no
   re-render. Emitted by the Logo component; never recolour or redraw it. ---- */
.navo-logo{ display:inline-flex; align-items:center; flex-shrink:0; }
.navo-logo > span{ display:inline-flex; align-items:center; }
.navo-logo svg{ height:100%; width:auto; display:block; }
.navo-logo .navo-logo-dark{ display:none; }
[data-theme="dark"] .navo-logo .navo-logo-light{ display:none; }
[data-theme="dark"] .navo-logo .navo-logo-dark{ display:inline-flex; }
.nav-brand{ display:flex; align-items:center; padding:var(--sp-2) var(--space-label-gap) var(--sp-7); }
.nav-brand .nav-brand-lockup svg{ height:22px; width:auto; display:block; }
.nav-brand .nav-brand-mark{ display:none; }
.nav-brand .nav-brand-mark svg{ width:26px; height:26px; display:block; }
.navlist-demo.collapsed .nav-brand{ justify-content:center; padding-left:var(--sp-0); padding-right:var(--sp-0); }
.navlist-demo.collapsed .nav-brand .nav-brand-lockup{ display:none; }
.navlist-demo.collapsed .nav-brand .nav-brand-mark{ display:block; }
.navlist-demo .nav-label{ white-space:nowrap; }

.navlist-demo.collapsed{ width:64px; }
.navlist-demo.collapsed .nav-label, .navlist-demo.collapsed .count,
.navlist-demo.collapsed .nav-sec{ display:none; }  /* a 64px rail has no room for a
   section header, and the App Shell already hides its own .nav-sec the same way — this
   line was the missing half of that pair. */
.navlist-demo.collapsed .nav-item{ justify-content:center; padding-left:var(--sp-0); padding-right:var(--sp-0); }
/* the active rail marks a position on the guide line; a collapsed rail has no
   guide line, so the wash surface alone carries the active state there. */
.navlist-demo.collapsed .nav-item.active::before{ display:none; }
/* In the rail the label is hidden, so a row with no glyph has nothing left to give it height
   and fell to 16px (its padding alone) against an iconed row's 34px — a visibly ragged
   column. A min-height keeps the rail's rhythm even. This is NOT the reserved slot coming
   back: it adds no box to the expanded menu, where those labels stay flush at the padding
   edge. 18px is the .ico box, --sp-4 the row's own vertical padding. */
.navlist-demo.collapsed .nav-item,
.ash-frame.side-collapsed .ash-side .nav-item{ min-height:calc(18px + var(--sp-4) * 2); }
/* A grouped menu collapses too: the group header and the guide line it hangs from are
   both label-scale chrome, so they go with the labels and the items return to the rail's
   own centred 64px column. */
.navlist-demo.collapsed .nav-group-label{ display:none; }
.navlist-demo.collapsed .nav-items{ border-left:none; margin-left:var(--sp-0); padding-left:var(--sp-0); }

/* ---- Admin shell: the header owns the logo, the menu owns its own collapse ---- */
/* The menu's edge is the control: a drag handle that resizes on drag and collapses on
   click — no separate button inside the menu. Lives inside .ash-side because that box
   carries overflow:hidden, so anything hanging outside it would be clipped. */
.ash-side{ position:relative; }
.menu-handle{ position:absolute; top:0; right:0; bottom:0; width:9px; z-index:5; padding:var(--sp-0);
  background:none; border:none; cursor:col-resize; display:flex; align-items:center; justify-content:center; }
.menu-handle::before{ content:''; width:3px; height:28px; border-radius:var(--r-pill);
  background:var(--border-strong); opacity:.3;
  transition:opacity var(--dur-moderate) var(--ease-out), background var(--dur-moderate) var(--ease-out); }
.menu-handle:hover::before, .menu-handle:focus-visible::before{ opacity:1; }
.menu-handle[data-dragging]::before{ opacity:1; background:var(--accent); }
/* The menu's second edge. The right edge governs width (drag narrow -> icon rail); the bottom
   edge governs where the navigation lives (drag up -> it leaves the side and becomes the top
   bar). Same grip, same affordance, turned ninety degrees. */
.menu-handle.handle-bottom{ top:auto; left:0; right:0; bottom:0; width:auto; height:9px; cursor:row-resize; }
.menu-handle.handle-bottom::before{ width:28px; height:3px; }
/* The menu's visible control (v1.31). The edge above keeps drag-to-resize and stays the
   signature gesture, but it is a 9px column whose grip only appears on hover: below the
   24x24 minimum of WCAG 2.5.8 Target Size, and invisible on any device without a pointer.
   This button is the plain answer — one click from a mouse, Enter/Space from the keyboard,
   a tap from a finger. v1.30 stated the menu carries no button at all; that is the decision
   this version reverses, and only that one — the edge is untouched.
   It sits in the brand row, where the shipped product puts it; a menu with no brand row
   takes it as its first child, where margin-left:auto still carries it to the right. */
.menu-collapse{ display:flex; align-items:center; justify-content:center; flex-shrink:0;
  width:28px; height:28px; margin-left:auto; padding:var(--sp-0); border:none;
  border-radius:var(--r-control-sm); background:transparent; color:var(--text-tertiary);
  cursor:pointer;
  transition:background var(--dur-moderate) var(--ease-out), color var(--dur-moderate) var(--ease-out); }
.menu-collapse:hover{ background:var(--nav-hover-bg); color:var(--text-secondary); }
/* The chevron points where the menu is about to go: left to fold it away, right to bring
   it back. The document's own .chev asset points right, so expanded is the rotated state
   and the collapsed one is the asset as authored — no second glyph enters the system. */
.menu-collapse svg{ width:16px; height:16px; display:block; transform:rotate(180deg);
  transition:transform var(--dur-default) var(--ease-lift); }
.menu-collapse[aria-expanded="false"] svg{ transform:none; }
/* Collapsed, the 64px rail cannot hold the mark and the button on one line (26 + 28 against
   48px of content box), so the brand row stacks them rather than pushing the button at an
   edge the row no longer has. */
.navlist-demo.collapsed .nav-brand,
.ash-frame.side-collapsed .ash-side .nav-brand{ flex-direction:column; gap:var(--sp-3); }
.navlist-demo.collapsed .menu-collapse,
.ash-frame.side-collapsed .ash-side .menu-collapse{ margin-left:var(--sp-0); }
.ash-side .nav-label{ white-space:nowrap; }
.ash-frame .ash-side{ transition:width var(--dur-default) var(--ease-lift); }
.ash-frame.side-collapsed .ash-side{ width:64px; }
/* the App Shell page pins its own width with an ID-scoped rule (#page-t-appshell .ash-frame:not(.ash-mini) .ash-side), which outranks a plain class chain — match its weight so the collapse actually lands. */
#page-t-appshell .ash-frame.side-collapsed .ash-side{ width:64px; }
.ash-frame.side-collapsed .ash-side .nav-label,
.ash-frame.side-collapsed .ash-side .count,
.ash-frame.side-collapsed .ash-side .nav-sec{ display:none; }
/* Same two folds the .navlist-demo rail makes, expressed against the shell's own flag:
   a group's header and its guide line go with the labels, and the brand row drops to
   the mark alone. */
.ash-frame.side-collapsed .ash-side .nav-group-label{ display:none; }
.ash-frame.side-collapsed .ash-side .nav-items{ border-left:none; margin-left:var(--sp-0); padding-left:var(--sp-0); }
.ash-frame.side-collapsed .ash-side .nav-brand{ justify-content:center; padding-left:var(--sp-0); padding-right:var(--sp-0); }
.ash-frame.side-collapsed .ash-side .nav-brand .nav-brand-lockup{ display:none; }
.ash-frame.side-collapsed .ash-side .nav-brand .nav-brand-mark{ display:block; }
.ash-frame.side-collapsed .ash-side-head .mini-btn{ margin-left:var(--sp-0); }
.ash-frame.side-collapsed .ash-side .nav-item{ justify-content:center; padding-left:var(--sp-0); padding-right:var(--sp-0); }
.ash-frame.side-collapsed .ash-side .nav-item.active::before{ display:none; }
.nav-sec{ font-size:var(--fs-1); font-weight:600; letter-spacing:var(--ls-6); text-transform:uppercase; color:var(--text-tertiary); padding:var(--sp-4) var(--space-label-gap) var(--sp-2); }
.nd-group-label{ display:flex; align-items:center; gap:var(--sp-4); padding:var(--sp-4) var(--space-menu-row-inset); border-radius:var(--radius-8); cursor:pointer; font-size:var(--fs-1); font-weight:600; color:var(--text-primary); user-select:none; }

/* ---- top / horizontal nav ---- */
/* Track is --bg-base, matching .seg-control: white in light, #181B20 in dark rather than the
   --bg-sunken that collapsed onto the canvas there. The border stays for the same reason it
   does on .seg-control — a white track on a white page has no other boundary.
   This forced the active item to change too: it had been --bg-base itself, which on a white
   track leaves no fill contrast. It is the accent wash now — see .topnav-item.active below. */
.topnav{ display:flex; align-items:center; gap:var(--sp-1); padding:var(--sp-2); border-radius:var(--r-control); background:var(--bg-base); border:1px solid var(--border-default); }
.topnav-item{ display:flex; align-items:center; gap:var(--sp-3); padding:var(--sp-4) var(--sp-5); border-radius:var(--r-control-sm); font-size:var(--fs-1); color:var(--text-secondary); cursor:pointer; background:none; border:none;
  transition:color var(--dur-default) var(--ease-out), background var(--dur-default) var(--ease-out); }
.topnav-item svg{ width:var(--size-icon-md); height:var(--size-icon-md); }
.topnav-item:hover{ color:var(--text-primary); background:var(--border-default); }
/* Active is the accent wash, not a raised white pill. On a white track the old
   --bg-base + drop-shadow pill had no fill contrast left at all, and Navigation's own
   Do/Don't says the active item gets a SURFACE — never weight or colour alone.
   These are the exact four declarations .nav-item.active already uses in the side menu, so
   the system has one active recipe in two places rather than two that nearly match. */
.topnav-item.active{ background:var(--accent-wash); color:var(--accent); font-weight:500; box-shadow:inset 0 0 0 1px var(--accent-wash-border); }
.topnav-item.active:hover{ background:var(--accent-wash); }  /* the active item does not re-shade on hover — it is already where you are */
.topnav-item.disabled{ color:var(--text-disabled); cursor:not-allowed; }
.topnav-item.disabled:hover{ background:none; }

/* ---- pagination ---- */
.pager{ display:flex; align-items:center; gap:var(--sp-2); }
.pager-btn{ display:flex; align-items:center; justify-content:center; width:32px; height:32px; border-radius:var(--r-control); border:1px solid var(--border-default); background:var(--bg-base); color:var(--text-secondary); cursor:pointer;
  transition:background var(--dur-moderate) var(--ease-out), border-color var(--dur-moderate) var(--ease-out), color var(--dur-moderate) var(--ease-out); }
.pager-btn svg{ width:var(--size-icon-lg); height:var(--size-icon-lg); }
.pager-btn:hover{ border-color:var(--border-strong); color:var(--text-primary); }
.pager-btn:disabled{ opacity:.4; cursor:not-allowed; }
.pager-page{ display:flex; align-items:center; justify-content:center; min-width:32px; height:32px; padding:var(--sp-0) var(--sp-2); border-radius:var(--r-control); font-size:var(--fs-1); color:var(--text-secondary); cursor:pointer; font-variant-numeric:tabular-nums;
  transition:background var(--dur-moderate) var(--ease-out), color var(--dur-moderate) var(--ease-out); }
.pager-page:hover{ background:var(--bg-sunken); color:var(--text-primary); }
.pager-page.active{ background:var(--accent); color:#fff; font-weight:500; }
.pager-ellipsis{ display:flex; align-items:center; justify-content:center; min-width:24px; height:32px; color:var(--text-disabled); font-size:var(--fs-1); }
.pager-compact{ display:flex; align-items:center; gap:var(--space-chrome-gap); font-size:var(--fs-1); color:var(--text-secondary); font-variant-numeric:tabular-nums; }
.pager-jump{ display:flex; align-items:center; gap:var(--sp-4); font-size:var(--fs-1); color:var(--text-tertiary); }
.pager-jump input{ width:48px; height:28px; text-align:center; border-radius:var(--radius-8); border:1px solid var(--border-default); background:var(--bg-base); color:var(--text-primary); font-size:var(--fs-1); font-variant-numeric:tabular-nums; }

/* ---- stepper ---- */
.stepper{ display:flex; align-items:flex-start; }
.stepper.vertical{ flex-direction:column; }
.step{ display:flex; align-items:center; gap:var(--space-chrome-gap); }
.stepper.vertical .step{ align-items:flex-start; min-height:56px; }
.step-dot{ display:flex; align-items:center; justify-content:center; width:26px; height:26px; border-radius:50%; font-size:var(--fs-1); font-weight:600; flex-shrink:0; border:1.5px solid var(--border-strong); color:var(--text-tertiary); background:var(--bg-base); }
.step-dot svg{ width:13px; height:13px; }
.step.completed .step-dot{ background:var(--accent); border-color:var(--accent); color:#fff; }
.step.current .step-dot{ border-color:#66AA12; color:#66AA12; box-shadow:0 0 0 3px rgba(198,243,95,.35); }
:root[data-theme="dark"] .step.current .step-dot{ border-color:#C6F35F; color:#C6F35F; box-shadow:0 0 0 3px rgba(198,243,95,.25); }
.step.error .step-dot{ background:var(--badge-error-text); border-color:var(--badge-error-text); color:#fff; }
:root[data-theme="dark"] .step.error .step-dot{ background:var(--badge-error-bg); border-color:var(--badge-error-text); color:var(--badge-error-text); } /* dark: --badge-error-text is the FOREGROUND colour (pale #FDA29B), so filling with it and putting a white icon on top gave ~1.9:1. Inverted to the same deep-surface/pale-mark pairing .alert.error already uses. Brand red stays out of it — NAVO Red is never Error. */
.step-label{ display:flex; flex-direction:column; gap:1px; }
.step-label .t{ font-size:var(--fs-1); font-weight:500; color:var(--text-tertiary); }
.step.current .step-label .t, .step.completed .step-label .t{ color:var(--text-primary); }
.step.error .step-label .t{ color:var(--badge-error-text); }
.step-label .s{ font-size:var(--fs-1); color:var(--text-tertiary); }
.step-line{ flex:1; height:1.5px; background:var(--border-default); margin:var(--sp-0) var(--sp-4); align-self:center; min-width:24px; }
.step.completed + .step-line{ background:var(--accent); }
.stepper.vertical .step-line{ width:1.5px; height:28px; margin:var(--sp-1) var(--sp-0) var(--sp-1) var(--sp-5); align-self:flex-start; }

/* ---- stepper: track variant (line + dot, short label — public/live tracking contexts) ---- */
.stepper.track{ display:flex; align-items:flex-start; padding-bottom:32px; }
.track-point{ position:relative; width:14px; flex-shrink:0; }
.track-dot-box{ height:14px; width:14px; display:flex; align-items:center; justify-content:center; }
.track-dot{ width:10px; height:10px; border-radius:50%; background:var(--bg-base); border:2px solid var(--border-strong); flex-shrink:0; }
.track-dot.done{ background:var(--blue-500); border-color:var(--blue-500); }
.track-dot.current{ position:relative; width:14px; height:14px; background:#C6F35F; border:none; }
.track-dot.current::after{ content:''; position:absolute; inset:-6px; border-radius:50%; background:#C6F35F; animation:navo-live-pulse 2s cubic-bezier(.22,.61,.36,1) infinite; }
.track-connector{ flex:1 1 auto; min-width:16px; height:3px; background:var(--border-default); margin-top:5.5px; }
.track-connector.first{ border-radius:999px 0 0 999px; }
.track-connector.last{ border-radius:0 999px 999px 0; }
.track-connector.done{ background:var(--blue-500); }
.track-connector.current{ background:linear-gradient(to right in oklch, var(--blue-500), var(--lime-300)); } /* v1.34: the leg into the current point runs from done (blue) to now (lime) */
.track-point span{ position:absolute; top:18px; left:50%; transform:translateX(-50%); white-space:nowrap; font-size:var(--fs-1); color:var(--text-tertiary); }
.track-point:first-child span{ left:0; transform:none; }
.track-point:last-child span{ left:auto; right:0; transform:none; }
.track-point.done span, .track-point.current span{ color:var(--text-primary); font-weight:500; }
@media (prefers-reduced-motion: reduce){ .track-dot.current::after{ animation:none; opacity:.3; } }

/* ---- back / forward ---- */
.back-link{ display:inline-flex; align-items:center; gap:var(--sp-3); font-size:var(--fs-1); color:var(--text-secondary); cursor:pointer; }
.back-link svg{ width:var(--size-icon-lg); height:var(--size-icon-lg); }
.back-link:hover{ color:var(--text-primary); }
.item-nav{ display:flex; align-items:stretch; border:1px solid var(--border-default); border-radius:var(--radius-16); overflow:hidden; }
.item-nav > div{ flex:1; display:flex; flex-direction:column; gap:var(--sp-1); padding:var(--sp-4) var(--sp-6); cursor:pointer; transition:background var(--dur-moderate) var(--ease-out); } /* flex:1 — the two halves must split the full width, or .next's right alignment stops at its own box and leaves dead space at the right edge */
.item-nav > div:hover{ background:var(--bg-sunken); }
.item-nav > div.next{ align-items:flex-end; text-align:right; border-left:1px solid var(--border-default); }
.item-nav .lbl{ font-size:var(--fs-1); color:var(--text-tertiary); display:flex; align-items:center; gap:var(--sp-2); }
.item-nav .val{ font-size:var(--fs-1); color:var(--text-primary); font-weight:500; }
.mini-skel{ background:linear-gradient(90deg,var(--bg-sunken) 25%,var(--border-default) 37%,var(--bg-sunken) 63%); background-size:400% 100%; animation:skel-shimmer 1.6s ease infinite; border-radius:var(--radius-6); }
@keyframes skel-shimmer{ 0%{background-position:100% 0;} 100%{background-position:-100% 0;} }
.mini-spinner{ width:20px; height:20px; border-radius:50%; border:2.5px solid var(--border-default); border-top-color:var(--accent); animation:spin .7s linear infinite; flex-shrink:0; }
@keyframes spin{ to{ transform:rotate(360deg); } }
.mini-spinner.xs{ width:12px; height:12px; border-width:2px; }
.mini-spinner.sm{ width:16px; height:16px; border-width:2px; }
.mini-spinner.lg{ width:28px; height:28px; border-width:3px; }
@media (prefers-reduced-motion: reduce){
  .mini-skel{ animation:none; background:var(--bg-sunken); }
  .mini-spinner{ animation:none; border-top-color:var(--border-default); border-right-color:var(--accent); }
}
.icon-anim{ width:40px; height:40px; }
.icon-anim-sync{ width:30px; height:30px; }
.icon-anim-radar circle{ fill:none; stroke:var(--border-default); }
.icon-anim-radar .sweep{ transform-origin:50% 50%; animation:spin 3s linear infinite; }
.icon-anim-sync{ color:var(--accent); animation:spin 1.4s linear infinite; }
.icon-anim-ping .track{ stroke:var(--border-default); }
.icon-anim-ping .dot{ fill:var(--accent); animation:navo-ping-travel 2.4s ease-in-out infinite; }
@keyframes navo-ping-travel{ 0%{ transform:translateX(0); opacity:1; } 45%{ transform:translateX(20px); opacity:1; } 50%{ opacity:0; } 51%{ transform:translateX(0); opacity:0; } 55%{ opacity:1; } 100%{ transform:translateX(20px); opacity:1; } }
.icon-anim-bars rect{ fill:var(--accent); transform-box:fill-box; transform-origin:50% 100%; animation:navo-bar-pulse 1.2s ease-in-out infinite; }
.icon-anim-bars rect:nth-child(2){ animation-delay:.15s; }
.icon-anim-bars rect:nth-child(3){ animation-delay:.3s; }
@keyframes navo-bar-pulse{ 0%,100%{ transform:scaleY(.4); } 50%{ transform:scaleY(1); } }
@media (prefers-reduced-motion: reduce){
  .icon-anim-radar .sweep, .icon-anim-sync{ animation:none; }
  .icon-anim-ping .dot{ animation:none; transform:translateX(10px); opacity:.6; }
  .icon-anim-bars rect{ animation:none; transform:scaleY(.7); }
}
/* ---- non-blocking refresh/updating indicator: sits inline next to already-visible
   content — background refresh never replaces or dims what's already on screen ---- */
.updating-indicator{ display:inline-flex; align-items:center; gap:var(--sp-4); font-size:var(--fs-1); color:var(--text-tertiary); }

/* ---- anatomy diagram ---- */
.anatomy-row{ display:flex; align-items:center; gap:var(--sp-6); padding:var(--space-label-gap) var(--sp-0); border-bottom:1px solid var(--divider); }
.anatomy-row:last-child{ border-bottom:none; }
.anatomy-num{ width:22px; height:22px; border-radius:50%; background:var(--n-900); color:#fff; font-size:var(--fs-1); font-weight:600; display:flex; align-items:center; justify-content:center; flex-shrink:0; }
.anatomy-name{ width:150px; font-size:var(--fs-1); font-weight:500; flex-shrink:0; }
.anatomy-desc{ font-size:var(--fs-1); color:var(--text-secondary); min-width:0; overflow-wrap:break-word; }

/* ---- template zone diagram ---- */
.zone-map{ display:flex; flex-direction:column; gap:var(--sp-4); border:1px solid var(--border-default); border-radius:var(--r-panel); padding:var(--sp-6); background:var(--bg-sunken); }
.zone-row{ display:flex; gap:var(--sp-4); }
.zone{ flex:1; border-radius:var(--radius-8); padding:var(--sp-5) var(--space-surface-inset); font-size:var(--fs-1); color:var(--text-secondary); display:flex; flex-direction:column; gap:var(--sp-1); }
.zone .zn{ font-size:var(--fs-1); font-weight:600; color:var(--text-primary); }
.zone.required{ background:var(--bg-base); border:1.5px solid var(--border-strong); }
.zone.optional{ background:var(--bg-base); border:1.5px dashed var(--border-strong); }
.zone.conditional{ background:var(--bg-base); border:1.5px dashed var(--blue-300); }

/* ---- domain sample card ---- */
.domain-card{ border:1px solid var(--border-default); border-radius:var(--r-card); background:var(--bg-base); padding:var(--sp-7) var(--sp-7); }
.lp-block{ border:1px solid var(--border-subtle-line); border-radius:var(--radius-32); overflow:hidden;
  background:
    repeating-linear-gradient(0deg, transparent, transparent 23px, var(--spec-grid-line, var(--border-subtle-line)) 23px, var(--spec-grid-line, var(--border-subtle-line)) 24px),
    repeating-linear-gradient(90deg, transparent, transparent 23px, var(--spec-grid-line, var(--border-subtle-line)) 23px, var(--spec-grid-line, var(--border-subtle-line)) 24px),
    var(--bg-canvas);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.6), inset 0 0 0 1px rgba(16,24,40,.02), 0 1px 2px rgba(16,24,40,.03); }
/* row-of-cards blocks stretch every .card to the tallest sibling by default (CSS
   grid) — without a flex column + margin-top:auto anchor, that extra height
   collects as uneven blank space and misaligns whatever sits last (a button,
   an attribution row, a date), instead of every card's trailing element lining
   up on one shared baseline. */
.lp-block .card{ display:flex; flex-direction:column; }
/* Theme-swapped block variants — one markup pair, only one half ever visible.
   Used where a block's whole visual language differs by theme (e.g. a fixed
   dark "Product Expression" hero vs. its light/neutral counterpart) rather
   than just re-pointing tokens. */
.lp-theme-dark{ display:none; }
.lp-theme-light{ display:block; }
:root[data-theme="dark"] .lp-theme-dark{ display:block; }
:root[data-theme="dark"] .lp-theme-light{ display:none; }
/* Soft/glass card treatment, scoped to Landing Page only — never applied to
   the base .card used in dense product UI (tables, forms), which keeps its
   bordered surface for legibility. Matches the approved Navo24 homepage
   concept: translucent glass fill (same --glass-card-bg/--glass-fill tokens
   as .glass-frame), no border, a soft diffused shadow, and a larger 32px
   rounding than the standard --r-card. */
#page-t-landing .card, #page-t-landing .icon-tile{ background:var(--glass-card-bg); border:none; border-radius:var(--radius-32); box-shadow:var(--shadow-4); }
/* the 1px stroke wrapper (.hero-search-wrap) needs a fully opaque
   card underneath — the page-wide translucent glass fill above would let the
   gradient bleed through the whole card instead of staying a thin ring */
#page-t-landing .hero-search-wrap > .card{ background:var(--bg-base); }
/* .ov-hero-art is 32px globally now — no page-scoped override needed here. */
#page-t-landing .glass-frame-inner{ border-radius:var(--radius-32); }
#page-t-landing .glass-frame{ border-radius:calc(var(--radius-32) + 8px); }
/* Optional companion for a leading icon — a small white circle chip behind
   it, per the same reference. A variant, not a requirement: some cards read
   fine with a bare icon, others suit the circle better. */
.lp-icon-chip{ display:flex; align-items:center; justify-content:center; width:44px; height:44px; border-radius:var(--radius-999); background:var(--bg-base); box-shadow:var(--shadow-1); flex-shrink:0; }
/* ---- landing top-nav mega-menu — real IA ported from navo24-web's Header.astro,
   click-to-open per this system's own Top / Horizontal Navigation accessibility
   rule (Components → Navigation): hover-only excludes touch and keyboard. ---- */
.lp-navdrop{ position:relative; }
.lp-navdrop-trigger{ display:flex; align-items:center; gap:var(--sp-2); background:none; border:none; padding:var(--sp-0); font-family:var(--font-sans); font-size:var(--fs-2); color:var(--text-secondary); cursor:pointer; }
.lp-navdrop-trigger:hover{ color:var(--text-primary); }
.lp-navdrop-trigger svg{ width:12px; height:12px; color:var(--text-tertiary); transition:transform var(--dur-default) var(--ease-out); }
.lp-navdrop-trigger[aria-expanded="true"]{ color:var(--text-primary); }
.lp-navdrop-trigger[aria-expanded="true"] svg{ transform:rotate(180deg); }
.lp-topnav-link{ font-size:var(--fs-2); color:var(--text-secondary); text-decoration:none; }
.lp-topnav-link:hover{ color:var(--text-primary); }
.lp-topnav-toggle{ display:none; }
.lp-navdrop-panel{ display:none; position:absolute; top:calc(100% + var(--sp-6)); left:50%; transform:translateX(-50%); z-index:40; border:1px solid var(--glass-card-border); border-radius:var(--radius-24); background:linear-gradient(var(--glass-card-bg-strong), var(--glass-card-bg-strong)), var(--glass-card-bg-strong); backdrop-filter:blur(var(--glass-blur-lg)) saturate(1.4); -webkit-backdrop-filter:blur(var(--glass-blur-lg)) saturate(1.4); box-shadow:var(--shadow-ovl); padding:var(--sp-3); }
.lp-navdrop-panel.open{ display:block; }
.lp-navdrop-cols{ display:grid; grid-template-columns:1fr 1fr; gap:var(--sp-2); }
.lp-navdrop-eyebrow{ padding:var(--sp-4) var(--sp-4) var(--sp-2); font-size:var(--fs-1); text-transform:uppercase; letter-spacing:var(--ls-7); color:var(--text-tertiary); }
.lp-navdrop-item{ display:flex; align-items:flex-start; gap:var(--sp-4); padding:var(--sp-4); border-radius:var(--radius-16); text-decoration:none; }
.lp-navdrop-item:hover{ background:var(--bg-sunken); text-decoration:none; }
.lp-navdrop-item:hover .lp-navdrop-item-title, .lp-navdrop-item:hover .lp-navdrop-item-desc{ text-decoration:none; }
.lp-navdrop-item svg{ width:22px; height:22px; flex-shrink:0; margin-top:2px; }
.lp-navdrop-item-title{ display:block; font-size:var(--fs-2); font-weight:600; color:var(--text-primary); }
.lp-navdrop-item-desc{ display:block; margin-top:2px; font-size:var(--fs-1); line-height:var(--lh-3); color:var(--text-tertiary); }
.lp-footer-heading{ font-size:var(--fs-1); text-transform:uppercase; letter-spacing:var(--ls-7); color:var(--n-500); margin-bottom:var(--sp-4); }
.lp-footer-links{ display:flex; flex-direction:column; gap:var(--sp-3); font-size:var(--fs-1); color:var(--n-300); }
.lp-footer-links a{ color:inherit; text-decoration:none; transition:color var(--dur-default) var(--ease-out); }
.lp-footer-links a:hover{ color:#fff; }
.email-shell{ max-width:480px; margin:0 auto; background:#fff; border-radius:var(--r-panel); overflow:hidden; box-shadow:var(--shadow-surface-rest); font-family:var(--font-sans); }
.email-header{ background:#0B0D10; padding:var(--sp-6) var(--sp-8); display:flex; align-items:center; justify-content:space-between; }
.email-header svg{ height:22px; width:auto; display:block; }
.email-badge{ font-family:var(--font-sans); font-size:var(--fs-1); font-weight:600; letter-spacing:.02em; background:#C6F35F; color:#0B0D10 !important; padding:var(--sp-2) var(--sp-5); border-radius:var(--r-button); text-decoration:none !important; display:inline-block; }
.email-body{ padding:var(--sp-9) var(--sp-8); color:#181B20; font-size:var(--fs-3); line-height:1.6; }
.email-body p{ margin:0 0 var(--sp-6); }
.email-body h1{ font-size:var(--fs-5); font-weight:var(--fw-semibold); color:#0B0D10; margin:0 0 var(--sp-6); }
.email-callout{ border-left:3px solid #113EC9; background:#F8F9FB; border-radius:0 var(--radius-16) var(--radius-16) 0; padding:var(--sp-6) var(--sp-7); margin:var(--sp-8) 0; }
.email-callout .eyebrow{ font-family:var(--font-sans); font-size:var(--fs-1); font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:#113EC9; margin-bottom:var(--sp-3); }
.email-callout h2{ font-size:var(--fs-4); font-weight:var(--fw-semibold); color:#0B0D10; margin:0 0 var(--sp-5); }
.step-pill-row{ display:flex; align-items:center; gap:var(--sp-5); }
.step-pill{ font-family:var(--font-sans); font-size:var(--fs-1); font-weight:700; padding:var(--sp-2) var(--sp-5); border-radius:var(--r-button); flex-shrink:0; width:68px; white-space:nowrap; text-align:center; box-sizing:border-box; }
.step-pill.blue{ background:#113EC9; color:#fff; }
.step-pill.lime{ background:#C6F35F; color:#0B0D10; }
.step-pill-connector{ width:1px; height:14px; margin-left:34px; border-left:2px dotted #CDD2DA; }
.email-btn{ display:inline-flex; align-items:center; justify-content:center; gap:var(--sp-4); height:48px; padding:var(--sp-0) var(--sp-8); border-radius:var(--r-button-lg); background:#113EC9; color:#fff !important; border:1px solid transparent; font-family:var(--font-sans); font-weight:500; font-size:14.5px; line-height:1; text-decoration:none !important; transition:background var(--dur-moderate) var(--ease-out), box-shadow var(--dur-moderate) var(--ease-out), transform var(--dur-moderate) var(--ease-out); }
.email-btn:hover{ background:#1235A3; box-shadow:0 16px 32px rgba(17,62,201,.32); text-decoration:none !important; }
.email-footer{ padding:var(--sp-8) var(--sp-8) var(--sp-9); border-top:1px solid #E3E6EB; text-align:center; }
.email-footer .links{ font-family:var(--font-sans); font-size:var(--fs-1); color:#113EC9; margin-bottom:var(--sp-5); }
.email-footer .links a{ color:#113EC9; text-decoration:none; }
.email-footer .tagline{ font-family:var(--font-sans); font-size:var(--fs-1); color:#9DA5B1; margin-bottom:var(--sp-5); }
.email-footer .copyright{ font-family:var(--font-sans); font-size:var(--fs-1); color:#9DA5B1; margin-bottom:var(--sp-2); }
.email-footer .legal{ font-family:var(--font-sans); font-size:var(--fs-1); color:#9DA5B1; line-height:1.7; }
.email-footer .legal a{ color:#505866; text-decoration:underline; text-decoration-color:#CDD2DA; text-underline-offset:3px; text-decoration-thickness:1px; transition:color var(--dur-moderate) var(--ease-out); }
.email-footer .legal a:hover{ color:#0B0D10; text-decoration-color:#505866; }
.domain-card .row{ display:flex; justify-content:space-between; padding:var(--sp-4) var(--sp-0); border-bottom:1px solid var(--divider); font-size:var(--fs-1); }
.domain-card .row:last-child{ border-bottom:none; }
.domain-card .row .k{ color:var(--text-tertiary); }
.domain-card .row .v{ color:var(--text-primary); font-weight:500; font-variant-numeric:tabular-nums; }

/* ---- pattern flow ---- */
.flow-row{ display:flex; align-items:center; gap:var(--sp-4); flex-wrap:wrap; }
.flow-arrow{ color:var(--text-disabled); font-size:var(--fs-2); }

/* ---- approved logo asset inventory ---- */
.logo-tile-row{ display:flex; gap:var(--space-stack-gap); flex-wrap:wrap; }
.logo-tile{ flex:1; min-width:150px; border:1px solid var(--border-default); border-radius:var(--r-card); overflow:hidden; }
.logo-tile .swatch{ height:96px; display:flex; align-items:center; justify-content:center; }
.logo-tile .swatch.on-light{ background:#FFFFFF; }
.logo-tile .swatch.on-dark{ background:#0B0D10; }
.logo-tile .cap{ padding:var(--sp-4) var(--sp-5); background:var(--bg-base); border-top:1px solid var(--border-default); }
.logo-tile .cap .fn{ font-size:var(--fs-1); font-weight:600; color:var(--text-primary); font-family:var(--font-sans); }
.logo-tile .cap .meta{ font-size:10.5px; color:var(--text-tertiary); margin-top:var(--sp-1); font-variant-numeric:tabular-nums; }
table.logotable{ width:100%; border-collapse:separate; border-spacing:0; font-size:var(--fs-1); background:var(--bg-base); border:1px solid var(--border-default); border-radius:var(--r-card); }
table.logotable th{ text-align:left; font-size:10.5px; text-transform:uppercase; letter-spacing:var(--ls-7); color:var(--text-tertiary); font-weight:600; padding:var(--sp-4) var(--space-dense-cell-inset); border-bottom:1px solid var(--border-default); }
table.logotable td{ padding:var(--sp-4) var(--space-dense-cell-inset); border-bottom:1px solid var(--divider); color:var(--text-secondary); font-variant-numeric:tabular-nums; }
table.logotable tr:last-child td{ border-bottom:none; }
table.logotable td.k{ color:var(--text-primary); font-weight:500; white-space:nowrap; }
.avail-yes{ color:#0F7A42; font-weight:600; }
.avail-no{ color:var(--text-disabled); }
.logo-note{ font-size:var(--fs-1); color:var(--text-tertiary); line-height:var(--lh-3); margin-top:var(--space-label-gap); }

/* ============================================================
   VISUAL DIFFERENTIATION — PASS 2 (Framer-inspired system language)
   Presentation-layer only. IA, content, typography, colors and every
   existing token VALUE are unchanged above this point — this block
   only adds depth, texture, motion and border refinement on top of
   the existing token system via new supplementary tokens (defined in
   :root / :root[data-theme="dark"]) and later-source-order overrides.
============================================================ */

/* ---- canvas: subtle neutral dot-grid texture, instead of flat white.
   The former ambient-wash layer (blue/violet radial tints) is removed —
   page-level surfaces stay strictly neutral per Foundations → Color;
   brand color is reserved for accents, never a page background. ---- */
.workspace{
  background-image:var(--canvas-grid);
  background-size:22px 22px;
  background-position:0 0;
}

/* ---- composition rhythm: slightly more air around title / sections ---- */
.section{ margin-top:var(--space-section-gap); }
/* Get Started reads as one dense reference page, not a series of
   full page-length chapters — halve the standard section gap everywhere
   on it (zone intro to its content, and section to section within a
   zone) instead of touching --space-section-gap globally. */
#page-ov-intro .section{ margin-top:calc(var(--space-section-gap) / 2); }


/* ---- static display surfaces: softer architectural hairline + quiet
   dimensional lift instead of a flat 1px box on a flat page ---- */
.domain-card, .icon-tile, .brand-tile, .logo-tile, .density-block, .zone-map, .mini-card,
.doctable-wrap, table.logotable{
  border-color:transparent; /* v1.34: no grey outline on surfaces — the edge is the shadow + sheen */
  box-shadow:var(--shadow-surface-rest), var(--surface-sheen);
}

/* ---- interactive-feeling surfaces: same rest treatment, deeper (never
   heavier) shadow on hover — dimensionality via layered soft shadow +
   top sheen, not a single hard drop shadow ---- */
.card, .principle-card, .product-row, .stub-list .row{
  border-color:transparent; /* v1.34: no grey outline on surfaces */
  transition:border-color var(--dur-default) var(--ease-lift), box-shadow var(--dur-slow) var(--ease-lift), transform var(--dur-default) var(--ease-lift);
}
.product-row, .stub-list .row{
  box-shadow:var(--shadow-surface-rest), var(--surface-sheen);
}
.principle-card:hover, .product-row:hover, .stub-list .row:hover{
  box-shadow:var(--shadow-surface-hover), var(--surface-sheen);
}
/* v1.34 — surfaces carry no grey outline (owner, 2026-09-24). A card's edge is the same quiet
   dimensional lift the static surfaces already use; hover deepens the shadow and never draws a
   darker border. The 1px border stays, transparent, so nothing changes size. A selected card keeps
   its accent edge — that is a state, not an outline. */
.card, .panel, .ash-sheet{ border-color:transparent; }
.card{ box-shadow:var(--shadow-surface-rest), var(--surface-sheen); }
.card.clickable:not(.selected), .card.clickable:not(.selected):hover,
.principle-card:hover, .product-row:hover, .stub-list .row:hover{ border-color:transparent; }
.card.clickable:not(.selected):hover{ box-shadow:var(--shadow-surface-hover), var(--surface-sheen); }

/* ---- specimen frame: read unmistakably as a "live canvas", not another
   card — corner reticle marks, an inner hairline ring, no heavy shadow ---- */
.spec-frame{ box-shadow:inset 0 0 0 1px var(--border-subtle-line), var(--surface-sheen); }
.spec-frame::after{
  content:''; position:absolute; inset:8px; pointer-events:none; border-radius:var(--radius-12);
  background:
    linear-gradient(var(--text-disabled),var(--text-disabled)) top left / 12px 1.5px no-repeat,
    linear-gradient(var(--text-disabled),var(--text-disabled)) top left / 1.5px 12px no-repeat,
    linear-gradient(var(--text-disabled),var(--text-disabled)) top right / 12px 1.5px no-repeat,
    linear-gradient(var(--text-disabled),var(--text-disabled)) top right / 1.5px 12px no-repeat,
    linear-gradient(var(--text-disabled),var(--text-disabled)) bottom left / 12px 1.5px no-repeat,
    linear-gradient(var(--text-disabled),var(--text-disabled)) bottom left / 1.5px 12px no-repeat,
    linear-gradient(var(--text-disabled),var(--text-disabled)) bottom right / 12px 1.5px no-repeat,
    linear-gradient(var(--text-disabled),var(--text-disabled)) bottom right / 1.5px 12px no-repeat;
  opacity:.4;
}

/* ---- sidebar: quiet top depth-fade, active item reads as a rail on the
   guide line rather than a boxed pill, group labels sharpen when open ---- */
.sidenav{ box-shadow:1px 0 0 var(--border-subtle-line); }
.nav-group.open > .nav-group-label{ color:var(--text-primary); }
.nav-item.active{ box-shadow:none; }
.nav-item.active::before{
  content:''; position:absolute; left:-17px; top:4px; bottom:4px; width:3px; border-radius:var(--radius-4);
  background:var(--accent);
}

/* ---- header chrome: search / toggle share the same soft-surface recipe as
   everything else; the topbar itself stays a flat structural surface,
   separated from the workspace by its hairline border only, no drop shadow ---- */
.searchbox{ box-shadow:inset 0 1px 2px rgba(16,24,40,.04), var(--surface-sheen); }
.mini-input:focus{ box-shadow:var(--ring-focus); }
.route-search-pill .mini-input:focus, .route-search-pill .mini-select:focus, .route-search-pill .mini-select.open{ outline:none; border-color:transparent; box-shadow:none; }

/* ---- page transitions: a touch more premium than a plain fade-up ---- */
@keyframes page-in{ from{ opacity:0; transform:translateY(6px) scale(.997); } to{ opacity:1; transform:translateY(0) scale(1); } }
.page.active{ animation-duration:320ms; }

/* ---- keyboard focus: consistent with the system's own accessibility
   principle — visible, not decorative ---- */
.nav-item:focus-visible, .nav-root-item:focus-visible, .nav-group-label:focus-visible,
.theme-toggle:focus-visible, .mini-btn:focus-visible,
.mini-check:focus-visible, .mini-radio:focus-visible, .mini-switch:focus-visible,
.seg-option:focus-visible, .chip-opt:focus-visible,
.mini-tab:focus-visible, .tab-pill:focus-visible, .crumb:focus-visible,
.topnav-item:focus-visible, .pager-btn:focus-visible, .pager-page:focus-visible,
.back-link:focus-visible, .dt-table thead th.sortable:focus-visible,
.dt-table .expand-btn:focus-visible, .dt-table tbody tr.clickable:focus-visible,
.alert .dismiss:focus-visible, .banner .dismiss:focus-visible, .toast .dismiss:focus-visible,
.alert .actions a:focus-visible, .toast .actions a:focus-visible,
.menu-collapse:focus-visible,
.card.clickable:focus-visible{
  outline:none; box-shadow:var(--ring-focus);
}

/* ============================= PRODUCT TYPE HIERARCHY — reusable utilities =============================
   Formalizes the in-product (non-marketing) type contrast pattern verified on Templates → Dashboard:
   a small Eyebrow (Label/S tier, --accent) sits above a Display/Product title (Ranade); large Numeric
   values use the existing Numeric scale at higher emphasis; Section headings get one consistent tier
   distinct from both. Built entirely from existing Foundations tokens — no new colors, no new fonts.
   See Foundations → Typography ("Display / Product" row) and → Spacing ("Stat/Block/Gap" alias). */
.type-eyebrow{ font-family:var(--font-sans); font-size:var(--fs-1); font-weight:var(--fw-bold); text-transform:uppercase; letter-spacing:var(--ls-8); color:var(--accent); }
.type-eyebrow.neutral{ color:var(--text-primary); }
.type-display-product{ font-family:var(--font-display); font-weight:var(--fw-semibold); font-size:var(--fs-6); letter-spacing:var(--ls-2); line-height:var(--lh-1); color:var(--text-primary); }
.type-section-heading{ font-family:var(--font-sans); font-size:var(--fs-1); font-weight:var(--fw-bold); text-transform:uppercase; letter-spacing:var(--ls-7); color:var(--text-primary); }
.type-numeric-hero{ font-family:var(--font-sans); font-size:var(--fs-6); font-weight:var(--fw-semibold); letter-spacing:var(--ls-1); line-height:var(--lh-1); color:var(--text-primary); font-variant-numeric:tabular-nums; }
.type-numeric-hero.negative{ color:var(--destructive); }
/* Landing Page marketing stat moments carry Ranade (display/brand). App Shell and Dashboard's
   own KPI-strip hero numbers were moved to Ranade too, by explicit request, reversing the prior
   "functional numerics stay Switzer" correction for just these two pages — Split View's
   comparison numerics ($2,450 vs $2,680) were NOT part of that request and still stay Switzer. */
#page-t-landing .type-numeric-hero, #page-t-appshell .type-numeric-hero, #page-t-dashboard .type-numeric-hero{ font-family:var(--font-display); }
/* Data Display's Chart demos are widget cards ported verbatim from Landing Page (see Chart —
   Radar/Position, Chart — Utilization Grid) — their hero numbers must match the Ranade look of
   their Landing Page originals, not silently regress to Switzer just because they render here. */
#page-c-datadisplay .type-numeric-hero{ font-family:var(--font-display); }
/* Mono is code only — <code>, .mono and .code-card. The Aura-era exception that put
   JetBrains Mono on small UI chrome (tags, badges, breadcrumbs, chips, flow steps,
   state pills, tabs, top-nav items) was retired on 2026-09-15: that chrome inherits
   Switzer like every other non-code surface. */
.type-label-stat{ font-family:var(--font-sans); font-size:var(--fs-1); font-weight:var(--fw-medium); text-transform:uppercase; letter-spacing:var(--ls-6); color:var(--text-tertiary); }

/* ---- The three non-code treatments .mono had been standing in for ----------
   Typography's rule is that mono means code and nothing else. Everything below
   carries a job mono was doing on a surface that is not code.

   Code / M — freight identifiers: container numbers, UN/LOCODEs, timestamps,
   rates, API keys. Switzer with tabular numerals and mono's own tracking, so
   columns still align once the monospace grid is gone. Code / S is the same
   plus color:var(--text-tertiary). Documented on Foundations -> Typography. */
.type-code{ font-family:var(--font-sans); font-variant-numeric:tabular-nums; letter-spacing:var(--ls-5); }
/* In a data table the identifier cell is also the row's primary value — the
   weight and colour .dt-table td.mono used to give it. */
.dt-table td.type-code{ font-variant-numeric:tabular-nums; color:var(--text-primary); font-weight:var(--fw-medium); }

/* A UI string quoted inside documentation prose — a button label, a status
   value, a message. Not code, so not mono: weight alone carries the emphasis.
   Colour is deliberately left to inherit, the way .mono did — many of these sit
   inside secondary or tertiary copy and must not jump out of their sentence. */
.type-ui-string{ font-family:var(--font-sans); font-weight:var(--fw-semibold); }

/* A keyboard key named in prose. The system already drew keys this way, scoped
   to .cmdk-demo and .field-kbd; promoted to a base class so prose can use it
   instead of setting keys in mono. */
.kbd{ display:inline-block; font-family:var(--font-sans); font-size:10.5px; padding:var(--sp-1) var(--sp-3); border-radius:var(--radius-6); background:var(--bg-sunken); border:1px solid var(--border-default); color:var(--text-tertiary); }
/* table.doctable td.k puts the display face on key cells, and its specificity
   (0,1,2) silently beats a font utility authored on the same cell (0,1,0) — each
   of which is a deliberate statement about what the content IS. Let the utility
   win. Both branches resolve to an existing family token: Font/Family/Mono for
   code (CSS custom properties, selectors, ARIA attributes, design-token paths)
   and Font/Family/UI for the non-code roles. */
table.doctable td.k.mono{ font-family:var(--font-mono); }
table.doctable td.k.type-code, table.doctable td.k.kbd{ font-family:var(--font-sans); }
.stat-block{ display:flex; flex-direction:column; gap:var(--sp-3); }
.delta{ font-size:var(--fs-1); font-weight:var(--fw-medium); }
.stat-block .delta{ color:var(--text-tertiary); }
.stat-block .delta.negative{ color:var(--destructive); }
/* ==== v1.34 — the documentation shell follows the App Shell (and TrackingMCP's side layout): one
   menu surface that carries the brand at its top, and a content column whose top row holds the
   breadcrumb and search on the page itself (the theme switch lives in the menu's foot). No full-width top bar, and no hairline between the
   bar and the menu or the menu and the page. The canonical page has no atmosphere, so the menu is a
   Solid surface (--bg-base) lifted by the surface shadow and sheen — glass on a flat page would be
   invisible. Desktop only: below 900px the existing top bar + drawer stay exactly as they were.
   The markup and scripts are untouched: the menu surface is the shell's own ::before, spanning both
   rows, so the brand (absolutely placed on it) and the scrolling list never overlap. ==== */
@media (min-width:901px){
  .shell{ position:relative; background:var(--bg-canvas); }
  .shell::before{ content:''; grid-column:1; grid-row:1 / -1; margin:var(--sp-5) var(--sp-0) var(--sp-5) var(--sp-5); border-radius:var(--r-card); background:var(--bg-base); box-shadow:var(--shadow-surface-rest), var(--surface-sheen); pointer-events:none; }
  /* The bar's content lines up with the page's own column (max 1200px, centred, --space-page-gutter-x). */
  .topbar{ grid-column:2; background:transparent; border-bottom:none; box-shadow:none; padding-block:var(--sp-0); padding-inline:max(var(--space-page-gutter-x), calc((100% - 1200px) / 2 + var(--space-page-gutter-x))); }
  .topbar .divider-v{ display:none; }
  .topbar .brand{ position:absolute; left:calc(var(--sp-5) + var(--sp-5) + var(--space-label-gap)); top:calc(var(--sp-5) + var(--sp-7)); z-index:31; }
  /* The theme switch sits in the menu's foot, as the App Shell's account row carries it; the list
     ends above that row, so nothing scrolls under the button. */
  .topbar .theme-toggle{ position:absolute; left:calc(var(--sp-5) + var(--sp-5) + var(--sp-2)); bottom:calc(var(--sp-5) + var(--sp-5)); z-index:31; }
  .sidenav{ grid-column:1; grid-row:2; position:relative; z-index:1; margin:var(--sp-0) var(--sp-0) calc(var(--sp-5) + var(--sp-5) + 36px + var(--sp-5)) var(--sp-5); padding-top:var(--sp-8); background:transparent; border-right:none; box-shadow:none; border-radius:var(--sp-0) var(--sp-0) var(--r-card) var(--r-card); }
}

/* ==== WORKSPACE BLOCKS — v1.35. Patterns → Workspace Blocks. Lifted from the TrackingMCP workspace and
   approved by the owner (2026-10-02). One build for every block: a frame (Glass 1) holding the head, ONE
   card under it, quiet tiles on the card. The higher a layer, the lighter it is, never the reverse. Space
   separates sections: no divider lines between figures or under heads (row hairlines in lists and tables
   stay). Tokens: Workspace Blocks in :root. ==== */
.u-ground{ background:var(--bg-ground); }
/* The block. */
.block-frame{ display:flex; flex-direction:column; min-width:0; padding:var(--sp-4); border-radius:var(--radius-32); background:var(--block-frame-bg); }
.block-head{ display:flex; flex-direction:column; gap:var(--sp-2); margin:var(--sp-3) var(--sp-3) var(--sp-5) var(--sp-5); }
.block-head-row{ display:flex; align-items:center; gap:var(--sp-4); min-height:36px; min-width:0; }
.block-title{ margin:var(--sp-0); font-family:var(--font-display); font-size:var(--fs-4); font-weight:var(--fw-semibold); line-height:var(--lh-1); color:var(--text-primary); }
/* A count on the title's line ("221 of 221"), in the subtitle's quiet type. */
.block-count{ margin-left:var(--sp-2); font-family:var(--font-sans); font-size:var(--fs-2); font-weight:var(--fw-regular); color:var(--text-secondary); font-variant-numeric:tabular-nums; white-space:nowrap; }
.block-sub{ margin:var(--sp-0); max-width:66ch; font-size:var(--fs-1); line-height:var(--lh-4); color:var(--text-secondary); }
.block-actions{ display:inline-flex; align-items:center; gap:var(--sp-2); margin-left:auto; }
.block-card{ flex:1 1 auto; display:flex; flex-direction:column; gap:var(--sp-6); min-width:0; padding:var(--sp-7); border-radius:var(--radius-24); background:var(--block-card-bg); }
/* A block with no head of its own is the card alone, at the frame's corner. */
.block-card.is-bare{ border-radius:var(--radius-32); }
/* Tiles: one quiet step on the card, no outline, a small gap instead of dividers. */
.block-tiles{ display:flex; flex-direction:column; gap:var(--sp-3); margin:var(--sp-0); padding:var(--sp-0); list-style:none; }
.block-tile{ display:block; min-width:0; padding:var(--sp-5) var(--sp-6); border:1px solid transparent; border-radius:var(--radius-16); background:var(--block-tile-bg); color:inherit; font:inherit; text-align:left; }
:is(a, button, [role="button"]).block-tile, .block-tile.clickable{ cursor:pointer; transition:background var(--dur-default) var(--ease-out), box-shadow var(--dur-default) var(--ease-out); }
:is(a, button, [role="button"]).block-tile:hover, .block-tile.clickable:hover{ background:linear-gradient(var(--layer-hover), var(--layer-hover)), var(--block-tile-bg); }
:is(a, button, [role="button"]).block-tile:focus-visible, .block-tile.clickable:focus-visible{ outline:none; box-shadow:var(--ring-focus); }
.block-tile.selected, .block-tile[aria-pressed="true"]{ box-shadow:inset 0 0 0 2px var(--selected-mark); }
.block-tile.disabled, .block-tile[aria-disabled="true"]{ color:var(--text-disabled); cursor:not-allowed; }
/* What sits on a layer moves one step up with it, or it vanishes into it. */
.block-card .prog-linear{ background:var(--block-tile-bg); box-shadow:none; }
.block-tile .prog-linear{ background:var(--block-track); }
.block-card .seg-control{ background:var(--block-tile-bg); border-color:transparent; }
/* A table on a block is flat: no second card, no shadow, no header slab, and every column reads from the left. */
.block-card .dt-wrap{ background:transparent; border:none; border-radius:var(--sp-0); box-shadow:none; }
.block-card .dt-wrap thead th{ background:transparent; }
.block-card .dt-wrap :is(th, td){ text-align:left; }
/* The block's way out and its head controls: a round button on the frame, on the card's fill. */
.icon-btn.block-action{ background:var(--block-card-bg); color:var(--text-primary); }
.icon-btn.block-action:hover{ background:color-mix(in srgb, var(--text-primary) 6%, var(--block-card-bg)); }
.icon-btn.block-action.has-active{ position:relative; }
.icon-btn.block-action.has-active::after{ content:''; position:absolute; top:6px; right:6px; width:8px; height:8px; border-radius:50%; background:var(--accent); box-shadow:0 0 0 2px var(--block-card-bg); }

/* The controls row: search first, then filter chips, then selects; a segmented switch ends the row. On the
   page it sits on a tray (the block's frame); inside a block or a dialog it is the content and has none. */
.controls-row{ display:flex; align-items:center; flex-wrap:wrap; gap:var(--sp-4); min-width:0; max-width:100%; }
.controls-row.tray{ padding:var(--sp-3); border-radius:var(--radius-32); background:var(--block-frame-bg); }
.controls-row .mini-select{ height:32px; min-width:140px; padding:var(--sp-0) var(--space-control-inset-sm); font-size:var(--fs-1); }
.controls-row > .seg-control:last-child{ margin-left:auto; }

/* Selected is the brand blue: a chosen chip is a solid blue pill with white ink; a chosen card or tile keeps
   its own fill and takes a 2px blue ring (no pale wash, no thin edge). Buttons, links and focus are unchanged. */
.chip-opt.selected, .chip-opt.selected:hover{ background:var(--selected-mark); border-color:var(--selected-mark); color:var(--selected-mark-ink); }
.card.selected, .card.clickable.selected:hover{ background:var(--bg-base); border-color:transparent; box-shadow:inset 0 0 0 2px var(--selected-mark), var(--shadow-surface-rest); }
.ash-frame.ash-glass .card.selected, .ash-frame.ash-glass .card.clickable.selected:hover{ background:var(--glass-card-bg); border-color:transparent; box-shadow:inset 0 0 0 2px var(--selected-mark); }

/* Status badges are solid: the 300 step with dark ink (the .step-pill recipe), the same on both themes;
   on the move is blue, error is the semantic error (NAVO red is never Error). Alerts, banners and status
   text keep their tonal pairs. */
.mini-badge.success, .mini-badge.live, :root[data-theme="dark"] .mini-badge.live{ background:var(--badge-solid-success-bg); color:var(--badge-solid-success-text); }
.mini-badge.live .bdot{ background:var(--badge-solid-success-text); }
.mini-badge.warning{ background:var(--badge-solid-warning-bg); color:var(--badge-solid-warning-text); }
.mini-badge.info{ background:var(--badge-solid-info-bg); color:var(--badge-solid-info-text); }
.mini-badge.error{ background:var(--badge-solid-error-bg); color:var(--badge-solid-error-text); }
.mini-badge.neutral{ background:var(--badge-solid-neutral-bg); color:var(--badge-solid-neutral-text); }

/* People: initials on one of six palette hues picked from the person (data-hue 0–5), dark ink; a photo,
   an icon and the dashed unknown keep their own. --avatar-size sizes any avatar and its type with it. */
.mini-avatar[data-hue]:not(.image):not(.icon):not(.fallback):not(.more){ background:var(--avatar-hue, var(--avatar-hue-0)); color:var(--n-950); }
.mini-avatar[data-hue="0"]{ --avatar-hue:var(--avatar-hue-0); } .mini-avatar[data-hue="1"]{ --avatar-hue:var(--avatar-hue-1); }
.mini-avatar[data-hue="2"]{ --avatar-hue:var(--avatar-hue-2); } .mini-avatar[data-hue="3"]{ --avatar-hue:var(--avatar-hue-3); }
.mini-avatar[data-hue="4"]{ --avatar-hue:var(--avatar-hue-4); } .mini-avatar[data-hue="5"]{ --avatar-hue:var(--avatar-hue-5); }
.mini-avatar.sized, .avatar-mark{ width:var(--avatar-size, 32px); height:var(--avatar-size, 32px); flex-shrink:0; }
.mini-avatar.sized{ font-size:calc(var(--avatar-size, 32px) * .42); letter-spacing:0; }
.avatar-mark{ display:inline-grid; place-items:center; }

/* The journey (the ProgressTrack's logic on every voyage visual): done blue, the leg into now blue to lime,
   now a lime point that always pulses. .journey-now adds the pulse to a dot that has its own size;
   .journey-now-dot is a stand-alone 12px point; .prog-linear.journey-bar is a voyage bar. */
.journey-now-dot{ display:block; width:12px; height:12px; border-radius:50%; }
.journey-now-dot, .journey-now{ position:relative; background:var(--journey-now); border-color:transparent; box-shadow:none; }
.journey-now-dot::after, .journey-now::after{ content:''; position:absolute; inset:-5px; border-radius:50%; background:var(--journey-now); animation:navo-live-pulse 2s cubic-bezier(.22,.61,.36,1) infinite; pointer-events:none; }
.journey-now-ring{ transform-box:fill-box; transform-origin:center; animation:navo-live-pulse 2s cubic-bezier(.22,.61,.36,1) infinite; pointer-events:none; }
.prog-linear.journey-bar{ overflow:visible; }
.prog-linear.journey-bar > span{ position:relative; background:linear-gradient(to right in oklch, var(--journey-done) 0 35%, var(--journey-now)); }
.prog-linear.journey-bar > span::after{ content:''; position:absolute; top:50%; right:-6px; width:12px; height:12px; margin-top:-6px; border-radius:50%; background:var(--journey-now); animation:journey-head 2s cubic-bezier(.22,.61,.36,1) infinite; }
@keyframes journey-head{ 0%{ box-shadow:0 0 0 0 color-mix(in srgb, var(--journey-now) 60%, transparent); } 70%,100%{ box-shadow:0 0 0 10px color-mix(in srgb, var(--journey-now) 0%, transparent); } }
.prog-linear.journey-bar.is-complete > span{ background:var(--journey-done); }
.prog-linear.journey-bar.is-complete > span::after{ display:none; }
@media (prefers-reduced-motion: reduce){
  .journey-now-dot::after, .journey-now::after, .journey-now-ring{ animation:none; opacity:.3; }
  .prog-linear.journey-bar > span::after{ animation:none; }
}
/* Stage marks: one hue per shipment stage, a swatch for keys and legends. */
.stage-swatch{ display:inline-block; width:10px; height:10px; border-radius:3px; flex-shrink:0; background:var(--stage, var(--stage-pre)); }
.stage-swatch.pre{ --stage:var(--stage-pre); } .stage-swatch.sea{ --stage:var(--stage-sea); } .stage-swatch.ts{ --stage:var(--stage-ts); }
.stage-swatch.arr{ --stage:var(--stage-arr); } .stage-swatch.port{ --stage:var(--stage-port); } .stage-swatch.done{ --stage:var(--stage-done); }

/* Floating panels on a control (InfoPop, FilterPop): the navigation dropdown's glass panel, opened under its
   button, closed by Escape or a click outside. Right-aligned under a head button; .align-start under a field. */
.pop-anchor{ position:relative; display:inline-flex; }
.pop-anchor > .lp-navdrop-panel.pop-panel{ left:auto; right:var(--sp-0); transform:none; top:calc(100% + var(--sp-4)); width:300px; max-width:calc(100vw - var(--sp-8)); padding:var(--sp-5); text-align:left; }
.pop-anchor > .lp-navdrop-panel.pop-panel.align-start{ left:var(--sp-0); right:auto; }
.pop-anchor > .lp-navdrop-panel.pop-panel.is-key{ width:auto; min-width:240px; max-width:320px; }
.pop-anchor > .lp-navdrop-panel.pop-panel.is-options{ width:440px; max-height:min(560px, 70vh); overflow-y:auto; padding:var(--sp-3); }
.pop-title{ margin-bottom:var(--sp-4); font-size:var(--fs-2); font-weight:var(--fw-medium); color:var(--text-primary); }
/* A key in a panel: the marks and words a legend would carry, one per line. */
.pop-key{ display:flex; flex-direction:column; gap:var(--sp-4); margin:var(--sp-0); padding:var(--sp-0); list-style:none; font-size:var(--fs-1); color:var(--text-secondary); }
.pop-key > li{ display:flex; align-items:center; gap:var(--sp-4); }
/* FilterPop options: a compact two-line row each, the name with its figures under it, badges beside. */
.pop-options{ display:flex; flex-direction:column; gap:var(--sp-2); margin:var(--sp-0); padding:var(--sp-0); list-style:none; }
.pop-option{ display:grid; grid-template-columns:minmax(0,1fr) auto; grid-template-areas:"title trail" "meta trail"; align-items:center; column-gap:var(--sp-4); row-gap:var(--sp-1); width:100%; padding:var(--sp-3) var(--sp-4); border:0; border-radius:var(--radius-16); background:var(--block-tile-bg); font-family:var(--font-sans); text-align:left; color:var(--text-primary); cursor:pointer; transition:background var(--dur-default) var(--ease-out); }
.pop-option:hover{ background:linear-gradient(var(--layer-hover), var(--layer-hover)), var(--block-tile-bg); }
.pop-option:focus-visible{ outline:none; box-shadow:var(--ring-focus); }
.pop-option[aria-pressed="true"], .pop-option.selected{ box-shadow:inset 0 0 0 2px var(--selected-mark); }
.pop-option-title{ grid-area:title; display:flex; align-items:center; gap:var(--sp-3); min-width:0; font-size:var(--fs-2); font-weight:var(--fw-semibold); }
.pop-option-title > span:last-child{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.pop-option-meta{ grid-area:meta; font-size:var(--fs-1); color:var(--text-tertiary); font-variant-numeric:tabular-nums; }
.pop-option-meta b{ color:var(--text-primary); font-weight:var(--fw-semibold); }
.pop-option.has-lead .pop-option-meta{ padding-left:calc(var(--avatar-size, 22px) + var(--sp-3)); }
.pop-option-trail{ grid-area:trail; display:flex; align-items:center; justify-content:flex-end; gap:var(--sp-2); }
@media (max-width:600px){
  .pop-option{ grid-template-columns:minmax(0,1fr); grid-template-areas:"title" "meta" "trail"; }
  .pop-option-trail{ justify-content:flex-start; flex-wrap:wrap; padding-top:var(--sp-1); }
}

/* Menus that float over the page (SelectField, ActionMenu, DateField): the select surface, portalled with a
   fixed position so a block's clipping never cuts it. A menu row hovers with the layer wash, never the
   sunken fill (which is n-950 on the dark scheme). The keyboard's row reads as the pointer's. */
.select-menu .opt:hover, .select-menu .opt.is-active{ background:var(--layer-hover); color:var(--text-primary); }
.select-menu .opt.selected:hover, .select-menu .opt.selected.is-active{ background:var(--accent-wash); color:var(--accent); }
.select-menu.is-floating{ position:fixed; z-index:1010; max-height:min(320px, 50vh); margin:var(--sp-3) var(--sp-0); overflow-x:hidden; overflow-y:auto; scrollbar-width:thin; scrollbar-color:var(--border-strong) transparent; }
.mini-select.is-field{ min-width:140px; }
.mini-select.is-field > span:first-child{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.mini-select.is-field:focus-visible{ outline:none; box-shadow:var(--ring-focus); }
/* ActionMenu: a row's ⋯ menu. */
.action-menu .opt{ justify-content:flex-start; width:100%; border:0; background:none; font-family:var(--font-sans); font-size:var(--fs-1); color:var(--text-primary); text-align:left; cursor:pointer; }
.action-menu .opt:focus-visible{ outline:none; background:var(--layer-hover); }
.action-menu .opt:disabled{ color:var(--text-disabled); cursor:not-allowed; }
.action-menu .opt.is-danger, .action-menu .opt.is-danger svg{ color:var(--badge-error-text); }
.action-menu-label{ display:inline-flex; align-items:center; gap:var(--sp-3); }
.action-menu-label svg{ width:14px; height:14px; color:var(--text-tertiary); }
/* DateField: the select trigger with a calendar glyph, a month grid on the select surface. A day is a 36px
   pill: hover lightens, the chosen day is the calendar fill, today wears the calendar ring. */
button.mini-select.date-field{ min-width:150px; font-family:var(--font-sans); text-align:left; }
.date-menu.select-menu{ max-height:none; overflow:visible; padding:var(--sp-5); }
.date-head{ display:flex; align-items:center; gap:var(--sp-1); margin-bottom:var(--sp-4); }
.date-title{ display:inline-flex; align-items:center; gap:var(--sp-2); padding:var(--sp-2) var(--sp-3); border:0; border-radius:var(--r-pill); background:none; font-family:var(--font-sans); font-size:var(--fs-2); font-weight:var(--fw-semibold); color:var(--text-primary); cursor:pointer; }
.date-title:hover{ background:var(--layer-hover); }
.date-title svg{ width:14px; height:14px; color:var(--text-tertiary); }
.date-grid{ width:100%; border-collapse:separate; border-spacing:0 var(--sp-1); table-layout:fixed; }
.date-grid td{ padding:var(--sp-0); text-align:center; }
.date-wd{ height:28px; padding:var(--sp-0); font-size:var(--fs-1); font-weight:var(--fw-regular); color:var(--text-tertiary); }
.date-day{ width:36px; height:36px; border:0; border-radius:var(--r-pill); background:none; font-family:var(--font-sans); font-size:var(--fs-1); font-variant-numeric:tabular-nums; color:var(--text-primary); cursor:pointer; transition:background var(--dur-default) var(--ease-out); }
.date-day:hover{ background:var(--layer-hover); }
.date-day.is-outside{ color:var(--text-disabled); }
.date-day.is-today{ box-shadow:inset 0 0 0 1px var(--cal-ink); color:var(--cal-ink); font-weight:var(--fw-semibold); }
.date-day.is-selected, .date-day.is-selected:hover{ background:var(--cal-fill); box-shadow:none; color:var(--n-0); font-weight:var(--fw-semibold); }
.date-day:focus-visible, .date-month:focus-visible, .date-title:focus-visible{ outline:none; box-shadow:var(--ring-focus); }
.date-day.is-today:focus-visible{ box-shadow:inset 0 0 0 1px var(--cal-ink), var(--ring-focus); }
.date-day.is-disabled, .date-day.is-disabled:hover{ background:none; color:var(--text-disabled); text-decoration:line-through; cursor:not-allowed; } /* v1.36 — a day before the field's min */
.date-months{ display:grid; grid-template-columns:repeat(3, 1fr); gap:var(--sp-2); }
.date-month{ height:40px; border:0; border-radius:var(--r-pill); background:none; font-family:var(--font-sans); font-size:var(--fs-1); color:var(--text-primary); cursor:pointer; }
.date-month:hover, .date-month.is-focus{ background:var(--layer-hover); }
.date-month.is-selected, .date-month.is-selected:hover{ background:var(--cal-fill); color:var(--n-0); font-weight:var(--fw-semibold); }
.date-foot{ display:flex; justify-content:space-between; margin-top:var(--sp-4); }
.controls-row button.mini-select.date-field{ height:32px; padding:var(--sp-0) var(--space-control-inset-sm); font-size:var(--fs-1); }
