/* tokens.css */
:root {
  /* Vellum canonical tokens */
  --vui-edge-margin: 12px;
  /* The z ladder, lowest to highest: flyout 50 < modal 110 < fab 120 <
     feedback canvas 125 < feedback widget 130 < toast 160. New overlays
     pick a rung here, never a raw number. */
  --vui-z-flyout: 50;
  --vui-z-modal: 110;
  --vui-z-fab: 120;
  --vui-z-feedback-canvas: 125;
  --vui-z-feedback: 130;
  --vui-control-height-compact: 28px;
  --vui-control-pad-y: 5px;
  --vui-control-pad-x: 10px;
  --vui-focus-ring: 2px solid var(--vui-color-text-strong);
  --vui-focus-ring-offset: 2px;
  --vui-font-body: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  /* BEN-623: quieter bookish serif — no unicase theatrics, no webfont. */
  --vui-font-heading: 'Palatino Linotype', Palatino, 'Book Antiqua', Georgia, serif;
  --vui-font-display: 'Palatino Linotype', Palatino, 'Book Antiqua', Georgia, serif;
  --vui-font-mono: 'Courier New', Courier, monospace;
  --vui-font-size-xxxs: 0.55rem;
  --vui-font-size-xxs: 0.68rem;
  --vui-font-size-xs: 0.72rem;
  --vui-font-size-sm: 0.78rem;
  --vui-font-size-md: 0.85rem;
  --vui-font-size-base: 0.9rem;
  --vui-font-size-lg: 0.95rem;
  --vui-font-size-xl: 1.02rem;
  --vui-font-size-heading: 1.3rem;
  --vui-font-size-display: 1.7rem;
  --vui-font-size-jumbo: 2rem;
  --vui-font-weight-body: 900;
  --vui-font-weight-title: 900;
  --vui-line-height-body: 1.4;
  --vui-letter-spacing-ui: 0;
  --vui-text-case: none;
  --vui-title-size: clamp(36px, 5.6vw, 68px);
  --vui-title-tracking: -0.06em;
  --vui-title-transform: none;
  --vui-title-shadow: 3px 3px 0 var(--vui-color-text-strong);
  --vui-label-tracking: 0.06em;
  --vui-label-transform: uppercase;
  --vui-color-bg: #f1eef6;
  --vui-color-surface: #e7e2ee;
  --vui-color-surface-sunken: #cec4dd;
  --vui-color-surface-raised: #faf8fd;
  --vui-color-surface-hover: #ece7f3;
  --vui-color-surface-placeholder: #e8d8ad;
  --vui-color-text: #15100d;
  --vui-color-text-muted: #5b3b25;
  --vui-color-text-strong: #15100d;
  --vui-color-text-inverse: #fff5d2;
  /* For content sitting on ink-colored surfaces (fab pills, dark bands). */
  --vui-color-on-dark-line: rgba(255, 255, 255, 0.4);
  --vui-color-on-dark-text-soft: rgba(255, 255, 255, 0.82);
  --vui-color-line: rgba(21, 16, 13, 0.4);
  --vui-color-line-strong: #15100d;
  --vui-color-line-focus: var(--vui-color-accent);
  --vui-color-line-faint: #eee;
  --vui-color-accent: #6c3aa4;
  --vui-color-accent-soft: #e7d8f5;
  --vui-color-accent-strong: #202842;
  --vui-color-success: #7f9461;
  --vui-color-warn: #f2c452;
  --vui-color-danger: #a73528;
  /* Alias: never diverged from danger, and as an alias it theme-flips free. */
  --vui-color-danger-strong: var(--vui-color-danger);
  --vui-color-danger-hover: #7a2820;
  --vui-color-info: #4aa6c8;
  --vui-color-success-soft: rgba(127, 148, 97, 0.18);
  --vui-color-warn-soft: #ead07a;
  --vui-color-warn-soft-pale: #fff8e0;
  --vui-color-danger-soft: rgba(167, 53, 40, 0.14);
  --vui-color-info-soft: #d7edf3;
  --vui-color-success-line: #7f9461;
  --vui-color-warn-line: #d4a830;
  --vui-color-danger-line: #a73528;
  --vui-color-info-line: #4aa6c8;
  --vui-color-btn-primary-hover: #5b3b25;
  --vui-color-shadow: #3d2b22;
  --vui-color-input-bg: rgba(255, 255, 255, 0.36);
  --vui-color-input-bg-focus: rgba(255, 255, 255, 0.52);
  --vui-color-overlay-strong: rgba(0, 0, 0, 0.8);
  --vui-color-overlay-soft: rgba(0, 0, 0, 0.4);
  --vui-modal-backdrop: var(--vui-color-overlay-soft);
  --vui-modal-card-bg: var(--vui-color-surface);
  --vui-modal-card-border: 3px solid var(--vui-color-text-strong);
  --vui-modal-card-radius: 6px;
  --vui-modal-card-shadow: 7px 7px 0 var(--vui-color-shadow);
  --vui-modal-card-max-height: calc(100vh - 32px);
  --vui-modal-card-min-width: 220px;
  --vui-modal-card-min-height: 140px;
  /* The head is the ink band (one head fleet-wide); the parchment texture
     tokens retired with the two-head split. */
  --vui-modal-head-padding: 9px 14px;
  --vui-modal-body-padding: 14px 16px;
  --vui-modal-actions-padding: 12px 16px;
  --vui-modal-actions-gap: 8px;
  /* Close geometry only — the quiet × carries no decoration (BEN-604). */
  --vui-modal-close-size: 28px;
  --vui-modal-close-offset: 11px;
  --vui-modal-resize-edge-size: 8px;
  --vui-modal-resize-corner-size: 28px;
  /* Status surfaces (badge-style bg/border/text trios). --vui-status-* is the
     ONE name; the parallel --vui-color-<tone>-bg family it once aliased is gone. */
  --vui-status-success-bg: #effaef;
  --vui-status-success-border: #c4e5c4;
  --vui-status-success-text: #2c6b2c;
  --vui-status-warn-bg: #fff5dc;
  --vui-status-warn-border: #e8d49a;
  --vui-status-warn-text: #7a5a10;
  --vui-status-danger-bg: #fbecec;
  --vui-status-danger-border: #e6bebe;
  --vui-status-danger-text: #8a2828;
  --vui-status-neutral-bg: #f4f4f4;
  --vui-status-neutral-border: #ddd;
  --vui-status-neutral-text: #777;
  --vui-color-neutral-black: #000;
  --vui-color-neutral-white: #fff;
  --vui-color-neutral-900: #111;
  --vui-color-neutral-700: #333;
  --vui-color-neutral-600: #444;
  --vui-color-neutral-550: #555;
  --vui-color-neutral-500: #666;
  --vui-color-neutral-400: #888;
  --vui-color-neutral-350: #999;
  --vui-color-neutral-250: #bbb;
  --vui-color-neutral-200: #ccc;
  --vui-color-neutral-surface-warm: #fffefb;
  --vui-color-neutral-surface-faint: #fafafa;
  --vui-color-neutral-border-warm: #ddd6ca;
  --vui-radius-sharp: 4px;
  --vui-radius-soft: 7px;
  --vui-radius-square: 0px;
  --vui-radius-pill: 999px;
  --vui-radius-card: 4%;
  --vui-radius-tight: 2px;
  --vui-radius-round: 10px;
  --vui-border-width: 3px;
  --vui-shadow-subtle: 0 0 0 var(--vui-color-shadow);
  --vui-shadow-soft: 3px 3px 0 var(--vui-color-shadow);
  --vui-shadow-firm: 4px 4px 0 var(--vui-color-shadow);
  --vui-shadow-lift: 0 3px 0 var(--vui-color-shadow);
  --vui-shadow-popover: 4px 4px 0 var(--vui-color-shadow);
  --vui-shadow-overlay: 8px 8px 0 var(--vui-color-shadow);
  --vui-shadow-hard: 6px 6px 0 var(--vui-color-shadow);
  --vui-shadow-hard-sm: 3px 3px 0 var(--vui-color-text-strong);
  /* The sanctioned soft shadow: floating depth cues over content (lightbox,
     drawer edges, slide-in panels). Everything else stays hard-offset. */
  --vui-shadow-float: 0 8px 24px rgba(0, 0, 0, 0.18);
  /* Press feedback: controls shift down-right and their shadow collapses to
     the remainder. One pair of values fleet-wide (BEN-624 follow-up). */
  --vui-press-shift: 2px;
  --vui-press-shadow: 2px 2px 0 var(--vui-color-shadow);
  /* Inset bevel that makes inputs read carved-in; theme-tuned below. */
  --vui-input-bevel:
    inset 3px 3px 0 rgba(0, 0, 0, 0.18),
    inset -2px -2px 0 rgba(255, 255, 255, 0.32);
  /* snap drives press/hover feedback on controls (BEN-624) */
  --vui-motion-snap: 70ms;
  --vui-motion-fast: 120ms;
  --vui-motion-base: 180ms;
  --vui-motion-slow: 260ms;
  --vui-space-1: 4px;
  --vui-space-2: 8px;
  --vui-space-3: 12px;
  --vui-space-4: 16px;
  --vui-space-5: 20px;

  /* Ink for text on warn/gold surfaces — fixed in BOTH themes so gold
     buttons stay legible in dark (BEN-560). */
  --vui-color-on-warn: #15100d;

  /* Vellum convenience aliases */
  --vui-control-height: 34px;
  --vui-space-6: 24px;
  --vui-z-toast: 160;
}

/* Dark vellum. Set data-theme="dark" on <html> — consumers that re-alias
   --vui-* tokens on their own :root (biblioplex) need the attribute there for
   their aliases to follow the theme. Only color-family tokens flip;
   shape, type, space, and motion are theme-invariant. */
