/**
 * Plugin SDK v2 — Component Stylesheet
 *
 * Single source of truth for all ui-* element styles.
 * Edit this file directly. No build step required.
 */

/* ══════════════════════════════════════════════════════════════════
   DEFAULT DESIGN TOKENS (on :root — cascades to all elements
   including portaled popovers/modals appended to <body>).
   Theme overrides are scoped to ui-app[theme] / ui-platform[theme].
   ══════════════════════════════════════════════════════════════════ */

:root {
  --bg: #0f1117;
  --surface: #1a1d27;
  --surface-2: #242836;
  --surface-3: #2e3345;
  --border: #363b4e;
  --text: #e4e6ef;
  /* Must exist in the BASE scope, not only in :root[theme='light'].
     It is consumed unconditionally (.vs-segment[aria-pressed="true"] sets
     color: var(--text-on-accent) on a var(--accent) background), so defining
     it only for the light theme left it resolving to EMPTY in dark mode — the
     default — and the text fell back to whatever it inherited.
     Found by tools/sdk-test.mjs `tokens-resolved`.
     NOTE: white on --accent measures 4.02:1 in dark mode, which fails WCAG AA
     for normal text. Raising that is ND-101's scope; this only stops the
     value being empty. */
  --text-on-accent: #ffffff;
  --text-muted: #8b8fa5;
  --text-dim: #5c6078;
  --accent: #7c6bf0;
  --accent-dim: rgba(124, 107, 240, 0.15);
  /* Derived from --accent so a carrier rebrand carries into hover states for
     free. Previously undefined while being referenced at two sites with
     DIFFERENT hardcoded fallbacks (#9688f5 and #9b8bf5), so the fallback was
     the only value that ever applied and the two disagreed. The 80% mix
     reproduces #9688f5 to within one step. Light theme mixes toward black
     instead — see :root[theme='light']. */
  --accent-hover: color-mix(in srgb, var(--accent) 80%, var(--white));
  --info: #3b82f6;
  --info-bg: rgba(59, 130, 246, 0.12);
  --warning: #f59e0b;
  --warning-bg: rgba(245, 158, 11, 0.12);
  --success: #22c55e;
  --success-bg: rgba(34, 197, 94, 0.12);
  --danger: #ef4444;
  --danger-bg: rgba(239, 68, 68, 0.12);
  --muted: #6b7280;
  --white: #ffffff;
  --black: #000000;
  /* Aliased to --surface-3 rather than kept as its former hardcoded #2a2d3a.
     It was referenced once (the floating selection bar in ui-attachments) as
     `var(--surface-elevated, #2a2d3a)` while never being defined anywhere, so
     the dark literal was the only value that ever applied — including in light
     mode, where it rendered a dark bar on a light page. Aliasing fixes that,
     at the cost of a 4-step colour shift in dark mode on that one element. */
  --surface-elevated: var(--surface-3);

  /* ── Chart series palette ──────────────────────────────────────────
     The multi-series identity palette, formerly hardcoded as hex literals in
     elements/dashboard/chart-utils.js where no carrier override could reach
     it — a rebranded deployment kept drawing OneShield purple in every chart.
     Values are unchanged from those literals; --chart-1 now tracks --accent so
     the primary series rebrands with no extra work.

     Deliberately NOT tokenised: the sequential and diverging ramps in
     chart-utils.js and ui-chart-heatmap.js. Those encode magnitude and
     direction, not identity — same reasoning as the status colours. */
  --chart-1: var(--accent);
  --chart-2: #3b82f6;
  --chart-3: #22c55e;
  --chart-4: #f59e0b;
  --chart-5: #ef4444;
  --chart-6: #06b6d4;
  --chart-7: #ec4899;
  --chart-8: #8b5cf6;
  --chart-9: #14b8a6;
  --chart-10: #f97316;

  /* ── Carrier logo ─────────────────────────────────────────────────
     Consumed by .app-switcher-trigger::before. All four move together; the
     copy-paste recipe lives in the platform plugin's ui/branding/tokens.css.

     --brand-logo-on is the generation switch and it is load-bearing: a
     generated pseudo-element is a flex item and therefore consumes the
     trigger's `gap` even at zero size, which would shift the header of every
     deployment that ships no logo. `content: none` generates nothing at all,
     so the default here is byte-identical to having no logo seam.

     Width and height are both explicit because `background-size: contain`
     needs a box to fit into. Set width to match the logo's aspect ratio at
     the chosen height — verified in Chrome that `content: url()` with
     `width: auto` does NOT derive width from the intrinsic ratio, it takes
     the intrinsic width and squashes, so that shortcut is not available. */
  --brand-logo: none;
  --brand-logo-on: none;
  --brand-logo-width: 96px;
  --brand-logo-height: 20px;
  /* Set to `none` when the logo already contains the company wordmark, so the
     app-switcher shows the mark alone instead of mark + duplicated text. */
  --brand-wordmark-display: block;
  --spacing-1: 2px;
  --spacing-2: 4px;
  --spacing-3: 6px;
  --spacing-4: 8px;
  --spacing-5: 10px;
  --spacing-6: 12px;
  --spacing-7: 16px;
  --spacing-8: 24px;
  --spacing-9: 32px;
  --spacing-10: 48px;
  /* Radius scale. --radius-sm and --radius-full were referenced by newer
     sections but never defined, so 6 declarations silently resolved to 0.
     Values chosen to match the dominant raw usage already in this file:
     6px appears 34 times (vs 4px 29), and 999px 5 times (vs 99px 3).
     ND-100 formalises the full scale and migrates the remaining raw values. */
  --radius-2xs: 3px;
  --radius-xs: 4px;
  --radius-sm: 6px;
  --radius: 8px;
  --radius-md: 10px;
  --radius-lg: 12px;
  --radius-full: 999px;
  --radius-circle: 50%;
  /* --radius-2xs/xs/md/circle added by ND-100 for values with 8+ uses that had no
     token: 4px (29 uses), 50% (17), 10px (11), 3px (8). The remaining long tail —
     5px, 9px, 7px, 2px, 1px, 14px, 16px and a 99px that means the same as
     --radius-full — is left inline and reported by lint as shrink-only debt,
     rather than rounded into a neighbouring step. Rounding would be a redesign,
     and this commit is a refactor. */
  --font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --mono: 'JetBrains Mono', 'Fira Code', monospace;


  /* ── Typography (ND-100) ──────────────────────────────────────────────────
     317 font-size, 156 font-weight and 50 line-height declarations were literal
     and none were tokenised, while colour and spacing were near-fully disciplined
     (2,029 var() uses). Values here are the EXACT ones already in use, so this
     moves no pixels; the scale is descriptive, not a redesign.

     Named --fs-/--fw-/--lh- rather than --text-*, because --text, --text-muted,
     --text-dim and --text-on-accent are COLOUR tokens. --text-sm sitting beside
     --text-muted would be actively misleading.

     Sizes cluster hard: 12/13/11/14/10px account for 290 of the 317 uses, which
     is why the scale is dense at the bottom and sparse above 16px. Ten
     declarations sit OFF this scale (8px, 12.5px, 15px, 17px, 22px and one
     font-size: 0) and are deliberately left inline — lint reports them as
     shrink-only debt so they stay visible instead of being quietly rounded into a
     neighbouring step, which would be a redesign disguised as a refactor. */
  /* 8px and 17px are MISSING STEPS, not off-scale accidents: 8px is both sidebar
     chevrons and 17px is every dialog/drawer/hero title. Each was already used
     consistently for one role, so naming them changes nothing and removes 5
     declarations from the off-scale list. */
  --fs-3xs: 8px;
  --fs-2xs: 9px;
  --fs-xs: 10px;
  --fs-sm: 11px;
  --fs-base: 12px;
  --fs-md: 13px;
  --fs-lg: 14px;
  --fs-xl: 16px;
  --fs-title: 17px;   /* dialog, drawer and hero titles */
  --fs-2xl: 18px;
  --fs-3xl: 20px;
  --fs-4xl: 24px;
  --fs-5xl: 28px;

  --fw-light: 300;
  --fw-normal: 400;
  --fw-medium: 500;
  --fw-semibold: 600;
  --fw-bold: 700;
  --fw-extrabold: 800;

  /* Not typography — the technique for removing inline-box descender space under
     an icon. Named so it is on-scale rather than reported as a stray 0. */
  --lh-flush: 0;
  --lh-none: 1;
  --lh-tight: 1.3;
  --lh-snug: 1.35;
  --lh-normal: 1.4;
  --lh-relaxed: 1.5;
  --lh-loose: 1.6;

  /* ── Stacking order (ND-100) ──────────────────────────────────────────────
     Before this, z-index was assigned ad hoc and had escalated to the sequence
     1, 2, 5, 10, 11, 20, 100, 1000, 9999, 10000, 11000 with FOUR-, THREE- and
     TWO-WAY TIES. A tie means DOM order decides which element wins, so adding a
     component could silently reorder existing ones, and a select inside a dialog
     was 1000 against a dialog backdrop of 1000.

     There are two bands, and the distinction is what the old numbers were
     groping towards:

     LOCAL — the element stays inside its component's subtree, so it only has to
     clear its own siblings. These are small on purpose.

     GLOBAL — the element is mounted on document.body or covers the viewport, so
     its value is a real contract against every other global layer. Ordering here
     is deliberate, not inherited:

       modal    < dropdown   a dropdown opened inside a dialog must appear over it
       modal    < toast      a notification must never be hidden by a modal
       dropdown < popover    a popover can be anchored to a dropdown item
       *        < tooltip    transient, pointer-events:none, must never be hidden

     Gaps of 100 leave room to insert a layer without renumbering, which is how
     the original values ran away. */

  /* Local band */
  --z-raised: 1;      /* chips, prefixes, background layers */
  --z-elevated: 2;    /* list/section headers above their own rows */
  --z-loading: 5;     /* in-component loading veil */
  --z-sticky: 10;     /* sticky headers, resize handles */
  --z-drag: 20;       /* drag-and-drop overlay */
  --z-menu: 100;      /* in-subtree menus and dropdowns, global header */


  /* ── Elevation (ND-100) ───────────────────────────────────────────────────
     Named by ROLE, because the roles already existed and the values did not
     agree with them. Values are the EXACT ones previously inline, so this
     commit moves no pixels.

     What the naming exposes, and what should be consolidated as a deliberate
     design decision rather than smuggled into a refactor:

       dropdowns used THREE different shadows — --elev-dropdown (4 uses),
       --elev-menu (3 uses) and --elev-dropdown-sm (1 use, .lt-dropdown)
       modals used THREE — --elev-modal (dialog + drawer), --elev-overlay
       (document viewer) and --elev-modal-lg (app launcher)

     --elev-dropdown-sm, --elev-overlay, --elev-modal-lg and --elev-image are
     single-use and named so they are greppable; they are the candidates for
     collapsing into the tier above them. Focus and status rings (0 0 0 Npx, and
     the 0 0 4px status glows) are deliberately NOT in this scale — they are state
     indicators, not elevation, and belong with the colour tokens. */
  --elev-raised: 0 1px 2px rgba(0, 0, 0, 0.2);
  --elev-card: 0 2px 8px rgba(0, 0, 0, 0.2);
  --elev-tooltip: 0 4px 12px rgba(0, 0, 0, 0.3);
  --elev-menu: 0 8px 24px rgba(0, 0, 0, 0.3);
  --elev-menu-up: 0 -8px 24px rgba(0, 0, 0, 0.3);
  --elev-dropdown: 0 8px 24px rgba(0, 0, 0, 0.4);
  --elev-popover: 0 16px 48px rgba(0, 0, 0, 0.25), 0 4px 12px rgba(0, 0, 0, 0.15);
  --elev-modal: 0 20px 60px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.04);
  --elev-dropdown-sm: 0 4px 16px rgba(0, 0, 0, 0.3);
  --elev-overlay: 0 16px 48px rgba(0, 0, 0, 0.5);
  --elev-modal-lg: 0 24px 64px rgba(0, 0, 0, 0.35);
  --elev-image: 0 2px 12px rgba(0, 0, 0, 0.3);

  /* Global band — body-mounted or viewport-covering */
  --z-modal: 1100;    /* dialog, drawer, app launcher, document viewer (+n when stacked) */
  --z-dropdown: 1300; /* body-mounted dropdowns */
  --z-popover: 1400;  /* body-mounted popovers */
  --z-toast: 1500;    /* notifications */
  --z-tooltip: 1600;  /* topmost, transient */
  /* The gap above --z-modal is 200, not 100, because it is the ONE layer that
     increments: ui-dialog stacks nested dialogs at --z-modal + n. With a gap of
     100 a 100-deep stack would tie with --z-dropdown, and a tie is precisely the
     defect this scale exists to remove. Every other gap can stay at 100 because
     nothing else counts upwards. */
}

:root[density='compact'] {
  --spacing-1: 1px;
  --spacing-2: 2px;
  --spacing-3: 4px;
  --spacing-4: 6px;
  --spacing-5: 8px;
  --spacing-6: 8px;
  --spacing-7: 12px;
  --spacing-8: 16px;
  --spacing-9: 24px;
  --spacing-10: 32px;
}

:root[density='comfortable'] {
  --spacing-1: 3px;
  --spacing-2: 6px;
  --spacing-3: 8px;
  --spacing-4: 12px;
  --spacing-5: 14px;
  --spacing-6: 16px;
  --spacing-7: 24px;
  --spacing-8: 32px;
  --spacing-9: 40px;
  --spacing-10: 56px;
}

:root[theme='light'] {
  --bg: #ffffff;
  --surface: #f8f9fa;
  --surface-2: #f0f1f3;
  --surface-3: #e8e9ec;
  --border: #e0e2e7;
  --text: #1a1d27;
  --text-on-accent: #ffffff;
  --text-muted: #6b7280;
  --text-dim: #9ca3af;
  --accent: #6d5ce7;
  --accent-dim: rgba(109, 92, 231, 0.12);
  /* Mixes toward black, not white: on a light background a hover state has to
     darken to read as emphasis. The dark-theme definition mixes toward white. */
  --accent-hover: color-mix(in srgb, var(--accent) 85%, var(--black));
  --info: #2563eb;
  --info-bg: rgba(37, 99, 235, 0.08);
  --warning: #d97706;
  --warning-bg: rgba(217, 119, 6, 0.08);
  --success: #16a34a;
  --success-bg: rgba(22, 163, 74, 0.08);
  --danger: #dc2626;
  --danger-bg: rgba(220, 38, 38, 0.08);
  --muted: #9ca3af;
  --white: #ffffff;
  --black: #000000;
}

/* ══════════════════════════════════════════════════════════════════
   PLUGIN-SDK TOKEN BRIDGE
   Maps SDK design tokens → plugin-sdk component tokens (--ui-*).
   Plugin-SDK shadow DOM components (ui-pdf-viewer, ui-marker-list,
   ui-floating-panel, ui-color-legend, etc.) inherit these via :root.
   ══════════════════════════════════════════════════════════════════ */

:root {
  --ui-background: var(--surface);
  --ui-foreground: var(--text);
  --ui-border: var(--border);
  --ui-muted: var(--surface-2);
  --ui-muted-foreground: var(--text-muted);
  --ui-accent: var(--accent-dim);
  --ui-ring: var(--accent);
  --ui-radius: var(--radius);
}

/* ══════════════════════════════════════════════════════════════════
   RESET
   ══════════════════════════════════════════════════════════════════ */

*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
body {
  margin: 0;
  line-height: var(--lh-relaxed);
  -webkit-font-smoothing: antialiased;

  /* Typography and palette belonged ONLY to ui-platform, so any page without
     the app shell fell back to the UA default and rendered in Times. The login
     page did exactly that. sdk.css has to be self-sufficient for a page that
     is not the app — ui-platform sets these on itself anyway, so the shell is
     unaffected. */
  font-family: var(--font);
  color: var(--text);
  background: var(--bg);
}

/* An element with a display rule beats the UA stylesheet's
   [hidden] { display: none }, so `hidden` silently did nothing on ui-form,
   ui-button and every other element sdk.css gives a display to — the login
   page rendered its MFA step and its Back button permanently. This was already
   known and patched per-element for ui-report-builder; it needs to be general.
   Author-level and !important, because the element rules it must beat are also
   author-level. */
[hidden] {
  display: none !important;
}

/* ══════════════════════════════════════════════════════════════════
   LAYOUT — ui-platform (Multi-App Shell)
   ══════════════════════════════════════════════════════════════════ */

ui-platform {
  display: grid;
  grid-template-rows: var(--header-height, 56px) 1fr;
  height: 100vh;
  max-height: 100vh;
  width: 100%;
  font-family: var(--font), serif;
  background: var(--bg);
  color: var(--text);

  /* Platform-specific layout tokens (not duplicating :root palette) */
  --header-height: 56px;
  --header-bg: var(--surface);
  --header-border: var(--border);
  --header-text: var(--text);
  --header-accent: var(--accent);
}


ui-platform > ui-global-header {
  grid-row: 1;
  grid-column: 1;
}

ui-platform > ui-app {
  grid-row: 2;
  grid-column: 1;
  min-height: 0;
  height: 100%;
  overflow: hidden;
}

/* ══════════════════════════════════════════════════════════════════
   LAYOUT — ui-global-header + child components
   ══════════════════════════════════════════════════════════════════ */

ui-global-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: var(--header-height, 56px);
  padding: 0 var(--spacing-7);
  background: var(--header-bg, var(--surface));
  border-bottom: 1px solid var(--header-border, var(--border));
  position: sticky;
  top: 0;
  z-index: var(--z-menu);
}

/* ── Header Actions (right side) ──────────────────────────────── */

ui-header-actions {
  display: flex;
  align-items: center;
  gap: var(--spacing-2);
}

ui-header-actions ui-theme-toggle {
  display: flex;
  align-items: center;
}

ui-header-actions .theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: var(--radius);
  border: none;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
  padding: 0;
  font-size: 0;
}

ui-header-actions .theme-toggle:hover {
  background: var(--surface-2);
  color: var(--text);
}

ui-header-actions .theme-toggle svg {
  width: 20px;
  height: 20px;
}

.header-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: var(--radius);
  border: none;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
  position: relative;
}

.header-icon-btn:hover {
  background: var(--surface-2);
  color: var(--text);
}

.header-icon-btn svg {
  width: 20px;
  height: 20px;
}

/* ── App Switcher Trigger ─────────────────────────────────────── */

.app-switcher-trigger {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-4);
  padding: var(--spacing-3) var(--spacing-5);
  border-radius: var(--radius);
  border: none;
  background: transparent;
  color: var(--text);
  cursor: pointer;
  font-family: var(--font);
  font-size: var(--fs-lg);
  font-weight: var(--fw-medium);
  transition: background 0.15s;
}

.app-switcher-trigger:hover {
  background: var(--surface-2);
}

/* Carrier logo. The only brand-image seam in the v3 shell, and it is CSS-only
   on purpose: introducing a `logo` attribute on <ui-app-switcher> instead would
   put a carrier concern into the frozen authored vocabulary and drag in the
   contract, docs and IntelliSense gates for something no consumer HTML should
   have to know about. Tokens are defined in :root; a carrier sets them in the
   platform plugin's ui/branding/tokens.css.

   Renders nothing until --brand-logo-on is set to '' — see the note on that
   token for why the switch cannot be folded into the width. */
.app-switcher-trigger::before {
  content: var(--brand-logo-on);
  width: var(--brand-logo-width);
  height: var(--brand-logo-height);
  background-image: var(--brand-logo);
  background-size: contain;
  background-repeat: no-repeat;
  background-position: left center;
  flex: none;
}

ui-app-switcher {
  display: flex;
  align-items: center;
  gap: var(--spacing-1);
}

.app-switcher-sidebar-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: var(--radius);
  border: none;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
  padding: 0;
}

.app-switcher-sidebar-toggle:hover {
  background: var(--surface-2);
  color: var(--text);
}

.app-switcher-sidebar-toggle svg {
  width: 20px;
  height: 20px;
}

.app-switcher-label {
  white-space: nowrap;
  /* `block` is the default only because this is already a flex item and an
     inline span is blockified to exactly that — so declaring it moves nothing.
     It exists so a carrier whose logo already contains the wordmark can set
     --brand-wordmark-display: none and avoid rendering the name twice. */
  display: var(--brand-wordmark-display);
}

.app-switcher-chevron svg {
  width: 14px;
  height: 14px;
  color: var(--text-muted);
}

/* ── Notification Bell ────────────────────────────────────────── */

.notification-trigger {
  position: relative;
}

.notification-badge {
  position: absolute;
  top: 4px;
  right: 4px;
  min-width: 16px;
  height: 16px;
  padding: 0 var(--spacing-2);
  border-radius: var(--radius);
  background: var(--danger);
  color: var(--white);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: var(--lh-none);
}

/* ── User Avatar ──────────────────────────────────────────────── */

.user-avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-circle);
  background: var(--accent-dim);
  border: 2px solid var(--border);
  overflow: hidden;
}

.user-avatar-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.user-avatar-initials {
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  color: var(--accent);
}

/* ── Popover ──────────────────────────────────────────────────── */

ui-popover {
  /* Tokens inherited from :root — no duplication needed */
  font-family: var(--font);
  color: var(--text);
  opacity: 0;
  transform-origin: top left;
  transition: opacity 0.15s ease, transform 0.15s ease;
  pointer-events: none;
}


ui-popover.popover-open {
  opacity: 1;
  pointer-events: auto;
}

.popover-panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--elev-popover);
  overflow: hidden;
}

/* ── Switcher Popover ─────────────────────────────────────────── */

.switcher-search {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
  padding: var(--spacing-5) var(--spacing-6);
  border-bottom: 1px solid var(--border);
}

.switcher-search-icon svg {
  width: 16px;
  height: 16px;
  color: var(--text-muted);
}

.switcher-search-input {
  flex: 1;
  border: none;
  background: transparent;
  color: var(--text);
  font-size: var(--fs-md);
  font-family: var(--font);
  outline: none;
}

/* ── Focus ring ── */
/* The rule above strips the UA outline on a borderless input, which left no
   focus indicator at all. Inset offset because the input sits flush inside a
   bordered search container. (ND-35) */
.switcher-search-input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.switcher-search-input::placeholder {
  color: var(--text-dim);
}

.switcher-list {
  padding: var(--spacing-3);
  max-height: 320px;
  overflow-y: auto;
}

.switcher-section-label {
  display: flex;
  align-items: center;
  gap: var(--spacing-3);
  padding: var(--spacing-3) var(--spacing-5) var(--spacing-2);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
}

.switcher-section-label svg {
  width: 12px;
  height: 12px;
}

.switcher-item {
  display: flex;
  align-items: center;
  gap: var(--spacing-5);
  padding: var(--spacing-4) var(--spacing-5);
  border-radius: var(--radius);
  cursor: pointer;
  transition: background 0.1s;
}

.switcher-item:hover {
  background: var(--surface-2);
}

.switcher-item.active {
  background: var(--accent-dim);
  color: var(--accent);
}

.switcher-item-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  flex-shrink: 0;
}

.switcher-item-icon svg {
  width: 18px;
  height: 18px;
}

.switcher-item-label {
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
}

.switcher-empty {
  padding: var(--spacing-7);
  text-align: center;
  font-size: var(--fs-md);
  color: var(--text-muted);
}

.switcher-footer {
  border-top: 1px solid var(--border);
  padding: var(--spacing-3);
}

.switcher-view-all {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: var(--spacing-4) var(--spacing-5);
  border: none;
  background: transparent;
  border-radius: var(--radius);
  color: var(--text-muted);
  font-size: var(--fs-md);
  font-family: var(--font);
  cursor: pointer;
  transition: background 0.1s, color 0.1s;
}

.switcher-view-all:hover {
  background: var(--surface-2);
  color: var(--text);
}

.switcher-view-all-icon svg {
  width: 14px;
  height: 14px;
}

/* ── App Launcher Modal ───────────────────────────────────────── */

.app-launcher-backdrop {
  /* Tokens inherited from :root — no duplication needed */
  font-family: var(--font);
  color: var(--text);
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  animation: fade-in 0.15s ease;
}


.app-launcher-modal {
  width: min(520px, 92vw);
  max-height: min(420px, 80vh);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--elev-modal-lg);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: scale-in 0.2s ease;
}

@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes scale-in {
  from { opacity: 0; transform: scale(0.95); }
  to { opacity: 1; transform: scale(1); }
}

.launcher-header {
  border-bottom: 1px solid var(--border);
}

.launcher-search {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
  padding: var(--spacing-6) var(--spacing-7);
}

.launcher-search-icon svg {
  width: 16px;
  height: 16px;
  color: var(--text-muted);
  flex-shrink: 0;
}

.launcher-search-input {
  flex: 1;
  border: none;
  background: transparent;
  color: var(--text);
  font-size: var(--fs-lg);
  font-family: var(--font);
  outline: none;
}

/* ── Focus ring ── */
/* See .switcher-search-input — same borderless-input-in-a-container shape. (ND-35) */
.launcher-search-input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.launcher-search-input::placeholder {
  color: var(--text-dim);
}

.launcher-close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: none;
  background: transparent;
  border-radius: var(--radius);
  color: var(--text-muted);
  cursor: pointer;
  transition: background 0.1s;
}

.launcher-close:hover {
  background: var(--surface-2);
  color: var(--text);
}

.launcher-close svg {
  width: 16px;
  height: 16px;
}

.launcher-grid {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: var(--spacing-6);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--spacing-4);
  align-content: start;
}

.launcher-card {
  display: flex;
  align-items: center;
  gap: var(--spacing-5);
  padding: var(--spacing-5) var(--spacing-6);
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text);
  cursor: pointer;
  font-family: var(--font);
  text-align: left;
  transition: background 0.1s, border-color 0.1s, transform 0.1s;
}

.launcher-card:hover {
  background: var(--surface-2);
  border-color: var(--text-dim);
}

.launcher-card:active {
  transform: scale(0.98);
}

.launcher-card.active {
  background: var(--accent-dim);
  border-color: var(--accent);
  color: var(--accent);
}

.launcher-card-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: var(--radius);
  background: var(--surface-2);
  flex-shrink: 0;
}

.launcher-card.active .launcher-card-icon {
  background: var(--accent-dim);
}

.launcher-card-icon svg {
  width: 16px;
  height: 16px;
}

.launcher-card-label {
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.launcher-empty {
  grid-column: 1 / -1;
  padding: var(--spacing-10) var(--spacing-7);
  text-align: center;
  color: var(--text-muted);
  font-size: var(--fs-md);
}

/* ── Notification Popover ─────────────────────────────────────── */

.notification-header {
  padding: var(--spacing-6) var(--spacing-7);
  border-bottom: 1px solid var(--border);
}

.notification-title {
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  color: var(--text);
}

.notification-list {
  padding: var(--spacing-4);
  max-height: 280px;
  overflow-y: auto;
}

.notification-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--spacing-4);
  padding: var(--spacing-8) var(--spacing-7);
  color: var(--text-muted);
  font-size: var(--fs-md);
}

.notification-empty-icon svg {
  width: 24px;
  height: 24px;
  opacity: 0.5;
}

.notification-item {
  padding: var(--spacing-5) var(--spacing-6);
  border-radius: var(--radius);
  cursor: pointer;
  transition: background 0.1s;
}

.notification-item:hover {
  background: var(--surface-2);
}

.notification-item.unread {
  border-left: 3px solid var(--accent);
}

.notification-item-text {
  font-size: var(--fs-md);
  color: var(--text);
  line-height: var(--lh-normal);
}

.notification-item-time {
  font-size: var(--fs-sm);
  color: var(--text-dim);
  margin-top: var(--spacing-2);
}

.notification-footer {
  border-top: 1px solid var(--border);
  padding: var(--spacing-4);
}

.notification-view-all {
  display: flex;
  align-items: center;
  gap: var(--spacing-3);
  width: 100%;
  padding: var(--spacing-4) var(--spacing-6);
  border: none;
  background: transparent;
  border-radius: var(--radius);
  color: var(--text-muted);
  font-size: var(--fs-md);
  font-family: var(--font);
  cursor: pointer;
  transition: background 0.1s, color 0.1s;
}

.notification-view-all:hover {
  background: var(--surface-2);
  color: var(--text);
}

.notification-view-all svg {
  width: 14px;
  height: 14px;
}

/* ── User Menu Popover ────────────────────────────────────────── */

.user-menu-header {
  padding: var(--spacing-6) var(--spacing-7) var(--spacing-5);
  border-bottom: 1px solid var(--border);
}

.user-menu-email {
  font-size: var(--fs-md);
  color: var(--text-muted);
}

.user-menu-items {
  padding: var(--spacing-3);
}

.user-menu-item {
  display: flex;
  align-items: center;
  gap: var(--spacing-5);
  width: 100%;
  padding: var(--spacing-4) var(--spacing-5);
  border: none;
  background: transparent;
  border-radius: var(--radius);
  color: var(--text);
  font-size: var(--fs-md);
  font-family: var(--font);
  cursor: pointer;
  transition: background 0.1s;
  text-align: left;
}

.user-menu-item:hover {
  background: var(--surface-2);
}

.user-menu-item svg {
  width: 16px;
  height: 16px;
  color: var(--text-muted);
}

.user-menu-item.danger {
  color: var(--danger);
}

.user-menu-item.danger svg {
  color: var(--danger);
}

.user-menu-divider {
  height: 1px;
  background: var(--border);
  margin: var(--spacing-2) 0;
}

.user-menu-sub-label {
  display: flex;
  align-items: center;
  gap: var(--spacing-5);
  padding: var(--spacing-3) var(--spacing-5);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
}

.user-menu-sub-label svg {
  width: 14px;
  height: 14px;
  color: var(--text-muted);
}

.user-menu-sub-options {
  padding: 0 var(--spacing-3);
}

.user-menu-sub-item {
  padding: var(--spacing-3) var(--spacing-5);
  font-size: var(--fs-base);
  gap: var(--spacing-4);
}

.user-menu-sub-item svg {
  width: 14px;
  height: 14px;
  color: var(--accent);
}

.user-menu-sub-item.active {
  color: var(--accent);
}

.density-check-placeholder {
  display: inline-block;
  width: 14px;
  height: 14px;
}

/* ── Brand Switcher Popover ───────────────────────────────────────
   <ui-brand-switcher>. The trigger reuses .header-icon-btn so it is pixel-
   identical to the bell and the avatar beside it; only the menu is new.

   NOTHING HERE NAMES OR COLOURS A BRAND. The active entry is marked with a
   check glyph rather than a colour swatch, because a swatch would require the
   SDK to know each brand's palette — and a brand's colours live in the
   carrier's own :root[data-brand='…'] token block, which cannot be sampled
   without applying it. A check is honest; an invented swatch colour would not
   be.

   Nothing here declares a stacking level, deliberately — the panel is
   <ui-popover>, which already owns the body-mounted --z-popover layer. Writing
   one on the trigger would create a second, competing answer to the same
   question. (Note for the next editor: the CSS-SCALE lint rule matches the
   literal property name in comments too, so do not spell it out here.) */

ui-header-actions ui-brand-switcher {
  display: flex;
  align-items: center;
}

/* The panel itself. Anchored to the trigger rather than body-mounted: it lives
   inside <ui-header-actions>, which is not clipped and is already the header's
   own stacking context, so the in-subtree band is the correct one — a
   body-mounted layer would be claiming a global level it does not need. */
.brand-menu {
  position: absolute;
  top: calc(100% + var(--spacing-3));
  right: 0;
  min-width: 220px;
  z-index: var(--z-menu);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--elev-menu);
}

.brand-menu[hidden] { display: none; }

/* The trigger is the positioning context for the panel above. */
ui-brand-switcher {
  position: relative;
}

.brand-menu-header {
  padding: var(--spacing-5) var(--spacing-7) var(--spacing-4);
  border-bottom: 1px solid var(--border);
}

.brand-menu-title {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
}

.brand-menu-items {
  padding: var(--spacing-3);
}

.brand-menu-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--spacing-5);
  width: 100%;
  padding: var(--spacing-4) var(--spacing-5);
  border: none;
  background: transparent;
  border-radius: var(--radius);
  color: var(--text);
  font-size: var(--fs-md);
  font-family: var(--font);
  cursor: pointer;
  transition: background 0.1s, color 0.1s;
  text-align: left;
}