[data-theme='dark'] {
  --vui-color-bg: #1c1722;
  --vui-color-surface: #241e2c;
  --vui-color-surface-sunken: #161219;
  --vui-color-surface-raised: #2e2738;
  --vui-color-surface-hover: #2a2333;
  --vui-color-surface-placeholder: #4a3f28;
  --vui-color-text: #e9e2f2;
  --vui-color-text-muted: #b8a18d;
  --vui-color-text-strong: #f3eefa;
  --vui-color-text-inverse: #1c1722;
  /* "Ink" surfaces are light in dark mode, so on-dark content flips dark. */
  --vui-color-on-dark-line: rgba(28, 23, 34, 0.4);
  --vui-color-on-dark-text-soft: rgba(28, 23, 34, 0.82);
  --vui-color-line: rgba(233, 226, 242, 0.35);
  --vui-color-line-strong: #e9e2f2;
  --vui-color-line-faint: #332c3d;
  --vui-color-accent: #a878e0;
  --vui-color-accent-soft: #3a2d52;
  --vui-color-accent-strong: #d8c8f0;
  --vui-color-success: #93ab72;
  --vui-color-danger: #d05546;
  --vui-color-danger-hover: #b03c2e;
  --vui-color-info: #62b8d8;
  --vui-color-success-soft: rgba(147, 171, 114, 0.22);
  --vui-color-warn-soft: #5a4a20;
  --vui-color-warn-soft-pale: #2e2614;
  --vui-color-danger-soft: rgba(208, 85, 70, 0.2);
  --vui-color-info-soft: #1e3640;
  --vui-color-success-line: #93ab72;
  --vui-color-warn-line: #d4a830;
  --vui-color-danger-line: #d05546;
  --vui-color-info-line: #62b8d8;
  --vui-color-btn-primary-hover: #c4a484;
  --vui-color-shadow: #0a0710;
  --vui-color-input-bg: rgba(0, 0, 0, 0.25);
  --vui-color-input-bg-focus: rgba(0, 0, 0, 0.4);
  --vui-status-success-bg: #1e2a1e;
  --vui-status-success-border: #3c5a3c;
  --vui-status-success-text: #a8d8a8;
  --vui-status-warn-bg: #2e2614;
  --vui-status-warn-border: #6a5a28;
  --vui-status-warn-text: #e8cc7a;
  --vui-status-danger-bg: #2e1818;
  --vui-status-danger-border: #6a3434;
  --vui-status-danger-text: #e89898;
  --vui-status-neutral-bg: #242028;
  --vui-status-neutral-border: #46404f;
  --vui-status-neutral-text: #a298ad;
  --vui-shadow-float: 0 8px 24px rgba(0, 0, 0, 0.55);
  /* Darker carve, fainter glint — the light-theme bevel reads embossed on
     dark surfaces. */
  --vui-input-bevel:
    inset 3px 3px 0 rgba(0, 0, 0, 0.5),
    inset -2px -2px 0 rgba(255, 255, 255, 0.06);
  --vui-color-neutral-black: #f3eefa;
  --vui-color-neutral-900: #e9e2f2;
  --vui-color-neutral-700: #cfc6da;
  --vui-color-neutral-600: #b8aec5;
  --vui-color-neutral-550: #a298ad;
  --vui-color-neutral-500: #8d8398;
  --vui-color-neutral-400: #776e82;
  --vui-color-neutral-350: #8d8398;
  --vui-color-neutral-250: #564e62;
  --vui-color-neutral-200: #46404f;
  --vui-color-neutral-surface-warm: #262030;
  --vui-color-neutral-surface-faint: #211b29;
  --vui-color-neutral-border-warm: #443a52;
}


/* base.css */
* {
  box-sizing: border-box;
}

html {
  min-height: 100%;
}

body.vui-app {
  min-height: 100vh;
  margin: 0;
  background: var(--vui-color-bg);
  color: var(--vui-color-text);
  font-family: var(--vui-font-body);
  font-size: var(--vui-font-size-base);
  line-height: var(--vui-line-height-body);
  letter-spacing: var(--vui-letter-spacing-ui);
}

.vui-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.vui-hidden,
.hidden {
  display: none !important;
}

/* One guard for the native hidden attribute/property, not a per-class patch.
   Author display rules (flex/grid on a component class) otherwise beat the
   UA's [hidden]{display:none} regardless of specificity, silently breaking
   the DOM's native hide mechanism for any component that also sets display
   (biblioplex BEN-703/BEN-684/BEN-687 — a dismissed banner/popover/menu that
   stayed rendered). This supersedes the per-class [hidden] guards that used
   to live next to each component below. */
[hidden] {
  display: none !important;
}

.vui-stack {
  display: flex;
  flex-direction: column;
  gap: var(--vui-space-3);
}

.vui-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--vui-space-2);
}

.vui-card {
  border: 2px solid var(--vui-color-line-strong);
  border-radius: var(--vui-radius-soft);
  background: var(--vui-color-surface-raised);
  box-shadow: var(--vui-shadow-hard);
}

.vui-label {
  color: var(--vui-color-text-muted);
  font-size: var(--vui-font-size-xs);
  letter-spacing: var(--vui-label-tracking);
  text-transform: uppercase;
}

:focus-visible {
  outline: var(--vui-focus-ring);
  outline-offset: var(--vui-focus-ring-offset);
}

/* Prose links: classless anchors inside a vui app get the canonical inked
   underline (components that style their own anchors — breadcrumb, btn-link —
   carry classes and are untouched). .vui-link opts any anchor in explicitly. */
.vui-app a:not([class]),
.vui-link {
  color: var(--vui-color-text-strong);
  text-decoration: underline;
  text-decoration-color: var(--vui-color-line);
  text-decoration-thickness: 1.5px;
  text-underline-offset: 2px;
  transition: text-decoration-color var(--vui-motion-fast);
}

.vui-app a:not([class]):hover,
.vui-link:hover {
  text-decoration-color: var(--vui-color-accent);
}


/* primitives.css */
.btn {
  align-items: center;
  border: var(--vui-border-width) solid var(--vui-color-text-strong);
  border-radius: var(--vui-radius-sharp);
  box-shadow: var(--vui-shadow-firm);
  display: inline-flex;
  flex-wrap: wrap;
  gap: 2px 6px;
  justify-content: center;
  align-content: center;
  text-align: center;
  text-wrap: balance;
  min-height: var(--vui-control-height-compact);
  padding: var(--vui-control-pad-y) var(--vui-control-pad-x);
  font-size: var(--vui-font-size-sm);
  font-family: var(--vui-font-mono);
  font-weight: var(--vui-font-weight-title);
  letter-spacing: 0.04em;
  cursor: pointer;
  transition:
    transform var(--vui-motion-snap) steps(2, end),
    box-shadow var(--vui-motion-snap) steps(2, end),
    background-color var(--vui-motion-snap),
    filter var(--vui-motion-snap);
  text-transform: lowercase;
  background-color: var(--vui-color-warn);
  background-image:
    radial-gradient(rgba(21, 16, 13, 0.1) 1px, transparent 1px),
    linear-gradient(rgba(255, 245, 210, 0.08), rgba(0, 0, 0, 0.05));
  background-size:
    6px 6px,
    auto;
  color: var(--vui-color-on-warn);
}

.btn:hover:not(:disabled),
.ds-force-hover .ds-zoom-stage .btn:not(:disabled) {
  transform: translate(var(--vui-press-shift), var(--vui-press-shift));
  box-shadow: var(--vui-press-shadow);
  filter: brightness(1.05);
}

.btn:active:not(:disabled),
.ds-force-active .ds-zoom-stage .btn:not(:disabled) {
  transform: translate(4px, 4px);
  box-shadow: 0 0 0 var(--vui-color-shadow);
  filter: brightness(0.94);
}

.btn:focus-visible,
.ds-force-focus .ds-zoom-stage .btn:not(:disabled) {
  outline: var(--vui-focus-ring);
  outline-offset: var(--vui-focus-ring-offset);
}

.btn:disabled {
  background-color: var(--vui-color-line);
  border-color: var(--vui-color-line-strong);
  box-shadow: none;
  color: var(--vui-color-text-muted);
  cursor: default;
  filter: grayscale(0.25);
}

/* Optional keyboard-shortcut hint inside any button (BEN-622). One treatment
   for .btn and the fab pills: currentColor-derived so it reads on gold,
   secondary paper, and ink surfaces alike. */
.btn-shortcut,
.fab-shortcut {
  border: 1px solid color-mix(in srgb, currentColor 45%, transparent);
  border-radius: var(--vui-radius-tight);
  color: color-mix(in srgb, currentColor 85%, transparent);
  font-size: var(--vui-font-size-xs);
  font-weight: var(--vui-font-weight-body);
  letter-spacing: 0;
  line-height: 1;
  margin-left: 2px;
  min-width: 16px;
  padding: 1px 4px;
  text-align: center;
}

.btn-secondary {
  background-color: var(--vui-color-info);
  color: var(--vui-color-text-strong);
  border-color: var(--vui-color-text-strong);
}

.btn-secondary:hover:not(:disabled),
.ds-force-hover .ds-zoom-stage .btn-secondary:not(:disabled) {
  filter: brightness(1.05);
}

.btn-danger {
  background-color: var(--vui-color-danger);
  color: var(--vui-color-text-inverse);
  border-color: var(--vui-color-text-strong);
}

.btn-danger:hover:not(:disabled),
.ds-force-hover .ds-zoom-stage .btn-danger:not(:disabled) {
  color: var(--vui-color-text-inverse);
}

.btn-ink {
  background-color: var(--vui-color-text-strong);
  color: var(--vui-color-text-inverse);
}

.btn-ink:hover:not(:disabled),
.ds-force-hover .ds-zoom-stage .btn-ink:not(:disabled) {
  filter: brightness(1.25);
}

.btn-danger:disabled,
.btn-danger:disabled:hover,
.btn-secondary:disabled,
.btn-secondary:disabled:hover,
.btn-ink:disabled,
.btn-ink:disabled:hover {
  background-color: var(--vui-color-line);
  color: var(--vui-color-text-muted);
  border-color: var(--vui-color-line-strong);
  box-shadow: none;
  cursor: default;
}

.btn-link,
.btn-link-danger {
  appearance: none;
  background: transparent;
  border: none;
  padding: 0;
  font: inherit;
  font-size: var(--vui-font-size-xs);
  text-transform: lowercase;
  text-decoration: underline;
  color: var(--vui-color-text-muted);
  cursor: pointer;
}

.btn-link:hover,
.btn-link:focus-visible {
  color: var(--vui-color-text-strong);
  outline: none;
}

.btn-link-danger:hover,
.btn-link-danger:focus-visible {
  color: var(--vui-color-danger);
  outline: none;
}

.btn-link:disabled,
.btn-link-danger:disabled {
  color: var(--vui-color-line-strong);
  cursor: default;
  text-decoration: none;
}

.segmented {
  display: inline-flex;
  width: fit-content;
}

/* Quiet segmented control (BEN-607): transparent segments, grey labels,
   ink-filled active — no shadows, no press transforms. One size scale
   plus .segmented-compact for dense chrome. */
.segment-btn {
  appearance: none;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: var(--vui-border-width) solid var(--vui-color-line-strong);
  border-radius: var(--vui-radius-sharp);
  background: transparent;
  color: var(--vui-color-neutral-550);
  cursor: pointer;
  font-family: var(--vui-font-mono);
  font-weight: 400;
  font-size: var(--vui-font-size-xs);
  line-height: 1;
  min-height: var(--vui-control-height-compact);
  padding: var(--vui-control-pad-y) var(--vui-control-pad-x);
  text-decoration: none;
  text-transform: lowercase;
  transition:
    color var(--vui-motion-fast),
    background-color var(--vui-motion-fast);
}

.segment-btn + .segment-btn {
  margin-left: calc(-1 * var(--vui-border-width));
}

/* Dense variant for chrome (toolbars, page furniture, zoom/state pickers). */
.segmented-compact .segment-btn {
  font-size: var(--vui-font-size-xxs);
  min-height: 0;
  padding: 4px 8px;
}

.segment-btn:not(:first-child) {
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
}

.segment-btn:not(:last-child) {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}

.segment-btn:hover:not(.active),
.ds-force-hover .ds-zoom-stage .segment-btn:not(.active) {
  color: var(--vui-color-text-strong);
}

.segment-btn.active,
.segment-btn[aria-pressed='true'] {
  background: var(--vui-color-text-strong);
  border-color: var(--vui-color-text-strong);
  color: var(--vui-color-text-inverse);
  z-index: 1;
}

/* The ring itself comes from the global :focus-visible rule (base.css);
   segments only need to climb above their overlapped neighbors. */
.segment-btn:focus-visible {
  z-index: 3;
}

/* Tabs (BEN-557): underline-active row for view switching within a surface.
   Quiet voice like the segmented control; segmented = exclusive options,
   tabs = panes. Apps wire the switching; use aria-selected on the buttons. */