.brand-menu-item:hover {
  background: var(--surface-2);
}

/* The menu is body-mounted and reached by keyboard immediately on open, so it
   needs its own ring — the .uib rule does not apply to these buttons. (ND-35) */
.brand-menu-item:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.brand-menu-item.active {
  color: var(--accent);
}

.brand-menu-item-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.brand-menu-check {
  display: inline-flex;
  align-items: center;
  flex: none;
  line-height: var(--lh-flush);
  color: var(--accent);
}

.brand-menu-check svg {
  width: 14px;
  height: 14px;
}

/* ══════════════════════════════════════════════════════════════════
   LAYOUT — ui-app
   ══════════════════════════════════════════════════════════════════ */

ui-app {
  display: grid;
  grid-template-columns: var(--sidebar-width, 260px) 1fr;
  grid-template-rows: 1fr;
  min-height: 100%;
  width: 100%;
  font-family: var(--font), serif;
  background: var(--bg);
  color: var(--text);
  transition: grid-template-columns 0.2s ease;
}

/* Disable transition during drag for instant feedback */
ui-app.sidebar-resizing {
  transition: none;
}

ui-app > ui-app-sidebar {
  grid-column: 1;
  grid-row: 1;
  min-width: 0;
  height: 100%;
}

ui-app > ui-module {
  grid-column: 2;
  grid-row: 1;
  min-width: 0;
  overflow-y: auto;
}

ui-app > ui-module ~ ui-module {
  display: none;
}

/* No sidebar — single column layout, module fills full width */
ui-app:not(:has(> ui-app-sidebar)) {
  grid-template-columns: 1fr;
}
ui-app:not(:has(> ui-app-sidebar)) > ui-module {
  grid-column: 1;
}

/* Collapsed sidebar — animate to zero width */
ui-app:has(> ui-app-sidebar[collapsed]) {
  grid-template-columns: 0px 1fr;
}

ui-app-sidebar[collapsed] {
  overflow: hidden;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s ease;
}

ui-app-sidebar:not([collapsed]) {
  opacity: 1;
  transition: opacity 0.15s ease 0.05s;
}

/* ══════════════════════════════════════════════════════════════════
   SHELL — ui-app-sidebar
   ══════════════════════════════════════════════════════════════════ */

ui-app-sidebar {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border-right: 1px solid var(--border);
  overflow: hidden;
}

ui-app-sidebar .sidebar-header {
  padding: var(--spacing-7) var(--spacing-7) var(--spacing-6);
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  letter-spacing: 1.5px;
  color: var(--text-muted);
  text-transform: uppercase;
  border-bottom: 1px solid var(--border);
}

ui-app-sidebar .sidebar-nav {
  padding: var(--spacing-4);
  flex: 1;
  overflow-y: auto;
  min-height: 0;
}

ui-app-sidebar .nav-item {
  display: flex;
  align-items: center;
  gap: var(--spacing-5);
  padding: var(--spacing-5) var(--spacing-6);
  border-radius: var(--radius);
  color: var(--text-muted);
  cursor: pointer;
  font-size: var(--fs-lg);
  font-weight: var(--fw-medium);
  transition:
    background 0.15s,
    color 0.15s;
  user-select: none;
}

ui-app-sidebar .nav-item > svg {
  flex-shrink: 0;
}

ui-app-sidebar .nav-item:hover {
  background: var(--surface-2);
  color: var(--text);
}

ui-app-sidebar .nav-item[aria-selected='true'] {
  background: var(--accent-dim);
  color: var(--accent);
}

ui-app-sidebar .nav-group-header {
  display: flex;
  align-items: center;
  gap: var(--spacing-3);
  padding: var(--spacing-5) var(--spacing-6) var(--spacing-3);
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  letter-spacing: 1.2px;
  color: var(--text-muted);
  text-transform: uppercase;
  cursor: pointer;
  user-select: none;
  position: sticky;
  top: 0;
  background: var(--surface);
  z-index: var(--z-raised);
}

ui-app-sidebar .nav-group-header:hover {
  color: var(--text);
}

ui-app-sidebar .nav-group-chevron {
  flex-shrink: 0;
  transition: transform 0.2s;
}

ui-app-sidebar .nav-group.collapsed .nav-group-chevron {
  transform: rotate(-90deg);
}

ui-app-sidebar .nav-group-items {
  overflow: hidden;
  transition: max-height 0.2s ease;
  max-height: 1000px;
  margin-left: var(--spacing-6);
  padding-left: var(--spacing-4);
  border-left: 1px solid var(--border);
}

ui-app-sidebar .nav-group-items .nav-item {
  font-size: var(--fs-md);
  padding: var(--spacing-3) var(--spacing-5);
}

ui-app-sidebar .nav-group.collapsed .nav-group-items {
  max-height: 0;
}

ui-app-sidebar .sidebar-footer {
  margin-top: auto;
  padding: var(--spacing-6);
  border-top: 1px solid var(--border);
}

ui-theme-toggle {
  display: block;
}

/* Base theme-toggle styles — works anywhere (breadcrumb, header, standalone) */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-3);
  padding: var(--spacing-3) var(--spacing-6);
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text-muted);
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  cursor: pointer;
  transition: all 0.15s;
  font-family: inherit;
}
.theme-toggle:hover {
  border-color: var(--accent);
  color: var(--text);
}

/* Sidebar override — full width */
ui-app-sidebar .theme-toggle {
  width: 100%;
  padding: var(--spacing-4) var(--spacing-6);
}

ui-app-sidebar .sidebar-branding {
  padding: var(--spacing-6) var(--spacing-7);
  font-size: var(--fs-sm);
  color: var(--text-dim);
}

ui-app-sidebar .sidebar-branding .version {
  color: var(--accent);
  font-weight: var(--fw-semibold);
}

/* ── Resize Handle ───────────────────────────────────────────── */

ui-app-sidebar[collapsible] {
  position: relative;
}

ui-app-sidebar .sidebar-resize-handle {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  width: 4px;
  cursor: col-resize;
  background: transparent;
  transition: background 0.15s;
  z-index: var(--z-sticky);
}

ui-app-sidebar .sidebar-resize-handle:hover,
ui-app-sidebar .sidebar-resize-handle.dragging {
  background: var(--accent);
}

/* ══════════════════════════════════════════════════════════════════
   MODULE — ui-module (breadcrumb + view container)
   ══════════════════════════════════════════════════════════════════ */

ui-module {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}

ui-module .view-container {
  padding: var(--spacing-8);
  flex: 1;
  min-height: 0;
}

/* When a detail-view is shown, lock the layout chain to its container
   so sidebar and content scroll independently within their grid cells.
   Uses 100% (not 100vh) so it respects ui-platform's grid when nested. */
ui-app:has(> ui-module:first-of-type ui-view:not([style*='none']) ui-detail-view) {
  height: 100%;
  max-height: 100%;
  overflow: hidden;
}

ui-module:has(ui-view:not([style*='none']) ui-detail-view) {
  overflow: hidden;
}

ui-module:has(ui-view:not([style*='none']) ui-detail-view) .view-container {
  overflow: hidden;
  padding: 0;
  display: flex;
  flex-direction: column;
}

/* ── View & Content Panel display fixes ── */
ui-view {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}

/* ui-list-view (display:block) and ui-dashboard (no host box) do not constrain their
   own height, so a layout taller than the module is clipped by the module's
   overflow:hidden with NO scrollbar — the last rows are rendered but unreachable.
   Scoped to those two on purpose: ui-detail-view, ui-router and ui-chat-view already
   set overflow:hidden + min-height:0 on themselves, and making every ui-view a scroll
   container would silently re-anchor every position:sticky descendant to it. */
ui-view:has(> ui-list-view),
ui-view:has(> ui-dashboard) {
  overflow-y: auto;
}

/* Simple views (no detail-view): direct ui-stack children scroll */
ui-view > ui-stack {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}


/* ══════════════════════════════════════════════════════════════════
   BREADCRUMB — ui-breadcrumb
   ══════════════════════════════════════════════════════════════════ */

ui-breadcrumb {
  display: block;
  flex-shrink: 0;
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  padding: 0 var(--spacing-8);
}

ui-breadcrumb .breadcrumb-nav {
  display: flex;
  align-items: center;
  gap: 0;
  padding: var(--spacing-6) 0;
  font-size: var(--fs-lg);
}

ui-breadcrumb .crumb {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-3);
  color: var(--text-muted);
  text-decoration: none;
  cursor: pointer;
  font-weight: var(--fw-medium);
  transition: color 0.15s;
}

ui-breadcrumb .crumb > svg {
  flex-shrink: 0;
}

ui-breadcrumb .crumb:hover:not(.current) {
  color: var(--accent);
}

ui-breadcrumb .crumb.current {
  color: var(--text);
  font-weight: var(--fw-semibold);
  cursor: default;
}

ui-breadcrumb .crumb.crumb-home {
  color: var(--accent);
  font-weight: var(--fw-semibold);
}

ui-breadcrumb .crumb.crumb-home svg {
  opacity: 0.8;
}

ui-breadcrumb .crumb.crumb-home:hover {
  color: var(--accent-hover);
}

ui-breadcrumb .crumb.crumb-home:hover svg {
  opacity: 1;
}

ui-breadcrumb .crumb-sep {
  margin: 0 var(--spacing-5);
  color: var(--text-dim);
  font-size: var(--fs-base);
  user-select: none;
}

/* ══════════════════════════════════════════════════════════════════
   SHARED TABLE STYLES (used by dashboard-table and list-view)
   ══════════════════════════════════════════════════════════════════ */

ui-dashboard-table table,
ui-list-view table {
  width: 100%;
  border-collapse: collapse;
}

ui-list-view table,
ui-list-view .lv-table {
  table-layout: fixed;
}

ui-dashboard-table th,
ui-list-view th {
  text-align: left;
  padding: var(--spacing-5) var(--spacing-7);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  border-bottom: 1px solid var(--border);
}

ui-dashboard-table td,
ui-list-view td {
  padding: var(--spacing-6) var(--spacing-7);
  font-size: var(--fs-lg);
  border-bottom: 1px solid var(--border);
}

ui-list-view td {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 0;
}

ui-dashboard-table tr:last-child td,
ui-list-view tr:last-child td {
  border-bottom: none;
}

ui-dashboard-table tr:hover td,
ui-list-view tbody tr:hover td {
  background: var(--surface-2);
}

ui-dashboard-table tbody tr,
ui-list-view tbody tr {
  cursor: pointer;
}

td.bold {
  font-weight: var(--fw-semibold);
}

/* ══════════════════════════════════════════════════════════════════
   BADGES (shared)
   ══════════════════════════════════════════════════════════════════ */

.badge {
  display: inline-flex;
  align-items: center;
  padding: var(--spacing-2) var(--spacing-5);
  border-radius: var(--radius-full);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
}

.badge.info {
  background: var(--info-bg);
  color: var(--info);
}
.badge.warning {
  background: var(--warning-bg);
  color: var(--warning);
}
.badge.success {
  background: var(--success-bg);
  color: var(--success);
}
.badge.danger {
  background: var(--danger-bg);
  color: var(--danger);
}
.badge.muted {
  background: rgba(107, 114, 128, 0.15);
  color: var(--muted);
}

/* ══════════════════════════════════════════════════════════════════
   BUTTONS (shared)
   ══════════════════════════════════════════════════════════════════ */

.btn {
  padding: var(--spacing-5) var(--spacing-7);
  border-radius: var(--radius);
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  cursor: pointer;
  border: 1px solid var(--border);
  transition: all 0.15s;
  background: transparent;
  color: var(--text-muted);
}

.btn:hover {
  border-color: var(--accent);
  color: var(--text);
}

.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: white;
}

.btn-primary:hover {
  opacity: 0.9;
}

.btn-danger {
  background: transparent;
  border-color: var(--danger);
  color: var(--danger);
}

.btn-outline {
  background: transparent;
  color: var(--text-muted);
}

/* ══════════════════════════════════════════════════════════════════
   UI-BUTTON — <ui-button>
   ══════════════════════════════════════════════════════════════════ */

ui-button {
  display: inline-flex;
}

/* A primary action that owns its container — a login submit, a dialog confirm.
   Without it the only way to get a full-width button was a bespoke class. */
ui-button[full-width] {
  display: flex;
  width: 100%;
}
ui-button[full-width] .uib {
  width: 100%;
}

.uib {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--spacing-3);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-family: var(--font);
  font-weight: var(--fw-semibold);
  cursor: pointer;
  transition: all 0.15s ease;
  background: transparent;
  color: var(--text-muted);
  white-space: nowrap;
  line-height: var(--lh-none);
  -webkit-user-select: none;
  user-select: none;
}

/* ── Sizes ── */
.uib-xs {
  padding: var(--spacing-2) var(--spacing-5);
  font-size: var(--fs-sm);
  border-radius: var(--radius-sm);
}
.uib-sm {
  padding: var(--spacing-3) var(--spacing-6);
  font-size: var(--fs-base);
}
.uib-md {
  padding: var(--spacing-5) var(--spacing-7);
  font-size: var(--fs-md);
}
.uib-lg {
  padding: var(--spacing-6) var(--spacing-8);
  font-size: var(--fs-lg);
}

/* ── Icon-only sizing ── */
.uib-icon-only.uib-xs {
  padding: var(--spacing-2);
  width: 24px;
  height: 24px;
}
.uib-icon-only.uib-sm {
  padding: var(--spacing-3);
  width: 28px;
  height: 28px;
}
.uib-icon-only.uib-md {
  padding: var(--spacing-3);
  width: 34px;
  height: 34px;
}
.uib-icon-only.uib-lg {
  padding: var(--spacing-5);
  width: 42px;
  height: 42px;
}

/* ── Variants ── */
.uib-default:hover {
  border-color: var(--accent);
  color: var(--text);
}

.uib-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: white;
}
.uib-primary:hover {
  opacity: 0.9;
}

.uib-outline {
  background: transparent;
  border-color: var(--border);
  color: var(--text-muted);
}
.uib-outline:hover {
  border-color: var(--accent);
  color: var(--text);
}

.uib-ghost {
  background: transparent;
  border-color: transparent;
  color: var(--text-muted);
}
.uib-ghost:hover {
  background: var(--surface-2);
  color: var(--text);
}

.uib-danger {
  background: transparent;
  border-color: var(--danger);
  color: var(--danger);
}
.uib-danger:hover {
  background: var(--danger-bg);
}

/* ── Disabled / Loading ── */
.uib-disabled {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}

/* ── Focus ring ── */
.uib:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ── Icon slot ── */
.uib-icon {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
}
.uib-label {
  display: inline-block;
}

/* ── Inline spinner ── */
.uib-spinner {
  display: inline-block;
  width: 14px;
  height: 14px;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: var(--radius-circle);
  animation: uib-spin 0.6s linear infinite;
  opacity: 0.7;
}
@keyframes uib-spin {
  to {
    transform: rotate(360deg);
  }
}

/* ══════════════════════════════════════════════════════════════════
   UI-BADGE — <ui-badge>
   ══════════════════════════════════════════════════════════════════ */

ui-badge {
  display: inline-block;
}

.bdg {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-2);
  padding: var(--spacing-2) var(--spacing-5);
  border-radius: var(--radius-full);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  font-family: var(--font);
  line-height: var(--lh-tight);
  white-space: nowrap;
}
.bdg-sm {
  padding: var(--spacing-1) var(--spacing-4);
  font-size: var(--fs-xs);
}

.bdg-icon {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
}

/* ── Variants ── */
.bdg-default {
  background: var(--surface-2);
  color: var(--text-muted);
}
.bdg-success {
  background: var(--success-bg);
  color: var(--success);
}
.bdg-warning {
  background: var(--warning-bg);
  color: var(--warning);
}
.bdg-danger {
  background: var(--danger-bg);
  color: var(--danger);
}
.bdg-info {
  background: var(--info-bg);
  color: var(--info);
}
.bdg-secondary {
  background: rgba(107, 114, 128, 0.15);
  color: var(--muted);
}
.bdg-muted {
  background: var(--surface-2);
  color: var(--text-dim);
}

/* ══════════════════════════════════════════════════════════════════
   UI-SPINNER — <ui-spinner>
   ══════════════════════════════════════════════════════════════════ */

ui-spinner {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.spn {
  display: inline-flex;
}
.spn-circle {
  display: block;
  border-radius: var(--radius-circle);
  border: 2px solid var(--border);
  border-top-color: var(--accent);
  animation: spn-spin 0.6s linear infinite;
}
@keyframes spn-spin {
  to {
    transform: rotate(360deg);
  }
}

/* ── Sizes ── */
.spn-xs .spn-circle {
  width: 12px;
  height: 12px;
  border-width: 1.5px;
}
.spn-sm .spn-circle {
  width: 16px;
  height: 16px;
  border-width: 2px;
}
.spn-md .spn-circle {
  width: 24px;
  height: 24px;
  border-width: 2px;
}
.spn-lg .spn-circle {
  width: 36px;
  height: 36px;
  border-width: 3px;
}

/* ══════════════════════════════════════════════════════════════════
   UI-ICON — <ui-icon>
   ══════════════════════════════════════════════════════════════════ */

ui-icon {
  display: inline-flex;
  align-items: center;
}
.ico {
  display: inline-flex;
  align-items: center;
  line-height: var(--lh-flush);
}

/* ══════════════════════════════════════════════════════════════════
   UI-STACK — <ui-stack>
   ══════════════════════════════════════════════════════════════════ */

ui-stack {
  display: flex;
  flex-direction: column;
}
ui-stack[inline] {
  display: inline-flex;
}

/* ── Direction ── */
ui-stack[direction='row'] {
  flex-direction: row;
  align-items: center;
}
ui-stack[direction='column'] {
  flex-direction: column;
}

/* ── Gap ── */
ui-stack[gap='none'] {
  gap: 0;
}
ui-stack[gap='xs'] {
  gap: var(--spacing-2);
}
ui-stack[gap='sm'] {
  gap: var(--spacing-4);
}
ui-stack,
ui-stack[gap='md'] {
  gap: var(--spacing-7);
}
ui-stack[gap='lg'] {
  gap: var(--spacing-8);
}
ui-stack[gap='xl'] {
  gap: var(--spacing-9);
}

/* ── Padding ── */
ui-stack[padding='none'] {
  padding: 0;
}
ui-stack[padding='xs'] {
  padding: var(--spacing-2);
}
ui-stack[padding='sm'] {
  padding: var(--spacing-4);
}
ui-stack[padding='md'] {
  padding: var(--spacing-7);
}
ui-stack[padding='lg'] {
  padding: var(--spacing-8);
}
ui-stack[padding='xl'] {
  padding: var(--spacing-9);
}

/* ── Align ── */
ui-stack[align='start'] {
  align-items: flex-start;
}
ui-stack[align='center'] {
  align-items: center;
}
ui-stack[align='end'] {
  align-items: flex-end;
}
ui-stack[align='stretch'] {
  align-items: stretch;
}

/* ── Justify ── */
ui-stack[justify='start'] {
  justify-content: flex-start;
}
ui-stack[justify='center'] {
  justify-content: center;
}
ui-stack[justify='end'] {
  justify-content: flex-end;
}
ui-stack[justify='between'] {
  justify-content: space-between;
}
ui-stack[justify='around'] {
  justify-content: space-around;
}

/* ── Wrap (default on for row) ── */
ui-stack[wrap] {
  flex-wrap: wrap;
}
ui-stack[direction='row'] {
  flex-wrap: wrap;
}
ui-stack[wrap='false'] {
  flex-wrap: nowrap;
}

/* ── Semantic surface variants ── */
ui-stack[surface] {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--spacing-7) var(--spacing-7);
}

/* Fill the viewport. With align/justify this centres content on a page that has
   no surrounding layout — an unauthenticated page. `min-height` rather than
   `height` so a tall card scrolls instead of being clipped. */
ui-stack[full-height] {
  min-height: 100vh;
  box-sizing: border-box;
}

/* max-width itself is set as an inline style by _applyMaxWidth(), because it
   takes an arbitrary length rather than a token. This only makes the constraint
   effective inside a flex parent, where the default is to stretch. */
ui-stack[max-width] {
  width: 100%;
  box-sizing: border-box;
}

/* ══════════════════════════════════════════════════════════════════
   DASHBOARD — ui-dashboard-hero, ui-dashboard-grid, ui-metric-card, ui-dashboard-table
   ══════════════════════════════════════════════════════════════════ */

/* Dashboard Hero */
ui-dashboard-hero {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  padding: var(--spacing-2) 0 var(--spacing-7);
  gap: var(--spacing-4) var(--spacing-7);
}

ui-dashboard-hero .dh-title-section {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-1);
}

ui-dashboard-hero .dh-title {
  font-size: var(--fs-3xl);
  font-weight: var(--fw-bold);
  color: var(--text);
  margin: 0;
  line-height: var(--lh-tight);
}

ui-dashboard-hero .dh-subtitle {
  font-size: var(--fs-md);
  color: var(--text-muted);
  margin: 0;
}

ui-dashboard-hero .dh-actions {
  display: flex;
  gap: var(--spacing-5);
  align-items: center;
  flex-shrink: 0;
}

ui-dashboard-hero ui-dashboard-toolbar {
  flex-basis: 100%;
  padding: 0;
}

ui-dashboard-grid {
  display: grid;
  gap: 1rem;
  margin-bottom: var(--spacing-8);
}

ui-dashboard-grid[span='full'],
ui-dashboard-grid [span='full'] {
  grid-column: 1 / -1;
}

/* Metric Grid — Responsive container for metric cards, charts, and graphs */
ui-metric-grid {
  display: grid;
  container-type: inline-size;
  gap: 1rem;
  grid-template-columns: repeat(var(--mg-cols, 4), 1fr);
  align-items: stretch;
  min-width: 0;
}

ui-metric-grid[span='full'],
ui-metric-grid [span='full'] {
  grid-column: 1 / -1;
}

@container (max-width: 900px) {
  ui-metric-grid {
    grid-template-columns: repeat(var(--mg-cols-tablet, 2), 1fr);
  }
}

@container (max-width: 500px) {
  ui-metric-grid {
    grid-template-columns: repeat(var(--mg-cols-mobile, 1), 1fr);
  }
}

/* Metric Card — Base (default: flat layout) */
ui-metric-card {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: var(--spacing-6);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--spacing-6) var(--spacing-7);
  transition: border-color 0.15s, background 0.15s;
  min-width: 0;
  flex: 1;
}

ui-metric-card:hover {
  border-color: color-mix(in srgb, var(--text-muted) 30%, transparent);
  background: color-mix(in srgb, var(--surface) 95%, white);
}

ui-metric-card .metric-body {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--spacing-1);
  min-width: 0;
  text-align: right;
}

ui-metric-card .metric-icon {
  width: 32px;
  height: 32px;
  border-radius: var(--radius);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
ui-metric-card .metric-icon svg {
  width: 16px;
  height: 16px;
}

ui-metric-card .metric-value {
  font-size: var(--fs-4xl);
  font-weight: var(--fw-extrabold);
  line-height: var(--lh-none);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.03em;
  color: var(--text);
}

ui-metric-card .metric-label {
  font-size: var(--fs-base);
  color: var(--text-dim);
  font-weight: var(--fw-medium);
  letter-spacing: 0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Metric Card — Trend indicator */
ui-metric-card .metric-trend {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-1);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
  margin-left: auto;
  flex-shrink: 0;
  padding: var(--spacing-1) var(--spacing-3);
  border-radius: var(--radius-xs);
  background: color-mix(in srgb, var(--text-muted) 8%, transparent);
}
ui-metric-card .metric-trend--up {
  color: var(--success);
  background: color-mix(in srgb, var(--success) 10%, transparent);
}
ui-metric-card .metric-trend--down {
  color: var(--danger);
  background: color-mix(in srgb, var(--danger) 10%, transparent);
}
ui-metric-card .metric-trend--flat { color: var(--text-muted); }

/* Metric Card — Size: sm */
ui-metric-card[size='sm'] {
  padding: var(--spacing-4) var(--spacing-6);
  gap: var(--spacing-4);
  border-radius: var(--radius);
}
ui-metric-card[size='sm'] .metric-icon {
  width: 26px;
  height: 26px;
  border-radius: var(--radius-sm);
}
ui-metric-card[size='sm'] .metric-icon svg {
  width: 13px;
  height: 13px;
}
ui-metric-card[size='sm'] .metric-value {
  font-size: var(--fs-xl);
  font-weight: var(--fw-bold);
}
ui-metric-card[size='sm'] .metric-label {
  font-size: var(--fs-xs);
}
ui-metric-card[size='sm'] .metric-trend {
  font-size: var(--fs-xs);
  padding: var(--spacing-1) var(--spacing-2);
}

/* Metric Card — Size: lg */
ui-metric-card[size='lg'] {
  padding: var(--spacing-7) var(--spacing-8);
  gap: var(--spacing-7);
  border-radius: var(--radius-lg);
}
ui-metric-card[size='lg'] .metric-icon {
  width: 44px;
  height: 44px;
  border-radius: var(--radius-md);
}
ui-metric-card[size='lg'] .metric-icon svg {
  width: 22px;
  height: 22px;
}
ui-metric-card[size='lg'] .metric-value {
  font-size: var(--fs-5xl);
}
ui-metric-card[size='lg'] .metric-label {
  font-size: var(--fs-md);
}
ui-metric-card[size='lg'] .metric-trend {
  font-size: var(--fs-base);
}

/* Metric Card — Layout: vertical (icon top, body below) */
ui-metric-card[layout='vertical'] {
  flex-direction: column;
  align-items: flex-start;
  gap: var(--spacing-6);
  padding: var(--spacing-7) var(--spacing-7);
  border-radius: var(--radius-lg);
}
ui-metric-card[layout='vertical'] .metric-icon {
  width: 36px;
  height: 36px;
  border-radius: var(--radius);
}
ui-metric-card[layout='vertical'] .metric-icon svg {
  width: 18px;
  height: 18px;
}
ui-metric-card[layout='vertical'] .metric-body {
  flex-direction: column;
  align-items: flex-start;
  gap: var(--spacing-1);
}
ui-metric-card[layout='vertical'] .metric-value {
  font-size: var(--fs-5xl);
  font-weight: var(--fw-bold);
}
ui-metric-card[layout='vertical'] .metric-label {
  font-size: var(--fs-base);
}
ui-metric-card[layout='vertical'] .metric-trend {
  margin-left: 0;
  margin-top: var(--spacing-2);
}

/* Metric Card — Layout: horizontal (icon left, body right) */
ui-metric-card[layout='horizontal'] {
  flex-direction: row;
  align-items: center;
  gap: var(--spacing-6);
}
ui-metric-card[layout='horizontal'] .metric-body {
  flex: 1;
  min-width: 0;
}

/* Metric Card — Layout: compact (icon + value inline, label below) */
ui-metric-card[layout='compact'] {
  flex-direction: column;
  gap: var(--spacing-3);
}
ui-metric-card[layout='compact'] .metric-icon {
  position: absolute;
  top: 12px;
  right: 12px;
}
ui-metric-card[layout='compact'] {
  position: relative;
}

/* Metric Card — Layout: inline (no border, pure inline stat — minimal height) */
ui-metric-card[layout='inline'] {
  flex-direction: row;
  align-items: center;
  gap: var(--spacing-4);
  background: none;
  border: none;
  border-radius: 0;
  padding: var(--spacing-3) 0;
}
ui-metric-card[layout='inline'] .metric-icon {
  width: 22px;
  height: 22px;
  border-radius: 5px;
}
ui-metric-card[layout='inline'] .metric-icon svg {
  width: 12px;
  height: 12px;
}
ui-metric-card[layout='inline'] .metric-body {
  flex-direction: row;
  align-items: baseline;
  gap: var(--spacing-3);
}
ui-metric-card[layout='inline'] .metric-value {
  font-size: var(--fs-xl);
  font-weight: var(--fw-bold);
}
ui-metric-card[layout='inline'] .metric-label {
  font-size: var(--fs-sm);
}
ui-metric-card[layout='inline'] .metric-trend {
  padding: var(--spacing-1) var(--spacing-2);
  font-size: var(--fs-xs);
}
ui-metric-card[layout='inline']:hover {
  border-color: transparent;
  background: none;
}

/* Metric Card — Layout: flat (same as base default — explicit attr is a no-op) */

/* Metric Card — Icon Size overrides */
ui-metric-card[icon-size='sm'] .metric-icon {
  width: 24px;
  height: 24px;
  font-size: var(--fs-base);
  border-radius: var(--radius-sm);
}
ui-metric-card[icon-size='lg'] .metric-icon {
  width: 48px;
  height: 48px;
  font-size: var(--fs-4xl);
  border-radius: var(--radius-md);
}

/* Color variants for metric icon/value */
ui-metric-card[color='info'] .metric-icon {
  background: var(--info-bg);
  color: var(--info);
}
ui-metric-card[color='warning'] .metric-icon {
  background: var(--warning-bg);
  color: var(--warning);
}
ui-metric-card[color='success'] .metric-icon {
  background: var(--success-bg);
  color: var(--success);
}
ui-metric-card[color='danger'] .metric-icon {
  background: var(--danger-bg);
  color: var(--danger);
}
ui-metric-card:not([color]) .metric-icon {
  background: var(--accent-dim);
  color: var(--accent);
}

ui-metric-card:not([color]) .metric-value {
  color: var(--text);
}

/* Dashboard Table */
ui-dashboard-table {
  display: block;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

ui-dashboard-table .table-header {
  padding: var(--spacing-7) var(--spacing-7);
  font-size: 15px;
  font-weight: var(--fw-semibold);
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: space-between;
}

ui-dashboard-table .empty {
  padding: var(--spacing-8) var(--spacing-7);
  text-align: center;
  color: var(--text-dim);
  font-size: var(--fs-md);
}

ui-dashboard-table .table-view-all {
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  color: var(--accent);
  text-decoration: none;
  transition: color 0.15s;
}

ui-dashboard-table .table-view-all:hover {
  color: var(--accent-hover);
  text-decoration: underline;
}


/* ══════════════════════════════════════════════════════════════════
   LIST VIEW — ui-list-view
   ══════════════════════════════════════════════════════════════════ */

ui-list-view {
  display: block;
}

/* ── Param Fields ── */
ui-list-view .lv-param-fields {
  display: flex;
  align-items: center;
  gap: var(--spacing-6);
  margin-bottom: var(--spacing-4);
}

/* ── Toolbar ── */
ui-list-view .lv-toolbar {
  display: flex;
  align-items: center;
  gap: var(--spacing-6);
  margin-bottom: var(--spacing-7);
  flex-wrap: wrap;
}

ui-list-view .lv-search-box {
  flex: 1;
  min-width: 200px;
  display: flex;
}

ui-list-view .lv-search-input {
  flex: 1;
  padding: var(--spacing-5) var(--spacing-6);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius) 0 0 var(--radius);
  color: var(--text);
  font-size: var(--fs-lg);
  outline: none;
}

ui-list-view .lv-search-input:focus {
  border-color: var(--accent);
}

ui-list-view .lv-search-field {
  padding: var(--spacing-5) var(--spacing-5);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-left: none;
  border-radius: 0 var(--radius) var(--radius) 0;
  color: var(--text-muted);
  font-size: var(--fs-md);
  outline: none;
}

/* ── Focus ring ── */
/* Native <select> (ui-list-view.js:206) with the outline stripped. It sits in a
   joined control group with the search input, so the ring is inset to avoid
   overlapping the neighbour's border. (ND-35) */
ui-list-view .lv-search-field:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

/* ── Status Chips ── */
ui-list-view .lv-status-chips-wrap {
  position: relative;
  flex-basis: 100%;
  min-width: 0;
}

ui-list-view .lv-status-chips-wrap::before,
ui-list-view .lv-status-chips-wrap::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  width: 32px;
  pointer-events: none;
  z-index: var(--z-elevated);
  opacity: 0;
  transition: opacity 0.2s;
}

ui-list-view .lv-status-chips-wrap::before {
  left: 0;
  background: linear-gradient(to right, var(--bg), transparent);
}

ui-list-view .lv-status-chips-wrap::after {
  right: 0;
  background: linear-gradient(to left, var(--bg), transparent);
}

ui-list-view .lv-status-chips-wrap.lv-fade-left::before {
  opacity: 1;
}

ui-list-view .lv-status-chips-wrap.lv-fade-right::after {
  opacity: 1;
}

ui-list-view .lv-status-chips {
  display: flex;
  gap: var(--spacing-3);
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
  scroll-behavior: smooth;
}

ui-list-view .lv-status-chips::-webkit-scrollbar {
  display: none;
}

ui-list-view .lv-chip {
  padding: var(--spacing-3) var(--spacing-6);
  border-radius: var(--radius-full);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  cursor: pointer;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-muted);
  transition: all 0.15s;
  user-select: none;
  white-space: nowrap;
  flex-shrink: 0;
}

ui-list-view .lv-chip:hover {
  border-color: var(--accent);
  color: var(--text);
}

ui-list-view .lv-chip[aria-selected='true'] {
  background: var(--accent-dim);
  border-color: var(--accent);
  color: var(--accent);
}

ui-list-view .lv-chip-count {
  font-size: var(--fs-sm);
  opacity: 0.7;
  margin-left: var(--spacing-2);
}

/* ── List Toolbar (ui-list-toolbar) ── */
ui-list-toolbar {
  display: block;
  margin-bottom: var(--spacing-7);
}

ui-list-toolbar .lt-row {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--spacing-3) var(--spacing-5);
}

ui-list-toolbar .lt-search {
  display: flex;
  align-items: center;
  gap: var(--spacing-3);
  flex: 0 1 280px;
  min-width: 120px;
  border-right: 1px solid var(--border);
  padding-right: var(--spacing-5);
}

ui-list-toolbar .lt-search ui-icon {
  color: var(--text-muted);
  flex-shrink: 0;
}

ui-list-toolbar .lt-search-input {
  flex: 1;
  background: none;
  border: none;
  color: var(--text);
  font-size: var(--fs-md);
  outline: none;
  padding: var(--spacing-2) 0;
  min-width: 0;
}

/* ── Focus ring ── */
/* Borderless input inside a bordered toolbar; outline was stripped with no
   replacement. Inset offset to stay within the toolbar chrome. (ND-35) */
ui-list-toolbar .lt-search-input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

ui-list-toolbar .lt-search-input::placeholder {
  color: var(--text-muted);
}

ui-list-toolbar .lt-search-field {
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: var(--fs-base);
  outline: none;
  cursor: pointer;
  padding: var(--spacing-2) var(--spacing-1);
}

/* ── Focus ring ── */
/* This is a native <select> (ui-list-toolbar.js:139) with its outline removed
   and nothing in its place, so keyboard users had no indication it was the
   active control. (ND-35) */
ui-list-toolbar .lt-search-field:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

ui-list-toolbar .lt-filters {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--spacing-3);
  flex: 1;
  min-width: 0;
  overflow-x: auto;
}

ui-list-toolbar .lt-filters::-webkit-scrollbar {
  display: none;
}

ui-list-toolbar .lt-facet-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-2);
  padding: var(--spacing-2) var(--spacing-4);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text);
  font-size: var(--fs-md);
  cursor: pointer;
  white-space: nowrap;
  transition: border-color 0.15s, background 0.15s;
  line-height: var(--lh-normal);
}

ui-list-toolbar .lt-facet-pill:hover {
  border-color: var(--accent);
}

ui-list-toolbar .lt-facet-pill[aria-expanded="true"] {
  border-color: var(--accent);
  background: var(--surface-3);
}

ui-list-toolbar .lt-facet-label {
  color: var(--text-muted);
  font-size: var(--fs-base);
}

ui-list-toolbar .lt-facet-value {
  font-weight: var(--fw-medium);
}

ui-list-toolbar .lt-facet-pill ui-icon {
  color: var(--text-muted);
  transition: transform 0.15s;
}

ui-list-toolbar .lt-facet-pill[aria-expanded="true"] ui-icon {
  transform: rotate(180deg);
}

ui-list-toolbar .lt-add-filter {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-2);
  padding: var(--spacing-2) var(--spacing-4);
  background: none;
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  color: var(--text-muted);
  font-size: var(--fs-md);
  cursor: pointer;
  white-space: nowrap;
  transition: border-color 0.15s, color 0.15s;
}

ui-list-toolbar .lt-add-filter:hover {
  border-color: var(--accent);
  color: var(--text);
}

ui-list-toolbar .lt-reset {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-2);
  padding: var(--spacing-2) var(--spacing-4);
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: var(--fs-base);
  cursor: pointer;
  white-space: nowrap;
  transition: color 0.15s;
}

ui-list-toolbar .lt-reset:hover {
  color: var(--danger);
}

/* Dropdown (portaled to body) */
.lt-dropdown {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--spacing-2) 0;
  z-index: var(--z-dropdown);
  box-shadow: var(--elev-dropdown-sm);
  max-height: 240px;
  overflow-y: auto;
  font-family: var(--font);
}

.lt-dropdown-item {
  display: flex;
  align-items: center;
  gap: var(--spacing-2);
  padding: var(--spacing-3) var(--spacing-5);
  color: var(--text);
  font-size: var(--fs-md);
  cursor: pointer;
  transition: background 0.1s;
}

.lt-dropdown-item:hover {
  background: var(--surface-3);
}

.lt-dropdown-item.lt-selected {
  color: var(--accent);
  font-weight: var(--fw-medium);
}

.lt-dropdown-count {
  color: var(--text-muted);
  font-size: var(--fs-base);
  margin-left: auto;
}

.lt-check {
  font-size: var(--fs-lg);
  line-height: 1;
  color: var(--text-muted);
}

.lt-dropdown-item.lt-selected .lt-check {
  color: var(--accent);
}

ui-list-toolbar .lt-facet-pill.lt-facet-active {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}

ui-list-toolbar .lt-facet-pill.lt-facet-active .lt-facet-value {
  color: var(--accent);
}

/* ── Dynamic List Filters (ui-list-filters) ── */
ui-list-filters {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-3);
  flex-basis: 100%;
}

ui-list-filters .lf-dimension {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
}

ui-list-filters .lf-label {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  white-space: nowrap;
  min-width: fit-content;
}

ui-list-filters .lf-chips-wrap {
  position: relative;
  min-width: 0;
  flex: 1;
}

ui-list-filters .lf-chips {
  display: flex;
  gap: var(--spacing-3);
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
  scroll-behavior: smooth;
}

ui-list-filters .lf-chips::-webkit-scrollbar {
  display: none;
}

ui-list-filters .lf-chip {
  padding: var(--spacing-3) var(--spacing-6);
  border-radius: var(--radius-full);
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
  color: var(--text-muted);
  background: transparent;
  border: 1px solid var(--border);
  cursor: pointer;
  transition: all 0.15s;
  white-space: nowrap;
  flex-shrink: 0;
}

ui-list-filters .lf-chip:hover {
  border-color: var(--accent);
  color: var(--text);
}

ui-list-filters .lf-chip[aria-selected='true'] {
  background: var(--accent-dim);
  border-color: var(--accent);
  color: var(--accent);
}

ui-list-filters .lf-chip-count {
  font-size: var(--fs-sm);
  opacity: 0.7;
  margin-left: var(--spacing-2);
}

/* ── Table Card ── */
ui-list-view .lv-table-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  position: relative;
}

/* ── Sort Headers ── */
ui-list-view .lv-th-sortable {
  cursor: pointer;
  user-select: none;
  transition: color 0.15s;
}

ui-list-view .lv-th-sortable:hover {
  color: var(--text);
}

ui-list-view .lv-th-sortable:hover .lv-sort-icon {
  color: var(--accent);
}

ui-list-view .lv-sort-icon {
  font-size: var(--fs-sm);
  color: var(--text-dim);
  transition: color 0.15s;
}

ui-list-view .lv-sort-icon.lv-sort-active {
  color: var(--accent);
}

/* ── Rows ── */
ui-list-view .lv-row {
  cursor: pointer;
  transition: background 0.1s;
}

ui-list-view .lv-cell-bold {
  font-weight: var(--fw-semibold);
}

/* Cell renderers ui-column declares. Without these the markup would be emitted
   against undefined classes and render identically to plain text — a renderer
   that appears implemented but is not. */
ui-list-view .lv-mono {
  font-family: var(--mono);
  font-size: var(--fs-sm);
}

ui-list-view .lv-muted {
  color: var(--text-muted);
}

/* ── Empty + Loading ── */
ui-list-view .lv-empty {
  padding: var(--spacing-10) var(--spacing-8);
  text-align: center;
  color: var(--text-dim);
  font-size: var(--fs-lg);
}

/* A failed load is not an empty list, and must not be dimmed like one. */
ui-list-view .lv-empty.lv-empty-error {
  color: var(--color-danger-fg, var(--text-primary));
}

ui-list-view .lv-loading {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.2);
  z-index: var(--z-loading);
}

ui-list-view .lv-loading[hidden] {
  display: none;
}

ui-list-view .lv-spinner {
  width: 24px;
  height: 24px;
  border: 3px solid var(--border);
  border-top-color: var(--accent);
  border-radius: var(--radius-circle);
  animation: lv-spin 0.6s linear infinite;
}

@keyframes lv-spin {
  to { transform: rotate(360deg); }
}

/* ── Pagination ── */
ui-list-view .lv-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--spacing-6) 0;
  margin-top: var(--spacing-6);
}

ui-list-view .lv-page-info {
  font-size: var(--fs-md);
  color: var(--text-muted);
}

ui-list-view .lv-page-controls {
  display: flex;
  align-items: center;
  gap: var(--spacing-2);
}

ui-list-view .lv-page-btn {
  padding: var(--spacing-3) var(--spacing-6);
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
  transition: all 0.15s;
}

ui-list-view .lv-page-btn:hover:not(:disabled) {
  border-color: var(--accent);
  color: var(--accent);
}

ui-list-view .lv-page-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

ui-list-view .lv-page-numbers {
  display: flex;
  align-items: center;
  gap: var(--spacing-1);
}

ui-list-view .lv-page-num {
  min-width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-md);
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  transition: all 0.15s;
}

ui-list-view .lv-page-num:hover {
  background: var(--surface-2);
  color: var(--text);
}

ui-list-view .lv-page-num.lv-page-active {
  background: var(--accent-dim);
  border-color: var(--accent);
  color: var(--accent);
  font-weight: var(--fw-semibold);
}

ui-list-view .lv-page-ellipsis {
  padding: 0 var(--spacing-3);
  color: var(--text-dim);
  font-size: var(--fs-lg);
}


/* ══════════════════════════════════════════════════════════════════
   DIALOG (shared overlay)
   ══════════════════════════════════════════════════════════════════ */

.overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: var(--z-menu);
  align-items: center;
  justify-content: center;
}

.overlay.open {
  display: flex;
}

.dialog {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--spacing-8);
  width: 420px;
  max-width: 90vw;
}

.dialog h3 {
  margin-bottom: var(--spacing-7);
  font-size: var(--fs-2xl);
}

.form-field {
  margin-bottom: var(--spacing-7);
}

.form-field label {
  display: block;
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
  margin-bottom: var(--spacing-3);
  text-transform: uppercase;
  letter-spacing: 0.3px;
}

.form-field input,
.form-field select {
  width: 100%;
  padding: var(--spacing-5) var(--spacing-6);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text);
  font-size: var(--fs-lg);
  outline: none;
  box-sizing: border-box;
}

.form-field input:focus,
.form-field select:focus {
  border-color: var(--accent);
}

/* Custom SDK Select Dropdown */
.sdk-select {
  position: relative;
}

.sdk-select-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: var(--spacing-5) var(--spacing-6);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text-muted);
  font-size: var(--fs-lg);
  cursor: pointer;
  box-sizing: border-box;
  transition: border-color 0.15s;
}

.sdk-select-trigger:hover {
  border-color: var(--text-muted);
}

.sdk-select-has-value {
  color: var(--text);
}

.sdk-select-arrow {
  font-size: var(--fs-base);
  color: var(--text-muted);
}

.sdk-select-dropdown {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  margin-top: var(--spacing-2);
  background: var(--surface-3);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--elev-dropdown);
  max-height: 240px;
  overflow-y: auto;
  z-index: var(--z-menu);
}

.sdk-select-dropdown.open {
  display: block;
}

.sdk-select-option {
  padding: var(--spacing-4) var(--spacing-6);
  color: var(--text);
  font-size: var(--fs-lg);
  cursor: pointer;
  transition: background 0.1s;
}

.sdk-select-option:hover {
  background: var(--accent);
  color: var(--white);
}

.sdk-select-option:first-child {
  border-radius: var(--radius) var(--radius) 0 0;
}

.sdk-select-option:last-child {
  border-radius: 0 0 var(--radius) var(--radius);
}

.form-actions {
  display: flex;
  gap: var(--spacing-4);
  justify-content: flex-end;
  margin-top: var(--spacing-8);
}

.required {
  color: var(--danger);
}

/* ══════════════════════════════════════════════════════════════════
   DIALOG — ui-dialog (v2 declarative modal)
   ══════════════════════════════════════════════════════════════════ */

ui-dialog {
  display: contents;
}

/* ─── Backdrop ─── */
.dlg-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  z-index: var(--z-modal);
  align-items: center;
  justify-content: center;
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  animation: dlg-fade-in 0.15s ease-out;
}
.dlg-backdrop.dlg-open {
  display: flex;
}

@keyframes dlg-fade-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* ─── Panel ─── */
.dlg-panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  display: flex;
  flex-direction: column;
  max-height: 90vh;
  box-shadow:
    var(--elev-modal);
  animation: dlg-slide-up 0.2s ease-out;
  /* Inert, deliberately left in place: .dlg-panel carries no tabindex
     (ui-dialog.js:241) so it can never receive focus, and an unfocusable
     element cannot render a focus ring. Do NOT "fix" this by adding a
     :focus-visible ring — it would never match. The real gap is that
     _focusFirst() (ui-dialog.js:462) silently does nothing when a dialog has
     no focusable children, leaving focus outside the modal. Resolved by
     ND-81's migration to native <dialog>, where the UA manages this. (ND-35) */
  outline: none;
}

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

/* ─── Size Variants ─── */
.dlg-sm {
  width: 400px;
  max-width: 92vw;
}
.dlg-md {
  width: 560px;
  max-width: 92vw;
}
.dlg-lg {
  width: 780px;
  max-width: 92vw;
}
.dlg-full {
  width: 96vw;
  height: 92vh;
  max-width: 96vw;
  max-height: 92vh;
}

/* ─── Header ─── */
.dlg-header {
  display: flex;
  align-items: center;
  padding: var(--spacing-7) var(--spacing-8) 0;
  gap: var(--spacing-6);
}
.dlg-header-danger .dlg-title {
  color: var(--danger);
}
.dlg-title {
  font-size: var(--fs-title);
  font-weight: var(--fw-bold);
  color: var(--text);
  line-height: var(--lh-tight);
}
.dlg-close-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border: none;
  background: transparent;
  color: var(--text-dim);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition:
    background 0.12s,
    color 0.12s;
  flex-shrink: 0;
}
.dlg-close-btn:hover {
  background: var(--surface-2);
  color: var(--text);
}

/* ─── Body ─── */
.dlg-body {
  padding: var(--spacing-7) var(--spacing-8);
  overflow-y: auto;
  flex: 1;
  min-height: 0;
  color: var(--text);
  font-size: var(--fs-lg);
  line-height: 1.55;
}
.dlg-body > ui-form {
  padding-top: var(--spacing-2);
}

/* ─── Error Banner ─── */
.dlg-error {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
  padding: var(--spacing-5) var(--spacing-8);
  background: var(--danger-bg);
  color: var(--danger);
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  border-top: 1px solid color-mix(in srgb, var(--danger) 25%, transparent);
}
.dlg-error svg {
  flex-shrink: 0;
}

/* ─── Footer ─── */
.dlg-footer {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--spacing-4);
  padding: var(--spacing-7) var(--spacing-8);
  border-top: 1px solid var(--border);
}

/* ─── Buttons ─── */
.dlg-btn {
  padding: var(--spacing-4) var(--spacing-7);
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  font-family: inherit;
  border-radius: var(--radius-sm);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-3);
  border: 1px solid transparent;
  transition:
    background 0.12s,
    color 0.12s,
    border-color 0.12s,
    opacity 0.12s;
  line-height: var(--lh-tight);
}
.dlg-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.dlg-btn-primary {
  background: var(--accent);
  color: var(--white);
  border-color: var(--accent);
}
.dlg-btn-primary:hover:not(:disabled) {
  background: color-mix(in srgb, var(--accent) 85%, #000);
}

.dlg-btn-danger {
  background: var(--danger);
  color: var(--white);
  border-color: var(--danger);
}
.dlg-btn-danger:hover:not(:disabled) {
  background: color-mix(in srgb, var(--danger) 85%, #000);
}

.dlg-btn-ghost {
  background: transparent;
  color: var(--text-muted);
  border-color: transparent;
}
.dlg-btn-ghost:hover:not(:disabled) {
  background: var(--surface-2);
  color: var(--text);
}

.dlg-btn-outline {
  background: transparent;
  color: var(--text);
  border-color: var(--border);
}
.dlg-btn-outline:hover:not(:disabled) {
  background: var(--surface-2);
  border-color: var(--text-dim);
}

/* ─── Save Spinner ─── */
.dlg-spinner {
  display: inline-block;
  width: 14px;
  height: 14px;
  border: 2px solid rgba(255, 255, 255, 0.25);
  border-top-color: var(--white);
  border-radius: var(--radius-circle);
  animation: dlg-spin 0.6s linear infinite;
  vertical-align: middle;
}
@keyframes dlg-spin {
  to {
    transform: rotate(360deg);
  }
}

/* ══════════════════════════════════════════════════════════════════
   DETAIL — ui-detail-hero (v2 — fully declarative)
   ══════════════════════════════════════════════════════════════════ */

:is(ui-detail-hero, ui-policy-hero) {
  display: block;
}

:is(ui-detail-hero, ui-policy-hero) .hero-v2 {
  display: flex;
  flex-direction: column;
  gap: 0;
  /* Horizontal padding is --spacing-7 (16px), not --spacing-8 (24px), so the hero's
     content sits on the same left edge as the detail sidebar's nav ICONS below it.
     Measured: sidebar left 260, nav icon left 276. At 24px the hero started at 284
     and everything in it was 8px out of alignment with the navigation. */
  padding: var(--spacing-5) var(--spacing-7);
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  /* Containing block for the pinned status badge. */
  position: relative;
}

/* Row 1: Title + Actions */
:is(ui-detail-hero, ui-policy-hero) .hero-row-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--spacing-6);
  min-height: 32px;
}

:is(ui-detail-hero, ui-policy-hero) .hero-title-group {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
  min-width: 0;
  flex: 1;
}

:is(ui-detail-hero, ui-policy-hero) .hero-title {
  font-size: var(--fs-title);
  font-weight: var(--fw-bold);
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin: 0;
  line-height: var(--lh-tight);
  /* Ellipsis inside a flex row needs an explicit min-width, or the title refuses
     to shrink and pushes the status badge out of the row instead. */
  min-width: 0;
}

/* Window controls (sidebar + collapse), leading the row left of the title.
   Kept as its own cluster with a divider so it reads as chrome rather than as part
   of the entity's identity — in the original the panel glyph sat flush against the
   insured's name and was mistaken for a logo. */
:is(ui-detail-hero, ui-policy-hero) .hero-chrome {
  display: flex;
  align-items: center;
  gap: var(--spacing-1);
  flex-shrink: 0;
  padding-right: var(--spacing-4);
  margin-right: var(--spacing-2);
  border-right: 1px solid var(--border);
}

/* The status badge is PINNED to the hero's lower-right corner.
   Absolute rather than in flow, so it is in the same place on every record however
   many subtitles, vitals or banners sit above it — and outside .hero-body, so
   collapsing the body never hides what state the record is in. */
:is(ui-detail-hero, ui-policy-hero) .hero-status-badge-slot {
  position: absolute;
  right: var(--spacing-7);
  bottom: var(--spacing-5);
  display: inline-flex;
  flex-shrink: 0;
}
/* Scoped to `.badge` so it styles only the PINNED pill (the no-vitals case). The same
   hero-status-badge hook is also on the status CARD's value, which must keep the card
   value's own type and zero padding. */
:is(ui-detail-hero, ui-policy-hero) .hero-status-badge.badge {
  flex-shrink: 0;
  font-size: var(--fs-sm);
  padding: var(--spacing-1) var(--spacing-4);
}

:is(ui-detail-hero, ui-policy-hero) .hero-toggle {
  flex-shrink: 0;
  background: none;
  border: none;
  cursor: pointer;
  padding: var(--spacing-2);
  color: var(--text-muted);
  border-radius: var(--radius-xs);
  display: flex;
  align-items: center;
  transition: color 0.15s, background 0.15s;
}
:is(ui-detail-hero, ui-policy-hero) .hero-toggle:hover {
  color: var(--accent);
  background: var(--surface-2);
}

:is(ui-detail-hero, ui-policy-hero) .hero-sidebar-toggle {
  flex-shrink: 0;
  background: none;
  border: none;
  cursor: pointer;
  padding: var(--spacing-2);
  color: var(--text-muted);
  border-radius: var(--radius-xs);
  display: flex;
  align-items: center;
  transition: color 0.15s, background 0.15s;
}
:is(ui-detail-hero, ui-policy-hero) .hero-sidebar-toggle:hover {
  color: var(--accent);
  background: var(--surface-2);
}

:is(ui-detail-hero, ui-policy-hero) .hero-actions {
  display: flex;
  /* --spacing-3 (6px), not --spacing-1 (2px). Now that every action is a 30px icon
     square, 2px ran them together into one undifferentiated blob — the gap was set
     when the buttons carried labels and were self-separating. */
  gap: var(--spacing-3);
  flex-shrink: 0;
  align-items: center;
}

:is(ui-detail-hero, ui-policy-hero) .hero-actions .hero-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: none;
  border-radius: var(--radius-sm);
  cursor: pointer;
  color: var(--text-muted);
  background: transparent;
  transition:
    background 0.15s,
    color 0.15s;
  position: relative;
}
:is(ui-detail-hero, ui-policy-hero) .hero-actions .hero-icon-btn:hover {
  background: var(--surface-2);
  color: var(--text);
}
/* Labelled action buttons.
   The old .hero-icon-btn.btn-* rules set COLOUR ONLY — btn-primary was an accent
   hue, btn-outline resolved identical to the default, and there was no size, fill
   or border difference. Hue was the entire hierarchy signal, which is both
   unreadable at a glance and WCAG 1.4.1 use-of-colour. */
:is(ui-detail-hero, ui-policy-hero) .hero-actions .hero-action-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-3);
  height: 30px;
  padding: 0 var(--spacing-6);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  line-height: var(--lh-none);
  white-space: nowrap;
  transition:
    background 0.15s,
    color 0.15s,
    border-color 0.15s;
}

/* Icon-only secondary: same 30px square as the kebab trigger, so the row reads as
   one control cluster rather than a mix of pills and glyphs. */
:is(ui-detail-hero, ui-policy-hero) .hero-actions .hero-action-btn.hero-action-icon-only {
  width: 30px;
  padding: 0;
  justify-content: center;
  gap: 0;
}

:is(ui-detail-hero, ui-policy-hero) .hero-actions .hero-action-btn.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--text-on-accent);
}
:is(ui-detail-hero, ui-policy-hero) .hero-actions .hero-action-btn.btn-primary:hover {
  background: color-mix(in srgb, var(--accent) 85%, black);
}

:is(ui-detail-hero, ui-policy-hero) .hero-actions .hero-action-btn.btn-outline {
  background: var(--surface-2);
  border-color: var(--border);
  color: var(--text);
}
:is(ui-detail-hero, ui-policy-hero) .hero-actions .hero-action-btn.btn-outline:hover {
  background: var(--surface-3);
}

:is(ui-detail-hero, ui-policy-hero) .hero-actions .hero-action-btn.btn-danger {
  background: var(--danger-bg);
  border-color: color-mix(in srgb, var(--danger) 35%, transparent);
  color: var(--danger);
}
:is(ui-detail-hero, ui-policy-hero) .hero-actions .hero-action-btn.btn-danger:hover {
  background: color-mix(in srgb, var(--danger) 20%, transparent);
}

/* Matches the outline/offset convention used for every other focusable control. */
:is(ui-detail-hero, ui-policy-hero) .hero-actions .hero-action-btn:focus-visible,
:is(ui-detail-hero, ui-policy-hero) .hero-actions .hero-icon-btn:focus-visible,
:is(ui-detail-hero, ui-policy-hero) .hero-menu-dropdown .menu-item:focus-visible,
:is(ui-detail-hero, ui-policy-hero) .hero-toggle:focus-visible,
:is(ui-detail-hero, ui-policy-hero) .hero-sidebar-toggle:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Action menu dropdown */
:is(ui-detail-hero, ui-policy-hero) .hero-action-menu {
  position: relative;
}
:is(ui-detail-hero, ui-policy-hero) .hero-action-menu .hero-menu-dropdown {
  display: none;
  position: absolute;
  top: 100%;
  right: 0;
  margin-top: var(--spacing-2);
  min-width: 160px;
  padding: var(--spacing-2) 0;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--elev-menu);
  z-index: var(--z-menu);
}
:is(ui-detail-hero, ui-policy-hero) .hero-action-menu.open .hero-menu-dropdown {
  display: block;
}
:is(ui-detail-hero, ui-policy-hero) .hero-menu-dropdown .menu-item {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
  padding: var(--spacing-3) var(--spacing-6);
  font-size: var(--fs-md);
  color: var(--text);
  cursor: pointer;
  border: none;
  background: none;
  width: 100%;
  text-align: left;
}
:is(ui-detail-hero, ui-policy-hero) .hero-menu-dropdown .menu-item:hover {
  background: var(--surface-3);
}
:is(ui-detail-hero, ui-policy-hero) .hero-menu-dropdown .menu-item.danger {
  color: var(--danger);
}
:is(ui-detail-hero, ui-policy-hero) .hero-menu-dropdown .menu-separator {
  height: 1px;
  background: var(--border);
  margin: var(--spacing-2) 0;
}

/* Collapsible body */
:is(ui-detail-hero, ui-policy-hero) .hero-body {
  overflow: hidden;
  max-height: 200px;
  transition:
    max-height 0.3s cubic-bezier(0.4, 0, 0.2, 1),
    opacity 0.2s cubic-bezier(0.4, 0, 0.2, 1);
  opacity: 1;
}
:is(ui-detail-hero, ui-policy-hero) .hero-body.collapsed {
  max-height: 0;
  opacity: 0;
  pointer-events: none;
  transition:
    max-height 0.25s cubic-bezier(0.4, 0, 1, 1),
    opacity 0.15s cubic-bezier(0.4, 0, 1, 1);
}

/* Row 2: Subtitle + Status badge */
:is(ui-detail-hero, ui-policy-hero) .hero-subtitle-row {
  display: flex;
  align-items: center;
  gap: var(--spacing-3);
  flex-wrap: wrap;
  font-size: var(--fs-base);
  color: var(--text-muted);
  padding: var(--spacing-1) 0 0;
  min-height: 0;
}
:is(ui-detail-hero, ui-policy-hero) .hero-subtitle-row.empty {
  display: none;
}

:is(ui-detail-hero, ui-policy-hero) .hero-sep {
  color: var(--text-dim);
  font-weight: var(--fw-light);
  margin: 0 var(--spacing-1);
}

:is(ui-detail-hero, ui-policy-hero) .hero-sub-part {
  white-space: nowrap;
}

/* Row 3: Meta cards (compact) */
:is(ui-detail-hero, ui-policy-hero) .hero-meta-row {
  display: flex;
  gap: var(--spacing-4);
  flex-wrap: wrap;
  padding: var(--spacing-3) 0 var(--spacing-1);
  min-height: 0;
}
:is(ui-detail-hero, ui-policy-hero) .hero-meta-row.empty {
  display: none;
}

:is(ui-detail-hero, ui-policy-hero) .hero-meta-card {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-1);
  padding: var(--spacing-3) var(--spacing-5);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  min-width: 70px;
  /* Cards GROW from their content width to fill the band, rather than clustering at
     the left. The vitals row was using 35% of a 1119px hero, so the actions sat
     marooned at the right with a void under them — the layout read as unbalanced
     wherever the status badge went.

     `1 1 auto`, not `1 1 0`: equal-basis flex made every card the same width, which
     cramped "POL-2026-00012" into two lines while wasting the same space on "KS".
     Growing from content keeps each card proportional to what it holds.

     max-width caps the growth so a hero with only two vitals gets two reasonable
     cards rather than two 550px slabs. */
  flex: 1 1 auto;
  max-width: 240px;
}

/* One line per value. A card that grows is a card that can also be squeezed, and a
   wrapped value changes the row's height and therefore the whole hero's. */
:is(ui-detail-hero, ui-policy-hero) .hero-meta-value {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The status card. Tinted from its own variant colour via currentColor, so the five
   variants need one rule each instead of three. */
:is(ui-detail-hero, ui-policy-hero) .hero-status-card {
  border-color: color-mix(in srgb, currentColor 45%, transparent);
  background: color-mix(in srgb, currentColor 12%, transparent);
}
:is(ui-detail-hero, ui-policy-hero) .hero-status-card .hero-meta-label,
:is(ui-detail-hero, ui-policy-hero) .hero-status-card .hero-meta-value {
  color: currentColor;
}
:is(ui-detail-hero, ui-policy-hero) .hero-status-card.status-muted { color: var(--text-muted); }
:is(ui-detail-hero, ui-policy-hero) .hero-status-card.status-info { color: var(--info); }
:is(ui-detail-hero, ui-policy-hero) .hero-status-card.status-success { color: var(--success); }
:is(ui-detail-hero, ui-policy-hero) .hero-status-card.status-warning { color: var(--warning); }
:is(ui-detail-hero, ui-policy-hero) .hero-status-card.status-danger { color: var(--danger); }

:is(ui-detail-hero, ui-policy-hero) .hero-meta-label {
  display: flex;
  align-items: center;
  gap: var(--spacing-2);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-dim);
}

:is(ui-detail-hero, ui-policy-hero) .hero-meta-icon {
  display: inline-flex;
  color: var(--text-dim);
}

:is(ui-detail-hero, ui-policy-hero) .hero-meta-value {
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  color: var(--text);
}

/* Row 4: Banners */
:is(ui-detail-hero, ui-policy-hero) .hero-banner-row {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-2);
  padding-top: var(--spacing-3);
  min-height: 0;
}
:is(ui-detail-hero, ui-policy-hero) .hero-banner-row.empty {
  display: none;
}

:is(ui-detail-hero, ui-policy-hero) .hero-banner {
  display: flex;
  align-items: center;
  gap: var(--spacing-3);
  padding: var(--spacing-3) var(--spacing-5);
  border-radius: var(--radius-sm);
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
  line-height: var(--lh-tight);
}

:is(ui-detail-hero, ui-policy-hero) .hero-banner-icon {
  display: inline-flex;
  flex-shrink: 0;
}

:is(ui-detail-hero, ui-policy-hero) .hero-banner-info {
  background: var(--info-bg);
  color: var(--info);
  border: 1px solid color-mix(in srgb, var(--info) 25%, transparent);
}
:is(ui-detail-hero, ui-policy-hero) .hero-banner-warning {
  background: var(--warning-bg);
  color: var(--warning);
  border: 1px solid color-mix(in srgb, var(--warning) 25%, transparent);
}
:is(ui-detail-hero, ui-policy-hero) .hero-banner-error {
  background: var(--danger-bg);
  color: var(--danger);
  border: 1px solid color-mix(in srgb, var(--danger) 25%, transparent);
}
:is(ui-detail-hero, ui-policy-hero) .hero-banner-success {
  background: var(--success-bg);
  color: var(--success);
  border: 1px solid color-mix(in srgb, var(--success) 25%, transparent);
}

/* ══════════════════════════════════════════════════════════════════
   DETAIL — ui-node-header (v2 — compact node identity bar)
   ══════════════════════════════════════════════════════════════════ */

ui-node-header {
  display: block;
  flex-shrink: 0;
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
}

ui-node-header .nh-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--spacing-4);
  padding: var(--spacing-3) var(--spacing-7);
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  min-height: 34px;
}

/* ── Left: back + title + badges + meta ── */
ui-node-header .nh-left {
  display: flex;
  align-items: center;
  gap: var(--spacing-3);
  min-width: 0;
  flex: 1;
  overflow: hidden;
}