.tab-row {
  display: flex;
  gap: 2px;
  border-bottom: var(--vui-border-width) solid var(--vui-color-line);
}

.tab-btn {
  appearance: none;
  border: none;
  border-bottom: var(--vui-border-width) solid transparent;
  margin-bottom: calc(-1 * var(--vui-border-width));
  background: transparent;
  color: var(--vui-color-neutral-550);
  cursor: pointer;
  font-family: var(--vui-font-mono);
  font-weight: 400;
  font-size: var(--vui-font-size-xs);
  line-height: 1;
  padding: 7px 10px;
  text-transform: lowercase;
  transition: color var(--vui-motion-fast);
}

.tab-btn:hover {
  color: var(--vui-color-text-strong);
}

.tab-btn.active,
.tab-btn[aria-selected='true'] {
  border-bottom-color: var(--vui-color-text-strong);
  color: var(--vui-color-text-strong);
}

/* Global ring, pulled inside the row so it isn't clipped by the underline. */
.tab-btn:focus-visible {
  outline-offset: -2px;
}

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: none;
  background: transparent;
  color: var(--vui-color-neutral-350);
  cursor: pointer;
  font: inherit;
  font-size: 1.2rem;
  line-height: 1;
}

.icon-btn:hover {
  color: var(--vui-color-neutral-black);
}

/* .field-chrome (BEN-692): the field visual for elements that are not real form
   controls — e.g. a <button> popover trigger that should read as a field.
   Carries chrome only; consumers own layout, cursor, and arrow affordances. */
input[type='text'],
input[type='search'],
input[type='number'],
input[type='email'],
input[type='url'],
input[type='tel'],
input[type='password'],
input:not([type]),
textarea,
select,
.field-chrome {
  border: var(--vui-border-width) solid var(--vui-color-line-strong);
  border-radius: var(--vui-radius-sharp);
  background: var(--vui-color-surface-raised);
  color: var(--vui-color-text-strong);
  padding: 8px 14px 8px 10px;
  font-family: var(--vui-font-mono);
  box-shadow: var(--vui-input-bevel);
}

input[type='text']:focus,
input[type='search']:focus,
input[type='number']:focus,
input[type='email']:focus,
input[type='url']:focus,
input[type='tel']:focus,
input[type='password']:focus,
input:not([type]):focus,
textarea:focus,
select:focus,
.field-chrome:focus,
.field-chrome:hover {
  outline: none;
  border-color: var(--vui-color-line-focus);
}

textarea {
  resize: vertical;
}

/* Field validation (BEN-557): flag the control with aria-invalid="true"
   (or .field-invalid where aria doesn't fit) and follow it with a
   .field-error line inside the field row. */
input[aria-invalid='true'],
textarea[aria-invalid='true'],
select[aria-invalid='true'],
.field-invalid {
  border-color: var(--vui-color-danger);
}

input[aria-invalid='true']:focus,
textarea[aria-invalid='true']:focus,
select[aria-invalid='true']:focus,
.field-invalid:focus {
  border-color: var(--vui-color-danger);
  outline: none;
}

.field-error {
  color: var(--vui-color-danger);
  font-family: var(--vui-font-mono);
  font-size: var(--vui-font-size-xs);
  font-weight: var(--vui-font-weight-body);
  letter-spacing: 0;
  line-height: 1.35;
  text-transform: lowercase;
}

input[type='checkbox']:not(.switch-input),
input[type='radio'] {
  appearance: none;
  width: 18px;
  height: 18px;
  flex: none;
  margin: 0;
  border: var(--vui-border-width) solid var(--vui-color-line-strong);
  border-radius: var(--vui-radius-tight);
  background: var(--vui-color-surface-raised);
  cursor: pointer;
  vertical-align: middle;
}

input[type='radio'] {
  border-radius: var(--vui-radius-pill);
}

input[type='checkbox']:not(.switch-input):checked,
input[type='radio']:checked {
  background: var(--vui-color-accent);
  box-shadow: inset 0 0 0 3px var(--vui-color-surface-raised);
}

input[type='checkbox']:not(.switch-input):focus-visible,
input[type='radio']:focus-visible,
.switch-input:focus-visible + .switch-track {
  outline: var(--vui-focus-ring);
  outline-offset: var(--vui-focus-ring-offset);
}

/* Switch: <label class="switch"><input type="checkbox" class="switch-input" /><span class="switch-track"></span>label</label> */
.switch {
  display: inline-flex;
  align-items: center;
  gap: var(--vui-space-2);
  cursor: pointer;
}

.switch-input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.switch-track {
  position: relative;
  width: 40px;
  height: 22px;
  flex: none;
  border: var(--vui-border-width) solid var(--vui-color-line-strong);
  border-radius: var(--vui-radius-pill);
  background: var(--vui-color-surface-sunken);
  transition: background var(--vui-motion-fast);
}

.switch-track::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 3px;
  width: 10px;
  height: 10px;
  border-radius: var(--vui-radius-pill);
  background: var(--vui-color-text-strong);
  transform: translateY(-50%);
  transition: transform var(--vui-motion-fast);
}

.switch-input:checked + .switch-track {
  background: var(--vui-color-accent);
}

.switch-input:checked + .switch-track::before {
  background: var(--vui-color-text-inverse);
  transform: translate(18px, -50%);
}

input[type='range'] {
  appearance: none;
  width: 160px;
  height: 18px;
  margin: 0;
  background: transparent;
  cursor: pointer;
}

input[type='range']::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: var(--vui-radius-pill);
  background: var(--vui-color-line);
}

input[type='range']::-moz-range-track {
  height: 4px;
  border-radius: var(--vui-radius-pill);
  background: var(--vui-color-line);
}

input[type='range']::-webkit-slider-thumb {
  appearance: none;
  width: 16px;
  height: 16px;
  margin-top: -6px;
  border: var(--vui-border-width) solid var(--vui-color-line-strong);
  border-radius: var(--vui-radius-tight);
  background: var(--vui-color-accent);
  box-shadow: var(--vui-shadow-hard-sm);
}

input[type='range']::-moz-range-thumb {
  width: 10px;
  height: 10px;
  border: var(--vui-border-width) solid var(--vui-color-line-strong);
  border-radius: var(--vui-radius-tight);
  background: var(--vui-color-accent);
  box-shadow: var(--vui-shadow-hard-sm);
}

input[type='range']:focus-visible {
  outline: var(--vui-focus-ring);
  outline-offset: var(--vui-focus-ring-offset);
}

.field-row {
  display: flex;
  flex-direction: column;
  gap: 4px;
  color: var(--vui-color-text-muted);
  font-size: var(--vui-font-size-xs);
  letter-spacing: var(--vui-label-tracking);
  text-transform: uppercase;
}

.field-row > input,
.field-row > textarea,
.field-row > select {
  letter-spacing: var(--vui-letter-spacing-ui);
  text-transform: none;
}

/* Edge resize — drag-only panel resizing (js/edgeResize.js). The divider is a
   thin hit strip on a panel edge; the grip is the dotted affordance marking a
   draggable edge (shown on collapsed edges and drag handles). */
.vui-resize-divider {
  position: absolute;
  touch-action: none;
  user-select: none;
  z-index: 6;
}
.vui-resize-divider-x {
  cursor: col-resize;
  top: 0;
  bottom: 0;
  width: 8px;
}
.vui-resize-divider-y {
  cursor: row-resize;
  left: 0;
  right: 0;
  height: 8px;
}
.vui-resize-divider::after {
  content: '';
  position: absolute;
  inset: 0;
  margin: auto;
  background: transparent;
  transition: background var(--vui-motion-fast) ease;
}
.vui-resize-divider-x::after {
  width: var(--vui-border-width);
}
.vui-resize-divider-y::after {
  height: var(--vui-border-width);
}
.vui-resize-divider:hover::after,
.vui-resize-divider:focus-visible::after {
  background: var(--vui-color-line-focus);
}
.vui-resize-divider:focus-visible {
  outline: var(--vui-focus-ring);
  outline-offset: -2px;
}

.vui-resize-grip {
  display: inline-block;
  background: repeating-linear-gradient(
    var(--vui-grip-angle, 0deg),
    var(--vui-grip-ink, var(--vui-color-text-strong)) 0 1.5px,
    transparent 1.5px 4px
  );
  opacity: 0.5;
  transition:
    opacity var(--vui-motion-fast) ease,
    background var(--vui-motion-fast) ease;
}
.vui-resize-grip-x {
  --vui-grip-angle: 90deg;
  width: 5px;
  height: 28px;
}
.vui-resize-grip-y {
  --vui-grip-angle: 0deg;
  width: 28px;
  height: 5px;
}
/* Hovering or focusing any divider lights its grip — the drag invitation. */
.vui-resize-divider:hover .vui-resize-grip,
.vui-resize-divider:focus-visible .vui-resize-grip,
*:hover > .vui-resize-grip {
  --vui-grip-ink: var(--vui-color-line-focus);
  opacity: 0.9;
}


/* overlays.css */
.ui-modal {
  align-items: center;
  background: var(--vui-modal-backdrop);
  display: none;
  inset: 0;
  justify-content: center;
  position: fixed;
  z-index: var(--vui-z-modal);
}

.ui-modal.visible,
.ui-modal.open {
  display: flex;
}

.ui-modal-backdrop {
  align-items: center;
  background: var(--vui-modal-backdrop);
  display: flex;
  inset: 0;
  justify-content: center;
  position: fixed;
  z-index: var(--vui-z-modal);
}

.ui-modal-card {
  background: var(--vui-modal-card-bg);
  border: var(--vui-modal-card-border);
  border-radius: var(--vui-modal-card-radius);
  box-shadow: var(--vui-modal-card-shadow);
  display: flex;
  flex-direction: column;
  max-height: var(--vui-modal-card-max-height);
  min-height: var(--vui-modal-card-min-height);
  min-width: var(--vui-modal-card-min-width);
  position: relative;
  overflow: visible;
  transform: translate(var(--vui-modal-x, 0), var(--vui-modal-y, 0));
  will-change: transform, width, height;
}

.ui-modal-card[data-vui-modal-interactive='true'] .ui-modal-head {
  cursor: move;
  touch-action: none;
}

.ui-modal-card.is-vui-modal-dragging,
.ui-modal-card.is-vui-modal-resizing {
  user-select: none;
}

.ui-modal-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: var(--vui-modal-body-padding);
}

/* ONE modal head fleet-wide: the ink band. The BEN-605 two-role split
   (parchment for centered, band for draggable) is retired — every panel
   wears the band whether it drags or not, so the two looks can't drift. */
.ui-modal-head {
  align-items: center;
  background: var(--vui-color-text);
  border-bottom: none;
  color: var(--vui-color-text-inverse);
  display: flex;
  flex: 0 0 auto;
  gap: 12px;
  justify-content: space-between;
  padding: var(--vui-modal-head-padding);
  user-select: none;
}

.ui-modal-title {
  font-family: var(--vui-font-body);
  font-size: var(--vui-font-size-md);
  font-weight: 700;
  letter-spacing: 0;
  line-height: 1.2;
  margin: 0;
}

.ui-modal-actions {
  align-items: center;
  border-top: var(--vui-border-width) solid var(--vui-color-line);
  display: flex;
  flex: 0 0 auto;
  gap: var(--vui-modal-actions-gap);
  justify-content: flex-end;
  padding: var(--vui-modal-actions-padding);
}

.vui-modal-resize-handle {
  position: absolute;
  z-index: 4;
  touch-action: none;
}

.vui-modal-resize-left {
  bottom: var(--vui-modal-resize-corner-size);
  cursor: ew-resize;
  left: calc(-1 * var(--vui-modal-resize-edge-size) / 2);
  top: 0;
  width: var(--vui-modal-resize-edge-size);
}

.vui-modal-resize-bottom {
  bottom: calc(-1 * var(--vui-modal-resize-edge-size) / 2);
  cursor: ns-resize;
  height: var(--vui-modal-resize-edge-size);
  left: var(--vui-modal-resize-corner-size);
  right: 0;
}

.vui-modal-resize-bottom-left {
  bottom: calc(-1 * var(--vui-modal-resize-edge-size) / 2);
  cursor: nesw-resize;
  height: var(--vui-modal-resize-corner-size);
  left: calc(-1 * var(--vui-modal-resize-edge-size) / 2);
  width: var(--vui-modal-resize-corner-size);
}

/* Corner grip — three hairline diagonals. The ONE bottom-left resize
   affordance, shared by modal cards and the feedback widget. */
.vui-modal-resize-bottom-left::before,
.feedback-capture-resize-bottom-left::before {
  content: '';
  position: absolute;
  bottom: 2px;
  left: 2px;
  width: 14px;
  height: 14px;
  background: repeating-linear-gradient(
    45deg,
    var(--vui-color-line-strong) 0 1px,
    transparent 1px 5px
  );
  clip-path: polygon(0 0, 0 100%, 100% 100%);
  opacity: 0.55;
  pointer-events: none;
  transition: opacity var(--vui-motion-fast) ease;
}

.vui-modal-resize-handle:hover::before,
.ui-modal-card.is-vui-modal-resizing .vui-modal-resize-bottom-left::before,
.feedback-capture-resize-handle:hover::before,
.feedback-capture-widget.is-resizing .feedback-capture-resize-bottom-left::before {
  opacity: 0.8;
}

/* The one dismiss affordance (BEN-604): a quiet grey × — transparent, no
   border, no shadow. The class name predates the redesign and stays so
   consumer markup doesn't churn. */
.rune-close {
  appearance: none;
  position: absolute;
  top: var(--vui-modal-close-offset);
  right: var(--vui-modal-close-offset);
  z-index: 5;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  flex: 0 0 auto;
  width: var(--vui-modal-close-size);
  height: var(--vui-modal-close-size);
  padding: 0;
  border: none;
  background: transparent;
  color: var(--vui-color-neutral-350);
  font-family: var(--vui-font-mono);
  font-size: var(--vui-font-size-lg);
  font-weight: var(--vui-font-weight-title);
  line-height: 1;
  cursor: pointer;
  transition: color var(--vui-motion-fast);
}

.rune-close:hover {
  color: var(--vui-color-neutral-black);
}

.rune-close:focus-visible {
  outline: var(--vui-focus-ring);
  outline-offset: var(--vui-focus-ring-offset);
}

/* .ui-modal-head-drag is a compat alias from the retired two-head era — the
   band IS the head now. .feedback-capture-head wears it natively; both are
   actually draggable, so they keep the move cursor unconditionally. */
.ui-modal-head-drag,
.feedback-capture-head {
  align-items: center;
  background: var(--vui-color-text);
  border-bottom: none;
  color: var(--vui-color-text-inverse);
  cursor: move;
  display: flex;
  justify-content: space-between;
  user-select: none;
}

.feedback-capture-title {
  font-family: var(--vui-font-body);
  font-size: var(--vui-font-size-md);
  font-weight: 700;
  letter-spacing: 0;
  line-height: 1.2;
  margin: 0;
}

/* On the ink band the quiet × sits in-flow and flips to on-dark colors. */
.ui-modal-head .rune-close,
.ui-modal-head-drag .rune-close,
.feedback-capture-head .rune-close {
  position: static;
  color: var(--vui-color-on-dark-text-soft);
}

.ui-modal-head .rune-close:hover,
.ui-modal-head-drag .rune-close:hover,
.feedback-capture-head .rune-close:hover {
  color: var(--vui-color-text-inverse);
}

/* Card-corner markup (× as a direct card child) still lands on the band —
   same on-dark ink, keeps its absolute corner position. */
.ui-modal-card > .rune-close {
  color: var(--vui-color-on-dark-text-soft);
}

.ui-modal-card > .rune-close:hover {
  color: var(--vui-color-text-inverse);
}

.ui-popover {
  position: absolute;
  z-index: var(--vui-z-flyout);
  min-width: 180px;
  border: var(--vui-border-width) solid var(--vui-color-text-strong);
  border-radius: var(--vui-radius-soft);
  background: var(--vui-color-surface-raised);
  color: var(--vui-color-text);
  box-shadow: var(--vui-shadow-popover);
  padding: var(--vui-space-2);
}

/* [hidden] handled globally in base.css. */

.floating-menu {
  display: flex;
  flex-direction: column;
  gap: var(--vui-space-1);
  min-width: 180px;
}

.floating-menu-item {
  appearance: none;
  border: 0;
  border-radius: var(--vui-radius-sharp);
  background: transparent;
  color: var(--vui-color-text);
  cursor: pointer;
  font: inherit;
  padding: var(--vui-space-2);
  text-align: left;
}

.floating-menu-item:hover,
.floating-menu-item.is-active,
.floating-menu-item[aria-selected='true'] {
  background: var(--vui-color-accent-soft);
}

.combobox {
  position: relative;
  display: inline-block;
}

.combobox-list {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  min-width: 100%;
  max-height: 260px;
  overflow-y: auto;
  z-index: var(--vui-z-flyout);
  display: flex;
  flex-direction: column;
  gap: var(--vui-space-1);
  padding: var(--vui-space-1);
  border: var(--vui-border-width) solid var(--vui-color-text-strong);
  border-radius: var(--vui-radius-sharp);
  background: var(--vui-color-surface-raised);
  box-shadow: var(--vui-shadow-popover);
}

/* [hidden] handled globally in base.css. */

.combobox-option {
  appearance: none;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--vui-space-3);
  border: 0;
  border-radius: var(--vui-radius-tight);
  background: transparent;
  color: var(--vui-color-text);
  cursor: pointer;
  font: inherit;
  font-family: var(--vui-font-mono);
  font-size: var(--vui-font-size-sm);
  padding: var(--vui-space-1) var(--vui-space-2);
  text-align: left;
  white-space: nowrap;
}

.combobox-option:hover,
.combobox-option.is-active {
  background: var(--vui-color-accent-soft);
}

.combobox-option-hint {
  color: var(--vui-color-text-muted);
  font-size: var(--vui-font-size-xs);
}

/* Feedback capture — shared file-it-to-Linear widget (see js/feedbackCapture.js).
   Upstreamed from biblioplex; .rune-close styling comes from the modal family. */
.feedback-annotation-canvas {
  inset: 0;
  pointer-events: none;
  position: fixed;
  touch-action: none;
  z-index: var(--vui-z-feedback-canvas);
}
body.feedback-capture-open.feedback-capture-draw-mode .feedback-annotation-canvas {
  cursor: crosshair;
  display: block;
  pointer-events: auto;
}
.feedback-capture-widget {
  --feedback-capture-width: 360px;
  --feedback-capture-height: 360px;
  /* left/top are set at runtime when the widget is dragged (.is-positioned). */
  --feedback-capture-left: 12px;
  --feedback-capture-top: 12px;
  /* frame tokens shared with .ui-modal-card so the widget reads as the same
     modal family (BEN-551/620) */
  background: var(--vui-color-surface);
  border: var(--vui-modal-card-border);
  border-radius: var(--vui-modal-card-radius);
  bottom: 148px;
  box-shadow: var(--vui-modal-card-shadow);
  display: flex;
  flex-direction: column;
  height: min(var(--feedback-capture-height), calc(100dvh - 24px));
  max-height: calc(100dvh - 24px);
  max-width: calc(100vw - 24px);
  min-height: min(280px, calc(100dvh - 24px));
  min-width: min(320px, calc(100vw - 24px));
  /* the rounded clip lives on the inner head (top) and body (bottom). */
  overflow: visible;
  position: fixed;
  right: 16px;
  width: min(var(--feedback-capture-width), calc(100vw - 24px));
  z-index: var(--vui-z-feedback);
}
.feedback-capture-widget.is-positioned {
  bottom: auto;
  left: var(--feedback-capture-left);
  right: auto;
  top: var(--feedback-capture-top);
}
.feedback-capture-widget.is-dragging,
.feedback-capture-widget.is-resizing {
  user-select: none;
}
/* [hidden] handled globally in base.css. */
body.feedback-capture-capturing .feedback-capture-widget {
  display: none;
}
/* Band colors/cursor come from the shared drag-band rules above; the inner
   clip radius follows the modal-card frame. */