ui-node-header .nh-back {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: none;
  border-radius: var(--radius-xs);
  cursor: pointer;
  color: var(--text-muted);
  background: transparent;
  transition:
    background 0.15s,
    color 0.15s;
}
ui-node-header .nh-back:hover {
  background: var(--surface-2);
  color: var(--text);
}

ui-node-header .nh-title {
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: var(--lh-tight);
  flex-shrink: 1;
  min-width: 0;
}

ui-node-header .nh-badges {
  display: inline-flex;
  gap: var(--spacing-2);
  flex-shrink: 0;
}

/* Small badges for node header */
ui-node-header .badge-sm {
  display: inline-block;
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  padding: var(--spacing-1) var(--spacing-3);
  border-radius: var(--radius-xs);
  line-height: var(--lh-normal);
  white-space: nowrap;
}

/* Casing normalisation is OPT-IN, added by ui-node-header per value.
   `text-transform` is content-blind — CSS cannot tell an enum token from a
   sentence — so it sat here as a blanket `capitalize` and re-wrote server-composed
   text: `Ready to issue, but the rate is $0` rendered as
   `Ready To Issue, But The Rate Is $0`, a warning restyled into a label. The
   element decides per value (see normalisesCase) and only all-lowercase values,
   which carry no casing of their own, get this class. Everything else renders
   exactly as the system stated it. */
ui-node-header .badge-sm.badge-cap {
  text-transform: capitalize;
}
ui-node-header .badge-sm.success {
  background: var(--success-bg);
  color: var(--success);
}
ui-node-header .badge-sm.warning {
  background: var(--warning-bg);
  color: var(--warning);
}
ui-node-header .badge-sm.info {
  background: var(--info-bg);
  color: var(--info);
}
ui-node-header .badge-sm.danger {
  background: var(--danger-bg);
  color: var(--danger);
}
ui-node-header .badge-sm.muted {
  background: var(--surface-2);
  color: var(--text-muted);
}

ui-node-header .nh-meta {
  font-size: var(--fs-base);
  color: var(--text-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex-shrink: 2;
  min-width: 0;
}
ui-node-header .nh-meta::before {
  content: '·';
  margin-right: var(--spacing-3);
  color: var(--text-dim);
}

/* ── Right: actions ── */
ui-node-header .nh-right {
  display: flex;
  flex-shrink: 0;
  align-items: center;
}

ui-node-header .nh-actions {
  display: flex;
  gap: var(--spacing-1);
  align-items: center;
}

ui-node-header .nh-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border: none;
  border-radius: var(--radius-xs);
  cursor: pointer;
  color: var(--text-muted);
  background: transparent;
  transition:
    background 0.15s,
    color 0.15s;
}
ui-node-header .nh-icon-btn:hover {
  background: var(--surface-2);
  color: var(--text);
}
ui-node-header .nh-icon-btn.nh-btn-primary {
  color: var(--accent);
}
ui-node-header .nh-icon-btn.nh-btn-primary:hover {
  background: var(--accent-dim);
}
ui-node-header .nh-icon-btn.nh-btn-danger {
  color: var(--danger);
}
ui-node-header .nh-icon-btn.nh-btn-danger:hover {
  background: var(--danger-bg);
}

/* Action divider between contextual and persistent */
ui-node-header .nh-divider {
  display: inline-block;
  width: 1px;
  height: 16px;
  background: var(--border);
  margin: 0 var(--spacing-2);
  flex-shrink: 0;
}

/* ── Kebab menu ── */
ui-node-header .nh-menu {
  position: relative;
}
ui-node-header .nh-menu-dropdown {
  display: none;
  position: absolute;
  top: 100%;
  right: 0;
  margin-top: var(--spacing-2);
  min-width: 150px;
  padding: var(--spacing-2) 0;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--elev-menu);
  z-index: var(--z-menu);
}
ui-node-header .nh-menu.open .nh-menu-dropdown {
  display: block;
}
ui-node-header .nh-menu-item {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
  padding: var(--spacing-3) var(--spacing-6);
  font-size: var(--fs-base);
  color: var(--text);
  cursor: pointer;
  border: none;
  background: none;
  width: 100%;
  text-align: left;
}
ui-node-header .nh-menu-item:hover {
  background: var(--surface-3);
}
ui-node-header .nh-menu-item.danger {
  color: var(--danger);
}
ui-node-header .nh-menu-separator {
  height: 1px;
  background: var(--border);
  margin: var(--spacing-2) 0;
}

/* ══════════════════════════════════════════════════════════════════
   DETAIL — ui-detail-sidebar (tree-capable)
   ══════════════════════════════════════════════════════════════════ */

:is(ui-detail-sidebar, ui-policy-nav) {
  display: block;
  overflow-y: auto;
  font-size: var(--fs-md);
}

/* ── Sections ─────────────────────────────────────────────────── */

:is(ui-detail-sidebar, ui-policy-nav) .sb-section {
  margin-bottom: var(--spacing-2);
}

:is(ui-detail-sidebar, ui-policy-nav) .sb-section-header {
  display: flex;
  align-items: center;
  gap: var(--spacing-3);
  padding: var(--spacing-4) var(--spacing-4) var(--spacing-3);
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--text-muted);
  cursor: pointer;
  user-select: none;
  border-radius: var(--radius-xs);
  transition: color 0.12s;
}

:is(ui-detail-sidebar, ui-policy-nav) .sb-section-header:hover {
  color: var(--text);
}

:is(ui-detail-sidebar, ui-policy-nav) .sb-section-icon {
  display: flex;
  align-items: center;
  color: var(--text-dim);
}

:is(ui-detail-sidebar, ui-policy-nav) .sb-section-label {
  flex: 1;
  min-width: 0;
}

:is(ui-detail-sidebar, ui-policy-nav) .sb-chevron {
  font-size: var(--fs-3xs);
  transition: transform 0.15s ease;
  color: var(--text-dim);
  display: inline-block;
}

:is(ui-detail-sidebar, ui-policy-nav) .sb-chevron.expanded {
  transform: rotate(90deg);
}

:is(ui-detail-sidebar, ui-policy-nav) .sb-section-body {
  overflow: hidden;
}

:is(ui-detail-sidebar, ui-policy-nav) .sb-section-body.collapsed {
  display: none;
}

/* ── Flat Nav Items ───────────────────────────────────────────── */

:is(ui-detail-sidebar, ui-policy-nav) .sb-item {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
  padding: var(--spacing-3) var(--spacing-5);
  margin: var(--spacing-1) var(--spacing-2);
  font-size: var(--fs-md);
  cursor: pointer;
  color: var(--text-muted);
  border-radius: var(--radius-sm);
  transition:
    background 0.12s,
    color 0.12s;
  user-select: none;
  white-space: nowrap;
  overflow: hidden;
}

:is(ui-detail-sidebar, ui-policy-nav) .sb-item:hover {
  background: var(--surface-2);
  color: var(--text);
}

:is(ui-detail-sidebar, ui-policy-nav) .sb-item.active {
  background: var(--accent-dim);
  color: var(--accent);
  font-weight: var(--fw-semibold);
}

:is(ui-detail-sidebar, ui-policy-nav) .sb-item-icon {
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

:is(ui-detail-sidebar, ui-policy-nav) .sb-item-label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ── Badges ───────────────────────────────────────────────────── */

:is(ui-detail-sidebar, ui-policy-nav) .sb-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 var(--spacing-3);
  border-radius: var(--radius-full);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  line-height: var(--lh-none);
  flex-shrink: 0;
  background: var(--surface-2);
  color: var(--text-muted);
}

:is(ui-detail-sidebar, ui-policy-nav) .sb-badge-success {
  background: var(--success-bg);
  color: var(--success);
}

:is(ui-detail-sidebar, ui-policy-nav) .sb-badge-danger {
  background: var(--danger-bg);
  color: var(--danger);
}

:is(ui-detail-sidebar, ui-policy-nav) .sb-badge-warning {
  background: var(--warning-bg);
  color: var(--warning);
}

:is(ui-detail-sidebar, ui-policy-nav) .sb-badge-info {
  background: var(--info-bg);
  color: var(--info);
}

:is(ui-detail-sidebar, ui-policy-nav) .sb-badge-money {
  background: var(--success-bg);
  color: var(--success);
}

:is(ui-detail-sidebar, ui-policy-nav) .sb-badge-muted {
  background: rgba(139, 143, 165, 0.1);
  color: var(--text-dim);
}

/* ── Tree ─────────────────────────────────────────────────────── */

:is(ui-detail-sidebar, ui-policy-nav) .sb-tree {
  padding: 0 0 var(--spacing-2);
}

:is(ui-detail-sidebar, ui-policy-nav) .sb-tree-empty {
  padding: var(--spacing-4) var(--spacing-6);
  font-size: var(--fs-base);
  color: var(--text-dim);
  font-style: italic;
}

:is(ui-detail-sidebar, ui-policy-nav) .tree-row {
  display: flex;
  align-items: center;
  gap: var(--spacing-2);
  padding: var(--spacing-3) var(--spacing-4);
  padding-left: calc(8px + var(--depth, 0) * 16px);
  margin: var(--spacing-1) var(--spacing-2);
  font-size: var(--fs-md);
  cursor: pointer;
  color: var(--text-muted);
  border-radius: var(--radius-sm);
  transition:
    background 0.12s,
    color 0.12s;
  user-select: none;
  white-space: nowrap;
  overflow: hidden;
}

:is(ui-detail-sidebar, ui-policy-nav) .tree-row:hover {
  background: var(--surface-2);
  color: var(--text);
}

:is(ui-detail-sidebar, ui-policy-nav) .tree-row.active {
  background: var(--accent-dim);
  color: var(--accent);
  font-weight: var(--fw-semibold);
}

:is(ui-detail-sidebar, ui-policy-nav) .tree-chevron {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  height: 14px;
  font-size: var(--fs-3xs);
  flex-shrink: 0;
  transition: transform 0.15s ease;
  color: var(--text-dim);
  cursor: pointer;
}

:is(ui-detail-sidebar, ui-policy-nav) .tree-chevron.expanded {
  transform: rotate(90deg);
}

:is(ui-detail-sidebar, ui-policy-nav) .tree-chevron.leaf {
  visibility: hidden;
}

:is(ui-detail-sidebar, ui-policy-nav) .tree-icon {
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

:is(ui-detail-sidebar, ui-policy-nav) .tree-label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

:is(ui-detail-sidebar, ui-policy-nav) .tree-label-muted {
  color: var(--text-dim);
}

/* ══════════════════════════════════════════════════════════════════
   DETAIL — ui-detail-view layout
   ══════════════════════════════════════════════════════════════════ */

ui-detail-view {
  display: grid;
  grid-template-columns: var(--detail-sidebar-width, 240px) 1fr;
  grid-template-rows: auto minmax(0, 1fr);
  gap: 0;
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

ui-detail-view:has(> :is(ui-detail-sidebar, ui-policy-nav)[collapsed]) {
  grid-template-columns: 0px 1fr;
}

ui-detail-view {
  transition: grid-template-columns 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

ui-detail-view.detail-sidebar-resizing {
  user-select: none;
  cursor: col-resize;
}

ui-detail-view > :is(ui-detail-hero, ui-policy-hero) {
  grid-column: 1 / -1;
}

ui-detail-view > :is(ui-detail-sidebar, ui-policy-nav) {
  grid-column: 1;
  grid-row: 2;
  padding: var(--spacing-4);
  border-right: 1px solid var(--border);
  min-height: 0;
  overflow-y: auto;
  position: relative;
  transition:
    padding 0.3s cubic-bezier(0.4, 0, 0.2, 1),
    opacity 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

ui-detail-view > :is(ui-detail-sidebar, ui-policy-nav)[collapsed] {
  padding: 0;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
  transition:
    padding 0.25s cubic-bezier(0.4, 0, 1, 1),
    opacity 0.2s cubic-bezier(0.4, 0, 1, 1);
}

ui-detail-view > :is(ui-detail-sidebar, ui-policy-nav) .detail-sb-resize-handle {
  position: absolute;
  top: 0;
  right: -2px;
  width: 4px;
  height: 100%;
  cursor: col-resize;
  z-index: var(--z-sticky);
  transition: background 0.15s;
}
ui-detail-view > :is(ui-detail-sidebar, ui-policy-nav) .detail-sb-resize-handle:hover,
ui-detail-view > :is(ui-detail-sidebar, ui-policy-nav) .detail-sb-resize-handle.dragging {
  background: var(--accent);
}

ui-detail-view > ui-detail-content {
  grid-column: 2;
  grid-row: 2;
  padding: 0;
  min-height: 0;
  overflow-y: auto;
}

ui-content-panel {
  /* Was `display: block` here while ui-content-panel.onConnected set
     `display: flex` INLINE on every instance, so the declaration was dead and
     wrong — the rules just below rely on this being a flex column. The layout now
     lives here and the element no longer writes it, because that write was also
     racing the parent: every panel made ITSELF visible on connect while
     ui-detail-content hides the inactive ones, and connect order decided the
     winner. See ND-91. */
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
}

/* Panels MANAGED by a ui-detail-content are hidden until that parent activates
   one. Declared here rather than assigned as an inline style so that visibility
   has a single, declarative source of truth and a panel that connects LATE — the
   src= fetch is async — is hidden by default instead of appearing alongside the
   active one. Two panels really were visible together in that case.

   Scoped to the direct-child selector on purpose: ui-content-panel is also used
   standalone in two consumer pages (platform sdk-explorer module.html and
   app.html) with no ui-detail-content ancestor, and those must stay visible. A
   blanket `display: none` default would have blanked both. */
/* ND-91: these three declared their own display in onConnected, which is the same
   shape that made ui-content-panel's visibility non-deterministic. Nothing
   currently hides them, so it was a latent hazard rather than a live bug — but an
   element that writes its own display will fight any parent that later hides it.
   Only `display` moved: the gap/margin/height values beside it in JS are
   attribute-driven or would become density-responsive if tokenised here, and that
   is a separate decision. */
ui-field-group {
  display: grid;
}
ui-file-slot {
  display: flex;
  flex-direction: column;
}
ui-master-detail {
  display: flex;
  height: 100%;
}

ui-detail-content > ui-content-panel {
  display: none;
}
ui-detail-content > ui-content-panel.cp-active {
  display: flex;
}

/* Inside content panels, tabs stay fixed at top; tab-panels scroll */
ui-content-panel > ui-tabs {
  flex-shrink: 0;
}
ui-content-panel > ui-tab-panels {
  min-height: 0;
}
ui-content-panel > ui-tab-panels > ui-tab-panel {
  min-height: 0;
  overflow-y: auto;
}

/* ── Skeleton Loading ── */

@keyframes skeleton-shimmer {
  0% { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}

.skeleton-bar {
  border-radius: var(--radius-xs);
  background: linear-gradient(
    90deg,
    var(--surface-2) 0%,
    var(--surface-3) 40%,
    var(--surface-2) 80%
  );
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.8s ease-in-out infinite;
}

/* Hero skeleton bars */
:is(ui-detail-hero, ui-policy-hero) .hero-skeleton-title {
  height: 20px;
  width: 45%;
  min-width: 160px;
}
:is(ui-detail-hero, ui-policy-hero) .hero-skeleton-badge {
  height: 22px;
  width: 64px;
  border-radius: var(--radius-md);
}
:is(ui-detail-hero, ui-policy-hero) .hero-skeleton-sub {
  height: 13px;
  border-radius: var(--radius-2xs);
}
:is(ui-detail-hero, ui-policy-hero) .hero-skeleton-sub:nth-child(1) { width: 100px; }
:is(ui-detail-hero, ui-policy-hero) .hero-skeleton-sub:nth-child(2) { width: 140px; }
:is(ui-detail-hero, ui-policy-hero) .hero-skeleton-sub:nth-child(3) { width: 80px; }
:is(ui-detail-hero, ui-policy-hero) .hero-skeleton-meta {
  width: 80px;
  height: 40px;
  border-radius: var(--radius-sm);
}

/* Content loading overlay */
.detail-loading-overlay {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--spacing-6);
  padding: var(--spacing-10);
  color: var(--text-muted);
  font-size: var(--fs-base);
  min-height: 200px;
}

/* Fade transition on hero content */
:is(ui-detail-hero, ui-policy-hero) .hero-row-top,
:is(ui-detail-hero, ui-policy-hero) .hero-body {
  transition: opacity 0.25s ease;
}
:is(ui-detail-hero, ui-policy-hero)[loading] .hero-row-top,
:is(ui-detail-hero, ui-policy-hero)[loading] .hero-body {
  opacity: 0;
  pointer-events: none;
}
/* Hide real hero content while skeleton is showing */
:is(ui-detail-hero, ui-policy-hero) .hero-skeleton-row:not(.hero-skeleton-hidden) ~ .hero-v2 {
  opacity: 0;
  pointer-events: none;
  max-height: 0;
  overflow: hidden;
}
:is(ui-detail-hero, ui-policy-hero) .hero-skeleton-row {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
  padding: var(--spacing-5) var(--spacing-8);
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  transition: opacity 0.3s ease, max-height 0.3s ease;
  overflow: hidden;
}
:is(ui-detail-hero, ui-policy-hero) .hero-skeleton-row.hero-skeleton-hidden {
  opacity: 0;
  max-height: 0;
  padding-top: 0;
  padding-bottom: 0;
  border-bottom: none;
}
:is(ui-detail-hero, ui-policy-hero) .hero-skeleton-subs {
  display: flex;
  gap: var(--spacing-5);
  margin-left: var(--spacing-4);
}
:is(ui-detail-hero, ui-policy-hero) .hero-skeleton-sep {
  color: var(--text-dim);
  font-size: var(--fs-sm);
}
:is(ui-detail-hero, ui-policy-hero) .hero-skeleton-metas {
  display: flex;
  gap: var(--spacing-4);
  margin-left: var(--spacing-4);
}

/* ══════════════════════════════════════════════════════════════════
   CONTENT — ui-key-value, ui-collapsible, ui-timeline
   ══════════════════════════════════════════════════════════════════ */

ui-key-value {
  display: block;
}

ui-key-value .kv-label {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  margin-bottom: var(--spacing-2);
}

ui-key-value .kv-value {
  font-size: var(--fs-lg);
  color: var(--text);
}
ui-key-value .kv-badge {
  display: inline-block;
  padding: var(--spacing-1) var(--spacing-4);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  border-radius: var(--radius-xs);
  background: var(--surface-2);
  color: var(--text-muted);
  line-height: var(--lh-normal);
}
ui-key-value .kv-badge-success { background: var(--success-bg); color: var(--success); }
ui-key-value .kv-badge-warning { background: var(--warning-bg); color: var(--warning); }
ui-key-value .kv-badge-danger  { background: var(--danger-bg); color: var(--danger); }
ui-key-value .kv-badge-info    { background: var(--info-bg); color: var(--info); }
ui-key-value .kv-badge-muted   { background: var(--surface-2); color: var(--text-muted); }
ui-key-value .kv-bool-pass { color: var(--success); display: inline-flex; }
ui-key-value .kv-bool-fail { color: var(--danger); display: inline-flex; }
ui-key-value .kv-code {
  font-family: var(--mono);
  font-size: var(--fs-base);
  padding: var(--spacing-1) var(--spacing-3);
  border-radius: var(--radius-2xs);
  background: var(--surface-2);
}

ui-text {
  display: block;
  font-size: var(--fs-lg);
  line-height: var(--lh-relaxed);
  color: var(--text);
}

ui-text[variant='heading'] {
  font-size: var(--fs-2xl);
  font-weight: var(--fw-semibold);
  color: var(--text);
}

ui-text[variant='caption'] {
  font-size: var(--fs-base);
  color: var(--text-muted);
}

ui-text[variant='title'] {
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  color: var(--text);
}

ui-text[variant='label'] {
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  color: var(--text);
}

ui-text[variant='muted'] {
  font-size: var(--fs-base);
  color: var(--text-muted);
  line-height: var(--lh-relaxed);
}

/* ui-text declared a `color` enum of five semantic tones and implemented NONE
   of them — no CSS rule, no JS. An authored color="danger" resolved to the
   inherited body colour, so a login error rendered in ordinary text. Third
   attribute found this way (ui-stack max-width, ui-form-field email/tel were
   the others), all by building a real page against the schema.

   After `variant`, so a tone beats a variant's colour — which is the point of
   asking for one. */
ui-text[color='danger'] { color: var(--danger); }
ui-text[color='warning'] { color: var(--warning); }
ui-text[color='success'] { color: var(--success); }
ui-text[color='info'] { color: var(--info); }
ui-text[color='muted'] { color: var(--text-muted); }

ui-text[variant='code'] {
  font-family: var(--mono);
  font-size: var(--fs-base);
  background: var(--surface-2);
  padding: var(--spacing-1) var(--spacing-3);
  border-radius: var(--radius-xs);
  color: var(--accent);
  display: inline;
}

ui-text[variant='mono'] {
  font-family: var(--mono);
  font-size: var(--fs-base);
  color: var(--success);
  min-height: 18px;
  white-space: pre-wrap;
}

ui-text[variant='mono'][color='danger'] {
  color: var(--danger);
}
ui-text[variant='mono'][color='warning'] {
  color: var(--warning);
}
ui-text[variant='mono'][color='muted'] {
  color: var(--text-muted);
}

ui-collapsible {
  display: block;
  margin-bottom: var(--spacing-6);
}

ui-collapsible .collapsible-header {
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  color: var(--text);
  cursor: pointer;
  padding: var(--spacing-4) 0;
  user-select: none;
  display: flex;
  align-items: center;
  gap: var(--spacing-2);
}

ui-collapsible .collapsible-badge {
  margin-left: auto;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  padding: var(--spacing-1) var(--spacing-4);
  border-radius: var(--radius-md);
  line-height: var(--lh-none);
}
ui-collapsible .collapsible-badge.badge-success { color: var(--success); background: rgba(34, 197, 94, 0.1); }
ui-collapsible .collapsible-badge.badge-danger { color: var(--danger); background: rgba(239, 68, 68, 0.1); }
ui-collapsible .collapsible-badge.badge-warning { color: var(--warning); background: rgba(245, 158, 11, 0.1); }
ui-collapsible .collapsible-badge.badge-info { color: var(--accent); background: rgba(59, 130, 246, 0.1); }
ui-collapsible .collapsible-badge.badge-muted { color: var(--text-muted); background: var(--surface-2); }

ui-collapsible .collapsible-arrow {
  font-size: var(--fs-base);
  margin-right: var(--spacing-2);
}

ui-collapsible .collapsible-body {
  padding: var(--spacing-4) 0 var(--spacing-4) var(--spacing-7);
}

/* ── ui-callout — inline status banner ─────────────────────────────
   Five tones over the EXISTING semantic tokens. No new colour values: the
   border is derived from the same token with color-mix, which is the pattern
   .hero-banner-* already uses, so the two banners cannot drift apart.

   `muted` is the one that has no --muted-bg token, because none exists — it
   uses --surface-2 over --text-muted rather than introducing one, since a
   neutral callout wants the ordinary raised-surface colour, not a tinted one.

   The heading carries the tone; the detail line stays --text-muted. A tone
   colour reads well on one short line (hero-banner is single-line) but fights
   legibility over a wrapped sentence, and the detail line here is prose. */

ui-callout {
  display: block;
}

ui-callout .callout {
  display: flex;
  align-items: flex-start;
  gap: var(--spacing-5);
  padding: var(--spacing-6) var(--spacing-7);
  border-radius: var(--radius-sm);
}

ui-callout .callout-icon {
  display: inline-flex;
  flex-shrink: 0;
  /* Optical alignment with the heading's cap height rather than its line box. */
  margin-top: var(--spacing-1);
}

ui-callout .callout-body {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-2);
  /* min-width:0 is what actually permits the wrap: a flex item's default
     min-width:auto refuses to shrink below its longest word, so a long detail
     sentence would widen the callout instead of wrapping inside it. */
  min-width: 0;
}

ui-callout .callout-heading {
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-tight);
}

ui-callout .callout-detail {
  font-size: var(--fs-base);
  font-weight: var(--fw-normal);
  line-height: var(--lh-relaxed);
  color: var(--text-muted);
}

ui-callout .callout-success {
  background: var(--success-bg);
  color: var(--success);
  border: 1px solid color-mix(in srgb, var(--success) 25%, transparent);
}
ui-callout .callout-warning {
  background: var(--warning-bg);
  color: var(--warning);
  border: 1px solid color-mix(in srgb, var(--warning) 25%, transparent);
}
ui-callout .callout-danger {
  background: var(--danger-bg);
  color: var(--danger);
  border: 1px solid color-mix(in srgb, var(--danger) 25%, transparent);
}
ui-callout .callout-info {
  background: var(--info-bg);
  color: var(--info);
  border: 1px solid color-mix(in srgb, var(--info) 25%, transparent);
}
ui-callout .callout-muted {
  background: var(--surface-2);
  color: var(--text-muted);
  border: 1px solid var(--border);
}

/* ── ui-requirement-list — prose rows with a state glyph ───────────
   SIZED FOR PROSE, NOT FOR THE SEEDED FIXTURES. Real remediation sentences
   reach ~96 characters while the longest name in the sample data is 33, so
   anything laid out to the sample would wrap badly the first time it met real
   content. Hence: no fixed row height, no truncation, no ellipsis, --lh-relaxed
   on both sentences, and min-width:0 on the flex body so a long sentence wraps
   inside the row instead of widening it.

   The three tones come from the existing semantic tokens. Only the glyph is
   tinted: tinting a whole three-line row in --danger would make a list of
   outstanding items unreadable, and the glyph already carries the state. */

ui-requirement-list {
  display: block;
}

ui-requirement-list .rql-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--spacing-6);
}

ui-requirement-list .rql-row {
  display: flex;
  align-items: flex-start;
  gap: var(--spacing-5);
}

ui-requirement-list .rql-glyph {
  display: inline-flex;
  flex-shrink: 0;
  /* Aligns the glyph to the label's cap height rather than its line box. */
  margin-top: var(--spacing-1);
}

ui-requirement-list .rql-met .rql-glyph { color: var(--success); }
ui-requirement-list .rql-outstanding .rql-glyph { color: var(--danger); }
ui-requirement-list .rql-waived .rql-glyph { color: var(--text-dim); }

ui-requirement-list .rql-body {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-2);
  min-width: 0;
  flex: 1;
}

ui-requirement-list .rql-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--spacing-5);
}

ui-requirement-list .rql-label {
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  line-height: var(--lh-tight);
  color: var(--text);
}

/* The trailing chip. flex-shrink:0 keeps it intact while the label wraps, which
   is the right priority: the target is a short identifier and the name is not. */
ui-requirement-list .rql-panel {
  flex-shrink: 0;
  padding: var(--spacing-1) var(--spacing-3);
  border-radius: var(--radius-full);
  background: var(--surface-2);
  border: 1px solid var(--border);
  font-family: var(--mono);
  font-size: var(--fs-sm);
  line-height: var(--lh-normal);
  color: var(--text-muted);
}

ui-requirement-list .rql-detail {
  font-size: var(--fs-base);
  line-height: var(--lh-relaxed);
  color: var(--text-muted);
}

/* The action line is the one a user acts on, so it is the one that stays at full
   text colour while the current-state sentence recedes. */
ui-requirement-list .rql-remediation {
  font-size: var(--fs-base);
  line-height: var(--lh-relaxed);
  color: var(--text);
}

ui-requirement-list .rql-waived .rql-label {
  color: var(--text-muted);
}

ui-requirement-list .rql-empty {
  margin: 0;
  font-size: var(--fs-base);
  line-height: var(--lh-relaxed);
  color: var(--text-muted);
}

/* ── Cards ─────────────────────────────────────────────────────── */

ui-card {
  display: block;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
}

ui-card[variant="outlined"] {
  background: transparent;
}

ui-card[variant="elevated"] {
  box-shadow: var(--elev-card);
  border-color: transparent;
}

ui-card[variant="flush"] {
  border: none;
  border-radius: 0;
  background: transparent;
}

ui-card[clickable] {
  cursor: pointer;
  transition: border-color 0.15s, box-shadow 0.15s;
}

ui-card[clickable]:hover {
  border-color: var(--accent);
}

ui-card[clickable]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

ui-card[selected] {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent);
}

ui-card[compact] ui-card-header {
  padding: var(--spacing-3) var(--spacing-5);
}

ui-card[compact] ui-card-body {
  padding: var(--spacing-4) var(--spacing-5);
}

ui-card[compact] ui-card-footer {
  padding: var(--spacing-3) var(--spacing-5);
}

ui-card-header {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
  padding: var(--spacing-5) var(--spacing-7);
  border-bottom: 1px solid var(--border);
}

ui-card-header[divider="false"],
ui-card-header:not([divider]) + ui-card-body:empty ~ ui-card-header {
  border-bottom: none;
}

ui-card-body {
  display: block;
  padding: var(--spacing-7);
}

ui-card-body[padding="none"] { padding: 0; }
ui-card-body[padding="sm"] { padding: var(--spacing-4); }
ui-card-body[padding="md"] { padding: var(--spacing-7); }
ui-card-body[padding="lg"] { padding: var(--spacing-9); }

ui-card-footer {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
  padding: var(--spacing-5) var(--spacing-7);
  border-top: 1px solid var(--border);
  justify-content: flex-end;
}

ui-card-footer[align="start"] { justify-content: flex-start; }
ui-card-footer[align="center"] { justify-content: center; }
ui-card-footer[align="end"] { justify-content: flex-end; }
ui-card-footer[align="between"] { justify-content: space-between; }

ui-timeline {
  display: block;
  padding: var(--spacing-4) 0;
}

ui-timeline-item {
  display: flex;
  gap: var(--spacing-6);
  padding: var(--spacing-6) 0;
  border-left: 2px solid var(--border);
  margin-left: var(--spacing-4);
  padding-left: var(--spacing-7);
  position: relative;
}

ui-timeline-item .timeline-dot {
  position: absolute;
  left: -9px;
  top: 14px;
  font-size: var(--fs-base);
}

ui-timeline-item .timeline-content {
  flex: 1;
}

ui-timeline-item .timeline-time {
  font-size: var(--fs-base);
  color: var(--text-muted);
  margin-top: var(--spacing-2);
}

/* ══════════════════════════════════════════════════════════════════
   DETAIL — ui-attachments (v2 — file listing with upload & actions)
   ══════════════════════════════════════════════════════════════════ */

ui-attachments {
  display: block;
  position: relative;
  height: 100%;
  /* Flush inside content panel */
  margin: -20px -24px 0;
  width: calc(100% + 48px);
}

ui-attachments .att-container {
  display: flex;
  flex-direction: column;
  height: 100%;
}

/* ── Toolbar ── */
ui-attachments .att-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--spacing-4) var(--spacing-7);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}

ui-attachments .att-toolbar-left {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
}

ui-attachments .att-title {
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  color: var(--text);
}

ui-attachments .att-count {
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--text-muted);
  background: var(--surface-2);
  padding: var(--spacing-1) var(--spacing-3);
  border-radius: var(--radius-md);
}

ui-attachments .att-count:empty {
  display: none;
}

ui-attachments .att-toolbar-right {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
}

/* Search */
ui-attachments .att-search {
  position: relative;
  display: flex;
  align-items: center;
}

ui-attachments .att-search-icon {
  position: absolute;
  left: 8px;
  display: flex;
  color: var(--text-muted);
  pointer-events: none;
}

ui-attachments .att-search-input {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: var(--spacing-3) var(--spacing-5) var(--spacing-3) var(--spacing-8);
  font-size: var(--fs-base);
  color: var(--text);
  width: 160px;
  outline: none;
  transition:
    border-color 0.15s,
    width 0.2s;
}

ui-attachments .att-search-input:focus {
  border-color: var(--accent);
  width: 200px;
}

/* View toggle */
ui-attachments .att-view-toggle {
  display: flex;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

ui-attachments .att-view-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 26px;
  background: transparent;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  transition:
    background 0.15s,
    color 0.15s;
}

ui-attachments .att-view-btn:hover {
  background: var(--surface-2);
}
ui-attachments .att-view-btn.active {
  background: var(--surface-2);
  color: var(--accent);
}