.feedback-capture-head {
  border-radius: calc(var(--vui-modal-card-radius) - var(--vui-border-width))
    calc(var(--vui-modal-card-radius) - var(--vui-border-width)) 0 0;
  gap: 12px;
  min-height: 40px;
  padding: var(--vui-modal-head-padding);
  touch-action: none;
}
.feedback-capture-body {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: 10px;
  min-height: 0;
  overflow: auto;
  padding: 10px;
  border-radius: 0 0 calc(var(--vui-modal-card-radius) - var(--vui-border-width))
    calc(var(--vui-modal-card-radius) - var(--vui-border-width));
}
.feedback-annotation-tools {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.feedback-annotation-tool {
  background: var(--vui-color-surface);
  border: var(--vui-border-width) solid var(--vui-color-line-strong);
  border-radius: var(--vui-radius-sharp);
  color: var(--vui-color-text);
  cursor: pointer;
  font: inherit;
  font-size: var(--vui-font-size-xs);
  line-height: 1;
  padding: 6px 8px;
}
.feedback-annotation-tool.active,
.feedback-annotation-tool[aria-pressed='true'] {
  background: var(--vui-color-text);
  border-color: var(--vui-color-text);
  color: var(--vui-color-text-inverse);
}
.feedback-capture-label {
  color: var(--vui-color-text-muted);
  font-size: var(--vui-font-size-xs);
}
.feedback-capture-note {
  background: var(--vui-color-surface);
  border: var(--vui-border-width) solid var(--vui-color-line-strong);
  border-radius: var(--vui-radius-sharp);
  box-sizing: border-box;
  color: var(--vui-color-text-strong);
  flex: 1 1 96px;
  font: inherit;
  line-height: 1.35;
  min-height: 88px;
  padding: 8px;
  resize: none;
  width: 100%;
}
.feedback-capture-details {
  border: var(--vui-border-width) solid var(--vui-color-line);
  flex: 0 0 auto;
  padding: 8px;
}
.feedback-capture-details summary {
  cursor: pointer;
}
.feedback-capture-details pre {
  font-family: var(--vui-font-mono);
  font-size: var(--vui-font-size-xs);
  line-height: 1.35;
  margin: 8px 0 0;
  white-space: pre-wrap;
}
.feedback-capture-status {
  color: var(--vui-color-text-muted);
  min-height: 1em;
}
.feedback-capture-status a {
  color: var(--vui-color-text-strong);
}
.feedback-capture-actions {
  border-top: var(--vui-border-width) solid var(--vui-color-line);
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  padding: 10px;
}
.feedback-capture-resize-handle {
  position: absolute;
  touch-action: none;
  z-index: 3;
}
.feedback-capture-resize-left {
  bottom: 12px;
  cursor: ew-resize;
  left: 0;
  top: 40px;
  width: 8px;
}
.feedback-capture-resize-right {
  bottom: 12px;
  cursor: ew-resize;
  right: 0;
  top: 40px;
  width: 8px;
}
.feedback-capture-resize-bottom {
  bottom: 0;
  cursor: ns-resize;
  height: 8px;
  left: 12px;
  right: 12px;
}
.feedback-capture-resize-bottom-left {
  bottom: 0;
  cursor: nesw-resize;
  height: 16px;
  left: 0;
  width: 16px;
}
.feedback-capture-resize-bottom-right {
  bottom: 0;
  cursor: nwse-resize;
  height: 16px;
  right: 0;
  width: 16px;
}
/* Floating action buttons — solid ink pills, upstreamed from biblioplex.
   Apps stack several in a fixed .fab-cluster bottom-right; the feedback
   widget mounts its own single-button cluster. Design pass (BEN-544): the
   family joins the hard-shadow press language — soft ledger shadow at rest,
   pressing flat on hover — and the shortcut chip picks up the tight radius. */
.fab-cluster {
  position: fixed;
  right: var(--vui-edge-margin);
  bottom: var(--vui-fab-cluster-bottom, var(--vui-edge-margin));
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 6px;
  z-index: var(--vui-z-fab);
}
.fab-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 12px;
  background: var(--vui-color-text-strong);
  color: var(--vui-color-text-inverse);
  border: var(--vui-border-width) solid var(--vui-color-text-strong);
  border-radius: var(--vui-radius-sharp);
  font-family: inherit;
  font-size: var(--vui-font-size-sm);
  cursor: pointer;
  box-shadow: var(--vui-shadow-soft);
  text-transform: lowercase;
  text-decoration: none;
  letter-spacing: 0;
}
.fab-btn:hover {
  background: var(--vui-color-btn-primary-hover);
  box-shadow: var(--vui-shadow-subtle);
  transform: translate(var(--vui-press-shift), var(--vui-press-shift));
}
/* Focus ring comes from the global :focus-visible rule. */
.fab-glyph {
  font-family: var(--vui-font-body);
  font-size: var(--vui-font-size-base);
  line-height: 1;
}
.fab-label {
  white-space: nowrap;
}
/* .fab-shortcut shares the .btn-shortcut rule in primitives.css (BEN-622). */


/* components.css */
/* One chip. Tags, statuses, filters, location pills — every .ui-chip surface
   wears the same sticker: sharp corners, hairline border, hard shadow, mono
   ink. Apps tint per-domain through the --ui-chip-* hooks (inline or via a
   domain class) instead of forking variant treatments. */
.ui-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  max-width: 100%;
  min-width: 0;
  padding: 1px 4px 1px 5px;
  border: 1px solid var(--ui-chip-border, var(--vui-color-line));
  border-radius: var(--vui-radius-sharp);
  background: var(--ui-chip-bg, var(--vui-color-surface-sunken));
  color: var(--ui-chip-ink, var(--vui-color-text-strong));
  box-shadow: 2px 2px 0 var(--vui-color-text-strong);
  font-family: var(--vui-font-mono);
  font-size: var(--vui-font-size-xxs);
  font-weight: var(--vui-font-weight-title);
  line-height: 1.4;
  white-space: nowrap;
  vertical-align: middle;
}

.ui-chip-label {
  text-transform: lowercase;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

/* Emoji/icon prefix. A bare unicode emoji sits off the text baseline inside a
   flex item; flex-center it on its own line box so it's optically centered
   with the label, and never let it shrink. */
.ui-chip-emoji {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  line-height: 1;
  font-size: calc(var(--vui-font-size-sm) - 1px);
}

/* Segmented delete affordance: a distinct full-height "x segment" inside the
   pill, split from the label by a divider in the pill's own border color, with
   its own padded hit area + hover highlight. The negative vertical margins
   bleed the segment to the pill's top/bottom border (pills use 1px vertical
   padding) so the divider reads as full-height. */
.ui-chip-remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  align-self: stretch;
  flex-shrink: 0;
  box-sizing: border-box;
  margin: -2px -5px -2px 1px;
  padding: 0 4px;
  min-width: 15px;
  border: 0;
  border-left: var(--vui-border-width) solid;
  border-color: inherit;
  border-top-right-radius: var(--vui-radius-sharp);
  border-bottom-right-radius: var(--vui-radius-sharp);
  background: transparent;
  cursor: pointer;
  font: inherit;
  font-size: var(--vui-font-size-md);
  line-height: 1;
  color: var(--vui-color-text-muted);
}

.ui-chip-remove:hover,
.ui-chip-remove:focus-visible {
  color: var(--vui-color-text-strong);
  background: var(--vui-color-surface-hover);
  outline: none;
}

.status-state {
  display: inline-flex;
  align-items: center;
  gap: var(--vui-space-1);
  min-height: 22px;
  border: 1px solid var(--vui-status-neutral-border);
  border-radius: var(--vui-radius-pill);
  background: var(--vui-status-neutral-bg);
  color: var(--vui-status-neutral-text);
  font-size: var(--vui-font-size-xs);
  font-family: var(--vui-font-mono);
  font-weight: 500;
  letter-spacing: 0.02em;
  line-height: 1.4;
  padding: 2px 8px;
  text-transform: lowercase;
}

.status-state-label,
.status-state-icon {
  font-weight: 500;
}

.status-state-success {
  border-color: var(--vui-status-success-border);
  background: var(--vui-status-success-bg);
  color: var(--vui-status-success-text);
}

.status-state-warn {
  border-color: var(--vui-status-warn-border);
  background: var(--vui-status-warn-bg);
  color: var(--vui-status-warn-text);
}

.status-state-danger {
  border-color: var(--vui-status-danger-border);
  background: var(--vui-status-danger-bg);
  color: var(--vui-status-danger-text);
}

.status-state-empty,
.status-state-loading,
.status-state-compact {
  border-color: var(--vui-status-neutral-border);
  background: var(--vui-status-neutral-bg);
  color: var(--vui-status-neutral-text);
}

.status-state-inline-error,
.status-state-blocking-error,
.status-state-retryable-error {
  border-color: var(--vui-status-danger-border);
  background: var(--vui-status-danger-bg);
  color: var(--vui-status-danger-text);
}

.status-state-message,
.status-state-detail {
  min-width: 0;
}

.status-state-detail {
  color: var(--vui-color-text-muted);
}

.status-state-retry {
  margin-left: var(--vui-space-1);
}

.loading-spinner {
  width: 0.8em;
  height: 0.8em;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: var(--vui-radius-pill);
  animation: vui-spin var(--vui-motion-slow) linear infinite;
}

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

/* [hidden] handled globally in base.css. */
.banner {
  align-items: center;
  background: var(--vui-color-surface-sunken);
  border-bottom: var(--vui-border-width) solid var(--vui-color-text-strong);
  color: var(--vui-color-text-strong);
  display: flex;
  font-family: var(--vui-font-mono);
  font-size: var(--vui-font-size-sm);
  gap: var(--vui-space-3);
  padding: var(--vui-space-2) var(--vui-space-4);
  position: relative;
  width: 100%;
  z-index: var(--vui-z-toast);
}

.banner-message {
  color: var(--vui-color-text-strong);
}

.banner-actions {
  display: flex;
  align-items: center;
  gap: var(--vui-space-1);
}

.banner-dismiss {
  margin-left: auto;
}

/* The .fab-* family lives in overlays.css (ink pills, upstreamed from
   biblioplex — BEN-543). An older accent-colored variant that used to live
   here was never consumed and is gone. */

.toast-stack {
  position: fixed;
  left: 50%;
  bottom: var(--vui-space-4);
  transform: translateX(-50%);
  z-index: var(--vui-z-toast);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--vui-space-2);
  pointer-events: none;
}

.toast {
  pointer-events: auto;
  display: inline-flex;
  align-items: center;
  gap: var(--vui-space-3);
  max-width: min(420px, calc(100vw - 2 * var(--vui-edge-margin)));
  border: var(--vui-border-width) solid var(--vui-color-line-strong);
  border-radius: var(--vui-radius-sharp);
  background: var(--vui-color-surface-raised);
  color: var(--vui-color-text);
  box-shadow: var(--vui-shadow-firm);
  font-family: var(--vui-font-mono);
  font-size: var(--vui-font-size-sm);
  padding: var(--vui-space-2) var(--vui-space-3);
  transition:
    opacity var(--vui-motion-base),
    transform var(--vui-motion-base);
}

.toast.is-leaving {
  opacity: 0;
  transform: translateY(4px);
}

.toast-success {
  border-color: var(--vui-color-success-line);
}

.toast-warn {
  border-color: var(--vui-color-warn-line);
}

.toast-danger {
  border-color: var(--vui-color-danger-line);
}

.toast-message {
  min-width: 0;
}

.toast-dismiss {
  flex: none;
}

@media (prefers-reduced-motion: reduce) {
  .toast {
    transition: none;
  }
}

/* CSS-first tooltip: put .tooltip-host + data-tooltip on any element.
   Night-blue hard-shadow bubble, upstreamed from biblioplex (BEN-606).
   .tooltip-term adds the dotted-underline inline-glossary treatment.
   Policy (BEN-636): labeled buttons don't get tooltips — their label is the
   explanation, and a .btn-shortcut chip carries any extra hint. Legit hosts
   are unlabeled icon buttons and inline glossary terms. */
.tooltip-host {
  position: relative;
}

.tooltip-host::after {
  content: attr(data-tooltip);
  position: absolute;
  bottom: calc(100% + 10px);
  left: 50%;
  transform: translateX(-50%);
  width: max-content;
  max-width: 240px;
  background: var(--vui-color-accent-strong);
  color: var(--vui-color-text-inverse);
  border: var(--vui-border-width) solid var(--vui-color-text-strong);
  box-shadow: var(--vui-shadow-hard-sm);
  font-family: var(--vui-font-mono);
  font-size: var(--vui-font-size-xs);
  font-weight: var(--vui-font-weight-body);
  line-height: 1.35;
  text-transform: lowercase;
  padding: 6px 9px;
  border-radius: var(--vui-radius-sharp);
  white-space: normal;
  z-index: var(--vui-z-flyout);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity var(--vui-motion-fast);
}

.tooltip-host:hover::after,
.tooltip-host:focus-visible::after {
  opacity: 1;
  visibility: visible;
}

.tooltip-term {
  text-decoration: underline dotted;
  text-underline-offset: 2px;
  cursor: help;
}

.vui-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--vui-font-size-sm);
}

.vui-table th {
  font-family: var(--vui-font-mono);
  font-size: var(--vui-font-size-xs);
  font-weight: var(--vui-font-weight-title);
  letter-spacing: var(--vui-label-tracking);
  text-transform: lowercase;
  text-align: left;
  color: var(--vui-color-text-muted);
  border-bottom: var(--vui-border-width) solid var(--vui-color-line-strong);
  padding: var(--vui-space-2) var(--vui-space-3);
}

.vui-table td {
  border-bottom: 1px solid var(--vui-color-line);
  padding: var(--vui-space-2) var(--vui-space-3);
  vertical-align: middle;
}

.vui-table tbody tr:hover {
  background: var(--vui-color-surface-hover);
}

.vui-table-compact th,
.vui-table-compact td {
  padding: var(--vui-space-1) var(--vui-space-2);
}

/* Loading + empty vocabulary. */
.skeleton {
  display: block;
  border-radius: var(--vui-radius-tight);
  background: var(--vui-color-surface-sunken);
  animation: vui-skeleton-pulse 1.2s ease-in-out infinite;
}

.skeleton-line {
  height: 0.9em;
  margin: 0.25em 0;
}

@keyframes vui-skeleton-pulse {
  0%,
  100% {
    opacity: 0.55;
  }

  50% {
    opacity: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .skeleton {
    animation: none;
  }
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--vui-space-2);
  padding: var(--vui-space-5) var(--vui-space-4);
  border: var(--vui-border-width) dashed var(--vui-color-line);
  border-radius: var(--vui-radius-soft);
  color: var(--vui-color-text-muted);
  font-family: var(--vui-font-mono);
  font-size: var(--vui-font-size-sm);
  text-align: center;
}

.empty-state-glyph {
  font-size: var(--vui-font-size-jumbo);
  line-height: 1;
  opacity: 0.6;
}

/* Pagination (BEN-557): quiet page stepper in the segmented voice —
   transparent buttons, grey labels, ink-filled current page. Mark the
   current page with aria-current="page"; use paginationRange() from
   pagination.js to build the number list. */
.pager {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  font-family: var(--vui-font-mono);
  font-size: var(--vui-font-size-xs);
}

.pager-btn {
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  min-height: 24px;
  padding: 0 5px;
  border: none;
  border-radius: var(--vui-radius-tight);
  background: transparent;
  color: var(--vui-color-neutral-550);
  cursor: pointer;
  font: inherit;
  line-height: 1;
  text-transform: lowercase;
  transition: color var(--vui-motion-fast);
}

.pager-btn:hover:not(:disabled) {
  color: var(--vui-color-text-strong);
}

.pager-btn[aria-current='page'] {
  background: var(--vui-color-text-strong);
  color: var(--vui-color-text-inverse);
}

.pager-btn:disabled {
  color: var(--vui-color-line);
  cursor: default;
}

/* Global ring, tighter offset for the dense row. */
.pager-btn:focus-visible {
  outline-offset: 1px;
}

.pager-gap {
  color: var(--vui-color-text-muted);
  padding: 0 2px;
  user-select: none;
}

/* Card in a plastic sleeve (BEN-550, iterated; BEN-637 made it the ONE sleeve):
   a penny-sleeved card inside a rigid toploader shell — visible shell ring,
   tape across the opening, optional price sticker. Size via --card-sleeve-width;
   every ornament (ring, specks, tape) scales with it so the same component
   works from a 76px deck-home thumbnail to a 340px hover preview.
   The decorative rgba layers are deliberate. Markup: .card-sleeve >
   .card-sleeve-slot (or an <img>), plus an optional
   <span class="card-sleeve-price">$ 4.20</span> (the space sets the price-gun
   gap; the consumer formats the string). */
.card-sleeve {
  --card-sleeve-width: 120px;
  position: relative;
  box-sizing: border-box;
  width: var(--card-sleeve-width);
  aspect-ratio: 63 / 88;
  /* extra headroom at the top: the shell opening */
  padding: calc(var(--card-sleeve-width) * 0.08) calc(var(--card-sleeve-width) * 0.055)
    calc(var(--card-sleeve-width) * 0.055);
  border: 1px solid rgba(113, 99, 79, 0.38);
  border-radius: var(--vui-radius-tight);
  background:
    linear-gradient(112deg, rgba(255, 255, 255, 0.42) 0 18%, rgba(255, 255, 255, 0.12) 19% 40%, transparent 41%),
    linear-gradient(180deg, rgba(222, 214, 198, 0.5), rgba(172, 158, 136, 0.4));
  /* the inset white ring is the hard shell's inner edge. Cards lie FLAT on
     the page — no drop shadow, ever (the ring/tape/sticker are drawn-on
     detail, not elevation). */
  box-shadow: inset 0 0 0 max(3px, calc(var(--card-sleeve-width) * 0.02)) rgba(255, 255, 255, 0.3);
}

.card-sleeve::before {
  /* penny-sleeve plastic: diagonal sheen + dust specks */
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  border-radius: inherit;
  background:
    linear-gradient(115deg, transparent 30%, rgba(255, 255, 255, 0.26) 36%, transparent 44%),
    radial-gradient(
      circle at 18% 82%,
      rgba(66, 50, 38, 0.14) 0 calc(var(--card-sleeve-width) * 0.0125),
      transparent calc(var(--card-sleeve-width) * 0.0165)
    ),
    radial-gradient(
      circle at 86% 14%,
      rgba(255, 255, 255, 0.5) 0 calc(var(--card-sleeve-width) * 0.0165),
      transparent calc(var(--card-sleeve-width) * 0.0215)
    );
  pointer-events: none;
}

.card-sleeve::after {
  /* tape sealing the shell opening */
  content: '';
  position: absolute;
  z-index: 3;
  top: calc(var(--card-sleeve-width) * 0.025);
  left: calc(var(--card-sleeve-width) * -0.05);
  width: calc(100% + var(--card-sleeve-width) * 0.1);
  height: calc(var(--card-sleeve-width) * 0.12);
  transform: rotate(-2deg);
  background: rgba(236, 230, 214, 0.55);
  border-top: 1px solid rgba(255, 255, 255, 0.5);
  border-bottom: 1px solid rgba(123, 101, 76, 0.25);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
  pointer-events: none;
}

/* A real card image in the sleeve: slightly muted, like print under plastic. */
.card-sleeve > img {
  display: block;
  position: relative;
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: var(--vui-radius-card);
  filter: saturate(0.9) contrast(0.96);
}

.card-sleeve-slot {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  border: var(--vui-border-width) dashed var(--vui-color-line);
  border-radius: var(--vui-radius-card);
  background: var(--vui-color-surface-placeholder);
  background-image: radial-gradient(rgba(21, 16, 13, 0.08) 1px, transparent 1px);
  background-size: 6px 6px;
  color: var(--vui-color-text-muted);
  font-family: var(--vui-font-mono);
  font-size: var(--vui-font-size-xxs);
  text-transform: lowercase;
}

/* Embedded subset (just "$ , . 0-9" + space) of Impact Label Reversed by Tension
   Type — a free label-gun typeface (donationware: mtension@gmail.com; full
   licence at src/assets/fonts/Impact-Label-Licence.txt). Subsetting + web
   embedding are expressly permitted by that licence. */
@font-face {
  font-family: 'vui-price-label';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('data:font/woff2;base64,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') format('woff2');
}

/* Price sticker — a small die-cut pricing-gun label slapped on the sleeve.
   Real ones are little: under a third of the card's width, tucked in the
   upper-right over the art. The paper (::before) is the warm off-white stock
   with a small notch die-cut from the top + bottom edge (aligned at 50%, like a
   roll-fed label) and a soft drop shadow; the price rides a nested <span> on top
   (its own layer so it can be stretched tall and set askew from the tag). The
   face is Impact Label Reversed — a real label gun — in solid faded grey ink.

   FIXED stock: --price-tag-w/-h size the label independently of the price string
   (real life — a longer price fills more of the label, it never enlarges it).
   The price is flex-anchored bottom-left, so short prices leave blank label
   up-right and long ones fill across.

   JITTER: --price-jitter-x/-y (px) and --price-jitter-rot (deg) nudge each
   instance so a 3x3 binder doesn't look rubber-stamped. Rotation is centred on
   flat — the jitter swings it to either side (default ±5deg), so stickers land
   flat, leaning left, or leaning right. Default 0 (flat, un-jittered);
   priceStickerNode/priceStickerHtml seed them per card so the placement is
   varied but stable across re-renders. */
.card-sleeve-price {
  --price-tag-w: 0.248;
  --price-tag-h: 0.154;
  --price-jitter-x: 0px;
  --price-jitter-y: 0px;
  --price-jitter-rot: 0deg;
  position: absolute;
  z-index: 4;
  top: calc(var(--card-sleeve-width) * 0.15);
  right: calc(var(--card-sleeve-width) * 0.05);
  box-sizing: border-box;
  width: calc(var(--card-sleeve-width) * var(--price-tag-w));
  height: calc(var(--card-sleeve-width) * var(--price-tag-h));
  display: flex;
  align-items: flex-end;
  justify-content: flex-start;
  /* inset of the print from the bottom-left corner of the fixed label */
  padding: 0 calc(var(--card-sleeve-width) * 0.03) calc(var(--card-sleeve-width) * 0.03)
    calc(var(--card-sleeve-width) * 0.004);
  /* placement jitter (translate first, in card space); rotation sits at flat so
     the jitter swings it to either side — see --price-jitter-rot */
  transform: translate(var(--price-jitter-x), var(--price-jitter-y))
    rotate(var(--price-jitter-rot));
  font-family: 'vui-price-label', Consolas, 'Courier New', monospace;
  font-size: calc(var(--card-sleeve-width) * 0.058);
  font-weight: 550;
  letter-spacing: 0.04em;
  word-spacing: -0.4em;
  line-height: 1.05;
  white-space: nowrap;
  color: #3f3b37;
}