/* Upload button */
ui-attachments .att-upload-btn {
  display: flex;
  align-items: center;
  gap: var(--spacing-2);
  padding: var(--spacing-3) var(--spacing-5);
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
  background: var(--accent);
  color: var(--white);
  border: none;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: opacity 0.15s;
}

ui-attachments .att-upload-btn:hover {
  opacity: 0.85;
}

/* ── Upload Panel ── */
ui-attachments .att-upload-panel {
  display: none;
  flex-direction: column;
  gap: var(--spacing-5);
  padding: var(--spacing-6) var(--spacing-7);
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}

ui-attachments .att-upload-panel.open {
  display: flex;
}

ui-attachments .att-dropzone {
  border: 2px dashed var(--border);
  border-radius: var(--radius);
  padding: var(--spacing-7);
  text-align: center;
  transition:
    border-color 0.15s,
    background 0.15s;
  cursor: pointer;
}

ui-attachments .att-dropzone.drag-active {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 5%, transparent);
}

ui-attachments .att-dropzone-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--spacing-4);
  color: var(--text-muted);
  font-size: var(--fs-md);
}

ui-attachments .att-browse-label {
  color: var(--accent);
  cursor: pointer;
  text-decoration: underline;
}

/* Staged files */
ui-attachments .att-staged-list {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-3);
}

ui-attachments .att-staged-item {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
  padding: var(--spacing-3) var(--spacing-5);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

ui-attachments .att-staged-icon {
  display: flex;
  flex-shrink: 0;
}

ui-attachments .att-staged-name {
  flex: 1;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  padding: var(--spacing-2) var(--spacing-4);
  font-size: var(--fs-base);
  color: var(--text);
  outline: none;
}

ui-attachments .att-staged-name:focus {
  border-color: var(--accent);
}

ui-attachments .att-staged-meta {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  white-space: nowrap;
}

ui-attachments .att-staged-remove {
  display: flex;
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: var(--spacing-1);
}

ui-attachments .att-staged-remove:hover {
  color: var(--danger);
}

ui-attachments .att-staged-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--spacing-4);
}

ui-attachments .att-staged-clear {
  padding: var(--spacing-3) var(--spacing-5);
  font-size: var(--fs-base);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text);
  cursor: pointer;
}

ui-attachments .att-staged-upload {
  display: flex;
  align-items: center;
  gap: var(--spacing-2);
  padding: var(--spacing-3) var(--spacing-6);
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
  background: var(--accent);
  color: var(--white);
  border: none;
  border-radius: var(--radius-sm);
  cursor: pointer;
}

ui-attachments .att-staged-upload:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ── Drag Overlay ── */
ui-attachments .att-drag-overlay {
  display: none;
  position: absolute;
  inset: 0;
  z-index: var(--z-drag);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  border: 2px dashed var(--accent);
  border-radius: var(--radius);
  align-items: center;
  justify-content: center;
}

ui-attachments .att-drag-overlay.visible {
  display: flex;
}

ui-attachments .att-drag-overlay-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--spacing-4);
  color: var(--accent);
  font-size: var(--fs-lg);
  font-weight: var(--fw-medium);
}

/* ── File Area ── */
ui-attachments .att-file-area {
  flex: 1;
  overflow-y: auto;
  padding: 0;
}

/* ── List View ── */
ui-attachments .att-list-header {
  display: flex;
  align-items: center;
  padding: var(--spacing-3) var(--spacing-7);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
  position: sticky;
  top: 0;
  z-index: var(--z-elevated);
}

ui-attachments .att-list-header [data-sort] {
  cursor: pointer;
}

ui-attachments .att-list-header [data-sort]:hover {
  color: var(--text);
}

ui-attachments .att-list-check {
  width: 28px;
  flex-shrink: 0;
}
ui-attachments .att-list-col-name {
  flex: 1;
  min-width: 0;
}
ui-attachments .att-list-col-size {
  width: 70px;
  text-align: right;
}
ui-attachments .att-list-col-date {
  width: 90px;
}
ui-attachments .att-list-col-user {
  width: 100px;
}
ui-attachments .att-list-col-actions {
  width: 60px;
  display: flex;
  justify-content: flex-end;
}

ui-attachments .att-list-row {
  display: flex;
  align-items: center;
  padding: var(--spacing-4) var(--spacing-7);
  font-size: var(--fs-md);
  color: var(--text);
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background 0.1s;
}

ui-attachments .att-list-row:hover {
  background: var(--surface-2);
}
ui-attachments .att-list-row.selected {
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}

ui-attachments .att-list-col {
  display: flex;
  align-items: center;
  gap: var(--spacing-3);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

ui-attachments .att-file-icon {
  display: flex;
  flex-shrink: 0;
}

ui-attachments .att-file-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

ui-attachments .att-file-ext {
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
  background: var(--surface-2);
  padding: var(--spacing-1) var(--spacing-2);
  border-radius: var(--radius-2xs);
  flex-shrink: 0;
}

ui-attachments .att-list-col-size,
ui-attachments .att-list-col-date,
ui-attachments .att-list-col-user {
  font-size: var(--fs-base);
  color: var(--text-muted);
}

/* Row actions — always visible (touch-friendly, no hover dependency) */
ui-attachments .att-row-action {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: var(--radius-xs);
  background: transparent;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  transition:
    background 0.15s,
    color 0.15s;
}
ui-attachments .att-row-action:hover {
  background: var(--surface-2);
  color: var(--accent);
}

/* Checkbox */
ui-attachments .att-checkbox {
  width: 14px;
  height: 14px;
  accent-color: var(--accent);
  cursor: pointer;
}

/* ── Grid View ── */
ui-attachments .att-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: var(--spacing-5);
  padding: var(--spacing-6) var(--spacing-7);
}

ui-attachments .att-grid-card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  cursor: pointer;
  transition:
    border-color 0.15s,
    background 0.15s;
}

ui-attachments .att-grid-card:hover {
  border-color: var(--accent);
}
ui-attachments .att-grid-card.selected {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 5%, transparent);
}

ui-attachments .att-grid-thumb {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 80px;
  background: var(--surface);
  position: relative;
}

ui-attachments .att-grid-ext {
  position: absolute;
  bottom: 4px;
  right: 6px;
  font-size: var(--fs-2xs);
  font-weight: var(--fw-bold);
  color: var(--text-muted);
  background: var(--surface-2);
  padding: var(--spacing-1) var(--spacing-2);
  border-radius: var(--radius-2xs);
}

ui-attachments .att-grid-info {
  padding: var(--spacing-4) var(--spacing-5);
  flex: 1;
}

ui-attachments .att-grid-name {
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

ui-attachments .att-grid-meta {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  margin-top: var(--spacing-1);
}

ui-attachments .att-grid-actions {
  position: absolute;
  top: 4px;
  right: 4px;
}

ui-attachments .att-grid-card {
  position: relative;
}

/* ── Floating Action Bar ── */
ui-attachments .att-action-bar {
  display: none;
  position: absolute;
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--surface-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--spacing-4) var(--spacing-6);
  box-shadow: var(--elev-dropdown);
  align-items: center;
  gap: var(--spacing-5);
  font-size: var(--fs-base);
  z-index: var(--z-sticky);
  white-space: nowrap;
}

ui-attachments .att-action-bar.visible {
  display: flex;
}

ui-attachments .att-bar-count {
  font-weight: var(--fw-semibold);
  color: var(--text);
}

ui-attachments .att-bar-btn {
  display: flex;
  align-items: center;
  gap: var(--spacing-2);
  padding: var(--spacing-3) var(--spacing-5);
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
  background: var(--accent);
  color: var(--white);
  border: none;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: opacity 0.15s;
}

ui-attachments .att-bar-btn:hover {
  opacity: 0.85;
}
ui-attachments .att-bar-btn-danger {
  background: var(--danger);
}
ui-attachments .att-bar-btn-ghost {
  background: transparent;
  color: var(--text-muted);
  padding: var(--spacing-3);
}

ui-attachments .att-bar-btn-ghost:hover {
  color: var(--text);
}

/* ── Empty State ── */
ui-attachments .att-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--spacing-10) var(--spacing-7);
  gap: var(--spacing-6);
}

ui-attachments .att-empty-icon {
  color: var(--text-muted);
  opacity: 0.5;
}

ui-attachments .att-empty-text {
  font-size: var(--fs-md);
  color: var(--text-muted);
}

/* ══════════════════════════════════════════════════════════════════
   CONTENT — ui-document-viewer (inline document viewer + overlay)
   ══════════════════════════════════════════════════════════════════ */

ui-document-viewer {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

ui-document-viewer .dv-container {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

/* Header bar */
ui-document-viewer .dv-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--spacing-5) var(--spacing-7);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}

ui-document-viewer .dv-header-info {
  display: flex;
  align-items: center;
  gap: var(--spacing-5);
  min-width: 0;
  flex: 1;
}

ui-document-viewer .dv-file-icon {
  display: flex;
  flex-shrink: 0;
}

ui-document-viewer .dv-title-group {
  min-width: 0;
}

ui-document-viewer .dv-title {
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

ui-document-viewer .dv-meta {
  display: flex;
  align-items: center;
  gap: var(--spacing-3);
  font-size: var(--fs-sm);
  color: var(--text-muted);
  margin-top: var(--spacing-1);
}

ui-document-viewer .dv-meta-sep {
  opacity: 0.4;
}

ui-document-viewer .dv-header-actions {
  display: flex;
  gap: var(--spacing-3);
  flex-shrink: 0;
}

ui-document-viewer .dv-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-3);
  padding: var(--spacing-3) var(--spacing-5);
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text);
  cursor: pointer;
  transition: background 0.15s;
  white-space: nowrap;
}

ui-document-viewer .dv-btn:hover {
  background: var(--surface-2);
}

ui-document-viewer .dv-btn-primary {
  background: var(--accent);
  color: var(--white);
  border-color: var(--accent);
}

ui-document-viewer .dv-btn-primary:hover {
  opacity: 0.85;
}

/* Content area */
ui-document-viewer .dv-content {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* Center helper (loading, error, fallback) */
ui-document-viewer .dv-center {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex: 1;
  padding: var(--spacing-9);
  gap: var(--spacing-6);
  text-align: center;
}

ui-document-viewer .dv-error-icon,
ui-document-viewer .dv-empty-icon,
ui-document-viewer .dv-fallback-icon {
  opacity: 0.5;
  color: var(--text-muted);
}

ui-document-viewer .dv-error-title {
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  color: var(--text);
}

ui-document-viewer .dv-error-sub {
  font-size: var(--fs-base);
  color: var(--text-muted);
  max-width: 320px;
}

ui-document-viewer .dv-loading-text {
  font-size: var(--fs-base);
  color: var(--text-muted);
  margin-top: var(--spacing-2);
}

/* Spinner */
ui-document-viewer .dv-spinner {
  width: 28px;
  height: 28px;
  border: 3px solid var(--border);
  border-top-color: var(--accent);
  border-radius: var(--radius-circle);
  animation: dv-spin 0.7s linear infinite;
}

@keyframes dv-spin {
  to { transform: rotate(360deg); }
}

/* Iframe (PDF + HTML) */
ui-document-viewer .dv-iframe {
  flex: 1;
  border: none;
  min-height: 0;
  width: 100%;
  background: var(--white);
}

/* Image viewer */
ui-document-viewer .dv-image-viewer {
  flex: 1;
  overflow: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--spacing-7);
  background-image: radial-gradient(circle, var(--border) 1px, transparent 1px);
  background-size: 16px 16px;
}

ui-document-viewer .dv-image-viewer img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: var(--radius-xs);
  box-shadow: var(--elev-image);
}

/* Text viewer */
ui-document-viewer .dv-text-viewer {
  flex: 1;
  overflow: auto;
  padding: var(--spacing-7);
  margin: 0;
  font-family: 'SF Mono', 'Fira Code', 'Cascadia Code', monospace;
  font-size: var(--fs-base);
  line-height: var(--lh-loose);
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--text);
  background: var(--surface);
}

/* ── Overlay mode ── */
.dv-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  background: rgba(0,0,0,0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.2s ease;
}

.dv-overlay.open {
  opacity: 1;
}

.dv-overlay-container {
  position: relative;
  width: 90vw;
  height: 85vh;
  max-width: 1200px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  box-shadow: var(--elev-overlay);
  transform: translateY(12px);
  transition: transform 0.2s ease;
}

.dv-overlay.open .dv-overlay-container {
  transform: translateY(0);
}

.dv-overlay-close {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: var(--z-sticky);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-sm);
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text-muted);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}

.dv-overlay-close:hover {
  background: var(--surface-2);
  color: var(--text);
}

/* ══════════════════════════════════════════════════════════════════
   FORMS — ui-form-field, ui-form, ui-editable-panel
   ══════════════════════════════════════════════════════════════════ */

/* ─── ui-form-field ─── */
ui-form-field {
  display: block;
  min-width: 0;
}
ui-form-field[full-width] {
  grid-column: 1 / -1;
}

.ff-group {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-2);
}
.ff-group-checkbox {
  flex-direction: row;
  align-items: center;
}

.ff-label {
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
  color: var(--text-muted);
  display: flex;
  align-items: center;
  gap: var(--spacing-2);
}
.ff-required {
  color: var(--danger);
  font-weight: var(--fw-bold);
}

.ff-input {
  height: 34px;
  width: 100%;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface);
  padding: 0 var(--spacing-5);
  font-family: inherit;
  font-size: var(--fs-md);
  color: var(--text);
  outline: none;
  transition:
    border-color 0.15s,
    box-shadow 0.15s;
  box-sizing: border-box;
}
.ff-input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-dim);
}
.ff-input::placeholder {
  color: var(--text-dim);
}
.ff-input:disabled,
.ff-input[readonly] {
  opacity: 0.6;
  cursor: not-allowed;
  background: var(--bg);
}
.ff-input-error {
  border-color: var(--danger) !important;
}
.ff-input-error:focus {
  box-shadow: 0 0 0 2px var(--danger-bg) !important;
}

.ff-textarea {
  height: auto;
  min-height: 80px;
  padding: var(--spacing-4) var(--spacing-5);
  resize: vertical;
  line-height: var(--lh-relaxed);
}

.ff-textarea-expand {
  flex: 1;
  min-height: 200px;
  resize: none;
}

.ff-select {
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  padding-right: var(--spacing-9);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2394a3b8' d='M2.5 4.5L6 8l3.5-3.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
}

.ff-currency-wrap {
  position: relative;
  display: flex;
  align-items: center;
}
.ff-currency-prefix {
  position: absolute;
  left: 10px;
  font-size: var(--fs-md);
  color: var(--text-muted);
  pointer-events: none;
  z-index: var(--z-raised);
}
.ff-currency-wrap .ff-input {
  padding-left: var(--spacing-8);
}

/* Number input: hide spinners */
.ff-input[type='number'] {
  appearance: textfield;
  -moz-appearance: textfield;
}
.ff-input[type='number']::-webkit-inner-spin-button,
.ff-input[type='number']::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.ff-hint {
  font-size: var(--fs-sm);
  color: var(--text-dim);
  line-height: var(--lh-normal);
}
.ff-error {
  font-size: var(--fs-sm);
  color: var(--danger);
  line-height: var(--lh-normal);
  min-height: 0;
}
.ff-error:empty {
  display: none;
}

/* Toggle (checkbox) */
.ff-toggle {
  display: flex;
  align-items: center;
  gap: var(--spacing-5);
  cursor: pointer;
  user-select: none;
  padding: var(--spacing-2) 0;
}
.ff-toggle-input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
  pointer-events: none;
}
.ff-toggle-track {
  position: relative;
  width: 36px;
  height: 20px;
  background: var(--border);
  border-radius: var(--radius-md);
  transition: background 0.15s;
  flex-shrink: 0;
}
.ff-toggle-track::after {
  content: '';
  position: absolute;
  top: 3px;
  left: 3px;
  width: 14px;
  height: 14px;
  background: white;
  border-radius: var(--radius-circle);
  transition: transform 0.15s;
  box-shadow: var(--elev-raised);
}
.ff-toggle-input:checked + .ff-toggle-track {
  background: var(--accent);
}
.ff-toggle-input:checked + .ff-toggle-track::after {
  transform: translateX(16px);
}
.ff-toggle-text {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-1);
}

/* Display value (view mode) */
.ff-display-value {
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  color: var(--text);
  min-height: 20px;
}

/* ─── Typeahead ─── */
.ff-ta-wrap {
  position: relative;
}
.ff-ta-input {
  padding-right: var(--spacing-8);
}
.ff-ta-spinner {
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
  width: 14px;
  height: 14px;
  border: 2px solid var(--border);
  border-top-color: var(--accent);
  border-radius: var(--radius-circle);
  animation: ff-ta-spin 0.6s linear infinite;
}
@keyframes ff-ta-spin {
  to { transform: translateY(-50%) rotate(360deg); }
}
.ff-ta-dropdown {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  margin-top: var(--spacing-2);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow: var(--elev-menu);
  max-height: 200px;
  overflow-y: auto;
  z-index: var(--z-menu);
}
.ff-ta-item {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-1);
  padding: var(--spacing-4) var(--spacing-5);
  cursor: pointer;
  transition: background 0.1s;
}
.ff-ta-item:hover,
.ff-ta-item-active {
  background: var(--accent-dim);
}
.ff-ta-item-primary {
  font-size: var(--fs-md);
  color: var(--text);
  font-weight: var(--fw-medium);
}
.ff-ta-item-secondary {
  font-size: var(--fs-sm);
  color: var(--text-muted);
}
.ff-ta-empty {
  padding: var(--spacing-5);
  font-size: var(--fs-base);
  color: var(--text-dim);
  text-align: center;
}
.ff-ta-create {
  padding: var(--spacing-4) var(--spacing-5);
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
  color: var(--accent);
  cursor: pointer;
  border-top: 1px solid var(--border);
  transition: background 0.1s;
}
.ff-ta-create:hover {
  background: var(--accent-dim);
}
.ff-ta-selected {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--spacing-4);
  padding: var(--spacing-3) var(--spacing-5);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  min-height: 34px;
  box-sizing: border-box;
}
.ff-ta-sel-info {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-1);
  min-width: 0;
}
.ff-ta-sel-primary {
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ff-ta-sel-secondary {
  font-size: var(--fs-sm);
  color: var(--text-muted);
}
.ff-ta-clear {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border: none;
  background: transparent;
  color: var(--text-muted);
  font-size: var(--fs-xl);
  cursor: pointer;
  border-radius: var(--radius-xs);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.1s, color 0.1s;
}
.ff-ta-clear:hover {
  background: var(--danger-bg);
  color: var(--danger);
}

/* ─── ui-form ─── */
ui-form,
.ui-form {
  display: grid;
  grid-template-columns: repeat(var(--ff-columns, 2), 1fr);
  gap: var(--spacing-6) var(--spacing-7);
  align-items: start;
}
.ff-description {
  grid-column: 1 / -1;
  font-size: var(--fs-base);
  color: var(--text-muted);
  line-height: var(--lh-relaxed);
  margin-bottom: var(--spacing-2);
}
.ff-actions {
  grid-column: 1 / -1;
  display: flex;
  gap: var(--spacing-4);
  justify-content: flex-end;
  padding-top: var(--spacing-4);
  border-top: 1px solid var(--border);
}
.ff-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--spacing-2);
  padding: var(--spacing-3) var(--spacing-6);
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition:
    background 0.15s,
    color 0.15s,
    opacity 0.15s;
  border: none;
  font-family: inherit;
}
.ff-btn-submit {
  background: var(--accent);
  color: white;
}
.ff-btn-submit:hover {
  opacity: 0.9;
}
.ff-btn-cancel {
  background: transparent;
  color: var(--text-muted);
  border: 1px solid var(--border);
}
.ff-btn-cancel:hover {
  background: var(--surface);
  color: var(--text);
}

/* ─── ui-editable-panel ─── */
ui-editable-panel,
.ep-panel {
  display: grid;
  grid-template-columns: repeat(var(--ep-columns, 2), 1fr);
  gap: var(--spacing-5) var(--spacing-7);
  align-items: start;
}

/*
 * Inline save failure. Spans every column like the title bar, because it must be
 * readable regardless of `columns`, and must appear even when `hide-header` removes
 * the title bar — that combination is precisely the case where a refused save used
 * to produce no feedback at all.
 */
.ep-save-error {
  grid-column: 1 / -1;
  padding: var(--spacing-3) var(--spacing-4);
  border: 1px solid var(--danger);
  border-radius: var(--radius-sm);
  background: var(--danger-bg);
  color: var(--danger);
  font-size: var(--fs-sm);
}

.ep-title-bar {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: var(--spacing-3);
  padding: var(--spacing-4) var(--spacing-6);
  background: var(--surface);
  border-radius: var(--radius-sm);
  margin-bottom: var(--spacing-2);
}
.ep-title-icon {
  color: var(--text-muted);
  flex-shrink: 0;
  display: flex;
}
.ep-title-text {
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  color: var(--text);
}
.ep-title-actions {
  margin-left: auto;
  display: flex;
  gap: var(--spacing-3);
  align-items: center;
}
.ep-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-2);
  border: none;
  border-radius: var(--radius-xs);
  cursor: pointer;
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  padding: var(--spacing-2) var(--spacing-4);
  transition:
    background 0.1s,
    color 0.1s;
  line-height: var(--lh-none);
  font-family: inherit;
}
.ep-btn-edit {
  background: transparent;
  color: var(--text-muted);
}
.ep-btn-edit:hover {
  background: var(--surface-2);
  color: var(--text);
}
.ep-btn-cancel {
  background: transparent;
  color: var(--text-muted);
}
.ep-btn-cancel:hover {
  background: var(--surface-2);
  color: var(--text);
}
.ep-btn-save {
  background: transparent;
  color: var(--success);
}
.ep-btn-save:hover {
  background: var(--success-bg);
}
.ep-btn-save:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Edit-mode transition */
ui-editable-panel[data-editing="true"] {
  animation: ep-enter-edit 0.35s ease-out;
}

@keyframes ep-enter-edit {
  0% {
    opacity: 0.6;
    transform: scale(0.985);
    filter: brightness(0.9);
  }
  50% {
    filter: brightness(1.08);
  }
  100% {
    opacity: 1;
    transform: scale(1);
    filter: brightness(1);
  }
}

ui-editable-panel .ff-input,
ui-editable-panel .ff-textarea,
ui-editable-panel .ff-select {
  transition: border-color 0.25s ease, box-shadow 0.25s ease, background 0.25s ease;
}

/* Light mode: no overrides needed — uses CSS vars from ui-app[theme="light"] */

/* Responsive: single column on narrow screens */
@media (max-width: 500px) {
  ui-form,
  .ui-form,
  ui-editable-panel,
  .ep-panel {
    grid-template-columns: 1fr !important;
  }
}

/* ══════════════════════════════════════════════════════════════════
   DATA TABLE — ui-data-table (.dt-* prefix)
   ══════════════════════════════════════════════════════════════════ */

ui-data-table {
  display: block;
}

.dt-root {
  display: flex;
  flex-direction: column;
  gap: 0;
  font-size: var(--fs-md);
}

/* ─── Toolbar ─── */
.dt-toolbar {
  display: flex;
  align-items: center;
  gap: var(--spacing-5);
  padding: var(--spacing-5) 0;
}
.dt-toolbar-right {
  margin-left: auto;
  display: flex;
  gap: var(--spacing-3);
}
.dt-search {
  position: relative;
  display: flex;
  align-items: center;
}
.dt-search-icon {
  position: absolute;
  left: 10px;
  color: var(--text-dim);
  display: flex;
  pointer-events: none;
}
.dt-search-input {
  padding: var(--spacing-3) var(--spacing-5) var(--spacing-3) 30px;
  font-size: var(--fs-base);
  font-family: inherit;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  width: 220px;
  outline: none;
  transition: border-color 0.15s;
}
.dt-search-input:focus {
  border-color: var(--accent);
}
.dt-search-input::placeholder {
  color: var(--text-dim);
}
.dt-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-2);
  padding: var(--spacing-3) var(--spacing-5);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  font-family: inherit;
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  background: var(--surface);
  color: var(--text-muted);
  cursor: pointer;
  transition:
    background 0.15s,
    color 0.15s,
    border-color 0.15s;
}
.dt-btn:hover {
  background: var(--surface-2);
  color: var(--text);
  border-color: var(--accent);
}

/* ─── Table Scroll Container ─── */
.dt-scroll {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

/* ─── Table ─── */
.dt-table {
  width: 100%;
  border-collapse: collapse;
  table-layout: auto;
}

/* ─── Header ─── */
.dt-th {
  padding: var(--spacing-5) var(--spacing-6);
  text-align: left;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
  user-select: none;
}
.dt-th-content {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-2);
}
.dt-th-sortable {
  cursor: pointer;
  transition: color 0.15s;
}
.dt-th-sortable:hover {
  color: var(--text);
}
.dt-th[aria-sort] {
  color: var(--accent);
}
.dt-sort-icon {
  display: inline-flex;
  color: var(--accent);
}
.dt-th-check {
  width: 36px;
  text-align: center;
}
.dt-th-expand {
  width: 32px;
}
.dt-th-actions {
  width: 1%;
  white-space: nowrap;
}
.dt-align-left {
  text-align: left;
}
.dt-align-center {
  text-align: center;
}
.dt-align-right {
  text-align: right;
}
.dt-nowrap {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 0;
}
.dt-wrap {
  white-space: normal;
  word-break: break-word;
}

/* ─── Rows ─── */
.dt-row {
  transition: background 0.1s;
}
.dt-row:not(:last-child) .dt-td {
  border-bottom: 1px solid var(--border);
}
.dt-row:hover {
  background: var(--surface);
}
.dt-row-clickable {
  cursor: pointer;
}
.dt-row-clickable:hover {
  background: var(--accent-dim);
}
.dt-row-selected {
  background: var(--accent-dim) !important;
}

/* Striped */
.dt-striped .dt-row:nth-child(even) {
  background: var(--surface);
}

/* Compact */
.dt-compact .dt-th {
  padding: var(--spacing-3) var(--spacing-5);
}
.dt-compact .dt-td {
  padding: var(--spacing-3) var(--spacing-5);
}

/* ─── Cells ─── */
.dt-td {
  padding: var(--spacing-5) var(--spacing-6);
  color: var(--text);
  vertical-align: middle;
}
.dt-td-check {
  width: 36px;
  text-align: center;
}
.dt-td-expand {
  width: 32px;
  text-align: center;
}
.dt-td-actions {
  white-space: nowrap;
  text-align: right;
}

/* Checkboxes */
.dt-select-all,
.dt-row-check {
  width: 14px;
  height: 14px;
  accent-color: var(--accent);
  cursor: pointer;
}

/* ─── Expand Button ─── */
.dt-expand-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border: none;
  background: transparent;
  color: var(--text-dim);
  border-radius: var(--radius-xs);
  cursor: pointer;
  transition:
    transform 0.15s,
    color 0.15s;
}
.dt-expand-btn:hover {
  color: var(--text);
  background: var(--surface-2);
}
.dt-expand-btn.dt-expanded {
  transform: rotate(90deg);
  color: var(--accent);
}


/* ─── Expand Row ─── */
.dt-expand-row .dt-expand-content {
  padding: 0;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
.dt-expand-inner {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: var(--spacing-4) var(--spacing-7);
  padding: var(--spacing-6) var(--spacing-7);
}
.dt-expand-field {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-1);
}
.dt-expand-label {
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.3px;
}
.dt-expand-value {
  font-size: var(--fs-md);
  color: var(--text);
}

/* ─── Row Detail (info icon + expandable detail panel) ─── */
.dt-info-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border: none;
  background: transparent;
  color: var(--text-dim);
  border-radius: var(--radius-xs);
  cursor: pointer;
  transition:
    background 0.15s,
    color 0.15s;
}
.dt-info-btn:hover {
  color: var(--accent);
  background: var(--surface-2);
}
.dt-info-btn.dt-info-active {
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}
.dt-detail-row .dt-detail-cell {
  padding: 0;
  border-bottom: 1px solid var(--border);
}
.dt-detail-inner {
  padding: var(--spacing-6) var(--spacing-7) var(--spacing-6) 52px;
  background: var(--surface);
  border-top: 1px solid color-mix(in srgb, var(--accent) 20%, transparent);
  animation: dt-detail-slide 0.15s ease-out;
}
.dt-detail-inner .dt-detail-label {
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.3px;
  margin-bottom: var(--spacing-1);
}
.dt-detail-inner .dt-detail-value {
  font-size: var(--fs-md);
  color: var(--text);
  margin-bottom: var(--spacing-4);
}
.dt-detail-inner .dt-detail-value:last-child {
  margin-bottom: 0;
}
@keyframes dt-detail-slide {
  from { opacity: 0; transform: translateY(-4px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ─── Row Action Buttons ─── */
.dt-action-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border: none;
  background: transparent;
  color: var(--text-dim);
  border-radius: var(--radius-xs);
  cursor: pointer;
  transition:
    background 0.1s,
    color 0.1s;
}
.dt-action-btn:hover {
  background: var(--surface-2);
  color: var(--text);
}
.dt-action-danger:hover {
  background: var(--danger-bg);
  color: var(--danger);
}
.dt-action-primary:hover {
  background: var(--accent-dim);
  color: var(--accent);
}

/* ─── Cell Formats ─── */
.dt-cell-empty {
  color: var(--text-dim);
}
.dt-bold {
  font-weight: var(--fw-semibold);
}
.dt-truncate {
  display: inline-block;
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: middle;
}
.dt-code {
  font-family: var(--mono);
  font-size: var(--fs-sm);
  background: var(--surface-2);
  padding: var(--spacing-1) var(--spacing-3);
  border-radius: var(--radius-xs);
  color: var(--accent);
}
.dt-code-bold {
  font-weight: var(--fw-bold);
  color: var(--text);
}
.dt-code-plain {
  color: var(--text-muted);
  font-weight: var(--fw-normal);
}

/* Badge */
.dt-badge {
  display: inline-block;
  padding: var(--spacing-1) var(--spacing-4);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  border-radius: var(--radius-md);
  background: var(--surface-2);
  color: var(--text-muted);
  line-height: var(--lh-normal);
}
.dt-badge-success {
  background: var(--success-bg);
  color: var(--success);
}
.dt-badge-warning {
  background: var(--warning-bg);
  color: var(--warning);
}
.dt-badge-danger {
  background: var(--danger-bg);
  color: var(--danger);
}
.dt-badge-info {
  background: var(--info-bg);
  color: var(--info);
}
.dt-badge-muted {
  background: var(--surface-2);
  color: var(--text-muted);
}
.dt-bool-pass { color: var(--success); display: inline-flex; }
.dt-bool-fail { color: var(--danger); display: inline-flex; }

/* ─── Status Dot ─── */
.dt-status {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-3);
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
}
.dt-status-dot {
  width: 8px;
  height: 8px;
  border-radius: var(--radius-circle);
  flex-shrink: 0;
}
.dt-status-success { color: var(--success); }
.dt-status-success .dt-status-dot { background: var(--success); box-shadow: 0 0 4px var(--success); }
.dt-status-warning { color: var(--warning); }
.dt-status-warning .dt-status-dot { background: var(--warning); box-shadow: 0 0 4px var(--warning); }
.dt-status-danger { color: var(--danger); }
.dt-status-danger .dt-status-dot { background: var(--danger); box-shadow: 0 0 4px var(--danger); }
.dt-status-info { color: var(--info); }
.dt-status-info .dt-status-dot { background: var(--info); box-shadow: 0 0 4px var(--info); }
.dt-status-muted { color: var(--text-muted); }
.dt-status-muted .dt-status-dot { background: var(--text-muted); }

/* ─── Pagination ─── */
.dt-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--spacing-5) 0;
  gap: var(--spacing-6);
}
.dt-page-info {
  font-size: var(--fs-base);
  color: var(--text-muted);
}
.dt-page-btns {
  display: flex;
  align-items: center;
  gap: var(--spacing-1);
}
.dt-page-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 28px;
  height: 28px;
  padding: 0 var(--spacing-3);
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
  font-family: inherit;
  border: 1px solid transparent;
  border-radius: var(--radius-xs);
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  transition:
    background 0.1s,
    color 0.1s,
    border-color 0.1s;
}
.dt-page-btn:hover:not(:disabled) {
  background: var(--surface-2);
  color: var(--text);
}
.dt-page-btn:disabled {
  opacity: 0.3;
  cursor: not-allowed;
}
.dt-page-active {
  background: var(--accent-dim);
  color: var(--accent);
  border-color: var(--accent);
}
.dt-page-dots {
  padding: 0 var(--spacing-2);
  color: var(--text-dim);
  font-size: var(--fs-base);
}