/* the paper label behind the ink */
.card-sleeve-price::before {
  --notch: calc(var(--card-sleeve-width) * 0.012);
  content: '';
  position: absolute;
  z-index: -1;
  inset: 0;
  background: #f8f6ee;
  border-radius: 0;
  -webkit-mask:
    radial-gradient(circle var(--notch) at 50% 0%, #0000 var(--notch), #000 calc(var(--notch) + 0.5px)),
    radial-gradient(circle var(--notch) at 50% 100%, #0000 var(--notch), #000 calc(var(--notch) + 0.5px));
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
  box-shadow:
    0 1px 1px rgba(21, 16, 13, 0.22),
    0 2px 4px rgba(21, 16, 13, 0.2);
}

/* the price ink — its own inline layer (paints above the ::before paper) so it
   can be stretched tall and set a few degrees askew from the tag, like a stamp
   pressed on by hand. Solid faded ink, inherits the label colour. Markup:
   <span class="card-sleeve-price"><span>$ 1.00</span></span>. */
.card-sleeve-price > span {
  display: inline-block;
  transform: rotate(-0.5deg) scale(0.9, 2.4);
  transform-origin: 50% 60%;
}

/* Lifestyle tilt for empty states — a card lying askew on the page. Hover
   straightens it slightly; it stays flat (no lift, no shadow). */
.card-sleeve-tilt {
  transform: rotate(-5deg);
  transition: transform var(--vui-motion-base);
}

.card-sleeve-tilt:hover {
  transform: rotate(-3deg);
}

.card-preview-anchor {
  cursor: zoom-in;
}

/* Flat like every card surface — the border alone frames it. */
.card-preview {
  position: fixed;
  z-index: var(--vui-z-toast);
  pointer-events: none;
  border: 2px solid var(--vui-color-line-strong);
  border-radius: var(--vui-radius-soft);
  background: var(--vui-color-surface-raised);
  overflow: hidden;
}

.card-preview img {
  display: block;
  max-width: 260px;
}

/* Badge — tiny numeric counter pinned to tabs, buttons, and nav items.
   Distinct from .ui-chip: a chip names a thing, a badge counts things.
   Default ink fill; .badge-quiet for resting counts, .badge-accent when the
   count is the point. */
.badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border: 1px solid var(--vui-color-line-strong);
  border-radius: var(--vui-radius-pill);
  background: var(--vui-color-text-strong);
  color: var(--vui-color-text-inverse);
  font-family: var(--vui-font-mono);
  font-size: var(--vui-font-size-xxs);
  font-weight: var(--vui-font-weight-title);
  line-height: 1;
  vertical-align: middle;
}

.badge-quiet {
  background: var(--vui-color-surface-sunken);
  color: var(--vui-color-text-strong);
}

.badge-accent {
  background: var(--vui-color-accent);
  color: var(--vui-color-text-inverse);
}

/* Progress — a thin inked bar. Drive it with --progress (a percentage) on
   the root; the fill carries a faint diagonal hatch so partial fills read
   at a glance. Markup: <div class="progress" role="progressbar"
   aria-valuenow="62" aria-valuemin="0" aria-valuemax="100"
   style="--progress: 62%"><span class="progress-fill"></span></div> */
.progress {
  display: block;
  width: 100%;
  height: 12px;
  border: var(--vui-border-width) solid var(--vui-color-line-strong);
  border-radius: var(--vui-radius-tight);
  background: var(--vui-color-surface-sunken);
  overflow: hidden;
}

.progress-fill {
  display: block;
  height: 100%;
  width: var(--progress, 0%);
  background-color: var(--vui-color-accent);
  background-image: repeating-linear-gradient(
    -45deg,
    rgba(255, 255, 255, 0.16) 0 4px,
    transparent 4px 8px
  );
  transition: width var(--vui-motion-base);
}

@media (prefers-reduced-motion: reduce) {
  .progress-fill {
    transition: none;
  }
}

/* Breadcrumb — the navigation trail (binder > page > slot). Current leaf
   carries aria-current="page" and the strong ink; separators are inert. */
.breadcrumb {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--vui-space-1);
  font-family: var(--vui-font-mono);
  font-size: var(--vui-font-size-xs);
  text-transform: lowercase;
}

.breadcrumb a {
  color: var(--vui-color-text-muted);
  text-decoration: none;
}

.breadcrumb a:hover,
.breadcrumb a:focus-visible {
  color: var(--vui-color-text-strong);
  text-decoration: underline;
}

.breadcrumb-sep {
  color: var(--vui-color-line);
  user-select: none;
}

.breadcrumb [aria-current='page'] {
  color: var(--vui-color-text-strong);
  font-weight: var(--vui-font-weight-title);
}

/* Accordion — styled <details> stack for filter panels and card detail
   sections. Items share borders like the segmented control; the marker is a
   mono +/− instead of the UA triangle. */
.accordion {
  display: flex;
  flex-direction: column;
}

.accordion-item {
  border: var(--vui-border-width) solid var(--vui-color-line-strong);
  background: var(--vui-color-surface-raised);
}

.accordion-item + .accordion-item {
  border-top: 0;
}

.accordion-item > summary {
  display: flex;
  align-items: center;
  gap: var(--vui-space-2);
  padding: var(--vui-space-2) var(--vui-space-3);
  cursor: pointer;
  list-style: none;
  font-family: var(--vui-font-mono);
  font-size: var(--vui-font-size-sm);
  font-weight: var(--vui-font-weight-title);
  text-transform: lowercase;
  color: var(--vui-color-text-strong);
  user-select: none;
}

.accordion-item > summary::-webkit-details-marker {
  display: none;
}

.accordion-item > summary::before {
  content: '+';
  flex: none;
  width: 1em;
  text-align: center;
  color: var(--vui-color-text-muted);
}

.accordion-item[open] > summary::before {
  content: '−';
}

.accordion-item > summary:hover {
  background: var(--vui-color-surface-hover);
}

.accordion-body {
  padding: 0 var(--vui-space-3) var(--vui-space-3) calc(var(--vui-space-3) + 1em + var(--vui-space-2));
  font-size: var(--vui-font-size-sm);
  color: var(--vui-color-text);
}


/* design-system.css */
body.design-system-page,
body.vui-design-system-page {
  overflow: auto;
  background: var(--vui-color-bg);
}

.vui-design-system,
.ds-page-wrap {
  max-width: 1080px;
  margin: 0 auto;
  padding: 32px 24px 64px;
  display: flex;
  flex-direction: column;
  gap: 32px;
}

.ds-page-head {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 22px 24px;
  border: var(--vui-border-width) solid var(--vui-color-text-strong);
  border-radius: var(--vui-radius-soft);
  background-image: linear-gradient(var(--vui-color-surface-sunken), var(--vui-color-surface-sunken));
  box-shadow: var(--vui-shadow-hard);
}

.ds-page-title {
  margin: 0;
  font-family: var(--vui-font-display);
  font-size: var(--vui-font-size-jumbo);
  font-weight: var(--vui-font-weight-title);
  letter-spacing: -0.02em;
}

.ds-page-sub {
  margin: 0;
  font-size: var(--vui-font-size-md);
  color: var(--vui-color-text-muted);
}

.ds-page-actions {
  position: absolute;
  top: 14px;
  right: 18px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: flex-end;
}

.ds-page-layout {
  display: grid;
  grid-template-columns: 190px minmax(0, 1fr);
  gap: 28px;
  align-items: start;
}

.ds-toc {
  position: sticky;
  top: 16px;
  align-self: start;
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: calc(100vh - 32px);
  overflow-y: auto;
  padding-right: 4px;
}

.ds-toc-title {
  font-family: var(--vui-font-mono);
  font-size: var(--vui-font-size-xxs);
  text-transform: uppercase;
  letter-spacing: var(--vui-label-tracking);
  color: var(--vui-color-text-muted);
  margin: 10px 0 4px;
}

.ds-toc-link {
  text-decoration: none;
  color: var(--vui-color-text-muted);
  font-size: var(--vui-font-size-sm);
  text-transform: lowercase;
  padding: 4px 8px;
  border-radius: var(--vui-radius-sharp);
  border-left: 2px solid transparent;
}

.ds-toc-link:hover {
  color: var(--vui-color-text-strong);
  background: var(--vui-color-surface-hover);
}

.ds-toc-link.active {
  color: var(--vui-color-accent);
  border-left-color: var(--vui-color-accent);
  background: var(--vui-color-surface-hover);
}

.ds-toc-states {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--vui-color-line);
}

/* The force-state picker is a compact segmented control; this just makes the
   four segments share the narrow toc width evenly. */
.ds-toc-state-row {
  width: 100%;
}

.ds-toc-state-row .segment-btn {
  flex: 1 1 0;
  padding: 4px 2px;
}

.ds-page-body {
  display: flex;
  flex-direction: column;
  gap: 28px;
}

.ds-group {
  display: flex;
  flex-direction: column;
  gap: 14px;
  scroll-margin-top: 16px;
}

.ds-group-title {
  margin: 0;
  padding-bottom: 6px;
  border-bottom: var(--vui-border-width) solid var(--vui-color-text-strong);
  font-family: var(--vui-font-mono);
  font-size: var(--vui-font-size-md);
  font-weight: var(--vui-font-weight-title);
  text-transform: uppercase;
  letter-spacing: var(--vui-label-tracking);
}

.ds-entry {
  display: grid;
  grid-template-columns: 280px 1fr;
  gap: 18px;
  align-items: start;
  padding: 12px;
  border: var(--vui-border-width) solid var(--vui-color-line);
  border-radius: var(--vui-radius-soft);
  background: var(--vui-color-surface-raised);
}

.ds-entry-head {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.ds-entry-name {
  margin: 0;
  font-family: var(--vui-font-body);
  font-size: var(--vui-font-size-xl);
  font-weight: var(--vui-font-weight-title);
  text-transform: lowercase;
}

.ds-entry-selectors {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.ds-entry-selectors code {
  font-family: var(--vui-font-mono);
  font-size: var(--vui-font-size-xs);
  padding: 2px 5px;
  border: 1px solid var(--vui-color-line);
  border-radius: var(--vui-radius-tight);
  background: var(--vui-color-surface);
}

.ds-entry-desc {
  grid-column: 1 / 2;
  margin: 0;
  font-size: var(--vui-font-size-sm);
  color: var(--vui-color-text-muted);
  line-height: 1.45;
}

.ds-entry-demo {
  grid-column: 2 / 3;
  grid-row: 1 / 3;
  padding: 14px;
  border: 1px solid var(--vui-color-line);
  border-radius: var(--vui-radius-soft);
  background: var(--vui-color-surface);
  display: flex;
  flex-direction: column;
  gap: 10px;
  /* Floating demos (combobox, tooltip, menu) must escape the panel; zoomed
     content opts back into clipping via .ds-entry-demo-scroll (BEN-553). */
  overflow: visible;
}
.ds-entry-demo.ds-entry-demo-scroll {
  overflow: auto;
}

/* The zoom picker is a compact segmented control pinned to the demo's edge.
   Hidden at rest so the components own the panel (BEN-561). */
.ds-zoom-bar {
  align-self: flex-end;
  opacity: 0;
  transition: opacity var(--vui-motion-fast) ease;
}
.ds-entry-demo:hover .ds-zoom-bar,
.ds-zoom-bar:focus-within {
  opacity: 1;
}

.ds-zoom-stage {
  width: 100%;
}

.ds-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
}

.ds-stack {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.ds-theme-toggle {
  font-size: var(--vui-font-size-xs);
  text-transform: lowercase;
  color: var(--vui-color-text-muted);
  margin-bottom: 6px;
}

.ds-inline-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--vui-font-size-sm);
  cursor: pointer;
}

.ds-playground {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 16px;
  padding: 14px;
  border: var(--vui-border-width) solid var(--vui-color-line);
  border-radius: var(--vui-radius-soft);
  background: var(--vui-color-surface-raised);
}