/* ─── Selection Bar ─── */
.dt-selection-bar {
  display: flex;
  align-items: center;
  gap: var(--spacing-6);
  padding: var(--spacing-4) var(--spacing-6);
  background: var(--accent-dim);
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
  margin-top: var(--spacing-4);
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
  color: var(--accent);
}
.dt-btn-deselect {
  margin-left: auto;
}

/* ─── Empty State ─── */
.dt-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--spacing-10) var(--spacing-8);
  gap: var(--spacing-4);
  border: 1px dashed var(--border);
  border-radius: var(--radius);
}
.dt-empty-icon {
  color: var(--text-dim);
  margin-bottom: var(--spacing-2);
}
.dt-empty-title {
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
}
.dt-empty-desc {
  font-size: var(--fs-base);
  color: var(--text-dim);
  max-width: 300px;
  text-align: center;
}

/* ─── Loading State ─── */
.dt-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--spacing-5);
  padding: var(--spacing-10) var(--spacing-8);
  color: var(--text-muted);
  font-size: var(--fs-md);
}
.dt-spinner {
  width: 18px;
  height: 18px;
  border: 2px solid var(--border);
  border-top-color: var(--accent);
  border-radius: var(--radius-circle);
  animation: dt-spin 0.6s linear infinite;
}
@keyframes dt-spin {
  to {
    transform: rotate(360deg);
  }
}

/* ══════════════════════════════════════════════════════════════════
   TABS — <ui-tabs>, <ui-tab-panels>, <ui-tab-panel>
   ══════════════════════════════════════════════════════════════════ */

ui-tabs {
  display: block;
  flex-shrink: 0;
}
ui-tab-panels {
  display: block;
}
ui-tab-panels[height='fill'] {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
ui-tab-panels[height='fill'] > ui-tab-panel {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
ui-tab-panel {
  display: block;
}
ui-tab-panel[hidden] {
  display: none !important;
}

/* ─── Tab Bar ─── */
.tabs-bar {
  display: flex;
  align-items: center;
  gap: var(--spacing-1);
  border-bottom: 1px solid var(--border);
  padding: 0 var(--spacing-2);
}

.tabs-tab {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-3);
  padding: var(--spacing-5) var(--spacing-6);
  border: none;
  background: none;
  color: var(--text-muted);
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  font-family: inherit;
  cursor: pointer;
  position: relative;
  border-radius: var(--radius) var(--radius) 0 0;
  transition:
    color 0.15s,
    background 0.15s;
  white-space: nowrap;
  user-select: none;
}

.tabs-tab:hover:not([disabled]) {
  color: var(--text);
  background: var(--surface-2);
}

.tabs-tab[aria-selected='true'] {
  color: var(--accent);
  font-weight: var(--fw-semibold);
}

.tabs-tab[aria-selected='true']::after {
  content: '';
  position: absolute;
  bottom: -1px;
  left: 8px;
  right: 8px;
  height: 2px;
  background: var(--accent);
  border-radius: 2px 2px 0 0;
}

.tabs-tab[disabled] {
  opacity: 0.4;
  cursor: not-allowed;
}

.tabs-tab:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

/* ─── Tab Icon ─── */
.tabs-icon {
  display: inline-flex;
  align-items: center;
  line-height: var(--lh-flush);
}
.tabs-icon svg {
  width: 14px;
  height: 14px;
}

/* ─── Tab Badge ─── */
.tabs-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 var(--spacing-3);
  border-radius: var(--radius-full);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  background: var(--surface-3);
  color: var(--text-muted);
}
.tabs-badge-info {
  background: var(--info-bg);
  color: var(--info);
}
.tabs-badge-success {
  background: var(--success-bg);
  color: var(--success);
}
.tabs-badge-warning {
  background: var(--warning-bg);
  color: var(--warning);
}
.tabs-badge-danger {
  background: var(--danger-bg);
  color: var(--danger);
}

/* ─── Variant: pills ─── */
.tabs-pills {
  border-bottom: none;
  gap: var(--spacing-2);
  padding: var(--spacing-2);
  background: var(--surface);
  border-radius: var(--radius);
  border: 1px solid var(--border);
}
.tabs-pills .tabs-tab {
  border-radius: var(--radius-sm);
  padding: var(--spacing-3) var(--spacing-6);
}
.tabs-pills .tabs-tab[aria-selected='true'] {
  background: var(--accent-dim);
  color: var(--accent);
}
.tabs-pills .tabs-tab[aria-selected='true']::after {
  display: none;
}

/* ─── Variant: underline (same as default but no bg hover) ─── */
.tabs-underline .tabs-tab:hover:not([disabled]) {
  background: none;
}

/* ─── Size: sm ─── */
.tabs-sz-sm .tabs-tab {
  padding: var(--spacing-3) var(--spacing-5);
  font-size: var(--fs-base);
  gap: var(--spacing-2);
}
.tabs-sz-sm .tabs-icon svg {
  width: 12px;
  height: 12px;
}
.tabs-sz-sm .tabs-badge {
  min-width: 16px;
  height: 16px;
  font-size: var(--fs-2xs);
}

/* ══════════════════════════════════════════════════════════════════
   ROUTER — <ui-router>, <ui-route>
   ══════════════════════════════════════════════════════════════════ */

ui-router {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  overflow: hidden;
  position: relative;
}

ui-route {
  display: none;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}

ui-route.rtr-active {
  display: flex;
}

ui-route[loading] {
  opacity: 0.6;
  pointer-events: none;
}

/* ─── Slide Transitions ─── */
@keyframes rtr-slide-in-right {
  from { transform: translateX(30px); opacity: 0; }
  to   { transform: translateX(0); opacity: 1; }
}
@keyframes rtr-slide-in-left {
  from { transform: translateX(-30px); opacity: 0; }
  to   { transform: translateX(0); opacity: 1; }
}
@keyframes rtr-slide-out-left {
  from { transform: translateX(0); opacity: 1; }
  to   { transform: translateX(-30px); opacity: 0; }
}
@keyframes rtr-slide-out-right {
  from { transform: translateX(0); opacity: 1; }
  to   { transform: translateX(30px); opacity: 0; }
}

ui-route.rtr-slide-in-right {
  animation: rtr-slide-in-right 200ms ease-out forwards;
}
ui-route.rtr-slide-in-left {
  animation: rtr-slide-in-left 200ms ease-out forwards;
}
ui-route.rtr-slide-out-left {
  animation: rtr-slide-out-left 150ms ease-in forwards;
}
ui-route.rtr-slide-out-right {
  animation: rtr-slide-out-right 150ms ease-in forwards;
}

/* ─── Fade Transitions ─── */
@keyframes rtr-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes rtr-fade-out {
  from { opacity: 1; }
  to   { opacity: 0; }
}

ui-route.rtr-fade-in {
  animation: rtr-fade-in 200ms ease-out forwards;
}
ui-route.rtr-fade-out {
  animation: rtr-fade-out 150ms ease-in forwards;
}

/* ══════════════════════════════════════════════════════════════════
   TOAST — <ui-toast> notification system
   ══════════════════════════════════════════════════════════════════ */

ui-toast {
  display: block;
  position: fixed;
  top: 16px;
  right: 16px;
  z-index: var(--z-toast);
  pointer-events: none;
}

.tst-container {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-4);
  align-items: flex-end;
}

.tst-item {
  display: flex;
  align-items: center;
  gap: var(--spacing-5);
  padding: var(--spacing-6) var(--spacing-7);
  min-width: 280px;
  max-width: 420px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--elev-dropdown);
  pointer-events: auto;
  opacity: 0;
  transform: translateX(100%);
  transition: none;
}

.tst-item.tst-show {
  animation: tst-slide-in 0.25s ease-out forwards;
}

.tst-item.tst-hide {
  animation: tst-fade-out 0.2s ease-in forwards;
}

@keyframes tst-slide-in {
  from {
    opacity: 0;
    transform: translateX(100%);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

@keyframes tst-fade-out {
  from {
    opacity: 1;
    transform: translateX(0);
  }
  to {
    opacity: 0;
    transform: translateX(40px);
  }
}

.tst-success {
  border-left: 3px solid var(--success);
}
.tst-error {
  border-left: 3px solid var(--danger);
}
.tst-warning {
  border-left: 3px solid var(--warning);
}
.tst-info {
  border-left: 3px solid var(--info);
}
.tst-default {
  border-left: 3px solid var(--text-muted);
}

.tst-icon {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  line-height: var(--lh-flush);
}
.tst-success .tst-icon {
  color: var(--success);
}
.tst-error .tst-icon {
  color: var(--danger);
}
.tst-warning .tst-icon {
  color: var(--warning);
}
.tst-info .tst-icon {
  color: var(--info);
}
.tst-default .tst-icon {
  color: var(--text-muted);
}

.tst-message {
  flex: 1;
  font-size: var(--fs-md);
  line-height: var(--lh-normal);
  color: var(--text);
}

.tst-action {
  flex-shrink: 0;
  padding: var(--spacing-2) var(--spacing-5);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  color: var(--accent);
  background: none;
  border: 1px solid var(--accent);
  border-radius: var(--radius-xs);
  cursor: pointer;
  transition: background 0.15s;
}
.tst-action:hover {
  background: var(--accent-dim);
}

.tst-close {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border: none;
  background: none;
  color: var(--text-dim);
  border-radius: var(--radius-xs);
  cursor: pointer;
  transition:
    color 0.15s,
    background 0.15s;
}
.tst-close:hover {
  color: var(--text);
  background: var(--surface-2);
}

/* ══════════════════════════════════════════════════════════════════
   TOOLTIP — global tooltip singleton
   ══════════════════════════════════════════════════════════════════ */

ui-tooltip {
  display: inline-block;
}

.tt-tooltip {
  position: fixed;
  z-index: var(--z-tooltip);
  padding: var(--spacing-3) var(--spacing-5);
  font-size: var(--fs-base);
  line-height: var(--lh-normal);
  color: var(--text);
  background: var(--surface-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow: var(--elev-tooltip);
  pointer-events: none;
  opacity: 0;
  transform: scale(0.95);
  transition:
    opacity 0.15s ease,
    transform 0.15s ease;
  white-space: normal;
  word-wrap: break-word;
  max-width: 240px;
}

.tt-tooltip.tt-visible {
  opacity: 1;
  transform: scale(1);
}

.tt-tooltip.tt-top {
  transform-origin: bottom center;
}
.tt-tooltip.tt-bottom {
  transform-origin: top center;
}
.tt-tooltip.tt-left {
  transform-origin: center right;
}
.tt-tooltip.tt-right {
  transform-origin: center left;
}

.tt-tooltip.tt-visible.tt-top,
.tt-tooltip.tt-visible.tt-bottom,
.tt-tooltip.tt-visible.tt-left,
.tt-tooltip.tt-visible.tt-right {
  transform: scale(1);
}

/* ═══════════════════════════════════════════════════════════════════
   REPEAT (ui-repeat)
   ═══════════════════════════════════════════════════════════════════ */

.repeat-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--spacing-10) var(--spacing-8);
  gap: var(--spacing-4);
  border: 1px dashed var(--border);
  border-radius: var(--radius);
}
.repeat-empty-compact {
  padding: var(--spacing-8) var(--spacing-7);
}
.repeat-empty-icon {
  color: var(--text-dim);
  margin-bottom: var(--spacing-2);
}
.repeat-empty-title {
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
}
.repeat-empty-desc {
  font-size: var(--fs-base);
  color: var(--text-dim);
  max-width: 300px;
  text-align: center;
}

/* ══════════════════════════════════════════════════════════════════
   PIPELINE LEDGER — <ui-pipeline-ledger>
   ══════════════════════════════════════════════════════════════════ */

ui-pipeline-ledger { display: block; }
ui-pipeline-ledger:empty { display: none; }

.pl-root {
  position: relative;
  border-radius: var(--radius-lg);
  background: var(--surface);
  border: 1px solid var(--border);
  transition: border-color 0.4s, box-shadow 0.4s;
}
.pl-inner {
  position: relative;
  z-index: var(--z-raised);
  padding: var(--spacing-7) var(--spacing-7);
}

/* Active state: rotating gradient border */
.pl-root.pl-active {
  border-color: transparent;
  background: transparent;
}
.pl-border-wrap { display: none; }
.pl-root.pl-active .pl-border-wrap {
  display: block;
  position: absolute;
  inset: -2px;
  /* Concentric with .pl-root, which is var(--radius-lg): an outset ring needs the
     parent radius PLUS its own inset or the corners visibly mismatch. Was a bare
     14px, which happened to equal 12+2 today and would silently break the moment
     --radius-lg changed. */
  border-radius: calc(var(--radius-lg) + 2px);
  overflow: hidden;
}
.pl-border-wrap .pl-spinner {
  position: absolute;
  inset: -40px;
  background: conic-gradient(
    var(--accent),
    color-mix(in srgb, var(--accent) 60%, transparent),
    color-mix(in srgb, var(--accent) 30%, transparent),
    color-mix(in srgb, var(--accent) 10%, transparent),
    color-mix(in srgb, var(--accent) 30%, transparent),
    color-mix(in srgb, var(--accent) 60%, transparent),
    var(--accent)
  );
  animation: pl-spin 6s linear infinite;
}
.pl-border-wrap .pl-bg {
  position: absolute;
  inset: 2px;
  border-radius: var(--radius-lg);
  background: var(--surface);
  z-index: var(--z-raised);
}
.pl-glow-layer { display: none; }
.pl-root.pl-active .pl-glow-layer {
  display: block;
  position: absolute;
  inset: -4px;
  border-radius: calc(var(--radius-lg) + 4px);  /* concentric, see .pl-border-wrap */
  opacity: 0.5;
  box-shadow: 0 0 15px 2px color-mix(in srgb, var(--accent) 30%, transparent);
  pointer-events: none;
}

/* Finished state */
.pl-root.pl-finished .pl-border-wrap,
.pl-root.pl-finished .pl-glow-layer { display: none; }
.pl-root.pl-finished {
  border-color: var(--border);
  background: var(--surface);
}

/* Heading */
.pl-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  color: var(--text);
  margin-bottom: var(--spacing-6);
}
.pl-total-duration {
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--text-dim);
  background: var(--surface-2);
  padding: var(--spacing-1) var(--spacing-4);
  border-radius: var(--radius-full);
}

/* Steps list */
.pl-steps {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-3);
}
.pl-step { border-radius: var(--radius); transition: background 0.15s; }
.pl-step.pl-expandable .pl-step-row { cursor: pointer; }
.pl-step.pl-expandable .pl-step-row:hover { background: var(--surface-2); }

.pl-step-row {
  display: flex;
  align-items: center;
  gap: var(--spacing-6);
  padding: var(--spacing-4) var(--spacing-5);
  border-radius: var(--radius);
}

.pl-step-dot {
  flex-shrink: 0;
  width: 10px;
  height: 10px;
  border-radius: var(--radius-circle);
  background: var(--border);
  transition: background 0.3s, box-shadow 0.3s;
}

.pl-step-content {
  flex: 1;
  display: flex;
  align-items: baseline;
  gap: var(--spacing-5);
  min-width: 0;
}
.pl-step-name {
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  color: var(--text-dim);
  white-space: nowrap;
  transition: color 0.3s;
}
.pl-step-detail {
  font-size: var(--fs-base);
  color: var(--text-dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
}
.pl-step-duration {
  flex-shrink: 0;
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--text-dim);
  background: var(--surface-2);
  padding: var(--spacing-1) var(--spacing-3);
  border-radius: var(--radius-full);
}
.pl-step-chevron {
  flex-shrink: 0;
  font-size: var(--fs-xl);
  font-weight: var(--fw-semibold);
  color: var(--text-dim);
  transition: transform 0.2s ease;
  width: 16px;
  text-align: center;
}
.pl-step-chevron.pl-expanded { transform: rotate(90deg); }

/* Status variants */
.pl-running .pl-step-dot {
  background: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 20%, transparent);
  animation: pl-pulse 1.5s ease-in-out infinite;
}
.pl-running .pl-step-name { color: var(--text); font-weight: var(--fw-semibold); }
.pl-running .pl-step-detail { color: var(--text-muted); }

.pl-done .pl-step-dot { background: var(--success); box-shadow: 0 0 0 2px color-mix(in srgb, var(--success) 12%, transparent); }
.pl-done .pl-step-name { color: var(--text); }
.pl-done .pl-step-detail { color: var(--text-muted); }

.pl-warn .pl-step-dot { background: var(--warning); box-shadow: 0 0 0 2px color-mix(in srgb, var(--warning) 12%, transparent); }
.pl-warn .pl-step-name { color: var(--text); }
.pl-warn .pl-step-detail { color: var(--warning); }

.pl-fail .pl-step-dot { background: var(--danger); box-shadow: 0 0 0 2px color-mix(in srgb, var(--danger) 12%, transparent); }
.pl-fail .pl-step-name { color: var(--text); }
.pl-fail .pl-step-detail { color: var(--danger); }

/* Evidence panel */
.pl-step-evidence {
  margin: 0 var(--spacing-5) var(--spacing-5) var(--spacing-9);
  padding: var(--spacing-6) var(--spacing-6);
  background: var(--surface-2);
  border-radius: var(--radius);
  border: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: var(--spacing-6);
}
.pl-ev-section { display: flex; flex-direction: column; gap: 4px; }
.pl-ev-section + .pl-ev-section { padding-top: 10px; border-top: 1px solid var(--border); }
.pl-ev-label {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-dim);
  margin-bottom: var(--spacing-1);
}
.pl-ev-pairs { display: flex; flex-direction: column; gap: 3px; }
.pl-ev-pair { display: flex; align-items: baseline; gap: 10px; font-size: var(--fs-base); }
.pl-ev-key { color: var(--text-muted); min-width: 90px; flex-shrink: 0; }
.pl-ev-val { color: var(--text); font-weight: var(--fw-medium); }
.pl-ev-val-success { color: var(--success); }
.pl-ev-val-warning { color: var(--warning); }
.pl-ev-val-danger { color: var(--danger); }
.pl-ev-val-info { color: var(--accent); }

.pl-ev-list { display: flex; flex-direction: column; gap: 4px; }
.pl-ev-process-item { display: flex; align-items: center; gap: 8px; font-size: var(--fs-base); color: var(--text); }
.pl-ev-process-icon { flex-shrink: 0; display: flex; align-items: center; color: var(--text-muted); }
.pl-ev-process-label { font-weight: var(--fw-medium); }
.pl-ev-process-detail { color: var(--text-muted); }

.pl-ev-reasoning {
  font-size: var(--fs-base);
  color: var(--text);
  line-height: var(--lh-relaxed);
  white-space: pre-wrap;
  word-wrap: break-word;
  background: var(--surface-2);
  padding: var(--spacing-5) var(--spacing-6);
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  max-height: 200px;
  overflow-y: auto;
}

.pl-ev-items-header {
  display: flex;
  align-items: center;
  gap: var(--spacing-3);
  cursor: pointer;
  padding: var(--spacing-2) 0;
  font-size: var(--fs-base);
  user-select: none;
}
.pl-ev-items-header:hover .pl-ev-items-label { color: var(--text); }
.pl-ev-items-chevron {
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  color: var(--text-dim);
  transition: transform 0.15s ease;
  width: 12px;
}
.pl-ev-items-chevron.pl-open { transform: rotate(90deg); }
.pl-ev-items-label { font-weight: var(--fw-medium); color: var(--text-muted); transition: color 0.15s; }
.pl-ev-items-count {
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  color: var(--text-dim);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  padding: 0 var(--spacing-3);
  min-width: 16px;
  text-align: center;
  line-height: var(--lh-relaxed);
}
.pl-ev-items-list { display: flex; flex-direction: column; gap: 2px; padding: 4px 0 4px 18px; }
.pl-ev-items-row {
  font-size: var(--fs-base);
  color: var(--text);
  padding: var(--spacing-2) var(--spacing-4);
  background: var(--surface-2);
  border-radius: var(--radius-xs);
  border: 1px solid var(--border);
}

/* Error / Summary banners */
.pl-error-banner {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
  margin-top: var(--spacing-6);
  padding: var(--spacing-5) var(--spacing-6);
  background: color-mix(in srgb, var(--danger) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--danger) 25%, transparent);
  border-radius: var(--radius);
  font-size: var(--fs-md);
  color: var(--danger);
}
.pl-error-icon { display: flex; align-items: center; }
.pl-error-text { flex: 1; }

.pl-summary-banner {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
  margin-top: var(--spacing-6);
  padding: var(--spacing-5) var(--spacing-6);
  background: var(--success-bg);
  border: 1px solid color-mix(in srgb, var(--success) 25%, transparent);
  border-radius: var(--radius);
  font-size: var(--fs-md);
  color: var(--success);
}
.pl-summary-icon { display: flex; align-items: center; }

@keyframes pl-pulse {
  0%, 100% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 20%, transparent); }
  50% { box-shadow: 0 0 0 5px color-mix(in srgb, var(--accent) 10%, transparent); }
}
@keyframes pl-spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

/* Compact variant */
ui-pipeline-ledger[compact] .pl-inner { padding: 12px 14px; }
ui-pipeline-ledger[compact] .pl-heading { font-size: var(--fs-md); margin-bottom: 10px; }
ui-pipeline-ledger[compact] .pl-steps { gap: 4px; }
ui-pipeline-ledger[compact] .pl-step-name { font-size: var(--fs-base); }
ui-pipeline-ledger[compact] .pl-step-detail { font-size: var(--fs-sm); }

/* ══════════════════════════════════════════════════════════════════
   INLINE LIST — <ui-inline-list> detail panel CRUD list
   ══════════════════════════════════════════════════════════════════ */

ui-inline-list {
  display: block;
}

ui-inline-list .il-header {
  display: flex;
  align-items: center;
  padding: var(--spacing-3) 0;
  border-bottom: 1px solid var(--border);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

ui-inline-list .il-hcell {
  flex: 1;
  padding: 0 var(--spacing-4);
  min-width: 0;
}

ui-inline-list .il-actions-col {
  flex: 0 0 auto !important;
  margin-left: auto;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--spacing-1);
  padding: 0 var(--spacing-2) 0 var(--spacing-4);
  border-left: 1px solid var(--border);
}

ui-inline-list .il-body {
  display: flex;
  flex-direction: column;
}

ui-inline-list .il-row {
  display: flex;
  align-items: center;
  padding: var(--spacing-4) 0;
  border-bottom: 1px solid var(--border);
  font-size: var(--fs-md);
  color: var(--text);
  transition: background 0.1s;
}

ui-inline-list .il-row:hover {
  background: var(--surface-2);
}

ui-inline-list .il-cell {
  flex: 1;
  padding: 0 var(--spacing-4);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

ui-inline-list .il-primary {
  font-weight: var(--fw-semibold);
}

ui-inline-list .il-edit {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  background: none;
  border: none;
  border-radius: var(--radius-xs);
  color: var(--text-muted);
  cursor: pointer;
  opacity: 0.5;
  transition: opacity 0.15s, color 0.15s;
}

ui-inline-list .il-edit:hover {
  opacity: 1;
  color: var(--accent);
}

ui-inline-list .il-remove {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  background: none;
  border: none;
  border-radius: var(--radius-xs);
  color: var(--text-muted);
  cursor: pointer;
  opacity: 0.5;
  transition: opacity 0.15s, color 0.15s;
}

ui-inline-list .il-remove:hover {
  opacity: 1;
  color: var(--danger);
}

ui-inline-list .il-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--spacing-4);
  padding: var(--spacing-9) var(--spacing-7);
  color: var(--text-muted);
  font-size: var(--fs-md);
  text-align: center;
}

ui-inline-list .il-empty svg {
  opacity: 0.4;
}

/* ══════════════════════════════════════════════════════════════════
   CHARTS — <ui-chart-*> declarative chart elements
   ══════════════════════════════════════════════════════════════════ */

/* Chart host elements */
ui-chart-bar,
ui-chart-line,
ui-chart-donut,
ui-chart-gauge,
ui-chart-sparkline,
ui-chart-funnel,
ui-chart-stacked-bar,
ui-chart-heatmap,
ui-chart-scatter,
ui-chart-treemap,
ui-chart-waterfall,
ui-chart-bullet,
ui-chart-progress-ring,
ui-chart-radar,
ui-chart-sankey {
  display: block;
}

ui-chart-sparkline {
  display: inline-block;
  vertical-align: middle;
}

/* Chart title */
.cht-title {
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  color: var(--text);
  margin-bottom: var(--spacing-4);
}

/* Empty state */
.cht-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 80px;
  color: var(--text-muted);
  font-size: var(--fs-base);
}

/* Grid lines */
.cht-grid-line {
  stroke: var(--border);
  stroke-width: 0.5;
}

/* Axis labels */
.cht-axis-label {
  font-size: var(--fs-xs);
  fill: var(--text-muted);
  font-family: inherit;
}

.cht-axis-title {
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  fill: var(--text-dim);
  font-family: inherit;
}

/* Tooltip (positioned absolutely on body) */
.cht-tooltip {
  display: none;
  position: fixed;
  z-index: var(--z-tooltip);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: var(--spacing-3) var(--spacing-5);
  font-size: var(--fs-base);
  color: var(--text);
  line-height: var(--lh-normal);
  pointer-events: none;
  box-shadow: var(--elev-tooltip);
  max-width: 200px;
}

.cht-tooltip strong {
  color: var(--text);
  font-weight: var(--fw-semibold);
}

/* Legend */
.cht-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--spacing-4) var(--spacing-6);
  padding-top: var(--spacing-4);
}

.cht-legend--right {
  flex-direction: column;
  position: absolute;
  right: 0;
  top: 30px;
}

.cht-legend--none { display: none; }

.cht-legend-item {
  display: flex;
  align-items: center;
  gap: var(--spacing-3);
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

.cht-legend-swatch {
  width: 10px;
  height: 10px;
  border-radius: 2px;
  flex-shrink: 0;
}

.cht-legend-swatch--line {
  width: 14px;
  height: 3px;
  border-radius: 1px;
}

.cht-legend-swatch--dot {
  width: 8px;
  height: 8px;
  border-radius: var(--radius-circle);
}

.cht-legend-label {
  white-space: nowrap;
}

.cht-legend-pct {
  color: var(--text-dim);
  font-size: var(--fs-xs);
}

/* Bar chart */
.cht-bar-rect {
  transition: opacity 0.15s;
}

.cht-bar-rect:hover {
  opacity: 0.8;
}

.cht-bar-value {
  font-size: var(--fs-xs);
  fill: var(--text);
  font-family: inherit;
}

/* Line chart */
.cht-line-path {
  transition: stroke-width 0.15s;
}

.cht-line-dot {
  transition: r 0.15s;
}

.cht-line-dot:hover {
  r: 5;
}

.cht-tooltip-hitbox {
  cursor: default;
}

/* Donut chart */
.cht-donut-area {
  display: flex;
  justify-content: center;
}

.cht-donut-segment {
  transition: opacity 0.15s;
  cursor: pointer;
}

.cht-donut-segment:hover {
  opacity: 0.8;
}

.cht-donut-center-value {
  font-size: var(--fs-3xl);
  font-weight: var(--fw-bold);
  fill: var(--text);
  font-family: inherit;
}

.cht-donut-center-label {
  font-size: var(--fs-sm);
  fill: var(--text-muted);
  font-family: inherit;
}

/* Gauge chart */
.cht-gauge-area {
  display: flex;
  justify-content: center;
}

.cht-gauge-value-text {
  font-size: 22px;
  font-weight: var(--fw-bold);
  font-family: inherit;
}

.cht-gauge-label {
  font-size: var(--fs-sm);
  fill: var(--text-muted);
  font-family: inherit;
}

.cht-gauge-range-label {
  font-size: var(--fs-2xs);
  fill: var(--text-dim);
  font-family: inherit;
}

.cht-gauge-needle {
  transition: transform 0.3s ease;
}

/* Funnel chart */
.cht-funnel-area {
  display: flex;
  justify-content: center;
}

.cht-funnel-stage {
  transition: opacity 0.15s;
  cursor: pointer;
}

.cht-funnel-stage:hover {
  opacity: 0.85;
}

.cht-funnel-label {
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  fill: var(--text);
  font-family: inherit;
  pointer-events: none;
}

.cht-funnel-value {
  font-size: var(--fs-sm);
  fill: rgba(255, 255, 255, 0.7);
  font-family: inherit;
  pointer-events: none;
}

.cht-funnel-conversion {
  font-size: var(--fs-xs);
  fill: var(--text-dim);
  font-family: inherit;
}

/* Heatmap */
.cht-heatmap-area {
  display: flex;
  justify-content: center;
  overflow-x: auto;
}

.cht-heatmap-cell {
  transition: opacity 0.15s;
  cursor: pointer;
}

.cht-heatmap-cell:hover {
  opacity: 0.8;
  stroke: var(--text);
  stroke-width: 1;
}

.cht-heatmap-cell-value {
  font-size: var(--fs-2xs);
  fill: var(--text);
  font-family: inherit;
  pointer-events: none;
}

/* Scatter chart */
.cht-scatter-point {
  transition: r 0.15s, opacity 0.15s;
  cursor: pointer;
}

.cht-scatter-point:hover {
  opacity: 1 !important;
}

/* Treemap */
.cht-treemap-area {
  display: flex;
  justify-content: center;
}

.cht-treemap-rect {
  transition: opacity 0.15s;
  cursor: pointer;
}

.cht-treemap-rect:hover {
  opacity: 0.8;
  stroke: var(--text);
  stroke-width: 1;
}

.cht-treemap-label {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  fill: var(--text);
  font-family: inherit;
  pointer-events: none;
}

.cht-treemap-value {
  font-size: var(--fs-xs);
  fill: rgba(255, 255, 255, 0.65);
  font-family: inherit;
  pointer-events: none;
}

/* Threshold lines */
.cht-threshold-line {
  pointer-events: none;
}

.cht-threshold-label {
  font-size: var(--fs-xs);
  font-family: inherit;
  pointer-events: none;
}

/* Waterfall chart */
.cht-waterfall-area {
  display: flex;
  justify-content: center;
}

/* Bullet chart */
.cht-bullet-area {
  display: flex;
  justify-content: center;
}

.cht-bullet-bar {
  transition: width 0.3s ease;
}

.cht-bullet-target {
  pointer-events: none;
}

/* Progress ring */
.cht-progress-ring-area {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.cht-progress-arc {
  transition: stroke-dasharray 0.6s ease;
}

/* Radar chart */
.cht-radar-area {
  display: flex;
  justify-content: center;
}

.cht-radar-fill {
  pointer-events: none;
}

.cht-radar-dot {
  transition: r 0.15s;
}

.cht-radar-dot:hover {
  r: 5;
}

/* Sankey chart */
.cht-sankey-area {
  display: flex;
  justify-content: center;
  overflow-x: auto;
}

.cht-sankey-link {
  transition: opacity 0.2s;
}

.cht-sankey-link:hover {
  opacity: 0.5 !important;
}

.cht-sankey-node {
  cursor: pointer;
  transition: opacity 0.15s;
}

.cht-sankey-node:hover {
  opacity: 0.85;
}

/* ── Chart Animations ── */
@keyframes cht-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes cht-line-draw {
  to { stroke-dashoffset: 0; }
}


@keyframes cht-gauge-sweep {
  from { transform: rotate(-120deg); }
  to   { transform: rotate(0deg); }
}

/* ══════════════════════════════════════════════════════════════════
   HTML PREVIEW — <ui-html-preview>
   ══════════════════════════════════════════════════════════════════ */

ui-html-preview {
  display: block;
}

.hp-label {
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: var(--spacing-4);
}

.hp-toolbar {
  display: flex;
  gap: var(--spacing-4);
  padding: var(--spacing-4) var(--spacing-6);
  background: var(--surface);
  border: 1px solid var(--border);
  border-bottom: none;
  border-radius: var(--radius) var(--radius) 0 0;
}

.hp-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-3);
  padding: var(--spacing-2) var(--spacing-5);
  font-size: var(--fs-base);
  font-family: var(--font);
  color: var(--text-muted);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  cursor: pointer;
  transition: all 0.15s;
}

.hp-btn:hover {
  color: var(--text);
  background: var(--surface-2);
}

.hp-btn svg {
  width: 14px;
  height: 14px;
}

.hp-container {
  border: 1px solid var(--border);
  border-radius: 0 0 var(--radius) var(--radius);
  overflow: auto;
  background: var(--white);
}

.hp-empty {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
  padding: var(--spacing-8);
  color: var(--text-dim);
  font-size: var(--fs-md);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.hp-empty svg {
  width: 16px;
  height: 16px;
  opacity: 0.5;
}

/* ══════════════════════════════════════════════════════════════════
   JSON VIEW — <ui-json-view>
   ══════════════════════════════════════════════════════════════════ */

ui-json-view {
  display: block;
}

.jv-label {
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: var(--spacing-4);
}

.jv-toolbar {
  display: flex;
  gap: var(--spacing-4);
  padding: var(--spacing-4) var(--spacing-6);
  background: var(--surface);
  border: 1px solid var(--border);
  border-bottom: none;
  border-radius: var(--radius) var(--radius) 0 0;
}

.jv-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-3);
  padding: var(--spacing-2) var(--spacing-5);
  font-size: var(--fs-base);
  font-family: var(--font);
  color: var(--text-muted);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  cursor: pointer;
  transition: all 0.15s;
}

.jv-btn:hover {
  color: var(--text);
  background: var(--surface-2);
}

.jv-btn svg {
  width: 14px;
  height: 14px;
}

.jv-container {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 0 0 var(--radius) var(--radius);
  padding: var(--spacing-7);
  overflow: auto;
  font-family: var(--mono);
  font-size: var(--fs-md);
  line-height: var(--lh-loose);
}

.jv-empty {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
  padding: var(--spacing-8);
  color: var(--text-dim);
  font-size: var(--fs-md);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.jv-empty svg {
  width: 16px;
  height: 16px;
  opacity: 0.5;
}

.jv-toggle {
  cursor: pointer;
  user-select: none;
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-2);
}

.jv-toggle:hover {
  opacity: 0.8;
}

.jv-arrow {
  display: inline-block;
  width: 12px;
  font-size: var(--fs-xs);
  color: var(--text-dim);
  transition: transform 0.15s;
}

.jv-node:not(.jv-collapsed) > .jv-toggle > .jv-arrow {
  transform: rotate(90deg);
}

.jv-brace {
  color: var(--text-muted);
  font-weight: var(--fw-semibold);
}

.jv-count {
  font-size: var(--fs-sm);
  color: var(--text-dim);
  margin-left: var(--spacing-3);
}

.jv-node:not(.jv-collapsed) > .jv-toggle > .jv-count {
  display: none;
}

.jv-children {
  padding-left: var(--spacing-7);
  border-left: 1px solid var(--border);
  margin-left: var(--spacing-3);
}

.jv-node.jv-collapsed > .jv-children,
.jv-node.jv-collapsed > .jv-close {
  display: none;
}

.jv-entry {
  padding: var(--spacing-1) 0;
}

.jv-key {
  color: var(--accent);
}

.jv-index {
  color: var(--text-dim);
}

.jv-colon {
  color: var(--text-dim);
}

.jv-string {
  color: var(--success);
  word-break: break-all;
}

.jv-number {
  color: var(--info);
}

.jv-boolean {
  color: var(--warning);
  font-weight: var(--fw-semibold);
}

.jv-null {
  color: var(--danger);
  font-style: italic;
}

.jv-close {
  display: block;
}

/* ─── Editable panel: hide form fields in view mode when has rich viewer ─── */
ui-editable-panel[view-hidden] > ui-form-field {
  display: none;
}
ui-editable-panel[view-hidden][data-editing="true"] > ui-form-field {
  display: block;
}
ui-editable-panel[view-hidden]:not([data-editing="true"]) + ui-code-block,
ui-editable-panel[view-hidden]:not([data-editing="true"]) + ui-json-view,
ui-editable-panel[view-hidden]:not([data-editing="true"]) + ui-report-parameters {
  display: block;
}
ui-editable-panel[view-hidden][data-editing="true"] + ui-code-block,
ui-editable-panel[view-hidden][data-editing="true"] + ui-json-view,
ui-editable-panel[view-hidden][data-editing="true"] + ui-report-parameters {
  display: none;
}

/* ══════════════════════════════════════════════════════════════════
   CODE BLOCK — <ui-code-block>
   ══════════════════════════════════════════════════════════════════ */

ui-code-block {
  display: block;
}
.cb-empty {
  padding: var(--spacing-7);
  color: var(--text-dim);
  font-style: italic;
  font-size: var(--fs-md);
}
.cb-container {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: auto;
  font-family: 'JetBrains Mono', 'Fira Code', 'SF Mono', 'Cascadia Code', monospace;
  font-size: 12.5px;
  line-height: var(--lh-loose);
}
.cb-table {
  border-collapse: collapse;
  width: 100%;
}
.cb-line:hover {
  background: var(--surface-2);
}
.cb-num {
  padding: 0 var(--spacing-6) 0 var(--spacing-6);
  text-align: right;
  color: var(--text-dim);
  user-select: none;
  font-size: var(--fs-sm);
  vertical-align: top;
  white-space: nowrap;
  border-right: 1px solid var(--border);
}
.cb-code {
  padding: 0 var(--spacing-6);
  white-space: pre;
  color: var(--text);
}
.cb-table tr:first-child .cb-num,
.cb-table tr:first-child .cb-code {
  padding-top: var(--spacing-6);
}
.cb-table tr:last-child .cb-num,
.cb-table tr:last-child .cb-code {
  padding-bottom: var(--spacing-6);
}

/* SQL syntax */
.cb-keyword { color: var(--accent); font-weight: var(--fw-semibold); }
.cb-string { color: var(--success); }
.cb-number { color: var(--info); }
.cb-comment { color: var(--text-dim); font-style: italic; }
.cb-param { color: var(--warning); background: rgba(245, 158, 11, 0.1); border-radius: var(--radius-2xs); padding: 0 3px; }

/* HTML syntax */
.cb-tag { color: var(--danger); }
.cb-attr { color: var(--warning); }

/* JSON syntax */
.cb-key { color: var(--accent); }


/* ══════════════════════════════════════════════════════════════════
   HOC — <ui-address> Higher-Order Address Component
   ══════════════════════════════════════════════════════════════════ */

ui-address {
  display: block;
}

ui-address[full-width] {
  grid-column: 1 / -1;
}

/* Label above the address block */
.addr-label {
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: var(--spacing-4);
}

/* Edit mode field grid */
.addr-fields {
  display: grid;
  grid-template-columns: repeat(var(--addr-columns, 3), 1fr);
  gap: var(--spacing-6) var(--spacing-6);
}

.addr-field {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-2);
}

/* Grid placement helpers */
.addr-full { grid-column: 1 / -1; }
.addr-city { grid-column: span 1; }
.addr-state { grid-column: span 1; }
.addr-zip { grid-column: span 1; }
.addr-half { grid-column: span 1; }

/* On narrow containers (2 columns), city/state/zip get separate rows */
@container (max-width: 400px) {
  .addr-fields {
    grid-template-columns: 1fr 1fr;
  }
  .addr-city { grid-column: 1 / -1; }
  .addr-state { grid-column: span 1; }
  .addr-zip { grid-column: span 1; }
}

/* View mode */
.addr-view {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-1);
}

.addr-view-row {
  display: flex;
  align-items: baseline;
  gap: var(--spacing-4);
  font-size: var(--fs-md);
  line-height: var(--lh-relaxed);
  color: var(--text);
}

.addr-view-key {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  min-width: 60px;
}

.addr-view-val {
  color: var(--text);
}

.addr-view-empty {
  font-size: var(--fs-md);
  color: var(--text-muted);
  font-style: italic;
}

/* Compact mode */
.addr-compact {
  display: flex;
  align-items: baseline;
  gap: var(--spacing-4);
}

.addr-compact-label {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.addr-compact-value {
  font-size: var(--fs-md);
  color: var(--text);
}

/* ══════════════════════════════════════════════════════════════════
   HOC — <ui-location-map> Location Map Component
   ══════════════════════════════════════════════════════════════════ */

ui-location-map {
  display: block;
  container-type: inline-size;
}

.lm-container {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--surface);
}

.lm-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--spacing-5) var(--spacing-7);
  border-bottom: 1px solid var(--border);
  background: var(--surface-2);
}

.lm-header-left {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  color: var(--text-muted);
}

.lm-header-left svg {
  width: 16px;
  height: 16px;
  color: var(--accent);
}

.lm-header-right {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
}

.lm-geocode-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-3);
  padding: var(--spacing-3) var(--spacing-6);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  color: white;
  background: var(--accent);
  border: none;
  border-radius: var(--radius);
  cursor: pointer;
  transition: opacity 0.15s;
}

.lm-geocode-btn:hover:not(:disabled) {
  opacity: 0.85;
}

.lm-geocode-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.lm-geocode-btn svg {
  width: 14px;
  height: 14px;
}

.lm-banner {
  display: flex;
  align-items: center;
  gap: var(--spacing-5);
  padding: var(--spacing-5) var(--spacing-7);
  font-size: var(--fs-base);
  line-height: var(--lh-normal);
}

.lm-banner svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

.lm-banner-info {
  background: var(--accent-dim);
  color: var(--info, var(--accent));
  border-bottom: 1px solid var(--border);
}

.lm-body {
  display: flex;
}

.lm-sidebar {
  width: 240px;
  min-width: 240px;
  border-right: 1px solid var(--border);
  overflow-y: auto;
  max-height: 500px;
  background: var(--surface);
}

.lm-list-item {
  display: flex;
  align-items: center;
  gap: var(--spacing-5);
  padding: var(--spacing-5) var(--spacing-6);
  border-bottom: 1px solid var(--border);
  cursor: default;
  transition: background 0.1s;
}

.lm-list-item.lm-geocoded {
  cursor: pointer;
}

.lm-list-item.lm-geocoded:hover {
  background: var(--surface-2);
}

.lm-list-marker {
  width: 24px;
  height: 24px;
  border-radius: var(--radius-circle);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  color: white;
  flex-shrink: 0;
}

.lm-list-info {
  min-width: 0;
}

.lm-list-label {
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.lm-list-desc {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.lm-map-container {
  flex: 1;
  min-width: 0;
}

.lm-loading,
.lm-error,
.lm-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--spacing-6);
  font-size: var(--fs-md);
  color: var(--text-muted);
}

.lm-error {
  color: var(--danger);
}

.lm-error svg,
.lm-empty svg {
  width: 32px;
  height: 32px;
  opacity: 0.5;
}

.lm-spinner {
  width: 24px;
  height: 24px;
  border: 3px solid var(--border);
  border-top-color: var(--accent);
  border-radius: var(--radius-circle);
  animation: lm-spin 0.8s linear infinite;
}

.lm-spinner-sm {
  display: inline-block;
  width: 14px;
  height: 14px;
  border: 2px solid var(--text-dim);
  border-top-color: var(--text);
  border-radius: var(--radius-circle);
  animation: lm-spin 0.8s linear infinite;
}

@keyframes lm-spin {
  to { transform: rotate(360deg); }
}

@container (max-width: 600px) {
  .lm-body {
    flex-direction: column;
  }
  .lm-sidebar {
    width: 100%;
    min-width: 100%;
    max-height: 200px;
    border-right: none;
    border-bottom: 1px solid var(--border);
  }
}

/* ══════════════════════════════════════════════════════════════════
   UTILITIES
   ══════════════════════════════════════════════════════════════════ */

/* Config-only elements should not render */
ui-sidebar-item,
ui-list-search,
ui-list-statuses,
ui-list-columns,
ui-list-new-item,
ui-search-field,
ui-match-type,
ui-status,
ui-column,
ui-field,
ui-option,
ui-status-color,
ui-hero-action,
ui-nav-section,
ui-nav-item,
ui-actions,
ui-action,
ui-table-column,
ui-table-action,
ui-dialog-action,
ui-tab,
ui-list-field,
ui-series,
ui-threshold,
ui-kanban-column,
ui-kanban-card-field {
  display: none;
}

/* ── Kanban Board ──────────────────────────────────────────────────── */

ui-kanban-board {
  display: block;
}

.kanban-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 0 var(--spacing-6) 0;
  flex-wrap: wrap;
  gap: var(--spacing-4);
}

.kanban-item-total {
  font-size: var(--fs-base);
  color: var(--text-muted);
  font-weight: var(--fw-medium);
  white-space: nowrap;
}

.kanban-toolbar {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
  flex-wrap: wrap;
}

.kanban-select {
  background: var(--surface-2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: var(--spacing-3) var(--spacing-5);
  font-size: var(--fs-base);
  cursor: pointer;
  appearance: auto;
}

.kanban-select:focus {
  outline: 1px solid var(--info);
}

.kanban-truncation {
  padding: var(--spacing-3) var(--spacing-6);
  margin-bottom: var(--spacing-5);
  background: var(--warning-bg);
  border-radius: var(--radius-sm);
  font-size: var(--fs-base);
  color: var(--warning);
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
  flex-wrap: wrap;
}

.kanban-load-rest {
  background: var(--surface-3);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  padding: var(--spacing-2) var(--spacing-5);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  cursor: pointer;
}

.kanban-load-rest:hover {
  background: var(--surface-2);
}

.kanban-board {
  display: flex;
  gap: var(--spacing-6);
  overflow-x: auto;
  height: calc(100vh - 220px);
  min-height: 300px;
  scrollbar-width: thin;
  scrollbar-color: var(--text-dim) transparent;
}

.kanban-board::-webkit-scrollbar {
  height: 6px;
}

.kanban-board::-webkit-scrollbar-track {
  background: transparent;
}

.kanban-board::-webkit-scrollbar-thumb {
  background: var(--text-dim);
  border-radius: var(--radius-2xs);
}

.kanban-board::-webkit-scrollbar-thumb:hover {
  background: var(--text-muted);
}

.kanban-col {
  flex: 1 0 0;
  min-width: 220px;
  max-width: 420px;
  display: flex;
  flex-direction: column;
  background: var(--surface-2);
  border-radius: var(--radius);
  overflow: hidden;
}

.kanban-col-header {
  padding: var(--spacing-5) var(--spacing-6) var(--spacing-4);
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background 0.15s;
  position: sticky;
  top: 0;
  z-index: var(--z-raised);
  background: var(--surface-2);
  flex-shrink: 0;
}

.kanban-col-header:hover {
  background: var(--surface-2);
}

.kanban-col-header-top {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
}

.kanban-col-subtitle {
  margin-top: var(--spacing-2);
  font-size: var(--fs-xs);
  line-height: var(--lh-snug);
  color: var(--text-muted);
  font-weight: var(--fw-normal);
}

.kanban-col-dot {
  width: 8px;
  height: 8px;
  border-radius: var(--radius-circle);
  flex-shrink: 0;
}

.kanban-col-label {
  flex: 1;
}

.kanban-col-count {
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  color: var(--text-muted);
  background: var(--surface-3);
  padding: var(--spacing-1) var(--spacing-3);
  border-radius: var(--radius-md);
  font-variant-numeric: tabular-nums;
}

.kanban-col-body {
  flex: 1;
  padding: var(--spacing-4);
  display: flex;
  flex-direction: column;
  gap: var(--spacing-3);
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--text-dim) transparent;
}

.kanban-col-body::-webkit-scrollbar {
  width: 4px;
}

.kanban-col-body::-webkit-scrollbar-track {
  background: transparent;
}

.kanban-col-body::-webkit-scrollbar-thumb {
  background: var(--text-dim);
  border-radius: var(--radius-xs);
}

.kanban-col-body::-webkit-scrollbar-thumb:hover {
  background: var(--text-muted);
}

.kanban-col-empty {
  padding: var(--spacing-7) var(--spacing-4);
  text-align: center;
  color: var(--text-muted);
  font-size: var(--fs-base);
}

.kanban-card {
  padding: var(--spacing-4) var(--spacing-5);
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid transparent;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}

.kanban-card:hover {
  background: var(--surface-2);
  border-color: var(--border);
}

.kanban-card-chip {
  display: inline-block;
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  /* Tokenised on merge (invariant 5). Was `1px 6px`; there is no 1px spacing
     token, so the vertical padding becomes 2px — a hair taller on a small
     uppercase chip. Raising the lint baseline instead was not an option. */
  padding: var(--spacing-1) var(--spacing-3);
  border-radius: var(--radius-2xs);
  margin-bottom: var(--spacing-2);
}

.kanban-card-title {
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  line-height: var(--lh-normal);
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.kanban-card-meta {
  margin-top: var(--spacing-2);
  font-size: var(--fs-sm);
  line-height: var(--lh-tight);
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.kanban-card-footer {
  margin-top: var(--spacing-3);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--spacing-3);
  font-size: var(--fs-sm);
}

.kanban-card-footer-left {
  color: var(--text-muted);
  font-weight: var(--fw-medium);
  font-variant-numeric: tabular-nums;
}

.kanban-card-footer-right {
  color: var(--text-muted);
  font-size: var(--fs-xs);
  white-space: nowrap;
  flex-shrink: 0;
}

.kanban-badge {
  display: inline-flex;
  align-items: center;
  width: fit-content;
  padding: var(--spacing-2) var(--spacing-5);
  border-radius: var(--radius-full);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  text-transform: capitalize;
  background: var(--info-bg);
  color: var(--info);
}

.kanban-loading,
.kanban-error {
  padding: var(--spacing-10);
  text-align: center;
  color: var(--text-muted);
  font-size: var(--fs-md);
}

.kanban-error {
  color: var(--danger);
}

/* ── View Switcher (Segmented Control) ─────────────────────────────── */

ui-view-switcher {
  display: flex;
  align-items: center;
}

.vs-segmented {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-1);
  height: 32px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--spacing-1);
  box-sizing: border-box;
}

.vs-segment {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-2);
  padding: 0 var(--spacing-5);
  height: 100%;
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-muted);
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
  white-space: nowrap;
}

.vs-segment:hover {
  color: var(--text);
  background: var(--surface-3);
}

.vs-segment[aria-pressed="true"] {
  background: var(--accent);
  color: var(--text-on-accent);
}

.vs-settings-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  margin-left: var(--spacing-2);
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  transition: color 0.15s, background 0.15s;
}

.vs-settings-btn:hover {
  color: var(--text);
  background: var(--surface-3);
}

/* ── Dashboard Toolbar ─────────────────────────────────────────────── */

ui-dashboard-toolbar {
  display: block;
  padding: 0 0 var(--spacing-4) 0;
}

ui-dashboard-toolbar ui-toolbar-sort,
ui-dashboard-toolbar ui-toolbar-filter {
  display: none;
}

.dbt-row {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
  min-height: 36px;
}

.dbt-left {
  display: flex;
  align-items: center;
  gap: var(--spacing-3);
}

.dbt-right {
  display: flex;
  align-items: center;
  gap: var(--spacing-3);
}

.dbt-actions {
  display: flex;
  align-items: center;
  gap: var(--spacing-3);
  margin-left: auto;
}

.dbt-actions:empty {
  display: none;
}

.dbt-actions:empty + .dbt-divider {
  display: none;
}

.dbt-actions:empty + .dbt-divider + .dbt-right {
  margin-left: auto;
}

.dbt-divider {
  width: 1px;
  height: var(--spacing-8);
  background: var(--border);
  margin: 0 var(--spacing-3);
}

.dbt-count {
  font-size: var(--fs-base);
  color: var(--text-muted);
  font-weight: var(--fw-medium);
  white-space: nowrap;
}

.dbt-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-2);
  height: 32px;
  padding: 0 var(--spacing-4);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text);
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
  white-space: nowrap;
}

.dbt-pill:hover {
  border-color: var(--accent);
}

.dbt-pill[aria-expanded="true"] {
  border-color: var(--accent);
  background: var(--surface-3);
}

.dbt-pill .dbt-pill-chevron {
  color: var(--text-muted);
  transition: transform 0.15s;
}

.dbt-pill[aria-expanded="true"] .dbt-pill-chevron {
  transform: rotate(180deg);
}

.dbt-pill-value {
  color: var(--text);
}

/* Uniform height for form-field selects inside the toolbar */
ui-dashboard-toolbar .ff-input {
  height: 32px;
  font-size: var(--fs-base);
}
ui-dashboard-toolbar ui-form-field {
  margin: 0;
}
ui-dashboard-toolbar ui-form-field .ff-group {
  gap: 0;
}
ui-dashboard-toolbar ui-form-field .ff-label {
  display: none;
}

/* ── Dashboard Toolbar Dropdown ────────────────────────────────────── */

.dbt-dropdown {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--spacing-2) 0;
  z-index: var(--z-dropdown);
  box-shadow: var(--elev-dropdown);
  max-height: 280px;
  overflow-y: auto;
  font-family: var(--font);
}

.dbt-dropdown-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--spacing-3) var(--spacing-5);
  font-size: var(--fs-md);
  color: var(--text);
  cursor: pointer;
  transition: background 0.1s;
}

.dbt-dropdown-item:hover {
  background: var(--surface-3);
}

.dbt-dropdown-item.dbt-selected {
  color: var(--accent);
  font-weight: var(--fw-medium);
}

.dbt-dropdown-item ui-icon {
  color: var(--accent);
}

/* ══════════════════════════════════════════════════════════════════
   DRAWER
   ══════════════════════════════════════════════════════════════════ */

ui-drawer {
  display: contents;
}

/* ─── Backdrop ─── */
.drawer-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  z-index: var(--z-modal);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  opacity: 0;
  transition: opacity 0.2s ease-out;
}
.drawer-backdrop.drawer-open {
  display: block;
  opacity: 1;
}

/* ─── Panel ─── */
.drawer-panel {
  position: fixed;
  background: var(--surface);
  border: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  box-shadow:
    var(--elev-modal);
  transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
  overflow: hidden;
}

/* ─── Position variants ─── */
.drawer-right {
  top: 0;
  right: 0;
  bottom: 0;
  transform: translateX(100%);
}
.drawer-left {
  top: 0;
  left: 0;
  bottom: 0;
  transform: translateX(-100%);
}
.drawer-top {
  top: 0;
  left: 0;
  right: 0;
  transform: translateY(-100%);
}
.drawer-bottom {
  bottom: 0;
  left: 0;
  right: 0;
  transform: translateY(100%);
}

.drawer-open .drawer-panel {
  transform: translate(0, 0);
}

/* ─── Size variants (horizontal drawers: left/right) ─── */
.drawer-right.drawer-size-sm,
.drawer-left.drawer-size-sm {
  width: 320px;
  max-width: 90vw;
}
.drawer-right.drawer-size-md,
.drawer-left.drawer-size-md {
  width: 480px;
  max-width: 90vw;
}
.drawer-right.drawer-size-lg,
.drawer-left.drawer-size-lg {
  width: 680px;
  max-width: 90vw;
}
.drawer-right.drawer-size-full,
.drawer-left.drawer-size-full {
  width: 100vw;
}

/* ─── Size variants (vertical drawers: top/bottom) ─── */
.drawer-top.drawer-size-sm,
.drawer-bottom.drawer-size-sm {
  height: 200px;
  max-height: 80vh;
}
.drawer-top.drawer-size-md,
.drawer-bottom.drawer-size-md {
  height: 360px;
  max-height: 80vh;
}
.drawer-top.drawer-size-lg,
.drawer-bottom.drawer-size-lg {
  height: 520px;
  max-height: 80vh;
}
.drawer-top.drawer-size-full,
.drawer-bottom.drawer-size-full {
  height: 100vh;
}

/* ─── Header ─── */
.drawer-header {
  display: flex;
  align-items: center;
  padding: var(--spacing-7) var(--spacing-8);
  gap: var(--spacing-6);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.drawer-title {
  font-size: var(--fs-title);
  font-weight: var(--fw-bold);
  color: var(--text);
  line-height: var(--lh-tight);
  margin: 0;
}
.drawer-close-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border: none;
  background: transparent;
  color: var(--text-dim);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition:
    background 0.12s,
    color 0.12s;
  flex-shrink: 0;
}
.drawer-close-btn:hover {
  background: var(--surface-2);
  color: var(--text);
}

/* ─── Body ─── */
.drawer-body {
  padding: var(--spacing-7) var(--spacing-8);
  overflow-y: auto;
  flex: 1;
  min-height: 0;
  color: var(--text);
}

/* ── Settings Drawer ─────────────────────────────────────────────── */

ui-settings-drawer {
  display: contents;
}

.settings-drawer-content {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-8);
}

.settings-section {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-5);
}

.settings-section-title {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
}

.settings-section-title svg {
  width: 14px;
  height: 14px;
}

.settings-option-group {
  display: flex;
  gap: var(--spacing-3);
}

.settings-option {
  display: flex;
  align-items: center;
  gap: var(--spacing-3);
  padding: var(--spacing-4) var(--spacing-6);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
  color: var(--text-muted);
  font-size: var(--fs-md);
  cursor: pointer;
  transition:
    border-color 0.12s,
    color 0.12s,
    background 0.12s;
  flex: 1;
  justify-content: center;
}

.settings-option svg {
  width: 14px;
  height: 14px;
}

.settings-option:hover {
  border-color: var(--text-dim);
  color: var(--text);
}

.settings-option.active {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--accent-dim);
}

/* ─── Toggle Switch ─── */
.settings-toggle-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--spacing-4) 0;
  cursor: pointer;
}

.settings-toggle-label {
  font-size: var(--fs-md);
  color: var(--text);
}

.settings-toggle-input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.settings-toggle-track {
  position: relative;
  width: 36px;
  height: 20px;
  background: var(--surface-3);
  border-radius: var(--radius-md);
  transition: background 0.2s;
  flex-shrink: 0;
}

.settings-toggle-track::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: var(--radius-circle);
  background: var(--text-muted);
  transition:
    transform 0.2s,
    background 0.2s;
}

.settings-toggle-input:checked + .settings-toggle-track {
  background: var(--accent);
}

.settings-toggle-input:checked + .settings-toggle-track::after {
  transform: translateX(16px);
  background: var(--white);
}

/* ══════════════════════════════════════════════════════════════════
   CHAT — ui-chat-toolbar, ui-chat-thread, ui-chat-message, ui-chat-input
   ══════════════════════════════════════════════════════════════════ */

/* Chat views need flush layout — no outer padding, no parent scroll */
ui-module:has(ui-chat-thread) {
  overflow: hidden;
}

/* ── Chat Toolbar ────────────────────────────────────────────────── */
ui-chat-toolbar {
  display: block;
  flex-shrink: 0;
  border-bottom: 1px solid var(--border);
}

ui-chat-toolbar .chat-toolbar {
  display: flex;
  align-items: center;
  gap: var(--spacing-3);
  padding: var(--spacing-3) var(--spacing-5);
  min-height: 40px;
}

ui-chat-toolbar .chat-toolbar-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}

ui-chat-toolbar .chat-toolbar-btn:hover {
  background: var(--surface-2);
  color: var(--text);
}

ui-chat-toolbar .chat-toolbar-btn svg {
  width: 16px;
  height: 16px;
}

ui-chat-toolbar .chat-toolbar-title {
  flex: 1;
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: default;
}

ui-chat-toolbar .chat-toolbar-model {
  font-size: var(--fs-sm);
  padding: var(--spacing-1) var(--spacing-3);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--text-muted);
}

ui-chat-toolbar .chat-toolbar-select {
  font-size: var(--fs-base);
  padding: var(--spacing-1) var(--spacing-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text-muted);
  cursor: pointer;
  max-width: 160px;
}

/* Mouse/programmatic focus: border tint only, no ring. */
ui-chat-toolbar .chat-toolbar-select:focus {
  outline: none;
  border-color: var(--accent);
}

/* ── Focus ring ── */
/* Keyboard focus needs more than a 1px border-colour change: --border measures
   1.70:1 against --surface, so the accent-vs-border delta is barely
   perceptible and fails SC 1.4.11 in practice. A real ring is additive here —
   the border tint above still applies. (ND-35; token contrast itself is ND-101) */
ui-chat-toolbar .chat-toolbar-select:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

ui-module:has(ui-chat-thread) .view-container {
  padding: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

ui-chat-view .chat-view-bar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--spacing-3);
  padding: var(--spacing-2) var(--spacing-4);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}

ui-chat-view .chat-view-status {
  font-size: var(--fs-2xs);
  color: var(--text-muted);
}

/* ui-chat-view — data-driven transcript orchestrator. Owns the column layout so the
   thread scrolls and the composer stays pinned to the bottom. */
ui-chat-view {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

ui-chat-thread {
  display: flex;
  flex-direction: column;
  flex: 1;
  overflow-y: auto;
  padding: var(--spacing-6);
  gap: var(--spacing-4);
  scroll-behavior: smooth;
}

ui-chat-thread .chat-thread-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex: 1;
  gap: var(--spacing-4);
  opacity: 0.5;
  padding: var(--spacing-10);
}

ui-chat-thread .chat-thread-empty-icon {
  width: 48px;
  height: 48px;
  color: var(--text-muted);
}

ui-chat-thread .chat-thread-empty-icon svg {
  width: 100%;
  height: 100%;
}

ui-chat-thread .chat-thread-empty-text {
  font-size: var(--fs-lg);
  color: var(--text-muted);
}

/* ── Chat Message ─────────────────────────────────────────── */

ui-chat-message {
  display: flex;
  gap: var(--spacing-4);
  padding: var(--spacing-4);
  border-radius: var(--radius);
  max-width: 100%;
}

ui-chat-message.chat-message-user {
  background: var(--surface-2);
}

ui-chat-message.chat-message-assistant {
  background: transparent;
}

ui-chat-message.chat-message-system {
  background: transparent;
  opacity: 0.7;
  font-size: var(--fs-base);
}

ui-chat-message .chat-message-avatar {
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-full);
  background: var(--surface-2);
  color: var(--text-muted);
}

ui-chat-message.chat-message-user .chat-message-avatar {
  background: var(--accent);
  color: var(--white);
}

ui-chat-message .chat-message-avatar svg {
  width: 16px;
  height: 16px;
}

ui-chat-message .chat-message-body {
  flex: 1;
  min-width: 0;
}

ui-chat-message .chat-message-header {
  display: flex;
  align-items: baseline;
  gap: var(--spacing-3);
  margin-bottom: var(--spacing-2);
}

ui-chat-message .chat-message-role {
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  color: var(--text);
}

ui-chat-message .chat-message-time {
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

ui-chat-message .chat-message-content {
  font-size: var(--fs-lg);
  line-height: var(--lh-loose);
  color: var(--text);
  word-wrap: break-word;
  overflow-wrap: break-word;
}

ui-chat-message .chat-message-content p {
  margin: 0 0 var(--spacing-3) 0;
}

ui-chat-message .chat-message-content p:last-child {
  margin-bottom: 0;
}

ui-chat-message .chat-message-content h2,
ui-chat-message .chat-message-content h3,
ui-chat-message .chat-message-content h4 {
  margin: var(--spacing-4) 0 var(--spacing-2) 0;
  font-weight: var(--fw-semibold);
}

ui-chat-message .chat-message-content h2 { font-size: var(--fs-xl); }
ui-chat-message .chat-message-content h3 { font-size: 15px; }
ui-chat-message .chat-message-content h4 { font-size: var(--fs-lg); }

ui-chat-message .chat-message-content ul,
ui-chat-message .chat-message-content ol {
  margin: var(--spacing-2) 0;
  padding-left: var(--spacing-6);
}

ui-chat-message .chat-message-content li {
  margin-bottom: var(--spacing-1);
}

ui-chat-message .chat-message-content a {
  color: var(--accent);
  text-decoration: none;
}

ui-chat-message .chat-message-content a:hover {
  text-decoration: underline;
}

ui-chat-message .chat-message-content strong {
  font-weight: var(--fw-semibold);
}

ui-chat-message .chat-message-content .chat-inline-code {
  font-family: var(--mono);
  font-size: var(--fs-base);
  padding: var(--spacing-1) var(--spacing-2);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
}

ui-chat-message .chat-message-content .chat-code-block {
  font-family: var(--mono);
  font-size: var(--fs-base);
  line-height: var(--lh-relaxed);
  padding: var(--spacing-4);
  border-radius: var(--radius);
  background: var(--bg);
  overflow-x: auto;
  margin: var(--spacing-3) 0;
}

ui-chat-message .chat-message-content .chat-code-block code {
  white-space: pre;
}

/* Streaming cursor blink */
ui-chat-message .chat-cursor {
  display: inline-block;
  width: 2px;
  height: 14px;
  background: var(--accent);
  margin-left: var(--spacing-1);
  vertical-align: text-bottom;
  animation: chat-cursor-blink 1s step-end infinite;
}

@keyframes chat-cursor-blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0; }
}