.ds-playground-col {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.ds-playground-col-label {
  font-family: var(--vui-font-mono);
  font-size: var(--vui-font-size-xs);
  font-weight: var(--vui-font-weight-title);
  text-transform: lowercase;
  letter-spacing: 0.04em;
  color: var(--vui-color-text-muted);
  padding-bottom: 4px;
  border-bottom: 1px solid var(--vui-color-line);
}

.ds-playground-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.ds-playground-token {
  font-family: var(--vui-font-mono);
  font-size: var(--vui-font-size-xxs);
  color: var(--vui-color-text-strong);
}

.ds-playground-row input[type='color'] {
  width: 42px;
  height: 24px;
  flex: none;
  padding: 0;
  border: 2px solid var(--vui-color-line-strong);
  border-radius: var(--vui-radius-sharp);
  background: none;
  cursor: pointer;
  box-shadow: none;
}

.ds-playground-text {
  flex: 1;
  min-width: 0;
  font-family: var(--vui-font-mono);
  font-size: var(--vui-font-size-xxs);
  padding: 3px 6px;
}

.ds-static-popover {
  border: var(--vui-border-width) solid var(--vui-color-text-strong);
  border-radius: var(--vui-radius-soft);
  background: var(--vui-color-surface-raised);
  box-shadow: var(--vui-shadow-overlay);
  overflow: hidden;
  width: 280px;
}

.ds-static-popover-body {
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.ds-token-output {
  min-height: 120px;
  border: var(--vui-border-width) solid var(--vui-color-line);
  border-radius: var(--vui-radius-soft);
  background: var(--vui-color-surface-raised);
  padding: 10px;
  font-family: var(--vui-font-mono);
  font-size: var(--vui-font-size-xxs);
  color: var(--vui-color-text-muted);
  white-space: pre-wrap;
}

@media (max-width: 900px) {
  .ds-page-actions {
    position: static;
    justify-content: flex-start;
    margin-top: 8px;
  }

  .ds-page-layout {
    grid-template-columns: 1fr;
  }

  .ds-toc {
    position: static;
    max-height: none;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
  }

  .ds-toc-states {
    flex-basis: 100%;
    border-bottom: none;
  }

  .ds-entry {
    grid-template-columns: 1fr;
  }

  .ds-entry-desc,
  .ds-entry-demo {
    grid-column: 1;
    grid-row: auto;
  }
}

/* Icon buttons shown in context (BEN-561). */
.ds-icon-btn-context {
  align-items: center;
  background: var(--vui-color-surface-raised);
  border: var(--vui-border-width) solid var(--vui-color-line);
  border-radius: var(--vui-radius-sharp);
  display: inline-flex;
  gap: var(--vui-space-1);
  padding: var(--vui-space-1) var(--vui-space-2);
}
.ds-icon-btn-context-label {
  font-family: var(--vui-font-mono);
  font-size: var(--vui-font-size-sm);
  margin-right: var(--vui-space-2);
}

/* Type specimen group (BEN-555). */
.ds-type-faces,
.ds-type-ramp {
  display: flex;
  flex-direction: column;
  gap: var(--vui-space-2);
  width: 100%;
}
.ds-type-ramp-row {
  align-items: baseline;
  display: flex;
  gap: var(--vui-space-3);
}
.ds-type-ramp-token {
  color: var(--vui-color-text-muted);
  flex: 0 0 64px;
  font-size: var(--vui-font-size-xs);
}
.ds-type-ramp-sample {
  white-space: nowrap;
}


/* labs.css */
body.vui-lab-page {
  overflow: auto;
  background: var(--vui-color-bg);
}

.vui-lab-wrap {
  width: min(1180px, calc(100% - 32px));
  margin: 0 auto;
  padding: 28px 0 64px;
}

.lab-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 16px;
  align-items: start;
  padding: 18px 20px;
  border: var(--vui-border-width) solid var(--vui-color-text-strong);
  border-radius: var(--vui-radius-soft);
  background: var(--vui-color-surface-sunken);
  box-shadow: var(--vui-shadow-hard);
}

.lab-title {
  margin: 0;
  font-family: var(--vui-font-display);
  font-size: var(--vui-font-size-jumbo);
  font-weight: var(--vui-font-weight-title);
  letter-spacing: 0;
}

.lab-sub {
  margin: 6px 0 0;
  color: var(--vui-color-text-muted);
  font-size: var(--vui-font-size-md);
  max-width: 680px;
}

.lab-head-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: flex-end;
}

.lab-shell {
  display: grid;
  grid-template-columns: minmax(260px, 320px) minmax(0, 1fr);
  gap: 24px;
  align-items: start;
  margin-top: 28px;
}

.lab-controls {
  position: sticky;
  top: 16px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-height: calc(100vh - 32px);
  overflow: auto;
}

.lab-panel {
  border: var(--vui-border-width) solid var(--vui-color-line);
  border-radius: var(--vui-radius-soft);
  background: var(--vui-color-surface-raised);
  padding: 14px;
}

.lab-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin: 0 0 10px;
}

.lab-panel-title {
  margin: 0;
  font-family: var(--vui-font-mono);
  font-size: var(--vui-font-size-md);
  font-weight: var(--vui-font-weight-title);
  letter-spacing: var(--vui-label-tracking);
  text-transform: uppercase;
}

.lab-reset-btn {
  appearance: none;
  border: 1px solid var(--vui-color-line);
  border-radius: var(--vui-radius-sharp);
  background: var(--vui-color-surface);
  color: var(--vui-color-text-muted);
  cursor: pointer;
  font-family: var(--vui-font-mono);
  font-size: var(--vui-font-size-xxs);
  line-height: 1;
  padding: 4px 6px;
  text-transform: lowercase;
}

.lab-reset-btn:hover,
.lab-reset-btn:focus-visible {
  border-color: var(--vui-color-text-strong);
  background: var(--vui-color-surface-hover);
  color: var(--vui-color-text-strong);
}

.lab-reset-btn:focus-visible {
  outline: var(--vui-focus-ring);
  outline-offset: var(--vui-focus-ring-offset);
}

.lab-control-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.lab-control {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 8px 10px;
  align-items: center;
}

.lab-control span {
  color: var(--vui-color-text-muted);
  font-size: var(--vui-font-size-xs);
  letter-spacing: var(--vui-label-tracking);
  text-transform: uppercase;
}

.lab-control output {
  font-family: var(--vui-font-mono);
  font-size: var(--vui-font-size-xxs);
  color: var(--vui-color-text-muted);
}

.lab-control input[type='range'] {
  grid-column: 1 / -1;
  width: 100%;
  accent-color: var(--vui-color-accent);
}

.lab-control input[type='color'] {
  width: 42px;
  height: 28px;
  padding: 0;
  border: 2px solid var(--vui-color-line-strong);
  border-radius: var(--vui-radius-sharp);
  background: var(--vui-color-surface-raised);
  box-shadow: none;
}

.lab-control select {
  grid-column: 1 / -1;
  width: 100%;
}

.lab-swatch-control {
  align-items: start;
}

.lab-swatch-control output {
  max-width: 130px;
  overflow: hidden;
  text-align: right;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.lab-swatch-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  grid-column: 1 / -1;
}

.lab-swatch {
  appearance: none;
  position: relative;
  width: 24px;
  height: 24px;
  border: 2px solid var(--vui-color-line);
  border-radius: var(--vui-radius-sharp);
  background:
    linear-gradient(135deg, rgba(255, 255, 255, 0.22), rgba(0, 0, 0, 0.12)),
    var(--lab-swatch-color);
  box-shadow: none;
  color: var(--vui-color-text-strong);
  cursor: pointer;
  font-family: var(--vui-font-mono);
  font-size: var(--vui-font-size-sm);
  font-weight: var(--vui-font-weight-title);
  line-height: 1;
  padding: 0;
}

.lab-swatch:hover,
.lab-swatch.active,
.lab-swatch[aria-pressed='true'] {
  border-color: var(--vui-color-text-strong);
  box-shadow: 2px 2px 0 var(--vui-color-shadow);
}

.lab-swatch.is-default::after {
  content: '';
  position: absolute;
  right: 2px;
  bottom: 2px;
  width: 6px;
  height: 6px;
  border: 1px solid var(--vui-color-surface-raised);
  border-radius: 50%;
  background: var(--vui-color-text-strong);
  box-shadow: 0 0 0 1px var(--vui-color-line-strong);
}

.lab-swatch:focus-visible {
  outline: var(--vui-focus-ring);
  outline-offset: var(--vui-focus-ring-offset);
}

.lab-swatch-custom {
  background:
    radial-gradient(rgba(21, 16, 13, 0.1) 1px, transparent 1px),
    var(--vui-color-surface-raised);
  background-size: 5px 5px, auto;
}

.lab-swatch-custom-input {
  grid-column: 1 / -1;
}

.lab-stage {
  display: flex;
  flex-direction: column;
  gap: 22px;
}

.modal-lab-preview-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 18px;
}

.modal-lab-preview {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
}

.modal-lab-preview-label {
  font-family: var(--vui-font-mono);
  font-size: var(--vui-font-size-xs);
  font-weight: var(--vui-font-weight-title);
  letter-spacing: var(--vui-label-tracking);
  text-transform: uppercase;
  color: var(--vui-color-text-muted);
}

.modal-lab-preview .ui-modal-card {
  width: 100%;
}

.modal-lab-copy {
  width: 100%;
  min-height: 180px;
  resize: vertical;
  font-family: var(--vui-font-mono);
  font-size: var(--vui-font-size-xs);
  line-height: 1.45;
}

.modal-lab-live {
  padding: 20px;
}

.modal-lab-live .ui-modal-card {
  width: min(560px, calc(100vw - 32px));
}

.modal-lab-scroll-body {
  max-height: 220px;
}

.modal-lab-form {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
}

/* data-close-style='quiet' needs no overrides: quiet IS the production
   .rune-close (BEN-604). The old override block leaned on --vui-modal-close-*
   decoration tokens that were never defined — silently a no-op, now gone. */

.modal-lab-page[data-close-style='rune'] .modal-lab-preview .rune-close,
.modal-lab-page[data-close-style='rune'] .modal-lab-live .rune-close {
  top: -15px;
  right: -15px;
  width: 30px;
  height: 30px;
  border: var(--vui-border-width) solid var(--vui-color-text-strong);
  border-radius: 50%;
  /* indigo hardcoded: the rune treatment is retired (BEN-604); the lab keeps
     it for comparison only, so it no longer earns a token. */
  background:
    radial-gradient(rgba(242, 196, 82, 0.18) 0 22%, transparent 23%),
    #374269;
  box-shadow: var(--vui-shadow-hard-sm);
  color: var(--vui-color-warn);
}

.modal-lab-page[data-close-style='rune'] .modal-lab-preview .rune-close:hover,
.modal-lab-page[data-close-style='rune'] .modal-lab-live .rune-close:hover {
  transform: translate(1px, 1px) rotate(8deg);
  background:
    radial-gradient(rgba(242, 196, 82, 0.28) 0 24%, transparent 25%),
    var(--vui-color-accent);
  box-shadow: 2px 2px 0 var(--vui-color-text-strong);
  color: var(--vui-color-warn);
}

.modal-lab-page[data-close-style='rune'] .modal-lab-preview .rune-close:active,
.modal-lab-page[data-close-style='rune'] .modal-lab-live .rune-close:active {
  transform: translate(3px, 3px);
  box-shadow: 0 0 0 var(--vui-color-text-strong);
}

.modal-lab-page[data-close-style='tab'] .modal-lab-preview .rune-close,
.modal-lab-page[data-close-style='tab'] .modal-lab-live .rune-close {
  top: -3px;
  right: -3px;
  width: 34px;
  height: 30px;
  border-radius: 0;
  background: var(--vui-color-surface-raised);
  color: var(--vui-color-text-strong);
  box-shadow: 3px 3px 0 var(--vui-color-shadow);
}

.modal-lab-page[data-close-style='tab'] .modal-lab-preview .rune-close:hover,
.modal-lab-page[data-close-style='tab'] .modal-lab-live .rune-close:hover {
  transform: translate(1px, 1px);
  background: var(--vui-color-warn);
  box-shadow: 2px 2px 0 var(--vui-color-shadow);
}

@media (max-width: 860px) {
  .lab-head,
  .lab-shell {
    grid-template-columns: 1fr;
  }

  .lab-controls {
    position: static;
    max-height: none;
  }

  .lab-head-actions {
    justify-content: flex-start;
  }
}