/* ── Chat Tool Card ──────────────────────────────────────── */

ui-chat-tool-card {
  display: block;
  margin: var(--spacing-1) 0;
  padding: 0 var(--spacing-4);
  font-size: var(--fs-sm);
  line-height: var(--lh-loose);
}

ui-chat-tool-card .chat-tool-header {
  display: flex;
  align-items: center;
  gap: var(--spacing-3);
  padding: var(--spacing-1) 0;
}

ui-chat-tool-card .chat-tool-icon {
  display: flex;
  width: 12px;
  height: 12px;
  flex-shrink: 0;
}

ui-chat-tool-card .chat-tool-icon svg {
  width: 100%;
  height: 100%;
}

ui-chat-tool-card .chat-tool-icon-running {
  color: var(--accent);
  animation: chat-tool-spin 1s linear infinite;
}

ui-chat-tool-card .chat-tool-icon-success {
  color: var(--success);
}

ui-chat-tool-card .chat-tool-icon-error {
  color: var(--danger);
}

@keyframes chat-tool-spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

ui-chat-tool-card .chat-tool-name {
  font-family: var(--mono);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text);
}

ui-chat-tool-card .chat-tool-args {
  font-family: var(--mono);
  font-size: var(--fs-xs);
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
  min-width: 0;
  opacity: 0.7;
}

ui-chat-tool-card .chat-tool-status {
  font-size: var(--fs-xs);
  color: var(--text-muted);
  flex-shrink: 0;
}

ui-chat-tool-card .chat-tool-expand {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border: none;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  border-radius: var(--radius-sm);
  flex-shrink: 0;
  opacity: 0.6;
}

ui-chat-tool-card .chat-tool-expand:hover {
  opacity: 1;
  background: var(--surface-3);
}

ui-chat-tool-card .chat-tool-expand svg {
  width: 12px;
  height: 12px;
}

ui-chat-tool-card .chat-tool-result {
  padding: var(--spacing-1) 0 var(--spacing-1) 18px;
  font-family: var(--mono);
  font-size: var(--fs-xs);
  line-height: var(--lh-normal);
  color: var(--text-muted);
  white-space: pre-wrap;
  word-break: break-all;
  max-height: 80px;
  overflow-y: auto;
  opacity: 0.8;
}

ui-chat-tool-card .chat-tool-result.expanded {
  max-height: none;
}

/* ── Chat Input ───────────────────────────────────────────── */

ui-chat-input {
  display: block;
  padding: var(--spacing-4) var(--spacing-6);
  border-top: 1px solid var(--border);
  flex-shrink: 0;
  overflow: visible;
}

ui-chat-input .chat-input-container {
  display: flex;
  align-items: flex-end;
  gap: var(--spacing-3);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--spacing-3) var(--spacing-4);
  transition: border-color 0.15s;
}

ui-chat-input .chat-input-container:focus-within {
  border-color: var(--accent);
}

ui-chat-input .chat-input-textarea {
  flex: 1;
  border: none;
  outline: none;
  background: transparent;
  color: var(--text);
  font-family: inherit;
  font-size: var(--fs-lg);
  line-height: var(--lh-relaxed);
  resize: none;
  overflow-y: hidden;
  padding: var(--spacing-1) 0;
  min-height: 20px;
}

ui-chat-input .chat-input-textarea::placeholder {
  color: var(--text-muted);
}

ui-chat-input .chat-input-send {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border: none;
  border-radius: var(--radius);
  background: var(--accent);
  color: var(--white);
  cursor: pointer;
  flex-shrink: 0;
  transition: opacity 0.15s;
}

ui-chat-input .chat-input-send:hover {
  opacity: 0.85;
}

ui-chat-input .chat-input-send:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

ui-chat-input .chat-input-send svg {
  width: 16px;
  height: 16px;
}

ui-chat-input .chat-input-stop {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border: none;
  border-radius: var(--radius);
  background: var(--danger);
  color: var(--white);
  cursor: pointer;
  flex-shrink: 0;
  transition: opacity 0.15s;
  animation: chat-stop-pulse 1.5s ease-in-out infinite;
}

ui-chat-input .chat-input-stop:hover {
  opacity: 0.85;
}

ui-chat-input .chat-input-stop svg {
  width: 14px;
  height: 14px;
}

@keyframes chat-stop-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.6; }
}

/* ── Skill Autocomplete Popover ── */

ui-chat-input .chat-input-wrapper {
  position: relative;
}

ui-chat-input .chat-skill-popover {
  position: absolute;
  bottom: 100%;
  left: 0;
  right: 0;
  max-height: 320px;
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-bottom: none;
  border-radius: var(--radius) var(--radius) 0 0;
  box-shadow: var(--elev-menu-up);
  z-index: var(--z-menu);
  padding: var(--spacing-2) 0;
}

ui-chat-input .chat-skill-category {
  padding: var(--spacing-2) var(--spacing-4) var(--spacing-1);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-dim);
}

ui-chat-input .chat-skill-item {
  padding: var(--spacing-2) var(--spacing-4);
  cursor: pointer;
  transition: background 0.1s;
}

ui-chat-input .chat-skill-item:hover,
ui-chat-input .chat-skill-active {
  background: var(--accent-dim);
}

ui-chat-input .chat-skill-header {
  display: flex;
  align-items: center;
  gap: var(--spacing-2);
}

ui-chat-input .chat-skill-name {
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  color: var(--accent);
  font-family: var(--mono);
}

ui-chat-input .chat-skill-badge {
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--info);
  background: var(--info-bg);
  padding: var(--spacing-1) 5px;
  border-radius: var(--radius-2xs);
}

ui-chat-input .chat-skill-args {
  font-size: var(--fs-sm);
  color: var(--text-dim);
  font-style: italic;
}

ui-chat-input .chat-skill-desc {
  font-size: var(--fs-base);
  color: var(--text-muted);
  margin-top: var(--spacing-1);
  line-height: var(--lh-tight);
}

ui-chat-input .chat-skill-empty {
  padding: var(--spacing-3) var(--spacing-4);
  font-size: var(--fs-base);
  color: var(--text-dim);
  text-align: center;
}

/* ── Thinking collapsible section ── */
.chat-thinking-section {
  margin: var(--spacing-2) var(--spacing-4);
  padding: var(--spacing-2) var(--spacing-3);
  border-radius: var(--radius);
  background: var(--surface-2);
  border: 1px solid var(--border);
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

.chat-thinking-section summary {
  cursor: pointer;
  font-weight: var(--fw-medium);
  user-select: none;
  color: var(--text);
}

.chat-thinking-section .chat-thinking-content {
  margin-top: var(--spacing-2);
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 300px;
  overflow-y: auto;
  font-family: var(--mono);
  font-size: var(--fs-xs);
  line-height: var(--lh-relaxed);
  color: var(--text-muted);
}

/* ── Step progress indicator ── */
.chat-step-indicator {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--spacing-1) var(--spacing-3);
  margin: var(--spacing-1) var(--spacing-4);
  font-size: var(--fs-sm);
  color: var(--text-muted);
  background: var(--surface-2);
  border-radius: var(--radius-xs);
}

.chat-step-indicator.chat-step-warning {
  color: var(--warning);
  background: var(--warning-bg);
}

/* ── Token / timing stats footer ── */
.chat-message-stats {
  display: flex;
  justify-content: flex-end;
  padding: var(--spacing-1) var(--spacing-4);
  font-size: var(--fs-sm);
  color: var(--text-muted);
  opacity: 0.6;
}

/* ── Check List ── */
ui-check-list {
  display: block;
}

.check-list-controls {
  display: flex;
  align-items: center;
  gap: var(--spacing-3);
  padding: var(--spacing-2) 0;
}

.check-list-count {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  font-weight: var(--fw-semibold);
}

.check-list-btn {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  cursor: pointer;
  color: var(--accent);
  font-size: var(--fs-sm);
  padding: var(--spacing-1) var(--spacing-3);
  font-weight: var(--fw-medium);
}

.check-list-btn:hover {
  background: var(--surface-3, var(--surface-2));
  border-color: var(--accent);
}

.check-list-scroll {
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--spacing-2);
}

.check-list-row {
  display: flex;
  align-items: center;
  gap: var(--spacing-2);
  padding: var(--spacing-1) var(--spacing-2);
  border-radius: var(--radius);
  cursor: pointer;
  font-size: var(--fs-base);
}

.check-list-row:hover {
  background: var(--surface-2);
}

.check-list-cb {
  flex-shrink: 0;
  accent-color: var(--accent);
}

.check-list-label {
  font-family: var(--mono);
  font-size: var(--fs-sm);
  color: var(--text);
  font-weight: var(--fw-medium);
  flex-shrink: 0;
}

.check-list-detail {
  font-family: var(--mono);
  font-size: var(--fs-xs);
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.check-list-empty {
  padding: var(--spacing-4);
  color: var(--text-muted);
  font-size: var(--fs-base);
  text-align: center;
}

/* ══════════════════════════════════════════════════════════════════
   REDUCED MOTION (ND-35)
   Honours the OS "reduce motion" accessibility preference.

   MUST remain the last block in this file — cascade order is currently
   positional (no @layer yet; ND-95 introduces layers, after which this
   should move into a top layer instead of relying on position).

   Approach: collapse durations to ~0 rather than `animation: none`.
   Removing an animation outright strips its end state, so anything that
   animates in (opacity 0 -> 1, translateY -> 0) would be left stuck in its
   start frame. Near-zero duration still applies the final keyframe and
   still fires animationend/transitionend, so JS that awaits those keeps
   working.
   ══════════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }

  /* ── Essential progress feedback: exempt ──
     WCAG 2.3.3 / vestibular guidance targets large-area, non-essential
     motion. These are small (12-20px), stationary, and are the only signal
     that work is in progress — freezing them mid-rotation reads as a hung
     UI rather than a calm one. They keep rotating, slowed to reduce
     stimulus. Non-essential motion (slides, shimmer, parallax, pulses) is
     NOT exempt and is collapsed by the rule above.

     ND-97 consolidates the 11 duplicate spin keyframes into one, at which
     point this list collapses to a single selector. */
  .uib-spinner,
  .spn-circle,
  .dlg-spinner,
  .ff-ta-spinner,
  .dt-spinner,
  .lm-spinner,
  .lm-spinner-sm,
  ui-list-view .lv-spinner,
  ui-document-viewer .dv-spinner,
  .pl-border-wrap .pl-spinner,
  ui-chat-tool-card .chat-tool-icon-running {
    animation-duration: 1.4s !important;
    animation-iteration-count: infinite !important;
  }

  /* Streaming caret: a blink conveys "still generating". Keep it, slowed.
     step-end timing means no smooth movement, so stimulus is minimal. */
  ui-chat-message .chat-cursor {
    animation-duration: 1.6s !important;
    animation-iteration-count: infinite !important;
  }
}

/* ══════════════════════════════════════════════════════════════════
   ui-query-tester — validate/preview a query without saving  (ND-264)
   ══════════════════════════════════════════════════════════════════ */

ui-query-tester {
  display: block;
}

ui-query-tester .qt-container {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-6);
}

ui-query-tester .qt-actions {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
  flex-wrap: wrap;
}

ui-query-tester .qt-btn {
  padding: var(--spacing-3) var(--spacing-6);
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  cursor: pointer;
}

ui-query-tester .qt-btn:hover:not(:disabled) {
  background: var(--surface-3);
}

ui-query-tester .qt-btn:disabled {
  opacity: 0.5;
  cursor: default;
}

ui-query-tester .qt-btn-primary {
  color: var(--text-on-accent);
  background: var(--accent);
  border-color: var(--accent);
}

ui-query-tester .qt-status {
  font-size: var(--fs-base);
  color: var(--text-muted);
}

ui-query-tester .qt-status.qt-success { color: var(--success); }
ui-query-tester .qt-status.qt-error   { color: var(--danger); }
ui-query-tester .qt-status.qt-warning { color: var(--warning); }

ui-query-tester .qt-warning {
  padding: var(--spacing-4) var(--spacing-6);
  font-size: var(--fs-base);
  border-radius: var(--radius-xs);
  border-left: 2px solid transparent;
}

ui-query-tester .qt-warning.qt-error {
  color: var(--danger);
  background: var(--danger-bg);
  border-left-color: var(--danger);
}

ui-query-tester .qt-warning.qt-info {
  color: var(--text-muted);
  background: var(--surface-2);
  border-left-color: var(--border);
}

ui-query-tester .qt-params,
ui-query-tester .qt-empty {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  font-family: var(--mono);
}

ui-query-tester .qt-table-wrap {
  overflow: auto;
  max-height: 320px;
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
}

ui-query-tester .qt-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-sm);
  font-family: var(--mono);
}

ui-query-tester .qt-table th {
  position: sticky;
  top: 0;
  text-align: left;
  padding: var(--spacing-3) var(--spacing-5);
  color: var(--text-muted);
  background: var(--surface-3);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

ui-query-tester .qt-table td {
  padding: var(--spacing-3) var(--spacing-5);
  color: var(--text);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

ui-query-tester .qt-table tbody tr:last-child td {
  border-bottom: none;
}

ui-query-tester .qt-sql {
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

ui-query-tester .qt-sql summary {
  cursor: pointer;
  padding: var(--spacing-2) 0;
}

ui-query-tester .qt-sql-body {
  margin: var(--spacing-3) 0 0 0;
  padding: var(--spacing-5);
  overflow: auto;
  max-height: 240px;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  font-family: var(--mono);
  font-size: var(--fs-sm);
  white-space: pre;
}

/* ui-report-chart — report results as a chart  (ND-267) */

ui-report-chart {
  display: block;
}

ui-report-chart .rc-message {
  margin: 0;
  font-size: var(--fs-base);
  color: var(--text-muted);
}

/* ══════════════════════════════════════════════════════════════════
   ui-report-builder — design a report by picking fields  (ND-267)

   A three-zone workbench under one editable sentence:

     ┌── strip: the whole report as words, plus Save ──────────────┐
     │ fields (280) │ canvas — table + chart │ settings (300, ⇔)  │
     └─────────────────────────────────────────────────────────────┘

   It was previously two panes — a 400px stack of six collapsible
   sections beside the results — which put every control in one
   scrolling column and left the canvas too narrow to show a wide
   table or a chart at all. Picking fields, reading the outcome and
   configuring the output are three different activities, so they get
   three places that do not move.
   ══════════════════════════════════════════════════════════════════ */

ui-report-builder {
  display: block;
  container-type: inline-size;
}

ui-report-builder .rb-workbench {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-6);
  min-width: 0;
}

/* ── The definition strip ── */

ui-report-builder .rb-strip {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--spacing-7);
  padding: var(--spacing-5) var(--spacing-6);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

ui-report-builder .rb-sentence {
  display: flex;
  align-items: center;
  gap: var(--spacing-5);
  flex-wrap: wrap;
  min-width: 0;
}

ui-report-builder .rb-seg {
  display: flex;
  align-items: center;
  gap: var(--spacing-3);
  flex-wrap: wrap;
}

ui-report-builder .rb-seg-label {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  white-space: nowrap;
}

ui-report-builder .rb-seg-empty {
  font-size: var(--fs-base);
  font-style: italic;
  color: var(--text-dim);
}

ui-report-builder .rb-strip-actions {
  display: flex;
  align-items: center;
  gap: var(--spacing-5);
  flex-shrink: 0;
}

/* ── Chips ── */

ui-report-builder .rb-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-2);
  max-width: 240px;
  padding: var(--spacing-2) var(--spacing-3) var(--spacing-2) var(--spacing-4);
  font-size: var(--fs-base);
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
}

ui-report-builder .rb-chip[draggable="true"] { cursor: grab; }
ui-report-builder .rb-chip-dragging { opacity: 0.4; }

ui-report-builder .rb-chip-drop {
  border-color: var(--accent);
  background: var(--accent-dim);
}

ui-report-builder .rb-chip-draft {
  border-style: dashed;
  color: var(--text-muted);
}

ui-report-builder .rb-chip-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: inherit;
  font-family: inherit;
  font-size: var(--fs-base);
  background: none;
  border: none;
  padding: 0;
}

ui-report-builder button.rb-chip-text { cursor: pointer; }
ui-report-builder button.rb-chip-text:hover { color: var(--accent); }

ui-report-builder .rb-chip-x {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  padding: 0;
  font-size: var(--fs-md);
  line-height: var(--lh-none);
  color: var(--text-dim);
  background: none;
  border: none;
  border-radius: var(--radius-circle);
  cursor: pointer;
}

ui-report-builder .rb-chip-x:hover {
  color: var(--danger);
  background: var(--danger-bg);
}

ui-report-builder .rb-chip-add {
  padding: var(--spacing-2) var(--spacing-5);
  color: var(--text-muted);
  background: none;
  border-style: dashed;
  cursor: pointer;
}

ui-report-builder .rb-chip-add:hover {
  color: var(--accent);
  border-color: var(--accent);
  border-style: solid;
}

ui-report-builder .rb-select-dataset { font-weight: var(--fw-semibold); }

/* ── Three zones ──
   min-height rather than a stretched height: the builder sits inside a
   scrolling panel body, so there is no fixed height to divide. When the
   panel is filling the window there is, and the canvas should take it. */

ui-report-builder .rb-body {
  display: grid;
  grid-template-columns: 280px minmax(0, 1fr) auto;
  gap: var(--spacing-6);
  align-items: stretch;
  min-height: 520px;
}

ui-content-panel[data-expanded] ui-report-builder .rb-body {
  min-height: calc(100vh - 320px);
}

@container (max-width: 1100px) {
  ui-report-builder .rb-body { grid-template-columns: 240px minmax(0, 1fr); }
  ui-report-builder .rb-rail-settings { grid-column: 1 / -1; }
}

@container (max-width: 720px) {
  ui-report-builder .rb-body { grid-template-columns: minmax(0, 1fr); min-height: 0; }
  ui-report-builder .rb-rail-fields { grid-column: 1 / -1; }
}

ui-report-builder .rb-rail {
  display: flex;
  flex-direction: column;
  min-width: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
}

ui-report-builder .rb-rail-body {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-3);
  padding: var(--spacing-5);
  overflow: auto;
  flex: 1;
}

/* ── Fields rail ── */

ui-report-builder .rb-search {
  display: flex;
  align-items: center;
  gap: var(--spacing-3);
  padding: var(--spacing-4) var(--spacing-5);
  border-bottom: 1px solid var(--border);
}

ui-report-builder .rb-search-input {
  flex: 1;
  min-width: 0;
}

ui-report-builder .rb-search-key {
  padding: var(--spacing-1) var(--spacing-3);
  font-family: var(--mono);
  font-size: var(--fs-xs);
  color: var(--text-dim);
  border: 1px solid var(--border);
  border-radius: var(--radius-2xs);
}

ui-report-builder .rb-group-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--spacing-4);
  padding: var(--spacing-4) var(--spacing-3) var(--spacing-2);
}

ui-report-builder .rb-group-title {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
}

ui-report-builder .rb-group-count {
  font-family: var(--mono);
  font-size: var(--fs-xs);
  color: var(--text-dim);
}

/* ── Settings rail ── */

ui-report-builder .rb-rail-settings { width: 300px; }
ui-report-builder .rb-rail-settings.rb-rail-shut { width: auto; }

ui-report-builder .rb-rail-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--spacing-4);
  padding: var(--spacing-4) var(--spacing-5);
  border-bottom: 1px solid var(--border);
}

ui-report-builder .rb-rail-title {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
}

ui-report-builder .rb-rail-toggle {
  padding: 0 var(--spacing-3);
  font-size: var(--fs-lg);
  color: var(--text-muted);
  background: none;
  border: none;
  cursor: pointer;
}

ui-report-builder .rb-rail-toggle:hover { color: var(--text); }

/* ── Canvas ── */

ui-report-builder .rb-canvas {
  display: flex;
  flex-direction: column;
  min-width: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
}

ui-report-builder .rb-canvas-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--spacing-6);
  padding: var(--spacing-4) var(--spacing-5);
  border-bottom: 1px solid var(--border);
}

ui-report-builder .rb-canvas-bar-right {
  display: flex;
  align-items: center;
  gap: var(--spacing-6);
  min-width: 0;
}

ui-report-builder .rb-canvas-body {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-6);
  padding: var(--spacing-6);
  overflow: auto;
  flex: 1;
}

ui-report-builder .rb-canvas-chart { min-width: 0; }

/* ── The PDF view ──
   The document fills the canvas, exactly where the chart and table were.
   There is no Generate button: choosing the PDF tab is the request, and a
   separate control to fulfil a request already made is a step too many. */

/* Anchors carrying .rb-btn need the box behaviour a button gets for free. */
ui-report-builder a.rb-btn {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
}

ui-report-builder .rb-canvas-pdf {
  display: flex;
  flex: 1;
  min-height: 480px;
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  overflow: hidden;
}

ui-report-builder .rb-canvas-pdf ui-document-viewer {
  flex: 1;
  min-width: 0;
}

/* Says the document no longer matches the design, and fixes it in one click.
   Not an auto-regenerate: every generate writes a run record and costs a
   round trip, so doing it on each keystroke would be both noisy and slow. */

ui-report-builder .rb-stale {
  display: flex;
  align-items: center;
  gap: var(--spacing-6);
  flex-wrap: wrap;
  padding: var(--spacing-4) var(--spacing-6);
  background: var(--warning-bg);
  border: 1px solid var(--warning);
  border-radius: var(--radius-xs);
}

ui-report-builder .rb-stale-text {
  flex: 1;
  min-width: 0;
  font-size: var(--fs-base);
  color: var(--text);
}

ui-report-builder .rb-switch {
  display: inline-flex;
  padding: var(--spacing-1);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
}

ui-report-builder .rb-switch-btn {
  padding: var(--spacing-2) var(--spacing-6);
  font-size: var(--fs-base);
  color: var(--text-muted);
  background: none;
  border: none;
  border-radius: var(--radius-2xs);
  cursor: pointer;
  white-space: nowrap;
}

ui-report-builder .rb-switch-btn:hover { color: var(--text); }

ui-report-builder .rb-switch-on {
  color: var(--text);
  background: var(--surface-3);
}

/* ── Sections ── */

ui-report-builder .rb-section {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

ui-report-builder .rb-section-head {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
  width: 100%;
  padding: var(--spacing-5) var(--spacing-6);
  color: var(--text);
  background: var(--surface-2);
  border: none;
  cursor: pointer;
  text-align: left;
}

ui-report-builder .rb-section-head:hover { background: var(--surface-3); }

ui-report-builder .rb-caret {
  color: var(--text-muted);
  font-size: var(--fs-xs);
}

ui-report-builder .rb-section-title {
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
}

ui-report-builder .rb-section-body {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-5);
  padding: var(--spacing-6);
}

/* `display: flex` above beats the UA stylesheet's [hidden] { display: none },
   so every collapsed section rendered its body while its caret said otherwise —
   collapsing had never worked. An author-level rule is required to win. */

ui-report-builder .rb-section-body[hidden] { display: none; }

ui-report-builder .rb-hint {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  line-height: var(--lh-normal);
}

/* ── Field pickers ── */

ui-report-builder .rb-field-list {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-1);
}

ui-report-builder .rb-field {
  display: flex;
  align-items: flex-start;
  gap: var(--spacing-4);
  padding: var(--spacing-3) var(--spacing-4);
  border-radius: var(--radius-2xs);
  cursor: pointer;
}

ui-report-builder .rb-field:hover { background: var(--surface-2); }
ui-report-builder .rb-field-on { background: var(--surface-2); }

ui-report-builder .rb-field input[type="checkbox"] { margin-top: var(--spacing-1); }

ui-report-builder .rb-field-text {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-1);
  min-width: 0;
}

ui-report-builder .rb-field-top {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
}

ui-report-builder .rb-field-label {
  font-size: var(--fs-base);
  color: var(--text);
}

ui-report-builder .rb-field-desc {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  line-height: var(--lh-snug);
}

ui-report-builder .rb-field-agg {
  padding: 0 var(--spacing-3);
  font-family: var(--mono);
  font-size: var(--fs-2xs);
  color: var(--text-muted);
  background: var(--surface-3);
  border-radius: var(--radius-full);
}

/* ── Controls ── */

ui-report-builder .rb-filter-row {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
  flex-wrap: wrap;
}

ui-report-builder .rb-filter-value {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
  flex-wrap: wrap;
  flex: 1;
  min-width: 140px;
}

ui-report-builder .rb-inline-label {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  white-space: nowrap;
}

/* A label and its control travel together, so a narrow rail can only ever
   wrap between pairs — never between a label and the thing it names. */

ui-report-builder .rb-pair {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-2);
  /* Wrap to the next line rather than squeeze: three pairs sharing a 270px rail
     shrank the sort select until its value read "Submissio". */
  min-width: 110px;
  flex: 1;
}

ui-report-builder .rb-select,
ui-report-builder .rb-input {
  padding: var(--spacing-3) var(--spacing-4);
  font-size: var(--fs-base);
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  max-width: 100%;
}

ui-report-builder .rb-select-grain { margin: 0 0 var(--spacing-2) var(--spacing-9); }
ui-report-builder .rb-input-narrow { width: 96px; }
ui-report-builder .rb-input-wide { flex: 1; min-width: 160px; }

/* ── Value picker ── */

ui-report-builder .rb-value-list {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-1);
  width: 100%;
  max-height: 200px;
  overflow: auto;
  padding: var(--spacing-3);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
}

ui-report-builder .rb-value {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
  padding: var(--spacing-2) var(--spacing-3);
  font-size: var(--fs-base);
  border-radius: var(--radius-2xs);
  cursor: pointer;
}

ui-report-builder .rb-value:hover { background: var(--surface-2); }
ui-report-builder .rb-value-on { background: var(--surface-3); }
ui-report-builder .rb-value-text { flex: 1; color: var(--text); }

ui-report-builder .rb-value-count {
  font-family: var(--mono);
  font-size: var(--fs-2xs);
  color: var(--text-muted);
}

/* ── Buttons ── */

ui-report-builder .rb-btn {
  padding: var(--spacing-3) var(--spacing-6);
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  cursor: pointer;
}

ui-report-builder .rb-btn:hover:not(:disabled) { background: var(--surface-3); }
ui-report-builder .rb-btn:disabled { opacity: 0.5; cursor: default; }

ui-report-builder .rb-btn-primary {
  color: var(--text-on-accent);
  background: var(--accent);
  border-color: var(--accent);
}

ui-report-builder .rb-btn-quiet {
  align-self: flex-start;
  font-size: var(--fs-sm);
}

ui-report-builder .rb-btn-icon {
  padding: var(--spacing-2) var(--spacing-4);
  color: var(--text-muted);
}

/* ── Status and warnings ── */

ui-report-builder .rb-status { font-size: var(--fs-sm); color: var(--text-muted); }
ui-report-builder .rb-status.rb-success { color: var(--success); }
ui-report-builder .rb-status.rb-error { color: var(--danger); }
ui-report-builder .rb-status.rb-busy { color: var(--accent); }

ui-report-builder .rb-warning {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-3);
  align-items: flex-start;
  padding: var(--spacing-4) var(--spacing-6);
  font-size: var(--fs-base);
  border-radius: var(--radius-xs);
  border-left: 2px solid transparent;
}

ui-report-builder .rb-warning.rb-error {
  color: var(--danger);
  background: var(--danger-bg);
  border-left-color: var(--danger);
}

ui-report-builder .rb-warning.rb-info {
  color: var(--text-muted);
  background: var(--surface-2);
  border-left-color: var(--border);
}

/* ── Results pane ── */

/* An empty state is a place to act, not a place to be told something —
   so it is a card with a title, a sentence and the button that does the
   thing the sentence describes. */

ui-report-builder .rb-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--spacing-5);
  margin: auto;
  padding: var(--spacing-10) var(--spacing-8);
  max-width: 420px;
  font-size: var(--fs-base);
  color: var(--text-muted);
  text-align: center;
  background: var(--surface-2);
  border: 1px dashed var(--border);
  border-radius: var(--radius-sm);
}

ui-report-builder .rb-empty-title {
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  color: var(--text);
}

ui-report-builder .rb-empty-text { line-height: var(--lh-relaxed); }

ui-report-builder .rb-empty-sm {
  margin: 0;
  padding: var(--spacing-7) var(--spacing-5);
  max-width: none;
  font-size: var(--fs-sm);
  line-height: var(--lh-relaxed);
}

/* ── The SQL view ──
   Was a <details> in the toolbar. It opened as a popover that overflowed the
   canvas and covered the settings rail, and a twisty implied a debugging aid
   rather than the report's actual output. It is a view like the others. */

ui-report-builder .rb-sql-view {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-5);
  min-width: 0;
}

ui-report-builder .rb-sql-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--spacing-6);
  flex-wrap: wrap;
}

ui-report-builder .rb-sql-title {
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

ui-report-builder .rb-sql-body {
  margin: 0;
  padding: var(--spacing-7);
  overflow: auto;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  font-family: var(--mono);
  font-size: var(--fs-base);
  line-height: var(--lh-relaxed);
  white-space: pre;
  user-select: text;
}

/* Values are listed, never substituted into the text above. That is the point:
   the SQL you are reading is the SQL that runs, and filter values reach it as
   bound parameters rather than concatenated literals. */

ui-report-builder .rb-sql-params {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-4);
  padding: var(--spacing-6);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
}

ui-report-builder .rb-sql-params-title {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
}

ui-report-builder .rb-sql-param-list {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-2);
}

ui-report-builder .rb-sql-param {
  display: flex;
  align-items: baseline;
  gap: var(--spacing-6);
  font-family: var(--mono);
  font-size: var(--fs-sm);
}

ui-report-builder .rb-sql-param-key { color: var(--accent); }
ui-report-builder .rb-sql-param-val { color: var(--text); }

ui-report-builder .rb-table-wrap {
  overflow: auto;
  max-height: 520px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

ui-report-builder .rb-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-sm);
}

ui-report-builder .rb-table th {
  position: sticky;
  top: 0;
  text-align: left;
  padding: var(--spacing-4) var(--spacing-5);
  color: var(--text-muted);
  background: var(--surface-3);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
  font-weight: var(--fw-semibold);
}

ui-report-builder .rb-table td {
  padding: var(--spacing-3) var(--spacing-5);
  color: var(--text);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
  font-family: var(--mono);
}

ui-report-builder .rb-table tbody tr:last-child td { border-bottom: none; }
ui-report-builder .rb-table tbody tr:hover td { background: var(--surface-2); }

/* ══════════════════════════════════════════════════════════════════
   Fill-window panels — <ui-node-header expandable>

   A CSS overlay rather than the Fullscreen API, so the app's theme and
   its toast/dropdown layers keep working. Sits in the --z-modal band,
   which is ordered BELOW dropdown/popover/toast/tooltip — so every
   control inside an expanded panel still layers above it correctly.
   ══════════════════════════════════════════════════════════════════ */

ui-content-panel[data-expanded],
ui-tab-panel[data-expanded] {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: flex;
  flex-direction: column;
  overflow: auto;
  padding: var(--spacing-7);
  background: var(--bg);
  /* Not `display: block` when hidden elsewhere — an expanded panel is always the
     active one, so it does not have to fight the panel-visibility rules. */
}

/* Keep the header pinned while the body scrolls: the exit control must stay
   reachable, otherwise a long report traps you until you remember Esc. */
ui-content-panel[data-expanded] > ui-node-header,
ui-tab-panel[data-expanded] > ui-node-header {
  position: sticky;
  top: calc(var(--spacing-7) * -1);
  z-index: var(--z-sticky);
  padding-top: var(--spacing-4);
  padding-bottom: var(--spacing-4);
  background: var(--bg);
}

/* Suppress scroll behind the overlay. */
html[data-panel-expanded] {
  overflow: hidden;
}

ui-node-header .nh-expand {
  margin-left: var(--spacing-3);
}
