/* AI Policy Hub, on design system v0.4.3 (vendored in ./design-system, see its README).
   The design system is layered; these app rules are unlayered, so they win where they need to.
   Only design system tokens are used here: no raw colours, no raw font sizes, spacing on the 4px grid,
   one hairline (--border-hairline), shadows only on floating layers (menus, the paste notice). */
/* Shared design system v0.4.3 concept (graphite, restrained). v0.3.2 rules unchanged above the "v0.4.1 refresh" section at the end. Values come only from tokens.css custom properties.
   Mobile first: base rules target 375px; @media (min-width: 768px) and (min-width: 1280px) step up. */
@layer reset, tokens, base, layout, components, utilities;
/* v0.4: Geist and Geist Mono, SIL Open Font License 1.1 (see ../fonts/OFL-Geist*.txt), from @fontsource-variable 5.3.0.
   Self-hosted, latin subset, one variable file each (weights 100 to 900). IBM Plex is not used in v0.4 (files moved to v0.4/moved/fonts-plex). */
@font-face { font-family: "Geist Variable"; font-style: normal; font-weight: 100 900; font-display: optional; src: url("design-system/fonts/geist-latin-wght-normal.woff2") format("woff2-variations"), url("design-system/fonts/geist-latin-wght-normal.woff2") format("woff2"); }
@font-face { font-family: "Geist Mono Variable"; font-style: normal; font-weight: 100 900; font-display: optional; src: url("design-system/fonts/geist-mono-latin-wght-normal.woff2") format("woff2-variations"), url("design-system/fonts/geist-mono-latin-wght-normal.woff2") format("woff2"); }
/* v0.4.1: metric-matched local fallbacks so the swap from the system font to Geist does not shift layout (CLS).
   Arial and Liberation Sans share metrics; Courier New and Liberation Mono share metrics. Overrides computed with
   fontTools from the Geist files at weight 400 (typo metrics, average width of an English sample). */
/* v0.4.2 (SF1): the web faces are named "Geist Variable" and "Geist Mono Variable" (the Fontsource names), so a copy of
   Geist installed on the device can never stand in mid-load and swap; an installed Geist is the first fallback instead.
   font-display is optional, not swap. Both files are preloaded, so a normal first load paints in Geist;
   on a slow link the page keeps the fallback for that visit and nothing reflows (CLS 0 with the files held 1.5 s).
   The fallback was 2 to 4 percent wider than Geist at 16px, so long lines wrapped one word early until
   Geist arrived (CLS 0.027 at 1280 in v0.4.1). Measured in Chromium over 300 strings from the reference pages:
   regular 102.77% keeps 14px to 18px text within 1 percent; weights 600 and up use the real bold face at 101%. */
@font-face { font-family: "Geist Fallback"; font-weight: 100 500; src: local("Arial"), local("ArialMT"), local("Liberation Sans"), local("LiberationSans"), local("Helvetica"); size-adjust: 102.77%; ascent-override: 97.8%; descent-override: 28.71%; line-gap-override: 0%; }
@font-face { font-family: "Geist Fallback"; font-weight: 600 900; src: local("Arial Bold"), local("Arial-BoldMT"), local("Liberation Sans Bold"), local("LiberationSans-Bold"), local("Helvetica Bold"); size-adjust: 101%; ascent-override: 99.51%; descent-override: 29.21%; line-gap-override: 0%; }
@font-face { font-family: "Geist Mono Fallback"; src: local("Courier New"), local("CourierNewPSMT"), local("Liberation Mono"), local("LiberationMono"), local("Menlo"); size-adjust: 99.98%; ascent-override: 100.52%; descent-override: 29.50%; line-gap-override: 0%; }

@layer tokens {
/* Generated by build/sd.mjs from tokens.json. Do not edit by hand. */
:root {
  --font-sans: "Geist Variable", Geist, "Geist Fallback", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-mono: "Geist Mono Variable", "Geist Mono", "Geist Mono Fallback", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --font-weight-regular: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-base: 1rem;
  --text-lg: 1.25rem;
  --text-xl: 1.5rem;
  --text-2xl: 2rem;
  --leading-xs: 1rem;
  --leading-sm: 1.25rem;
  --leading-base: 1.5rem;
  --leading-lg: 1.75rem;
  --leading-xl: 2rem;
  --leading-2xl: 2.5rem;
  --leading-prose: 1.75;
  --tracking-normal: 0;
  --tracking-lg: -0.01rem;
  --tracking-xl: -0.025rem;
  --tracking-2xl: -0.05rem;
  --space-0: 0;
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;
  --space-16: 64px;
  --space-0-5: 2px;
  --radius-sm: 4px;
  --radius-md: 6px;
  --radius-lg: 8px;
  --radius-xl: 12px;
  --radius-full: 9999px;
  --border-hairline: 1px;
  --border-strong: 2px;
  --focus-width: 2px;
  --focus-offset: 2px;
  --size-control-sm: 28px;
  --size-control-md: 32px;
  --size-control-lg: 44px;
  --size-row-condensed: 32px;
  --size-row-normal: 40px;
  --size-row-spacious: 48px;
  --size-header: 56px;
  --size-icon-xs: 12px;
  --size-icon-sm: 16px;
  --size-icon-md: 20px;
  --size-mark: 10px;
  --size-dot: 8px;
  --size-switch-width: 36px;
  --size-target-min: 24px;
  --size-target-touch: 44px;
  --size-content-max: 72rem;
  --size-wide-max: 90rem;
  --size-prose-max: 42rem;
  --size-measure: 52ch;
  --size-form-max: 35rem;
  --size-bp-md: 768px;
  --size-bp-lg: 1280px;
  --size-menu-min: 12rem;
  --size-overlay-max: 22rem;
  --size-tooltip-max: 18rem;
  --size-dialog-max: 32rem;
  --size-toast-max: 24rem;
  --size-sidebar: 16rem;
  --size-search-max: 24rem;
  --size-label-col: 10rem;
  --size-summary-col: 14rem;
  --size-cell-max: 36rem;
  --size-pane-min: 30rem;
  --size-scroll-max: 40rem;
  --duration-press: 120ms;
  --duration-fast: 160ms;
  --duration-base: 220ms;
  --duration-slow: 300ms;
  --duration-spin: 800ms;
  --duration-pulse: 1600ms;
  --easing-out: cubic-bezier(0.23, 1, 0.32, 1);
  --easing-spring: cubic-bezier(0.24, 1, 0.4, 1);
  --easing-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --easing-drawer: cubic-bezier(0.32, 0.72, 0, 1);
  --blur-header: 12px;
  --z-base: 0;
  --z-raised: 1;
  --z-sticky: 10;
  --z-header: 20;
  --z-dropdown: 30;
  --z-toast: 40;
  --z-overlay: 50;
}

/* Light theme, blue accent (default) */
:root,
[data-theme="light"] {
  color-scheme: light;
  --background: #fbfbfc;
  --foreground: #121215;
  --card: #ffffff;
  --card-foreground: #121215;
  --popover: #ffffff;
  --popover-foreground: #121215;
  --secondary: #f2f2f4;
  --secondary-foreground: #121215;
  --muted: #f7f7f8;
  --muted-foreground: #535358;
  --subtle-foreground: #6a6a6e;
  --accent: #f2f2f4;
  --accent-foreground: #121215;
  --border: #e5e5e8;
  --input: #7b7b80;
  --destructive: #b02a2d;
  --destructive-foreground: #ffffff;
  --destructive-soft: #ffefee;
  --warning: #915c08;
  --warning-soft: #fff1e2;
  --success: #2b7440;
  --success-soft: #e6fae9;
  --info: #32669a;
  --info-soft: #ebf5ff;
  --scrim: #0f0f1373;
  --chart-1: #093180;
  --chart-2: #ba7702;
  --chart-3: #449b86;
  --chart-4: #5a1642;
  --chart-5: #62676c;
  --syntax-keyword: #84377f;
  --syntax-string: #296a3b;
  --syntax-number: #925019;
  --syntax-property: #2855ad;
  --syntax-comment: #6a6a6e;
  --shadow-1: 0 1px 2px 0 #1616180f;
  --shadow-2: 0 4px 12px -2px #1616181a, 0 0 0 1px #1616180f;
  --shadow-3: 0 16px 40px -8px #1616181a, 0 0 0 1px #1616180f;
  --header-background: #fbfbfce0;
  --primary: #1d5fe2;
  --primary-hover: #104fca;
  --primary-foreground: #ffffff;
  --primary-soft: #ecf3fe;
  --primary-soft-foreground: #1545a2;
  --link: #1d5fe2;
  --selection: #ecf3fe;
  --ring: #1d5fe2;
}

/* Teal accent, light */
[data-accent="teal"] {
  --primary: #06726e;
  --primary-hover: #00605c;
  --primary-foreground: #ffffff;
  --primary-soft: #e2f5f3;
  --primary-soft-foreground: #00635f;
  --link: #06726e;
  --selection: #e2f5f3;
  --ring: #2f8adc;
}

/* Dark theme, explicit */
[data-theme="dark"] {
  color-scheme: dark;
  --background: #0b0b0d;
  --foreground: #f1f1f3;
  --card: #121215;
  --card-foreground: #f1f1f3;
  --popover: #19191c;
  --popover-foreground: #f1f1f3;
  --secondary: #202023;
  --secondary-foreground: #f1f1f3;
  --muted: #19191c;
  --muted-foreground: #b2b2b6;
  --subtle-foreground: #9f9fa4;
  --accent: #202023;
  --accent-foreground: #f1f1f3;
  --border: #2a2a2d;
  --input: #86868a;
  --destructive: #f07f77;
  --destructive-foreground: #0b0b0d;
  --destructive-soft: #2d1716;
  --warning: #efb062;
  --warning-soft: #271c0e;
  --success: #76c788;
  --success-soft: #142216;
  --info: #79b0e8;
  --info-soft: #131f2c;
  --scrim: #00000099;
  --chart-1: #4170cb;
  --chart-2: #fbc865;
  --chart-3: #7fddde;
  --chart-4: #9b527d;
  --chart-5: #969ca3;
  --syntax-keyword: #e3a6dd;
  --syntax-string: #89d298;
  --syntax-number: #f2b772;
  --syntax-property: #9ebef8;
  --syntax-comment: #9f9fa4;
  --shadow-1: 0 1px 2px 0 #ffffff14;
  --shadow-2: 0 4px 12px -2px #00000080, 0 0 0 1px #ffffff14;
  --shadow-3: 0 16px 40px -8px #00000080, 0 0 0 1px #ffffff14;
  --header-background: #0b0b0de0;
  --primary: #2366e9;
  --primary-hover: #1c5bd6;
  --primary-foreground: #ffffff;
  --primary-soft: #0f1e3b;
  --primary-soft-foreground: #b9d2ff;
  --link: #86b1ff;
  --selection: #1c3461;
  --ring: #86b1ff;
}

[data-theme="dark"][data-accent="teal"] {
  --primary: #52bfb9;
  --primary-hover: #67d2cc;
  --primary-foreground: #0b0b0d;
  --primary-soft: #0b3533;
  --primary-soft-foreground: #9be0db;
  --link: #52bfb9;
  --selection: #0b3533;
  --ring: #a5c5ff;
}

/* Dark theme from the operating system when no explicit choice */
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
  color-scheme: dark;
  --background: #0b0b0d;
  --foreground: #f1f1f3;
  --card: #121215;
  --card-foreground: #f1f1f3;
  --popover: #19191c;
  --popover-foreground: #f1f1f3;
  --secondary: #202023;
  --secondary-foreground: #f1f1f3;
  --muted: #19191c;
  --muted-foreground: #b2b2b6;
  --subtle-foreground: #9f9fa4;
  --accent: #202023;
  --accent-foreground: #f1f1f3;
  --border: #2a2a2d;
  --input: #86868a;
  --destructive: #f07f77;
  --destructive-foreground: #0b0b0d;
  --destructive-soft: #2d1716;
  --warning: #efb062;
  --warning-soft: #271c0e;
  --success: #76c788;
  --success-soft: #142216;
  --info: #79b0e8;
  --info-soft: #131f2c;
  --scrim: #00000099;
  --chart-1: #4170cb;
  --chart-2: #fbc865;
  --chart-3: #7fddde;
  --chart-4: #9b527d;
  --chart-5: #969ca3;
  --syntax-keyword: #e3a6dd;
  --syntax-string: #89d298;
  --syntax-number: #f2b772;
  --syntax-property: #9ebef8;
  --syntax-comment: #9f9fa4;
  --shadow-1: 0 1px 2px 0 #ffffff14;
  --shadow-2: 0 4px 12px -2px #00000080, 0 0 0 1px #ffffff14;
  --shadow-3: 0 16px 40px -8px #00000080, 0 0 0 1px #ffffff14;
  --header-background: #0b0b0de0;
  --primary: #2366e9;
  --primary-hover: #1c5bd6;
  --primary-foreground: #ffffff;
  --primary-soft: #0f1e3b;
  --primary-soft-foreground: #b9d2ff;
  --link: #86b1ff;
  --selection: #1c3461;
  --ring: #86b1ff;
}

:root:not([data-theme="light"])[data-accent="teal"] {
  --primary: #52bfb9;
  --primary-hover: #67d2cc;
  --primary-foreground: #0b0b0d;
  --primary-soft: #0b3533;
  --primary-soft-foreground: #9be0db;
  --link: #52bfb9;
  --selection: #0b3533;
  --ring: #a5c5ff;
}

}
}

/* ---------- reset ---------- */
@layer reset {
  *, *::before, *::after { box-sizing: border-box; }
  * { margin: 0; }
  html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
  a, button, input, select, textarea, label, summary { touch-action: manipulation; }
  img, svg, video, canvas { display: block; max-width: 100%; }
  input, button, textarea, select { font: inherit; color: inherit; letter-spacing: inherit; }
  button { background: none; border: 0; padding: 0; cursor: pointer; }
  table { border-collapse: collapse; }
  fieldset { border: 0; padding: 0; min-width: 0; }
  legend { padding: 0; }
  ul[role], ol[role] { list-style: none; padding: 0; }
  dialog { padding: 0; border: 0; color: inherit; }
  [hidden] { display: none !important; }
}

/* ---------- base ---------- */
@layer base {
  :root {
    --control-h: var(--size-control-lg);      /* 44px touch size below 768px */
    --control-h-sm: var(--size-control-md);
    --item-h: var(--size-control-lg);
    --gutter: var(--space-4);
    --row-h: var(--size-row-normal);
  }
  @media (min-width: 768px) {
    :root { --control-h: var(--size-control-md); --control-h-sm: var(--size-control-sm); --item-h: var(--size-row-condensed); --gutter: var(--space-6); }
  }
  @media (min-width: 1280px) { :root { --gutter: var(--space-8); } }

  html {
    font-family: var(--font-sans);
    background: var(--background);
    color: var(--foreground);
    scroll-padding-top: calc(var(--size-header) + var(--space-4));
    -webkit-font-smoothing: antialiased;
  }
  body { font-size: var(--text-base); line-height: var(--leading-base); letter-spacing: var(--tracking-normal); min-height: 100dvh; }
  /* v0.2: reading measure. v0.4.1: --size-measure is 52ch, which keeps 14px and 16px Geist text at 75 characters a line or less (measured). */
  p, li, dd { max-width: var(--size-measure); }
  ::selection { background: var(--selection); color: var(--foreground); }
  :focus-visible { outline: var(--focus-width) solid var(--ring); outline-offset: var(--focus-offset); }
  h1, h2, h3, h4 { font-weight: var(--font-weight-semibold); text-wrap: balance; }
  h1 { font-size: var(--text-xl); line-height: var(--leading-xl); letter-spacing: var(--tracking-xl); }
  h2 { font-size: var(--text-lg); line-height: var(--leading-lg); }
  h3 { font-size: var(--text-base); line-height: var(--leading-base); }
  h4 { font-size: var(--text-sm); line-height: var(--leading-sm); }
  p { text-wrap: pretty; }
  a { color: var(--link); text-decoration-line: underline; text-decoration-thickness: var(--border-hairline); text-underline-offset: 0.2em; }
  a:hover { text-decoration-thickness: var(--border-strong); }
  code, kbd, samp, pre { font-family: var(--font-mono); font-size: var(--text-sm); }
  small { font-size: var(--text-sm); line-height: var(--leading-sm); }
  strong, b { font-weight: var(--font-weight-semibold); }
  hr { border: 0; border-top: var(--border-hairline) solid var(--border); }
  .icon { width: var(--size-icon-sm); height: var(--size-icon-sm); flex: none; stroke-width: 2; }
  .icon-md { width: var(--size-icon-md); height: var(--size-icon-md); }
  @media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation-duration: 1ms !important; animation-iteration-count: 1 !important; transition-duration: 1ms !important; scroll-behavior: auto !important; }
  }
}

/* ---------- layout and app shell ---------- */
@layer layout {
  .skip-link { position: absolute; left: var(--space-2); top: calc(-1 * var(--size-header)); z-index: var(--z-overlay); background: var(--card); color: var(--foreground); padding: var(--space-2) var(--space-3); border: var(--border-hairline) solid var(--border); border-radius: var(--radius-md); }
  .skip-link:focus { top: var(--space-2); }

  .app-header { position: sticky; top: 0; z-index: var(--z-header); height: var(--size-header); background: var(--card); --_header-rule: var(--border); box-shadow: inset 0 calc(-1 * var(--border-hairline)) 0 var(--_header-rule); }
  /* v0.4.2: the bottom rule is an inset shadow, not a border, so the 56px header keeps a 56px content box and 32px
     controls centered in it land on whole pixels (12px above and below). Forced colors drop shadows, so a real border returns there. */
  @media (forced-colors: active) { .app-header { border-bottom: var(--border-hairline) solid CanvasText; } }
  .app-header__inner { height: 100%; max-width: var(--size-wide-max); margin-inline: auto; padding-inline: var(--gutter); display: flex; align-items: center; gap: var(--space-4); }
  .app-mark { display: inline-flex; align-items: center; gap: var(--space-2); color: var(--foreground); text-decoration: none; font-size: var(--text-sm); line-height: var(--leading-sm); font-weight: var(--font-weight-semibold); white-space: nowrap; min-height: var(--size-target-min); }
  .app-mark:hover { text-decoration: none; }
  .app-mark .icon { width: var(--size-icon-md); height: var(--size-icon-md); }
  .app-nav { display: none; align-items: stretch; gap: var(--space-1); height: 100%; }
  .app-nav a { display: inline-flex; align-items: center; padding-inline: var(--space-3); color: var(--muted-foreground); text-decoration: none; font-size: var(--text-sm); line-height: var(--leading-sm); font-weight: var(--font-weight-medium); box-shadow: inset 0 calc(-1 * var(--border-strong)) 0 transparent; }
  .app-nav a:hover { color: var(--foreground); }
  .app-nav a[aria-current="page"] { color: var(--foreground); box-shadow: inset 0 calc(-1 * var(--border-strong)) 0 var(--primary); }
  .app-header__end { margin-left: auto; display: flex; align-items: center; gap: var(--space-2); }
  .app-menu-btn { display: inline-flex; }
  @media (min-width: 768px) { .app-nav { display: flex; } .app-header .app-menu-btn { display: none; } }

  /* v0.3: a hairline strip on the page color with a small Concept tag, not a full-bleed tinted block.
     v0.4.2: the line is an inset shadow, not a border, so the strip is 36px (a multiple of 4) and everything below it stays on the 4px grid. */
  .concept-flag { background: var(--background); color: var(--muted-foreground); box-shadow: inset 0 calc(-1 * var(--border-hairline)) 0 var(--border); font-size: var(--text-sm); line-height: var(--leading-sm); }
  .concept-flag p { max-width: var(--size-measure); } /* v0.4.1: keeps the strip under 75 characters a line, like help text */
  .concept-flag strong { color: var(--foreground); }
  .concept-flag__inner { max-width: var(--size-wide-max); margin-inline: auto; padding: var(--space-2) var(--gutter); display: flex; gap: var(--space-2); align-items: flex-start; }
  .concept-flag .icon { color: var(--warning); margin-block: var(--space-0-5); flex: none; }
  .concept-flag__tag { display: inline-block; margin-right: var(--space-1); padding-inline: var(--space-1); border-radius: var(--radius-sm); background: var(--warning-soft); color: var(--foreground); font-weight: var(--font-weight-semibold); }

  .page { max-width: var(--size-content-max); margin-inline: auto; padding: var(--space-6) var(--gutter) var(--space-16); }
  .page--wide { max-width: var(--size-wide-max); }
  .page--prose { max-width: calc(var(--size-prose-max) + 2 * var(--gutter)); }
  .page-header { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--space-4); margin-bottom: var(--space-6); }
  .page-header__text { max-width: var(--size-measure); }
  .page-header p { color: var(--muted-foreground); margin-top: var(--space-1); }
  .page-header__actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }
  .eyebrow { font-size: var(--text-sm); line-height: var(--leading-sm); color: var(--muted-foreground); margin-bottom: var(--space-1); }
  /* v0.4.3 (Testingralph v0.4.3 MF-C): only a shown child after another shown child gets the gap, so hidden siblings
     (the builder's earlier steps) add no space. :where keeps the old specificity of * + *. */
  .stack > :where(:not([hidden]) ~ :not([hidden])) { margin-top: var(--space-4); }
  .stack-lg > :where(:not([hidden]) ~ :not([hidden])) { margin-top: var(--space-8); }
  .cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
  .section-title { font-size: var(--text-base); line-height: var(--leading-base); font-weight: var(--font-weight-semibold); margin-bottom: var(--space-3); }

  .grid-2 { display: grid; gap: var(--space-6); }
  @media (min-width: 768px) { .grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
  .grid-sidebar { display: grid; gap: var(--space-6); }
  @media (min-width: 1280px) { .grid-sidebar { grid-template-columns: var(--size-sidebar) minmax(0, 1fr); } }

  .app-footer { border-top: var(--border-hairline) solid var(--border); color: var(--muted-foreground); font-size: var(--text-sm); line-height: var(--leading-sm); }
  .app-footer__inner { max-width: var(--size-wide-max); margin-inline: auto; padding: var(--space-6) var(--gutter); display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-6); }
  .app-footer a { color: var(--muted-foreground); }
  .app-footer nav { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-4); }
  /* v0.3: each link is at least a 24px target (WCAG 2.5.8), 44px on touch screens */
  .app-footer nav a { display: inline-flex; align-items: center; min-height: var(--size-target-min); }
  @media (pointer: coarse) { .app-footer nav a { min-height: var(--size-target-touch); } }
}

/* ---------- components ---------- */
@layer components {
  /* Panel (the only container). Flat, hairline border, no shadow at rest. */
  .panel { background: var(--card); color: var(--card-foreground); border: var(--border-hairline) solid var(--border); border-radius: var(--radius-lg); }
  .panel__header { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-3) var(--space-4); border-bottom: var(--border-hairline) solid var(--border); }
  .panel__title { font-size: var(--text-base); line-height: var(--leading-base); font-weight: var(--font-weight-semibold); }
  .panel__body { padding: var(--space-4); }
  .panel__footer { padding: var(--space-3) var(--space-4); border-top: var(--border-hairline) solid var(--border); display: flex; flex-wrap: wrap; gap: var(--space-2); justify-content: flex-end; }

  /* Button */
  .btn { --_bg: var(--card); --_fg: var(--foreground); --_bd: var(--input); --_bg-hover: var(--accent);
    display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
    height: var(--control-h); min-width: var(--size-target-min); padding-inline: var(--space-3);
    border: var(--border-hairline) solid var(--_bd); border-radius: var(--radius-md);
    background: var(--_bg); color: var(--_fg); white-space: nowrap; text-decoration: none;
    font-size: var(--text-sm); line-height: var(--leading-sm); font-weight: var(--font-weight-medium);
    transition: background-color var(--duration-fast) var(--easing-out), transform var(--duration-press) var(--easing-out);
    -webkit-tap-highlight-color: transparent; user-select: none; }
  .btn:hover, .btn.is-hover { background: var(--_bg-hover); text-decoration: none; }
  .btn:active, .btn.is-active { transform: scale(0.98); }
  .btn.is-focus { outline: var(--focus-width) solid var(--ring); outline-offset: var(--focus-offset); }
  .btn--primary { --_bg: var(--primary); --_fg: var(--primary-foreground); --_bd: var(--primary); --_bg-hover: var(--primary-hover); }
  .btn--primary:hover, .btn--primary.is-hover { border-color: var(--primary-hover); }
  .btn--ghost { --_bg: transparent; --_bd: transparent; }
  .btn--destructive { --_fg: var(--destructive); --_bg-hover: var(--destructive-soft); }
  .btn--destructive-solid { --_bg: var(--destructive); --_fg: var(--destructive-foreground); --_bd: var(--destructive); --_bg-hover: var(--destructive); }
  .btn--sm { height: var(--control-h-sm); padding-inline: var(--space-2); }
  .btn--lg { height: var(--size-control-lg); padding-inline: var(--space-4); font-size: var(--text-base); line-height: var(--leading-base); }
  .btn--icon { width: var(--control-h); padding-inline: 0; }
  .btn--icon.btn--sm { width: var(--control-h-sm); }
  .btn[aria-disabled="true"], .btn:disabled { --_bg: var(--muted); --_fg: var(--muted-foreground); --_bd: var(--border); --_bg-hover: var(--muted); cursor: not-allowed; transform: none; }
  .btn[aria-busy="true"] { cursor: progress; }
  .btn[aria-busy="true"] .spinner { color: currentColor; }
  .btn .icon { margin-inline: calc(-1 * var(--space-0-5)); }

  /* Link variants */
  .link-quiet { color: var(--foreground); text-decoration-color: var(--input); }
  .link-quiet:hover { text-decoration-color: currentColor; }
  .link-external .icon { display: inline; vertical-align: -0.125em; width: 0.875em; height: 0.875em; margin-left: var(--space-0-5); }

  /* Form field */
  .field { display: grid; gap: var(--space-2); max-width: var(--size-form-max); }
  .field__label { font-size: var(--text-sm); line-height: var(--leading-sm); font-weight: var(--font-weight-medium); color: var(--foreground); }
  .field__optional { font-weight: var(--font-weight-regular); color: var(--muted-foreground); }
  .field__hint { font-size: var(--text-sm); line-height: var(--leading-sm); color: var(--muted-foreground); margin-top: calc(-1 * var(--space-1)); }
  .field__error { display: flex; gap: var(--space-1); align-items: flex-start; font-size: var(--text-sm); line-height: var(--leading-sm); color: var(--destructive); font-weight: var(--font-weight-medium); }
  .field__error .icon { margin-top: var(--space-0-5); }

  .input, .textarea, .select select { width: 100%; min-height: var(--control-h); padding: 0 var(--space-3);
    background: var(--card); color: var(--foreground);
    border: var(--border-hairline) solid var(--input); border-radius: var(--radius-md);
    font-size: var(--text-base); line-height: var(--leading-base);
    transition: border-color var(--duration-fast) var(--easing-out); }
  @media (min-width: 768px) { .input, .textarea, .select select { font-size: var(--text-sm); line-height: var(--leading-sm); } }
  .input::placeholder, .textarea::placeholder { color: var(--subtle-foreground); opacity: 1; }
  .input:hover, .textarea:hover, .select select:hover, .input.is-hover { border-color: var(--muted-foreground); }
  .input:focus-visible, .textarea:focus-visible, .select select:focus-visible, .input.is-focus { outline: var(--focus-width) solid var(--ring); outline-offset: 0; border-color: var(--ring); border-radius: var(--radius-md); }
  .input:user-invalid, .input[aria-invalid="true"], .textarea[aria-invalid="true"], .select select[aria-invalid="true"] { border-color: var(--destructive); }
  .input:disabled, .textarea:disabled, .select select:disabled { background: var(--muted); color: var(--muted-foreground); border-color: var(--border); cursor: not-allowed; }
  .input[readonly] { background: var(--muted); }
  .input--mono { font-family: var(--font-mono); }
  .input-group { position: relative; display: flex; align-items: center; }
  .input-group > .icon { position: absolute; left: var(--space-3); color: var(--muted-foreground); pointer-events: none; }
  .input-group > .input { padding-left: calc(var(--space-3) + var(--size-icon-sm) + var(--space-2)); }
  .input-group > .kbd { position: absolute; right: var(--space-2); }
  .textarea { padding: var(--space-2) var(--space-3); min-height: calc(5 * var(--leading-sm) + 2 * var(--space-2)); resize: vertical; }
  .textarea--code { font-family: var(--font-mono); font-size: var(--text-sm); line-height: var(--leading-sm); white-space: pre; overflow-wrap: normal; overflow-x: auto; }

  .select { position: relative; display: block; }
  .select select { appearance: none; padding-right: calc(var(--space-3) + var(--size-icon-sm) + var(--space-2)); cursor: pointer; }
  .select > .icon { position: absolute; right: var(--space-3); top: 50%; translate: 0 -50%; pointer-events: none; color: var(--muted-foreground); }
  .select--inline { display: inline-block; width: auto; }
  .select--inline select { width: auto; }

  .kbd { display: inline-flex; align-items: center; height: var(--space-5); padding-inline: var(--space-1); border: var(--border-hairline) solid var(--border); border-radius: var(--radius-sm); background: var(--muted); color: var(--muted-foreground); font-family: var(--font-mono); font-size: var(--text-xs); line-height: var(--leading-xs); }

  /* Checkbox and radio: native inputs, custom drawn. v0.4.2: a 20px box that fills the 20px text line, so no 2px offset. */
  .choice { display: flex; align-items: flex-start; gap: var(--space-2); min-height: var(--size-target-touch); padding-block: calc((var(--size-target-touch) - var(--leading-sm)) / 2); cursor: pointer; font-size: var(--text-sm); line-height: var(--leading-sm); }
  @media (min-width: 768px) { .choice { min-height: var(--size-target-min); padding-block: var(--space-0-5); } }
  /* v0.4.2 note: the 2px block padding above centers a 20px line in the 24px target; it is a target size, not an inset. */
  .choice__hint { display: block; color: var(--muted-foreground); }
  .choice__count { margin-left: auto; color: var(--muted-foreground); font-variant-numeric: tabular-nums; padding-left: var(--space-2); }
  .check, .radio { appearance: none; flex: none; width: var(--size-icon-md); height: var(--size-icon-md); margin: 0; display: grid; place-content: center;
    border: var(--border-hairline) solid var(--input); background: var(--card); cursor: pointer;
    transition: background-color var(--duration-press) var(--easing-out); }
  .check { border-radius: var(--radius-sm); }
  .radio { border-radius: var(--radius-full); }
  .check:hover, .radio:hover, .check.is-hover { border-color: var(--foreground); }
  .check:focus-visible, .radio:focus-visible, .check.is-focus { outline: var(--focus-width) solid var(--ring); outline-offset: var(--focus-offset); }
  .check:checked, .check:indeterminate { background: var(--primary); border-color: var(--primary); }
  .check:checked::before { content: ""; width: var(--size-mark); height: var(--size-mark); background: var(--primary-foreground); clip-path: polygon(14% 44%, 0 59%, 39% 98%, 100% 21%, 86% 7%, 38% 69%); }
  .check:indeterminate::before { content: ""; width: var(--size-mark); height: var(--border-strong); background: var(--primary-foreground); }
  .radio:checked { border-color: var(--primary); }
  .radio:checked::before { content: ""; width: var(--size-dot); height: var(--size-dot); border-radius: var(--radius-full); background: var(--primary); }
  .check:disabled, .radio:disabled { background: var(--muted); border-color: var(--border); cursor: not-allowed; }
  .check:disabled:checked { background: var(--input); border-color: var(--input); }
  .choice:has(:disabled) { color: var(--muted-foreground); cursor: not-allowed; }
  .check[aria-invalid="true"] { border-color: var(--destructive); }

  /* Radio cards (one choice with a description) */
  .choice-card { display: flex; gap: var(--space-3); padding: var(--space-3) var(--space-4); border: var(--border-hairline) solid var(--border); border-radius: var(--radius-md); background: var(--card); cursor: pointer; }
  .choice-card:hover { border-color: var(--input); }
  .choice-card:has(:checked) { border-color: var(--primary); background: var(--primary-soft); box-shadow: inset 0 0 0 var(--border-hairline) var(--primary); }
  .choice-card__title { display: block; font-weight: var(--font-weight-medium); font-size: var(--text-sm); line-height: var(--leading-sm); }
  .choice-card__text { display: block; margin-top: 0; color: var(--muted-foreground); font-size: var(--text-sm); line-height: var(--leading-sm); }

  /* Switch: <button role="switch" aria-checked> */
  .switch { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--control-h); font-size: var(--text-sm); line-height: var(--leading-sm); cursor: pointer; }
  .switch__track { position: relative; width: var(--size-switch-width); height: var(--space-5); flex: none; border-radius: var(--radius-full); background: var(--card); border: var(--border-hairline) solid var(--input); transition: background-color var(--duration-fast) var(--easing-out); }
  .switch__track::after { content: ""; position: absolute; top: var(--border-hairline); left: var(--border-hairline); width: var(--size-icon-sm); height: var(--size-icon-sm); border-radius: var(--radius-full); background: var(--input); transition: translate var(--duration-fast) var(--easing-out); }
  .switch[aria-checked="true"] .switch__track { background: var(--primary); border-color: var(--primary); }
  .switch[aria-checked="true"] .switch__track::after { translate: var(--size-icon-sm) 0; background: var(--primary-foreground); }
  .switch:focus-visible { outline: none; }
  .switch:focus-visible .switch__track, .switch.is-focus .switch__track { outline: var(--focus-width) solid var(--ring); outline-offset: var(--focus-offset); }
  .switch:hover .switch__track { border-color: var(--foreground); }
  .switch[aria-checked="true"]:hover .switch__track { border-color: var(--primary-hover); background: var(--primary-hover); }
  .switch[aria-disabled="true"] { color: var(--muted-foreground); cursor: not-allowed; }
  .switch[aria-disabled="true"] .switch__track { background: var(--muted); border-color: var(--border); }
  .switch[aria-disabled="true"] .switch__track::after { background: var(--border); }

  /* File drop zone (behavior per Carbon file uploader) */
  .dropzone { display: grid; gap: var(--space-3); justify-items: start; padding: var(--space-6) var(--space-4); background: var(--card); border: var(--border-hairline) dashed var(--input); border-radius: var(--radius-lg); transition: background-color var(--duration-fast) var(--easing-out); }
  @media (min-width: 768px) { .dropzone { padding: var(--space-8) var(--space-6); } }
  .dropzone__title { font-size: var(--text-base); line-height: var(--leading-base); font-weight: var(--font-weight-semibold); }
  .dropzone__hint { font-size: var(--text-sm); line-height: var(--leading-sm); color: var(--muted-foreground); }
  .dropzone__icon { color: var(--muted-foreground); }
  .dropzone.is-dragover { background: var(--primary-soft); border-style: solid; border-color: var(--primary); box-shadow: inset 0 0 0 var(--border-hairline) var(--primary); }
  .dropzone.is-dragover .dropzone__icon { color: var(--primary); }
  .dropzone.is-invalid { border-color: var(--destructive); border-style: solid; }
  .dropzone[aria-disabled="true"] { background: var(--muted); border-color: var(--border); }
  .dropzone[aria-disabled="true"] .dropzone__title { color: var(--muted-foreground); }
  .file-list { list-style: none; padding: 0; display: grid; gap: var(--space-2); width: 100%; }
  .file-item { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: var(--space-1) var(--space-3); padding: var(--space-2) var(--space-3); border: var(--border-hairline) solid var(--border); border-radius: var(--radius-md); background: var(--card); font-size: var(--text-sm); line-height: var(--leading-sm); }
  .file-item__name { font-weight: var(--font-weight-medium); overflow-wrap: anywhere; }
  .file-item__meta { color: var(--muted-foreground); font-variant-numeric: tabular-nums; }
  .file-item .progress { grid-column: 2 / -1; }
  .file-item__error { grid-column: 2 / -1; color: var(--destructive); }

  /* Tabs */
  .tabs { display: flex; gap: var(--space-1); border-bottom: var(--border-hairline) solid var(--border); overflow-x: auto; scrollbar-width: none; }
  .tab { display: inline-flex; align-items: center; gap: var(--space-2); height: var(--control-h); padding-inline: var(--space-3); white-space: nowrap; color: var(--muted-foreground); font-size: var(--text-sm); line-height: var(--leading-sm); font-weight: var(--font-weight-medium); box-shadow: inset 0 calc(-1 * var(--border-strong)) 0 transparent; text-decoration: none; }
  @media (min-width: 768px) { .tab { height: var(--size-row-normal); } }
  .tab:hover, .tab.is-hover { color: var(--foreground); box-shadow: inset 0 calc(-1 * var(--border-strong)) 0 var(--border); }
  .tab[aria-selected="true"] { color: var(--foreground); box-shadow: inset 0 calc(-1 * var(--border-strong)) 0 var(--primary); }
  .tab:focus-visible, .tab.is-focus { outline-offset: calc(-1 * var(--focus-width)); }
  .tab[aria-disabled="true"] { color: var(--subtle-foreground); cursor: not-allowed; box-shadow: none; }
  .count { display: inline-flex; align-items: center; min-width: var(--space-5); height: var(--space-5); justify-content: center; padding-inline: var(--space-1); border-radius: var(--radius-sm); background: var(--secondary); color: var(--secondary-foreground); font-size: var(--text-xs); line-height: var(--leading-xs); font-weight: var(--font-weight-medium); font-variant-numeric: tabular-nums; }

  /* Segmented control: radio group */
  .seg { display: inline-flex; padding: calc(var(--space-1) - var(--border-hairline)); gap: var(--space-1); background: var(--muted); border: var(--border-hairline) solid var(--border); border-radius: var(--radius-md); max-width: 100%; overflow-x: auto; }
  .seg__item { position: relative; display: inline-flex; }
  .seg__item input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
  .seg__item span { display: inline-flex; align-items: center; gap: var(--space-1); height: calc(var(--control-h) - 2 * var(--space-1)); padding-inline: var(--space-3); border-radius: var(--radius-sm); color: var(--muted-foreground); font-size: var(--text-sm); line-height: var(--leading-sm); font-weight: var(--font-weight-medium); white-space: nowrap; }
  .seg__item:hover span { color: var(--foreground); }
  .seg__item input:checked + span { background: var(--primary); color: var(--primary-foreground); } /* v0.4.3 (Paperralph v0.4.3 nit 3, Testingralph nit): the selected segment is a filled thumb, no shadow and no second ring inside the --input frame */
  @media (forced-colors: active) { .seg__item input:checked + span { background: Highlight; color: HighlightText; forced-color-adjust: none; } }
  .seg__item input:focus-visible + span { outline: var(--focus-width) solid var(--ring); outline-offset: var(--border-hairline); }
  .seg__item input:disabled + span { color: var(--subtle-foreground); cursor: not-allowed; }

  /* Menu (popover attribute, role="menu") */
  .menu { min-width: var(--size-menu-min); max-width: min(var(--size-overlay-max), calc(100vw - 2 * var(--space-4))); padding: var(--space-1); background: var(--popover); color: var(--popover-foreground); border: var(--border-hairline) solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-2); }
  .menu[popover] { margin: 0; inset: auto; }
  .menu--static { display: inline-block; }
  .menu__label { padding: var(--space-2) var(--space-2) var(--space-1); font-size: var(--text-xs); line-height: var(--leading-xs); color: var(--muted-foreground); font-weight: var(--font-weight-medium); }
  .menu__item { display: flex; align-items: center; gap: var(--space-2); width: 100%; min-height: var(--item-h); padding-inline: var(--space-2); border-radius: var(--radius-sm); text-align: left; font-size: var(--text-sm); line-height: var(--leading-sm); color: var(--popover-foreground); text-decoration: none; }
  .menu__item:hover, .menu__item:focus-visible, .menu__item.is-hover { background: var(--accent); outline: none; }
  .menu__item:focus-visible { box-shadow: inset 0 0 0 var(--focus-width) var(--ring); }
  .menu__item .icon { color: var(--muted-foreground); }
  .menu__item[aria-checked="true"] .icon--check { color: var(--foreground); }
  .menu__item--destructive { color: var(--destructive); }
  .menu__item--destructive .icon { color: var(--destructive); }
  .menu__item[aria-disabled="true"] { color: var(--subtle-foreground); cursor: not-allowed; background: none; }
  .menu__item kbd, .menu__hint { margin-left: auto; color: var(--muted-foreground); font-size: var(--text-xs); line-height: var(--leading-xs); }
  .menu__sep { height: var(--border-hairline); background: var(--border); margin: var(--space-1) calc(-1 * var(--space-1)); }

  /* Dialog (native <dialog>) and sheet */
  .dialog { width: min(var(--size-dialog-max), calc(100vw - 2 * var(--space-4))); max-height: calc(100dvh - 2 * var(--space-8)); background: var(--popover); color: var(--popover-foreground); border: var(--border-hairline) solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-3); }
  .dialog::backdrop { background: var(--scrim); }
  .dialog[open] { animation: dialog-in var(--duration-base) var(--easing-out); }
  .dialog__header { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-4); padding: var(--space-4) var(--space-4) 0 var(--space-6); }
  .dialog__title { font-size: var(--text-lg); line-height: var(--leading-lg); padding-top: var(--space-2); }
  .dialog__body { padding: var(--space-3) var(--space-6) var(--space-6); color: var(--muted-foreground); }
  .dialog__footer { display: flex; flex-wrap: wrap-reverse; justify-content: flex-end; gap: var(--space-2); padding: var(--space-4) var(--space-6); border-top: var(--border-hairline) solid var(--border); }
  .dialog--static { position: static; display: block; margin: 0; width: 100%; max-width: var(--size-dialog-max); }
  .sheet { margin: auto 0 0; width: 100%; max-width: 100%; max-height: 85dvh; overflow: auto; border-radius: var(--radius-lg) var(--radius-lg) 0 0; }
  .sheet[open] { animation: sheet-in var(--duration-slow) var(--easing-drawer); }
  @keyframes sheet-in { from { transform: translateY(100%); } }
  @keyframes dialog-in { from { opacity: 0; transform: translateY(var(--space-2)) scale(0.98); } }

  /* Tooltip (inverted) and popover */
  .tooltip { display: inline-block; max-width: var(--size-tooltip-max); padding: var(--space-1) var(--space-2); background: var(--foreground); color: var(--background); border-radius: var(--radius-sm); font-size: var(--text-xs); line-height: var(--leading-xs); box-shadow: var(--shadow-2); }
  .tooltip[popover] { margin: 0; border: 0; inset: auto; }
  .tooltip[popover]:not(:popover-open) { display: none; } /* v0.3: .tooltip sets display, which would otherwise override the UA rule that hides a closed popover */
  .popover { max-width: min(var(--size-overlay-max), calc(100vw - 2 * var(--space-4))); padding: var(--space-3) var(--space-4); background: var(--popover); color: var(--popover-foreground); border: var(--border-hairline) solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-2); font-size: var(--text-sm); line-height: var(--leading-sm); }
  .popover[popover] { margin: 0; inset: auto; }
  .popover--static, .tooltip--static { position: static; }

  /* Toast */
  .toast-region { position: fixed; z-index: var(--z-toast); left: var(--space-4); right: var(--space-4); bottom: var(--space-4); display: grid; gap: var(--space-2); justify-items: end; pointer-events: none; }
  @media (min-width: 768px) { .toast-region { left: auto; right: var(--space-6); bottom: var(--space-6); width: var(--size-toast-max); } }
  .toast-region--static { position: static; width: auto; justify-items: start; }
  /* v0.4.3 round 5 (Testingralph round 4 N1, nit c): the static toasts are a picture, so their Dismiss is inert and looks it:
     out of the tab order and aria-disabled in the markup, and no hover or press here. */
  .toast-region--static .btn { pointer-events: none; }
  .toast { pointer-events: auto; width: 100%; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: var(--space-2) var(--space-3); align-items: start; padding: var(--space-3) var(--space-3) var(--space-3) var(--space-4); background: var(--popover); color: var(--popover-foreground); border: var(--border-hairline) solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-2); font-size: var(--text-sm); line-height: var(--leading-sm); animation: toast-in var(--duration-base) var(--easing-out); }
  .toast > .icon { margin-top: var(--space-0-5); }
  .toast__title { font-weight: var(--font-weight-medium); }
  .toast__text { color: var(--muted-foreground); }
  .toast__actions { grid-column: 2 / -1; display: flex; gap: var(--space-2); }
  @keyframes toast-in { from { opacity: 0; transform: translateY(var(--space-2)); } }

  /* Alert / banner: soft surface, icon and title. No side stripe. */
  .alert { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--space-1) var(--space-3); padding: var(--space-3) var(--space-4); border-radius: var(--radius-md); background: var(--muted); color: var(--foreground); font-size: var(--text-sm); line-height: var(--leading-sm); }
  .alert > .icon { margin-top: var(--space-0-5); color: var(--muted-foreground); }
  .alert__title { font-weight: var(--font-weight-semibold); }
  .alert__body { grid-column: 2; color: var(--foreground); }
  .alert__body ul { padding-left: var(--space-5); }
  .alert__actions { grid-column: 2; display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-2); }
  /* v0.3: soft tint plus a colored hairline border (light and dark) */
  .alert { border: var(--border-hairline) solid var(--_alert-bd, var(--border)); }
  .alert--error { --_alert-bd: color-mix(in oklab, var(--destructive) 45%, transparent); }
  .alert--warning { --_alert-bd: color-mix(in oklab, var(--warning) 45%, transparent); }
  .alert--success { --_alert-bd: color-mix(in oklab, var(--success) 45%, transparent); }
  .alert--info { --_alert-bd: color-mix(in oklab, var(--info) 45%, transparent); }
  .banner { border-inline: 0; }
  .alert--error { background: var(--destructive-soft); } .alert--error > .icon { color: var(--destructive); }
  .alert--warning { background: var(--warning-soft); } .alert--warning > .icon { color: var(--warning); }
  .alert--success { background: var(--success-soft); } .alert--success > .icon { color: var(--success); }
  .alert--info { background: var(--info-soft); } .alert--info > .icon { color: var(--info); }
  .banner { border-radius: 0; }
  .error-summary { padding: var(--space-4); border: var(--border-strong) solid var(--destructive); border-radius: var(--radius-md); background: var(--card); }
  .error-summary h2 { font-size: var(--text-base); line-height: var(--leading-base); margin-bottom: var(--space-2); }
  .error-summary ul { padding-left: var(--space-5); }
  .error-summary a { color: var(--destructive); font-weight: var(--font-weight-medium); }

  /* Status (icon plus word, no fill) and badge (soft fill) */
  .status { display: inline-flex; align-items: center; gap: var(--space-1); font-size: var(--text-sm); line-height: var(--leading-sm); font-weight: var(--font-weight-medium); white-space: nowrap; color: var(--foreground); }
  .status > .icon { color: var(--muted-foreground); }
  .status--error > .icon { color: var(--destructive); }
  .status--warning > .icon { color: var(--warning); }
  .status--success > .icon { color: var(--success); }
  .status--info > .icon { color: var(--info); }
  .badge { display: inline-flex; align-items: center; gap: var(--space-1); height: var(--space-6); padding-inline: var(--space-2); border-radius: var(--radius-sm); background: var(--secondary); color: var(--secondary-foreground); font-size: var(--text-xs); line-height: var(--leading-xs); font-weight: var(--font-weight-medium); white-space: nowrap; }
  .badge .icon { width: var(--size-icon-xs); height: var(--size-icon-xs); }
  .badge--error { background: var(--destructive-soft); color: var(--foreground); } .badge--error .icon { color: var(--destructive); }
  .badge--warning { background: var(--warning-soft); color: var(--foreground); } .badge--warning .icon { color: var(--warning); }
  .badge--success { background: var(--success-soft); color: var(--foreground); } .badge--success .icon { color: var(--success); }
  .badge--info { background: var(--info-soft); color: var(--foreground); } .badge--info .icon { color: var(--info); }
  .badge--accent { background: var(--primary-soft); color: var(--primary-soft-foreground); }

  /* Summary strip: counts as words, not KPI tiles */
  .result-summary { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-6); align-items: center; font-size: var(--text-sm); line-height: var(--leading-sm); }
  .result-summary__verdict { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-lg); line-height: var(--leading-lg); font-weight: var(--font-weight-semibold); width: 100%; }
  .result-summary__verdict .icon { width: var(--size-icon-md); height: var(--size-icon-md); }
  .result-summary__meta { color: var(--muted-foreground); font-variant-numeric: tabular-nums; }
  .num { font-variant-numeric: tabular-nums; text-align: right; }
  .mono { font-family: var(--font-mono); font-size: var(--text-sm); line-height: var(--leading-sm); }

  /* Toolbar above tables */
  .toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); padding: var(--space-3) var(--space-4); border-bottom: var(--border-hairline) solid var(--border); }
  .toolbar__search { flex: 1 1 var(--size-sidebar); max-width: var(--size-search-max); }
  .toolbar__end { margin-left: auto; display: flex; gap: var(--space-2); flex-wrap: wrap; }
  .toolbar--batch { background: var(--primary-soft); color: var(--primary-soft-foreground); }
  .chip { display: inline-flex; align-items: center; gap: var(--space-1); height: var(--control-h-sm); min-height: var(--size-target-min); padding-left: var(--space-2); border-radius: var(--radius-sm); background: var(--secondary); color: var(--secondary-foreground); font-size: var(--text-sm); line-height: var(--leading-sm); }
  .chip__remove { display: inline-grid; place-items: center; width: var(--control-h-sm); height: var(--control-h-sm); border-radius: var(--radius-sm); color: var(--muted-foreground); }
  .chip__remove:hover { color: var(--foreground); background: var(--accent); }

  /* Table */
  .table-wrap { position: relative; z-index: var(--z-base); overflow: auto; background: var(--card); overscroll-behavior-x: contain; }
  .table-wrap--scroll { max-height: min(var(--size-scroll-max), calc(100dvh - var(--size-header) - var(--space-16) - var(--space-16) - var(--space-8))); }
  .table { width: 100%; font-size: var(--text-sm); line-height: var(--leading-sm); font-variant-numeric: tabular-nums; }
  .table th, .table td { height: var(--row-h); padding: var(--space-2) var(--space-3); text-align: left; vertical-align: top; border-bottom: var(--border-hairline) solid var(--border); }
  .table thead th { position: sticky; top: 0; z-index: var(--z-sticky); background: var(--muted); color: var(--foreground); font-weight: var(--font-weight-medium); vertical-align: bottom; white-space: nowrap; }
  .table tbody th { font-weight: var(--font-weight-regular); }  /* v0.2: no browser bold (700) on row headers */
  .table tbody tr:hover, .table tbody tr.is-hover { background: var(--muted); }
  .table tbody tr[aria-selected="true"] { background: var(--primary-soft); }
  .table tbody tr:last-child td { border-bottom: 0; }
  .table .num { text-align: right; }
  .table .nowrap { white-space: nowrap; }
  .table .clamp { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; max-width: var(--size-cell-max); }
  .table .wrap-anywhere { overflow-wrap: anywhere; }
  .table .col-select { width: var(--space-10); padding-right: 0; }
  .table .col-actions { width: var(--space-12); text-align: right; padding-block: var(--space-1); }
  .table .pin { position: sticky; left: 0; z-index: var(--z-raised); background: var(--card); box-shadow: inset calc(-1 * var(--border-hairline)) 0 0 var(--border); }
  .table thead .pin { z-index: calc(var(--z-sticky) + 1); background: var(--muted); }
  .table tbody tr:hover .pin { background: var(--muted); }
  .table tbody tr[aria-selected="true"] .pin { background: var(--primary-soft); }
  .table[data-density="condensed"] { --row-h: var(--size-row-condensed); }
  .table[data-density="condensed"] td { padding-block: var(--space-1); }
  .table[data-density="spacious"] { --row-h: var(--size-row-spacious); }
  .table td.is-error { background: var(--destructive-soft); }
  .th-sort { display: inline-flex; align-items: center; gap: var(--space-1); font-weight: inherit; color: inherit; min-height: var(--size-target-min); text-align: left; border-radius: var(--radius-sm); }
  .th-sort .icon { color: var(--subtle-foreground); }
  [aria-sort] .th-sort .icon { color: var(--foreground); }
  @media (hover: hover) {
    th:not([aria-sort]) .th-sort .icon { opacity: 0; transition: opacity var(--duration-fast) var(--easing-out); }
    th:not([aria-sort]) .th-sort:hover .icon, th:not([aria-sort]) .th-sort:focus-visible .icon { opacity: 1; }
  }
  .th-sort:hover { color: var(--foreground); text-decoration: underline; text-underline-offset: 0.2em; }
  .th-count { display: block; font-size: var(--text-xs); line-height: var(--leading-xs); font-weight: var(--font-weight-regular); color: var(--muted-foreground); }
  .not-stated, .nil { color: var(--muted-foreground); }
  .row-link { color: var(--foreground); font-weight: var(--font-weight-medium); text-decoration: none; }
  .row-link:hover { text-decoration: underline; }
  .cell-sub { display: block; color: var(--muted-foreground); }
  @media (max-width: 767.98px) { .table .p3 { display: none; } }
  @media (max-width: 1279.98px) { .table .p4 { display: none; } }

  /* Pagination */
  .pagination { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-3) var(--space-4); border-top: var(--border-hairline) solid var(--border); font-size: var(--text-sm); line-height: var(--leading-sm); color: var(--muted-foreground); }
  .pagination__pages { display: flex; align-items: center; gap: var(--space-2); }
  .pagination__range { font-variant-numeric: tabular-nums; }

  /* Filters / facets */
  .facets { display: grid; gap: var(--space-6); align-content: start; }
  .facet legend { font-size: var(--text-sm); line-height: var(--leading-sm); font-weight: var(--font-weight-semibold); margin-bottom: var(--space-1); }
  .facet__more { margin-top: var(--space-1); }
  .facet-toggle { display: inline-flex; }
  @media (max-width: 1279.98px) { .facets--side { display: none; } }
  @media (min-width: 1280px) { .facet-toggle { display: none; } }

  /* Empty, loading and error states */
  .state { display: grid; justify-items: start; gap: var(--space-2); padding: var(--space-8) var(--space-4); max-width: var(--size-form-max); }
  .state--center { justify-items: center; text-align: center; margin-inline: auto; }
  .state > .icon { width: var(--size-icon-md); height: var(--size-icon-md); color: var(--muted-foreground); margin-bottom: var(--space-1); }
  .state__title { font-size: var(--text-base); line-height: var(--leading-base); font-weight: var(--font-weight-semibold); }
  .state__text { font-size: var(--text-sm); line-height: var(--leading-sm); color: var(--muted-foreground); }
  .state__actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-2); }
  .state--error > .icon { color: var(--destructive); }
  .skeleton { display: block; height: var(--leading-sm); border-radius: var(--radius-sm); background: var(--secondary); animation: pulse var(--duration-pulse) var(--easing-in-out) infinite; }
  .skeleton--text { height: var(--space-3); margin-block: var(--space-1); }
  .skeleton--w25 { width: 25%; } .skeleton--w40 { width: 40%; } .skeleton--w60 { width: 60%; } .skeleton--w80 { width: 80%; }
  @keyframes pulse { 50% { opacity: 0.55; } }
  /* Spinner (v0.4.2, MF10): our own mark, not the stock ring. A 2px comet: a faint full track with a tail that fades into
     a bright head, drawn with a conic gradient and cut to a ring with a mask. currentColor, so it follows the button. */
  /* v0.4.3 round 4 (Paperralph r3 nit 1): the ring and the head turn as pseudo-elements, so the .spinner box itself never
     rotates. Its getBoundingClientRect stays 16 by 16 px at every moment, and the gaps inside a busy button measure equal
     (a turning box reported up to 1 px more on the spinner side). Same drawing as v0.4.2. */
  .spinner { --_w: var(--border-strong); display: inline-block; position: relative; width: var(--size-icon-sm); height: var(--size-icon-sm); flex: none; border-radius: var(--radius-full); color: var(--primary); }
  .spinner::before { content: ""; position: absolute; inset: 0; border-radius: inherit;
    background: conic-gradient(from 0turn, transparent 0turn, color-mix(in oklab, currentColor 12%, transparent) 0.15turn, currentColor 0.9turn, transparent 0.9turn), color-mix(in oklab, currentColor 16%, transparent);
    -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - var(--_w) - var(--border-hairline)), #000 calc(100% - var(--_w))); mask: radial-gradient(farthest-side, transparent calc(100% - var(--_w) - var(--border-hairline)), #000 calc(100% - var(--_w)));
    animation: spin var(--duration-spin) linear infinite; }
  .spinner::after { content: ""; position: absolute; top: 0; left: 50%; width: var(--_w); height: var(--_w); margin-left: calc(-0.5 * var(--_w)); border-radius: var(--radius-full); background: currentColor; rotate: -0.1turn; transform-origin: 50% calc(var(--size-icon-sm) / 2);
    animation: spin-head var(--duration-spin) linear infinite; }
  @keyframes spin { to { rotate: 1turn; } }
  @keyframes spin-head { from { rotate: -0.1turn; } to { rotate: 0.9turn; } }
  @media (prefers-reduced-motion: reduce) { .spinner::before, .spinner::after { animation: none; } .skeleton { animation: none; } }
  @media (forced-colors: active) { .spinner::before { background: CanvasText; } }

  /* Progress */
  .progress { display: grid; gap: var(--space-1); width: 100%; }
  .progress__label { display: flex; justify-content: space-between; gap: var(--space-3); font-size: var(--text-sm); line-height: var(--leading-sm); }
  .progress__value { color: var(--muted-foreground); font-variant-numeric: tabular-nums; }
  .progress__track { height: var(--space-2); border-radius: var(--radius-sm); background: var(--secondary); overflow: hidden; box-shadow: inset 0 0 0 var(--border-hairline) var(--input); }
  /* v0.2: the bar width is set from aria-valuenow by script through the CSSOM (allowed under style-src 'self'); no width classes. */
  .progress__bar { width: 0; height: 100%; background: var(--primary); border-radius: var(--radius-sm); transition: width var(--duration-base) var(--easing-out); }
  .progress--error .progress__bar { background: var(--destructive); }

  /* Stepper */
  .stepper { list-style: none; padding: 0; display: grid; gap: var(--space-1); counter-reset: step; }
  .stepper__item a, .stepper__item > span { display: flex; align-items: center; gap: var(--space-2); min-height: var(--item-h); padding-inline: var(--space-2); border-radius: var(--radius-sm); color: var(--muted-foreground); text-decoration: none; font-size: var(--text-sm); line-height: var(--leading-sm); }
  .stepper__item a:hover { background: var(--accent); color: var(--foreground); }
  .stepper__num { display: inline-grid; place-items: center; width: var(--space-5); height: var(--space-5); flex: none; border-radius: var(--radius-full); border: var(--border-hairline) solid var(--input); font-size: var(--text-xs); line-height: var(--leading-xs); font-variant-numeric: tabular-nums; color: var(--muted-foreground); }
  .stepper__item.is-done .stepper__num { background: var(--primary); border-color: var(--primary); color: var(--primary-foreground); }
  .stepper__item.is-done a { color: var(--foreground); }
  .stepper__item [aria-current="step"] { background: var(--primary-soft); color: var(--primary-soft-foreground); font-weight: var(--font-weight-semibold); }
  .stepper__item [aria-current="step"] .stepper__num { border-color: var(--primary); color: var(--primary-soft-foreground); border-width: var(--border-strong); }
  .stepper__item.is-error a { color: var(--foreground); }
  .stepper__item.is-error .stepper__num { border-color: var(--destructive); color: var(--destructive); }
  .stepper__state { margin-left: auto; font-size: var(--text-xs); line-height: var(--leading-xs); color: var(--muted-foreground); }
  .stepper__item.is-error .stepper__state { color: var(--destructive); }
  .stepper-compact { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); font-size: var(--text-sm); line-height: var(--leading-sm); }
  .step-footer { display: flex; justify-content: space-between; gap: var(--space-2); padding: var(--space-3) var(--space-4); background: var(--card); border-top: var(--border-hairline) solid var(--border); }

  /* Summary list (check your answers) */
  .summary-list { display: grid; font-size: var(--text-sm); line-height: var(--leading-sm); }
  .summary-list__row { display: grid; gap: var(--space-1) var(--space-4); padding-block: var(--space-3); border-bottom: var(--border-hairline) solid var(--border); }
  @media (min-width: 768px) { .summary-list__row { grid-template-columns: var(--size-summary-col) minmax(0, 1fr) auto; } }
  .summary-list dt { font-weight: var(--font-weight-medium); }
  .summary-list dd { margin: 0; }

  /* Code block */
  .code { position: relative; background: var(--muted); border: var(--border-hairline) solid var(--border); border-radius: var(--radius-md); }
  .code pre { margin: 0; padding: var(--space-3) var(--space-4); overflow-x: auto; font-size: var(--text-sm); line-height: var(--leading-sm); tab-size: 2; }
  .code__copy { position: absolute; top: var(--space-1); right: var(--space-1); }
  .code__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); padding: var(--space-1) var(--space-1) var(--space-1) var(--space-4); border-bottom: var(--border-hairline) solid var(--border); font-size: var(--text-xs); line-height: var(--leading-xs); color: var(--muted-foreground); }
  .tok-keyword { color: var(--syntax-keyword); } .tok-string { color: var(--syntax-string); } .tok-number { color: var(--syntax-number); } .tok-property { color: var(--syntax-property); } .tok-comment { color: var(--syntax-comment); font-style: italic; }
  .tok-punct { color: var(--syntax-comment); }
  .editor__group--end { margin-left: auto; }
  .hl-error { text-decoration: underline wavy var(--destructive); text-decoration-thickness: var(--border-hairline); text-underline-offset: var(--space-0-5); }
  .hl-warning { text-decoration: underline wavy var(--warning); text-decoration-thickness: var(--border-hairline); text-underline-offset: var(--space-0-5); }

  /* CodeMirror 6 theme (class names are CodeMirror's own) */
  .cm-editor { background: var(--card); color: var(--foreground); font-family: var(--font-mono); font-size: var(--text-sm); line-height: var(--leading-sm); height: 100%; }
  .cm-scroller { overflow: auto; font-family: inherit; display: flex; align-items: flex-start; }
  .cm-gutters { background: var(--muted); color: var(--subtle-foreground); border-right: var(--border-hairline) solid var(--border); flex: none; text-align: right; user-select: none; position: sticky; left: 0; z-index: var(--z-raised); padding: var(--space-2) 0; }
  .cm-gutterElement { padding: 0 var(--space-2) 0 var(--space-3); min-width: var(--space-10); display: flex; align-items: center; justify-content: flex-end; gap: var(--space-1); height: var(--leading-sm); }
  .cm-gutterElement .icon { width: var(--size-icon-xs); height: var(--size-icon-xs); }
  .cm-gutterElement.is-error .icon { color: var(--destructive); }
  .cm-gutterElement.is-warning .icon { color: var(--warning); }
  .cm-content { padding: var(--space-2) 0; white-space: pre; flex: 1 0 auto; caret-color: var(--foreground); }
  .cm-line { padding: 0 var(--space-4) 0 var(--space-3); height: var(--leading-sm); }
  .cm-activeLine { background: var(--muted); }
  .cm-activeLineGutter { color: var(--foreground); }
  .cm-selectionBackground { background: var(--selection); }
  .cm-editor.cm-focused { outline: var(--focus-width) solid var(--ring); outline-offset: calc(-1 * var(--focus-width)); }

  /* ProseMirror document (Policy Hub editor) */
  /* v0.4.2: the frame is a control edge, so it takes --input (3:1 or more on card and page), not the decorative hairline. */
  .editor { background: var(--card); border: var(--border-hairline) solid var(--input); border-radius: var(--radius-lg); }
  /* v0.2: the toolbar never clips (no overflow: hidden). Below 768px it is not sticky, so it cannot cover the focused item (2.4.11). */
  .editor__toolbar { display: flex; flex-wrap: nowrap; align-items: center; gap: var(--space-1); padding: var(--space-1) var(--space-2); background: var(--card); border-bottom: var(--border-hairline) solid var(--border); }
  @media (min-width: 768px) { .editor__toolbar { position: sticky; top: var(--size-header); z-index: var(--z-sticky); } }
  .editor__toolbar .btn[aria-pressed="true"] { background: var(--secondary); }
  .editor__group { display: flex; gap: var(--space-1); }
  .editor__divider { width: var(--border-hairline); align-self: stretch; margin: var(--space-1) var(--space-1); background: var(--border); }
  .editor__toolbar .p3 { display: none; }
  @media (min-width: 768px) { .editor__toolbar .p3 { display: flex; } }
  .editor__toolbar .more { margin-left: auto; }
  .ProseMirror { max-width: var(--size-prose-max); margin-inline: auto; padding: var(--space-6) var(--space-4) var(--space-12); font-size: var(--text-base); line-height: var(--leading-prose); color: var(--foreground); white-space: pre-wrap; word-wrap: break-word; }
  @media (min-width: 768px) { .ProseMirror { padding-inline: var(--space-8); } }
  .ProseMirror:focus { outline: none; }
  .ProseMirror:focus-visible { outline: var(--focus-width) solid var(--ring); outline-offset: calc(-1 * var(--focus-width)); }
  .ProseMirror h1 { font-size: var(--text-xl); line-height: var(--leading-xl); margin-bottom: var(--space-4); }
  .ProseMirror h2 { font-size: var(--text-lg); line-height: var(--leading-lg); margin-top: var(--space-8); margin-bottom: var(--space-2); }
  .ProseMirror h3 { font-size: var(--text-base); line-height: var(--leading-base); margin-top: var(--space-6); margin-bottom: var(--space-1); }
  .ProseMirror p + p, .ProseMirror ul, .ProseMirror ol { margin-top: var(--space-3); }
  .ProseMirror ul, .ProseMirror ol { padding-left: var(--space-6); }
  .ProseMirror li + li { margin-top: var(--space-1); }
  .ProseMirror blockquote { margin-top: var(--space-4); padding-left: var(--space-4); color: var(--muted-foreground); box-shadow: inset var(--border-strong) 0 0 var(--border); }
  .ProseMirror code { background: var(--muted); border-radius: var(--radius-sm); padding: 0 var(--space-1); }
  .ProseMirror .is-empty::before { content: attr(data-placeholder); color: var(--subtle-foreground); pointer-events: none; float: left; height: 0; }
  .ProseMirror-selectednode { outline: var(--focus-width) solid var(--ring); }
  .ProseMirror .is-filled { background: var(--primary-soft); color: var(--primary-soft-foreground); border-radius: var(--radius-sm); padding: 0 var(--space-0-5); }
  .editor__status { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-4); padding: var(--space-2) var(--space-4); border-top: var(--border-hairline) solid var(--border); font-size: var(--text-xs); line-height: var(--leading-xs); color: var(--muted-foreground); }

  /* Two-pane workspace */
  .workspace { display: grid; grid-template-rows: auto minmax(0, 1fr) auto; height: calc(100dvh - var(--size-header) - 2 * var(--space-4)); min-height: var(--size-pane-min); background: var(--card); border: var(--border-hairline) solid var(--border); border-radius: var(--radius-lg); overflow: hidden; }
  .workspace__bar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-3); border-bottom: var(--border-hairline) solid var(--border); }
  .workspace__bar .tabs { border-bottom: 0; }
  .workspace__panes { display: grid; min-height: 0; }
  .workspace__pane { min-height: 0; min-width: 0; overflow: auto; display: flex; flex-direction: column; }
  .workspace__pane-head { position: sticky; top: 0; z-index: var(--z-sticky); display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); min-height: var(--size-row-normal); padding: var(--space-1) var(--space-3); background: var(--muted); border-bottom: var(--border-hairline) solid var(--border); font-size: var(--text-sm); line-height: var(--leading-sm); font-weight: var(--font-weight-medium); }
  .workspace__pane + .workspace__pane { border-top: var(--border-hairline) solid var(--border); }
  .workspace__pane[data-hidden-below-lg] { display: none; }
  .workspace__switch { display: flex; }
  @media (min-width: 1280px) {
    .workspace__panes { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
    .workspace__pane + .workspace__pane { border-top: 0; border-left: var(--border-hairline) solid var(--border); }
    .workspace__pane[data-hidden-below-lg] { display: flex; }
    .workspace__switch { display: none; }
  }
  .workspace__status { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-4); padding: var(--space-1) var(--space-3); border-top: var(--border-hairline) solid var(--border); background: var(--muted); font-size: var(--text-xs); line-height: var(--leading-xs); color: var(--muted-foreground); }

  /* Problems list */
  .problems { list-style: none; padding: 0; }
  .problem { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: var(--space-1) var(--space-3); padding: var(--space-3); border-bottom: var(--border-hairline) solid var(--border); font-size: var(--text-sm); line-height: var(--leading-sm); }
  .problem:hover { background: var(--muted); }
  .problem > .icon { margin-top: var(--space-0-5); }
  .problem--error > .icon { color: var(--destructive); }
  .problem--warning > .icon { color: var(--warning); }
  .problem--note > .icon { color: var(--muted-foreground); }
  .problem__loc { font-family: var(--font-mono); font-size: var(--text-sm); line-height: var(--leading-sm); color: var(--muted-foreground); white-space: nowrap; }
  .problem__fix { grid-column: 2 / -1; color: var(--muted-foreground); }
  .problem__msg { font-weight: var(--font-weight-medium); }

  /* Charts (static SVG built by Observable Plot in apps) */
  .chart { display: grid; gap: var(--space-2); }
  .chart svg { width: 100%; height: auto; overflow: visible; font-family: var(--font-sans); font-variant-numeric: tabular-nums; }
  .chart__title { font-size: var(--text-sm); line-height: var(--leading-sm); font-weight: var(--font-weight-semibold); }
  .chart__note { font-size: var(--text-sm); line-height: var(--leading-sm); color: var(--muted-foreground); }
  .chart .axis text, .chart .label { fill: var(--muted-foreground); font-size: var(--text-xs); }
  .chart .label-strong { fill: var(--foreground); font-size: var(--text-xs); font-weight: var(--font-weight-medium); }
  .chart .grid line { stroke: var(--border); }
  .chart .baseline { stroke: var(--input); }
  .chart .mark-gap { stroke: var(--card); stroke-width: var(--border-strong); }
  .fill-chart-1 { fill: var(--chart-1); } .fill-chart-2 { fill: var(--chart-2); } .fill-chart-3 { fill: var(--chart-3); } .fill-chart-4 { fill: var(--chart-4); } .fill-chart-5 { fill: var(--chart-5); }
  .stroke-chart-1 { stroke: var(--chart-1); } .stroke-chart-2 { stroke: var(--chart-2); }
  .legend { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-4); list-style: none; padding: 0; font-size: var(--text-xs); line-height: var(--leading-xs); color: var(--muted-foreground); }
  .legend li { display: inline-flex; align-items: center; gap: var(--space-1); }
  .legend .swatch { width: var(--size-mark); height: var(--size-mark); border-radius: var(--radius-sm); }
  .bg-chart-1 { background: var(--chart-1); } .bg-chart-2 { background: var(--chart-2); } .bg-chart-3 { background: var(--chart-3); } .bg-chart-4 { background: var(--chart-4); } .bg-chart-5 { background: var(--chart-5); }

  /* Description list for row detail */
  .detail { display: grid; gap: var(--space-3); font-size: var(--text-sm); line-height: var(--leading-sm); }
  .detail dt { color: var(--muted-foreground); }
  .detail dd { margin: 0; overflow-wrap: anywhere; }
  @media (min-width: 768px) { .detail { grid-template-columns: var(--size-label-col) minmax(0, 1fr); } }
}

/* ---------- v0.2 additions ---------- */
@layer components {
  /* Missing value with a tooltip. The words are the label; the title adds the reason. */
  button.not-stated { font: inherit; line-height: inherit; background: none; border: 0; padding: 0; margin: 0; color: var(--muted-foreground); text-align: inherit; border-radius: var(--radius-sm); }
  .not-stated[data-tip], .not-stated[title] { cursor: help; text-decoration-line: underline; text-decoration-style: dotted; text-decoration-color: var(--subtle-foreground); text-underline-offset: 0.2em; }

  /* Popover menus are placed next to their button by script (CSSOM, allowed under style-src 'self') */
  .menu[popover], .popover[popover] { position: fixed; }
  /* v0.3: app.js caps max-height to the space left in the viewport; the popover then scrolls inside. */
  .menu[popover], .popover[popover] { overflow-y: auto; overscroll-behavior: contain; }
  .menu .choice { padding-inline: var(--space-2); border-radius: var(--radius-sm); }
  .menu .choice:hover { background: var(--accent); }
  .menu__item[role="menuitemradio"] .icon--check { visibility: hidden; }
  .menu__item[role="menuitemradio"][aria-checked="true"] .icon--check { visibility: visible; color: var(--foreground); }
  .menu-btn .icon:last-child { color: var(--muted-foreground); }

  /* Batch selection bar: replaces nothing, appears under the toolbar while rows are selected */
  .toolbar--batch { gap: var(--space-2) var(--space-4); }
  .toolbar__count { font-size: var(--text-sm); line-height: var(--leading-sm); font-weight: var(--font-weight-medium); }
  .table tbody tr[aria-selected="true"]:hover { background: var(--primary-soft); }
  .table .col-select .check { margin-top: 0; }

  /* Editor: file row, then a separate formatting toolbar */
  .editor__files { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); padding: var(--space-2) var(--space-3); border-bottom: var(--border-hairline) solid var(--border); }
  .editor__files .tabs { border-bottom: 0; flex: 1 1 auto; min-width: 0; display: none; }
  .editor__files .file-select { flex: 1 1 auto; }
  @media (min-width: 768px) { .editor__files .tabs { display: flex; } .editor__files .file-select { display: none; } }
  .editor__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin-left: auto; }
  .select--sm select { min-height: var(--control-h-sm); font-size: var(--text-sm); line-height: var(--leading-sm); }
  .editor__toolbar .select--sm select { padding-left: var(--space-2); }
  .doc-preview[contenteditable="true"]:focus-visible, .doc-edit:focus-visible { outline: var(--focus-width) solid var(--ring); outline-offset: calc(-1 * var(--focus-width)); }
  .ProseMirror .task-list { list-style: none; padding-left: 0; }
  .ProseMirror .task-list li { display: flex; gap: var(--space-2); align-items: flex-start; }
  .ProseMirror .task-list .check { margin-top: var(--space-1); }

  /* Statement and preview boxes */
  .preview-box { padding: var(--space-4); background: var(--muted); border: var(--border-hairline) solid var(--border); border-radius: var(--radius-md); font-size: var(--text-base); line-height: var(--leading-base); }

  /* Problems list with jump to line */
  .problem__loc a { color: inherit; }
  .problem.is-current { background: var(--accent); }
  .cm-line.is-target { background: var(--selection); }
  .cm-gutterElement.is-target { color: var(--foreground); }
  .problems__more { padding: var(--space-3); font-size: var(--text-sm); line-height: var(--leading-sm); color: var(--muted-foreground); }

  /* Facets in a bottom sheet below 1280px */
  .sheet .facets { padding: 0 var(--space-6) var(--space-6); }
  .sheet .dialog__header { position: sticky; top: 0; background: var(--popover); }

  /* Visible label for a region that scrolls on its own */
  .scroll-note { font-size: var(--text-sm); line-height: var(--leading-sm); color: var(--muted-foreground); }

  /* One list of definitions in a resumable job */
  .job { display: grid; gap: var(--space-3); }
}

@layer components {
  /* v0.2 additions, part 2 */
  .th-sort .icon--sort-asc, .th-sort .icon--sort-desc { display: none; }
  [aria-sort="ascending"] .th-sort .icon--sort-asc, [aria-sort="descending"] .th-sort .icon--sort-desc { display: inline-block; }
  [aria-sort="ascending"] .th-sort .icon--sort-none, [aria-sort="descending"] .th-sort .icon--sort-none { display: none; }
  .sheet .facets--side { display: grid; }
  button.row-link { text-align: left; font: inherit; background: none; border: 0; padding: 0; color: inherit; cursor: pointer; }
  button.row-link:hover { text-decoration: underline; text-underline-offset: 0.2em; }
  /* v0.3 A5: in-table buttons get a 24px target (WCAG 2.5.8) without changing the 40px row. */
  button.not-stated, button.row-link { display: inline-flex; align-items: center; min-height: 24px; vertical-align: middle; }
  .menu__item .icon--check { margin-left: auto; }
  .cm-line { scroll-margin-block: var(--space-16); }
  .cm-line:target { background: var(--selection); }
  @media (max-width: 1279.98px) {
    .workspace[data-show="problems"] .workspace__pane:not([data-hidden-below-lg]) { display: none; }
    .workspace[data-show="problems"] .workspace__pane[data-hidden-below-lg] { display: flex; }
  }
  .workspace--fit { height: min(var(--size-scroll-max), 80dvh); }
  .field--inline { display: flex; align-items: center; gap: var(--space-2); }
  .preview-source { white-space: pre-wrap; max-width: var(--size-measure); margin: 0; }
  .prose { max-width: var(--size-measure); }
  .not-stated { white-space: nowrap; }
  @media (min-width: 1280px) { .table tbody .pin { min-width: var(--size-summary-col); } }
}
@layer components {
  /* v0.3: Base UI ScrollArea viewport. With CSPProvider disableStyleElements, Base UI no longer injects
     its own style element, but still puts this class on the viewport, so the native scrollbar has to be
     hidden here (same rules Base UI 1.9.0 ships in utils/styles.js). */
  .base-ui-disable-scrollbar { scrollbar-width: none; }
  .base-ui-disable-scrollbar::-webkit-scrollbar { display: none; }
}
@layer components {
  /* v0.3 layout polish (Testingralph should-fix 5) */
  @media (min-width: 768px) { .grid-2__sticky { position: sticky; top: calc(var(--size-header) + var(--space-4)); } }
  .ProseMirror > :first-child { margin-top: 0; }
  .problems > li { max-width: none; }
  /* Long V2 lines scroll sideways; a short fade at the pane edge keeps text off the divider. */
  .workspace__pane .cm-scroller { mask-image: linear-gradient(to left, transparent, #000 var(--space-4)); }
  /* v0.3 nits: a modal dialog locks the page scroll; on phones long tables grow with the page instead of nesting a second vertical scroll. */
  html:has(dialog:modal) { overflow: hidden; scrollbar-gutter: stable; }
  @media (max-width: 767.98px) { .table-wrap--scroll { max-height: none; } }
}
/* ---------- utilities ---------- */
@layer utilities {
  @media (min-width: 768px) { .app-menu-btn { display: none; } }
  .not-mono { font-family: var(--font-sans); font-weight: var(--font-weight-regular); color: var(--muted-foreground); }
  .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
  .muted { color: var(--muted-foreground); }
  .text-sm { font-size: var(--text-sm); line-height: var(--leading-sm); }
  .text-xs { font-size: var(--text-xs); line-height: var(--leading-xs); }
  .mb-4 { margin-bottom: var(--space-4); } .mt-2 { margin-top: var(--space-2); } .mt-4 { margin-top: var(--space-4); } .mt-6 { margin-top: var(--space-6); } .mt-8 { margin-top: var(--space-8); }
  .w-full { width: 100%; }
  .hide-sm { display: none; }
  @media (min-width: 768px) { .hide-sm { display: revert; } .show-sm-only { display: none; } }
}

/* =====================================================================
   v0.4.1 refresh (graphite, restrained). Visual only: same classes, same
   markup, same behavior as v0.3.2. Hierarchy comes from type, spacing and
   contrast. Cards are flat with a hairline; only floating layers cast a
   shadow. Full pills only on status, badges, tab counts, switch and radio.
   Every value is a token. Reasoning: ../../direction.md.
   ===================================================================== */
@layer base {
  html { font-optical-sizing: auto; text-rendering: optimizeLegibility; -moz-osx-font-smoothing: grayscale; }
  h1, h2, h3, h4 { font-weight: var(--font-weight-semibold); color: var(--foreground); }
  h1 { font-size: var(--text-xl); line-height: var(--leading-xl); letter-spacing: var(--tracking-xl); }
  @media (min-width: 768px) { h1 { font-size: var(--text-2xl); line-height: var(--leading-2xl); letter-spacing: var(--tracking-2xl); } }
  h2 { letter-spacing: var(--tracking-lg); }
  h3 { letter-spacing: var(--tracking-lg); }
  .num, .result-summary__meta, .file-item__meta, .count { font-variant-numeric: tabular-nums; }

  /* At 768px and up the editor toolbar is sticky under the header (28px buttons, 4px padding each side, two hairlines).
     While the document has focus, the caret line scrolls in below the toolbar, not only below the header. */
  :root { --editor-toolbar-h: calc(var(--size-control-sm) + 2 * var(--space-1) + 2 * var(--border-hairline)); }
  @media (min-width: 768px) {
    html:has(.editor [contenteditable="true"]:focus) { scroll-padding-top: calc(var(--size-header) + var(--editor-toolbar-h) + var(--space-4)); }
  }
}

@layer layout {
  /* Header: the page background, slightly translucent with a light blur; solid where transparency is reduced or unsupported. */
  .app-header { background: var(--header-background); -webkit-backdrop-filter: blur(var(--blur-header)); backdrop-filter: blur(var(--blur-header)); }
  @supports not ((backdrop-filter: none) or (-webkit-backdrop-filter: none)) { .app-header { background: var(--background); } }
  @media (prefers-reduced-transparency: reduce) { .app-header { background: var(--background); -webkit-backdrop-filter: none; backdrop-filter: none; } }
  .app-mark .icon { width: var(--size-icon-sm); height: var(--size-icon-sm); }
  /* Current page: 2px accent bar drawn as a box, so forced colors can repaint it (box-shadow is dropped there). */
  .app-nav a { position: relative; box-shadow: none; }
  .app-nav a[aria-current="page"] { box-shadow: none; }
  .app-nav a[aria-current="page"]::after { content: ""; position: absolute; left: var(--space-3); right: var(--space-3); bottom: 0; height: var(--border-strong); background: var(--primary); }

  .page { padding-top: var(--space-8); }
  @media (min-width: 768px) { .page { padding-top: var(--space-10); } }
  .page-header { margin-bottom: var(--space-8); }
  .page-header p { margin-top: var(--space-2); }
  .eyebrow { margin-bottom: var(--space-2); font-weight: var(--font-weight-medium); }
}

@layer components {
  /* Buttons: the v0.3.2 rules apply unchanged. Flat, no shadow, no gradient; solid accent primary;
     secondary keeps the input-colored 1px edge (3:1, project rule). Only the tokens behind them changed. */

  /* Drop zone: muted well, plain icon. */
  .dropzone { background: var(--muted); }
  .dropzone:hover { background: var(--secondary); }

  /* Tabs: same accent bar as the nav, as a box so forced colors can repaint it. Counts are pills. */
  .tab { position: relative; }
  .tab[aria-selected="true"] { box-shadow: none; }
  .tab[aria-selected="true"]::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: var(--border-strong); background: var(--primary); }
  .count { border-radius: var(--radius-full); padding-inline: var(--space-2); }
  .tab[aria-selected="true"] .count { background: var(--foreground); color: var(--background); }

  /* Overlays: solid surface, hairline, one subtle elevation; overlays take the large radius. */
  .menu, .popover, .toast { border-radius: var(--radius-xl); }
  .dialog { border-radius: var(--radius-xl); box-shadow: var(--shadow-2); }

  /* Status and badges: tinted pills that keep icon plus word. */
  .status { padding: 0 var(--space-2); height: var(--space-6); border-radius: var(--radius-full); background: var(--secondary); font-size: var(--text-xs); line-height: var(--leading-xs); }
  .status--error { background: var(--destructive-soft); }
  .status--warning { background: var(--warning-soft); }
  .status--success { background: var(--success-soft); }
  .status--info { background: var(--info-soft); }
  .status > .icon { width: var(--size-icon-xs); height: var(--size-icon-xs); }
  .badge { border-radius: var(--radius-full); }

  /* Summary: the verdict is the loudest line on the page; the icon is plain, in the status color. */
  .result-summary { gap: var(--space-2) var(--space-3); }
  .result-summary__verdict { font-size: var(--text-xl); line-height: var(--leading-xl); letter-spacing: var(--tracking-xl); margin-bottom: var(--space-1); }
  .result-summary__verdict .icon.status--error { color: var(--destructive); }
  .result-summary__verdict .icon.status--warning { color: var(--warning); }
  .result-summary__verdict .icon.status--success { color: var(--success); }
  .result-summary__verdict .icon.status--info { color: var(--info); }

  /* Table: quiet header labels on the muted band, roomier outer gutters. */
  .table thead th { color: var(--muted-foreground); font-size: var(--text-xs); line-height: var(--leading-xs); }
  .table th:first-child, .table td:first-child { padding-left: var(--space-4); }
  .table th:last-child, .table td:last-child { padding-right: var(--space-4); }
  .table tbody tr:hover, .table tbody tr.is-hover { background: var(--muted); }
  .table tbody tr:hover .pin { background: var(--muted); }
  .table td.mono:first-child { font-weight: var(--font-weight-medium); }
}

@layer components {
  /* Lines (v0.4.2). One 1px hairline token (--border) for every frame and divider: panels, the table frame and its
     rows, the header bottom, toolbars. Control edges (inputs, selects, the editor frame) use --input.
     v0.4.1's second hairline (--border-subtle for rows) is merged into --border.
     Where two boxes meet, only one of them draws the line. */
  .table { border-collapse: separate; border-spacing: 0; }
  .panel .table tbody tr:last-child > *,
  .problems > .problem:last-child { border-bottom: 0; }
  /* Pills in table cells sit on the top of the line box, so rows stay on whole pixels (no blurry half pixel lines). */
  .table .status, .table .badge, .table .count, .table .th-sort, .table .not-stated { vertical-align: top; }
  /* Tabs that sit in a toolbar or bar use its bottom line: no second rule, the selected bar lands on the frame line. */
  .toolbar:has(> .tabs) { padding-block: 0; }
  .toolbar > .tabs, .panel__header > .tabs { border-bottom: 0; align-self: stretch; }
  .toolbar > .tabs .tab, .panel__header > .tabs .tab { height: 100%; min-height: var(--control-h); }
  /* Nested radius: a box inside a padded box takes the parent radius minus nothing larger than its own step. */
  .panel .alert, .panel .preview-box, .panel .code { border-radius: var(--radius-md); }
}

@layer components {
  /* EmptyState. v0.4.2 (Testingralph v0.4.1 MF3, MF6, MF7): every size sits top left with 24px padding, like the table
     cells and text around it. Nothing is centered, so nothing lands on a half pixel, and the box is sized to its content. */
  .panel > .state { padding: var(--space-6); max-width: none; }
  .state--success > .icon { color: var(--success); }
  .table td.empty-cell { padding: 0; white-space: normal; }
  .table tbody tr:has(> .empty-cell):hover { background: transparent; }
  .state--inline { padding: var(--space-6) var(--space-4); max-width: none; justify-items: start; text-align: start; }
  .state--inline > .icon { width: var(--size-icon-sm); height: var(--size-icon-sm); }

  /* Loading (v0.4.1). The busy label replaces the button text; the width is reserved by the script before the first click. */
  .btn[aria-busy="true"] { pointer-events: none; }
  .btn__busy { white-space: nowrap; }
  .btn--probe { position: absolute; visibility: hidden; pointer-events: none; }
  .load-error:not([hidden]) { display: block; padding: var(--space-3) var(--space-4); }
  .demo-net { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-4); margin-bottom: var(--space-4); }
  .lazy { display: grid; }
  .lazy .skeleton { opacity: 0; }
  .lazy.is-waiting .skeleton { opacity: 1; transition: opacity var(--duration-fast) var(--easing-out); }
  @media (prefers-reduced-motion: reduce) { .lazy.is-waiting .skeleton { transition: none; } }
}

@layer layout {
  /* Alignment (v0.4.1). Boxes in one row share top and bottom. --equal stretches both columns and lets the main box in
     each grow; --follow lets the left column set the height and the right panel scrolls inside it. */
  .grid-2--equal { align-items: stretch; }
  .grid-2--equal > * { display: flex; flex-direction: column; }
  .grid-2--equal > .stack > :first-child, .grid-2--equal > * > .panel__body, .grid-2--equal > .code > .cm-editor,
  .grid-2--equal > .editor > .doc-preview, .grid-2--equal > * > .panel__body > .preview-box { flex: 1 1 auto; }
  .grid-2--equal > * > .panel__body { display: flex; flex-direction: column; }
  .grid-2--equal .code { display: flex; flex-direction: column; }
  .grid-2--equal .code > .cm-editor { flex: 1 1 auto; }
  .grid-2--grow-last > .stack > :first-child { flex: 0 0 auto; }
  .grid-2--grow-last > .stack > :last-child { flex: 1 1 auto; }
  .grid-2--follow { align-items: stretch; }
  @media (min-width: 768px) {
    .grid-2--follow > :last-child { height: 0; min-height: 100%; display: flex; flex-direction: column; }
    .grid-2--follow > :last-child > .panel__body { flex: 1 1 auto; min-height: 0; overflow: auto; }
  }
}

@layer utilities {
  /* v0.4: .hide-sm used revert, which made header buttons display block and lost vertical centering */
  @media (min-width: 768px) { .btn.hide-sm { display: inline-flex; } }
  /* Forced colors: repaint the current-page and selected-tab bars in the system text color. */
  @media (forced-colors: active) {
    .app-nav a[aria-current="page"]::after, .tab[aria-selected="true"]::after { background: CanvasText; }
  }
}

@layer components {
  /* Two-line rows (v0.4.2). Every row of a list that can show a skeleton holds exactly two text lines, so skeleton
     rows and loaded rows are the same height at every width (57px with the row line). List items in a cell keep to
     one line each; the summary is already clamped to two. */
  .table--two-line { --row-h: calc(2 * var(--leading-sm) + 2 * var(--space-2)); }
  .table--two-line .cell-list li { white-space: nowrap; }
  /* Skeleton table (v0.4.2): the real header row and the real cell classes, one 20px bar per text line, so the
     columns, header height and row height match the loaded table. It never takes hover or selection. */
  .table--skeleton tbody tr:hover, .table--skeleton tbody tr:hover .pin { background: var(--card); }
  .table--skeleton .skeleton--text + .skeleton--text { margin-top: var(--space-2); }
  .table--skeleton .th-sort { cursor: default; }
  .table--skeleton .th-sort:hover { text-decoration: none; }

  /* Top progress line (v0.4.2). One 2px primary line on the top edge of the window for a page level load that no
     single button owns (a list or a block loading). It follows the loading timing: hidden for 300ms, then shown at
     least 600ms, eases toward 90 percent and fills on arrival. Decorative: aria-hidden, the region being loaded has
     aria-busy and the page status region says what is loading. Reduced motion: a still, full line. */
  .top-progress { position: fixed; inset: 0 0 auto; z-index: calc(var(--z-header) + 1); height: var(--border-strong); pointer-events: none; opacity: 0; transition: opacity var(--duration-base) var(--easing-out); }
  .top-progress.is-active { opacity: 1; }
  .top-progress__bar { display: block; height: 100%; background: var(--primary); transform-origin: left center; transform: scaleX(0); transition: transform var(--duration-slow) var(--easing-out); }
  /* Logo loader (v0.4.2): while the top line shows, the product mark in the header breathes. Reduced motion: still. */
  .app-header.is-loading .app-mark__tile { animation: pulse var(--duration-pulse) var(--easing-in-out) infinite; }
  @media (prefers-reduced-motion: reduce) {
    .top-progress, .top-progress__bar { transition: none; }
    .app-header.is-loading .app-mark__tile { animation: none; }
  }
  @media (forced-colors: active) { .top-progress__bar { background: Highlight; } }

  /* Breadcrumbs (v0.4.2). Deeper pages only (help, templates, docs, a dataset); never in the editor. It takes the
     eyebrow's place above the page title, so the header keeps its height. */
  .breadcrumbs ol { display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--space-2); font-size: var(--text-sm); line-height: var(--leading-sm); color: var(--muted-foreground); }
  .breadcrumbs li { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--size-target-min); }
  .breadcrumbs li + li::before { content: "/" / ""; color: var(--subtle-foreground); }
  .breadcrumbs a { display: inline-flex; align-items: center; min-height: var(--size-target-min); color: var(--muted-foreground); text-decoration: none; }
  .breadcrumbs a:hover { color: var(--foreground); text-decoration: underline; text-underline-offset: 0.2em; }
  .breadcrumbs [aria-current="page"] { color: var(--foreground); font-weight: var(--font-weight-medium); }
  .page-header .breadcrumbs { margin-bottom: var(--space-1); }
  @media (pointer: coarse) { .breadcrumbs li, .breadcrumbs a { min-height: var(--size-target-touch); } }

  /* Blank document (v0.4.2). When the open file has no text, an inline EmptyState sits under the first line with one
     action, Start from a template. Typing hides it. */
  .doc-empty { max-width: var(--size-prose-max); margin-inline: auto; padding: 0 var(--space-4) var(--space-12); }
  @media (min-width: 768px) { .doc-empty { padding-inline: var(--space-8); } }
  .doc-empty > .state { padding: 0; }
  .doc-preview.is-blank > .ProseMirror { padding-bottom: var(--space-4); }
}

@layer components {
  /* ---------- v0.4.2 (Testingralph v0.4.1 review, FIX 68/78) ---------- */
  /* MF14: our own product marks. A 24px tile in the foreground ink with the mark knocked out in the page color. */
  .app-mark__tile { display: inline-grid; place-items: center; flex: none; width: var(--size-target-min); height: var(--size-target-min); border-radius: var(--radius-md); background: var(--foreground); color: var(--background); }
  .app-mark__glyph { width: var(--size-icon-sm); height: var(--size-icon-sm); }

  /* MF15 (v0.4.2) gave panels a resting --shadow-1. v0.4.3 (Testingralph v0.4.2 SF-B) takes it out again: panels are
     flat with a hairline (spec G7, R1, T2); shadows are only for floating layers (menus, popovers, dialogs, toasts). */
  /* Quieter chrome: the header has no rule; its glass and the page color separate it. A rule fades in once the page scrolls under it. */
  .app-header { --_header-rule: transparent; transition: box-shadow var(--duration-fast) var(--easing-out); }
  html.is-scrolled .app-header { --_header-rule: var(--border); }

  /* MF1: editor frames are control edges, 3:1 or more on card and page. */
  .code:has(.cm-editor) { border-color: var(--input); }

  /* MF13: a file button is a label around a hidden input; it shows the ring when its input has keyboard focus. */
  .btn:has(> input:focus-visible) { outline: var(--focus-width) solid var(--ring); outline-offset: var(--focus-offset); }

  /* MF4, MF5: the drop zone is a full width row at 768px and up (icon, words, actions), so it never sits beside a box
     of another height. Icon and actions center on the 44px of title and hint: (44 - 20) / 2 and (44 - 32) / 2, whole pixels. */
  @media (min-width: 768px) {
    .dropzone--row { grid-template-columns: auto minmax(0, 1fr) auto; grid-template-rows: auto auto; column-gap: var(--space-4); row-gap: 0; align-items: start; padding: var(--space-6); }
    .dropzone--row > .dropzone__icon { grid-row: 1 / span 2; align-self: center; }
    .dropzone--row > .dropzone__title { grid-column: 2; }
    .dropzone--row > .dropzone__hint { grid-column: 2; }
    .dropzone--row > .cluster { grid-column: 3; grid-row: 1 / span 2; align-self: center; flex-wrap: nowrap; }
  }
  /* One panel holds the summary and the table it summarizes; the toolbar line separates them. */
  .panel > .panel__body + .toolbar, .panel > .panel__body + .table-wrap { border-top: var(--border-hairline) solid var(--border); }

  /* MF7: job and loading bodies use the same 24px padding as the states beside them. */
  .panel__body--state { padding: var(--space-6); }

  /* MF6: the statement and its preview live in one panel. The form sets the height; the statement column is sized to
     its text and stays in view while you scroll the form. */
  .statement { display: grid; align-content: start; } /* v0.4.3: when data-snap4 adds up to 3 px, it goes under the rows, not half into each row */
  .statement__form { padding: var(--space-4); border-bottom: var(--border-hairline) solid var(--border); }
  .statement__out { display: grid; gap: var(--space-3); align-content: start; padding: var(--space-4); }
  .statement__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
  @media (min-width: 768px) {
    .statement { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; }
    .statement__form { border-bottom: 0; border-right: var(--border-hairline) solid var(--border); }
    .statement__out { position: sticky; top: calc(var(--size-header) + var(--space-4)); }
  }

  /* SF2: a lazy region that failed keeps the height it had (locked by the script), and its error sits at the top. */
  .lazy.is-failed > [data-lazy-slot] { align-self: start; }
}

@layer components {
  /* v0.4.2 (SF2, MF3): a lazy chart and its skeleton take a whole number of 4px steps of height for their width, so
     the box, its skeleton and its error are the same size and every edge below lands on a whole pixel. */
  .lazy .chart { container-type: inline-size; }
  .lazy .chart > svg, .lazy .skeleton.skeleton--chart-bar { height: round(down, calc(100cqi * 150 / 560), var(--space-1)); aspect-ratio: auto; }
}

@layer components {
  /* v0.4.2: a file row spans its list like the drop zone above it (li elements otherwise keep to the 75 character measure). */
  .file-list > .file-item { max-width: none; }
  /* MF6: a job or loading card is a state with a bar: the same 24px padding and 8px steps, so it is no taller than the states beside it. */
  .panel__body--state.stack > * + * { margin-top: var(--space-2); }
  .panel__body--state.stack > .cluster { margin-top: var(--space-4); }
}

@layer components {
  /* v0.4.2 (MF3): static charts take a whole number of 4px steps of height for their width (the two viewBox shapes the
     reference uses), so nothing below a chart lands on a half pixel. The drawing keeps its aspect and centers in the box. */
  .chart { container-type: inline-size; }
  .chart > svg[viewBox="0 0 560 150"] { height: round(down, calc(100cqi * 150 / 560), var(--space-1)); }
  .chart > svg[viewBox="0 0 560 72"] { height: round(down, calc(100cqi * 72 / 560), var(--space-1)); }
  /* The last problem in a pane has no bottom rule; the status bar line closes the pane (no doubled line). */
  .workspace__pane > .problems > .problem:last-child { border-bottom: 0; }
}

@layer utilities {
  /* v0.4.2 (MF3): .hide-sm reverted a flex group to block at 768px and up, which made the editor toolbar 29px and put
     every control on a half pixel (#blk at y.5). Groups stay flex. */
  @media (min-width: 768px) { .editor__group.hide-sm { display: flex; } }
  /* A Not stated button inside running text sits on the top of its 24px line, not the middle (no 0.77px taller lines). */
  p > button.not-stated, li > button.not-stated { vertical-align: top; }
}
@layer components {
  /* v0.4.2: key combinations stay on one line, so stacked keys never put two borders 1px apart at 375px. */
  .table th:has(> .kbd) { white-space: nowrap; }
}

@layer components {
  /* v0.4.2 (SF2): a lazy region's error sits inside the panel body, which already has the padding, and its sentence fits
     one line at 375px, so the error (icon, title, sentence, Retry: 128px) fits the smallest skeleton box (136px) and
     nothing below it moves at any width. */
  .lazy.is-failed .state--inline { padding: 0; }
}

@layer components {
  /* v0.4.2: the verdict is a p, so it took the 75 character measure; at 1280 the meta then sat beside it and the
     warning count wrapped alone. The verdict line spans the summary, and the meta and counts share the next line. */
  .result-summary > .result-summary__verdict { max-width: none; }
}

@layer components {
  /* v0.4.2 (MF6): the statement column was half empty under its text. Now the panel is one two column grid: tool,
     uses and parts on the left; checker and the statement on the right. Each column stacks on its own (no shared row
     to leave a gap under the shorter field), and neither column has a blank band. The statement keeps its measure. DOM, reading and tab order are unchanged. */
  @media (min-width: 768px) {
    .statement { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); grid-template-rows: auto 1fr; grid-auto-flow: row; gap: var(--space-4) var(--space-6); padding: var(--space-4); align-items: start; }
    .statement__form { display: contents; }
    .statement__form > .statement__col:first-child { grid-column: 1; grid-row: 1 / span 2; }
    .statement__form > .statement__col:last-child { grid-column: 2; grid-row: 1; }
    .statement__form.stack > * + * { margin-top: 0; }
    .statement__out { grid-column: 2; grid-row: 2; position: static; padding: 0; }
  }
}
@layer components {
  /* v0.4.2: the FSH problem list is full width now (the health #states row is one stack), so a long message capped to
     the reading measure, like other text; the line number stays at the right edge of the row. */
  .problem__msg { max-width: var(--size-measure); }
}
@layer components {
  /* v0.4.2 app feedback (Buildralph). */
  /* Breadcrumbs: no browser list indent or bullets, so the trail starts on the page edge like the h1 under it. */
  .breadcrumbs ol { margin: 0; padding: 0; list-style: none; }
  /* Keycaps on whole pixels in any mono font: the width is the text in ch plus padding and border, rounded up to a
     4px step and the text centered. One character by default; .kbd--2, .kbd--3, .kbd--4 for longer keys (Esc is 3,
     Ctrl is 4). Browsers without round() keep the content width with a 20px minimum. */
  .kbd { --_n: 1; justify-content: center; min-width: var(--space-5); white-space: nowrap;
    width: round(up, calc(var(--_n) * 1ch + 2 * var(--space-1) + 2 * var(--border-hairline)), var(--space-1)); }
  .kbd--2 { --_n: 2; }
  .kbd--3 { --_n: 3; }
  .kbd--4 { --_n: 4; }
  /* v0.4.3: .kbd--5 for five character keys (Enter, Shift). 48px in Geist Mono. */
  .kbd--5 { --_n: 5; }
  /* Blank editor: the empty line and the EmptyState under it are one unit. The focus ring goes round the whole
     document area, never as a thin box round the empty line above the state. */
  .doc-preview.is-blank > .ProseMirror:focus-visible { outline: none; }
  .doc-preview.is-blank:has(> .ProseMirror:focus-visible) { outline: var(--focus-width) solid var(--ring); outline-offset: calc(-1 * var(--focus-width)); }
}

@layer components {
  /* ---------- v0.4.3 (Paperralph v0.4.2 click test, Testingralph v0.4.2 review) ---------- */
  /* Ghost skeleton (SF3): the loaded rows sit under the bars with their text hidden, so columns and rows match the
     loaded table exactly. Scoped to .table--ghost so plain skeleton tables keep their bars. Rows after the visible ones only size the columns. */
  /* v0.4.3 (Testingralph v0.4.3 nit): the cell text sits in .skel-src and is visibility hidden, so it cannot be
     selected or found with find in page, and axe no longer meets transparent text. */
  .table--ghost { user-select: none; }
  .table--ghost tbody :is(th, td):not(.pin) { position: relative; }
  .table--ghost tbody :is(th, td) > :not(.skel-cell) { visibility: hidden; }
  .table--ghost .skel-cell { position: absolute; inset: var(--space-2) var(--space-3); }
  .table--ghost tr.skel-ghost { visibility: collapse; }
  /* .zip menu item (Paperralph v0.4.3 must-fix): a second line names the blank files left out. The two lines are
     20px and 16px with a 4px pad above and below, so the item is 44px tall, on the 4px grid. */
  .menu__text { display: grid; }
  .menu__sub { font-size: var(--text-xs); line-height: var(--leading-xs); color: var(--muted-foreground); }
  .menu__item:has(.menu__sub:not([hidden])) { padding-block: var(--space-1); }
  /* Cancel stands in the busy button's slot at the same size (SF2); its width comes from the busy button. */
  .btn--cancel { justify-content: center; }
  /* v0.4.3 (Paperralph v0.4.3 nit 2): the busy label is visible beside the spinner, muted, and Cancel follows after a
     hairline divider. The resting button already reserves this width (lock in 15-lazy.js), so nothing moves. */
  .btn--cancel .btn__busy { color: var(--muted-foreground); font-weight: var(--font-weight-regular); }
  .btn__stop { padding-inline-start: var(--space-2); border-inline-start: var(--border-hairline) solid var(--border); }
  /* Builder panel headers (MF-A): the two panels side by side have the same header height, a control plus the
     header padding and rule (57px from 768px, 69px below), so their bottom rules line up. */
  [data-builder] .grid-2 .panel > .panel__header { min-block-size: calc(var(--control-h) + 2 * var(--space-3) + var(--border-hairline)); }
  /* Blank file (MF-B and the blank editor nit): the editor's status region is always in the page and takes no room
     while it is empty; the Preview shows its own empty state. */
  .doc-empty:empty { padding: 0; }
  .preview-empty > .state { padding: 0; }
  /* v0.4.3 (Testingralph v0.4.3 nit): while Preview shows its empty state the panel keeps its content height instead
     of stretching to the step panel, so no tall empty card is left under the state. Its top and header still line up. */
  .grid-2--follow > .panel:has([data-preview-empty]:not([hidden])) { align-self: start; height: auto; min-height: 0; }
  /* Dataset rows (SF-D): a "Not stated" button in a summary row keeps its 24px target but takes only the 20px line,
     so the row is the same height as the others and its text sits on the label's baseline. */
  .summary-list dd > button.not-stated { vertical-align: baseline; margin-block: calc((var(--leading-sm) - var(--size-target-min)) / 2); }
  /* Segmented control frame (nit): a control edge, so --input (3:1 or more on card and page), like the editor frame. */
  .seg { border-color: var(--input); }
  /* Text selection (nit): the primary fill with its own foreground, 3:1 or more against the page in both themes.
     --selection stays for target lines in code blocks. */
  ::selection { background: var(--primary); color: var(--primary-foreground); }
  /* Top progress line: eases toward 90 percent while waiting, fills on arrival. */
  .top-progress.is-active .top-progress__bar { transform: scaleX(.9); transition-duration: calc(5 * var(--duration-pulse)); }
  .top-progress.is-done .top-progress__bar { transform: scaleX(1); transition-duration: var(--duration-fast); }
  /* Reduced motion (Testingralph v0.4.3 nit): no growth, so a still line must not read as done. While loading it is a
     dashed line (8px on, 8px off) across the width; it turns solid only for the short done state. */
  @media (prefers-reduced-motion: reduce) {
    .top-progress.is-active .top-progress__bar { transform: scaleX(1); background: repeating-linear-gradient(90deg, var(--primary) 0 var(--space-2), transparent var(--space-2) var(--space-4)); }
    .top-progress.is-done .top-progress__bar { background: var(--primary); }
  }
}
/* v0.4.3 round 3 (Testingralph r2 SF-1, SF-2, N3; Paperralph r2 nits) */
@layer components {
  /* Toast kinds: the icon carries the kind in its status color. Success (circle-check, --success), warning for an
     action that did nothing (circle-alert, --warning) and error (octagon-alert, --destructive). */
  .toast > .icon.status--success { color: var(--success); }
  .toast > .icon.status--warning { color: var(--warning); }
  .toast > .icon.status--error { color: var(--destructive); }
  /* Busy note: the visible busy label, outside the button flow, so the busy button keeps its resting size. */
  .busy-note { color: var(--muted-foreground); font-size: var(--text-sm); line-height: var(--leading-sm); white-space: nowrap; pointer-events: none; }
  [data-busy-note="side"] { position: relative; }
  .busy-note--side { position: absolute; inset-inline-end: calc(100% + var(--space-2)); inset-block-start: 50%; transform: translateY(-50%); text-align: end; }
  /* v0.4.3 round 4 (Testingralph r3 SF-B): the labels are short enough for one line at 375 ("Making Word..." 90 px in 103 px);
     below that (320) every label wraps the same way and keeps the same size as the one line note. */
  .busy-note--wrap { white-space: normal; inline-size: min-content; }
  [data-busy-status].is-busy-host { position: relative; visibility: hidden; }
  .busy-note--status { position: absolute; inset-inline-start: 0; inset-block-start: 0; visibility: visible; font-size: inherit; line-height: inherit; }
  .busy-note--after { align-self: center; }
  /* Cancel on a primary button: the spinner arc takes the button text color, as on the busy button itself. */
  .btn--primary.btn--cancel .spinner { color: currentColor; }
  /* Zip note: no single word left on its own line. */
  .menu__sub { text-wrap: pretty; }
}
@layer components {
  /* Snapped card grid (policy states): the grid box takes the 4px step, the cards keep their own height. */
  .grid-cards[data-snap4] { align-content: start; }
}
@layer components {
  /* v0.4.3 round 5 (Testingralph v0.4.3 round 4 SF-2): a state card's outer height is a multiple of 4 px on every page.
     Its content is built from 4 px steps (24 px padding, 20 and 24 px lines, 20 px icon with a 4 px gap, 36 px
     buttons), and the 1 px border on each side made every card 2 px off (182, 190, 202, 214, 238). One more hairline
     of padding at the top and bottom puts the outer box back on the grid (184, 192, 204, 216, 240), on every page and
     in the apps, with no script. .grid-cards keeps grid-auto-rows: 1fr, so the cards of a grid share that height. */
  .panel:has(> .state, > .panel__body--state) { padding-block: var(--border-hairline); }
  /* Round 5 nit b: a progress card carries a status icon in the same slot as the other state cards, so the titles
     of cards side by side start at the same height. */
  .panel__body--state > .icon:first-child { display: block; width: var(--size-icon-md); height: var(--size-icon-md); color: var(--muted-foreground); }
  .panel__body--state.stack > .icon:first-child + * { margin-top: calc(var(--space-1) + var(--space-2)); }
  /* Round 5 nit a: a section, main or heading that takes focus from script after a same-page jump (tabindex -1, not a
     control) shows no ring; the jump itself shows where you are. Controls keep their :focus-visible ring. */
  :is(main, section, article, aside, form, div, h1, h2, h3, h4, h5, h6)[tabindex="-1"]:not([role]):focus { outline: none; }
}


[hidden] { display: none !important; }
html { scroll-padding-top: calc(var(--size-header) + var(--space-4)); }
body { min-height: 100vh; display: flex; flex-direction: column; }
main { flex: 1 0 auto; }
/* PR 13 review MF4: before app.js fills a view, main is already a screen tall, so the footer is
   never painted in view and then pushed down. */
main { min-block-size: 100dvh; }
main:focus { outline: none; }
.short { display: none; }

/* ---------- Header: logo mark, tabs styled like app-nav, help and theme ---------- */
.app-tabs { display: flex; align-items: stretch; gap: var(--space-1); height: 100%; min-width: 0; }
.app-tab { position: relative; display: inline-flex; align-items: center; gap: var(--space-2); padding-inline: var(--space-3); color: var(--muted-foreground); background: none; border: 0;
  font-size: var(--text-sm); line-height: var(--leading-sm); font-weight: var(--font-weight-medium); white-space: nowrap; cursor: pointer; }
.app-tab:hover { color: var(--foreground); }
.app-tab[aria-selected="true"] { color: var(--foreground); }
.app-tab[aria-selected="true"]::after { content: ""; position: absolute; left: var(--space-3); right: var(--space-3); bottom: 0; height: var(--border-strong); background: var(--primary); }
.app-tab:focus-visible { outline-offset: calc(-1 * var(--focus-width)); }
.tab-dot { width: var(--size-dot); height: var(--size-dot); border-radius: var(--radius-full); background: var(--warning); flex: none; }
.header-link { display: none; }
@media (min-width: 1024px) { .header-link { display: inline-flex; } }
@media (max-width: 1023.98px) { .app-tabs .long { display: none; } .app-tabs .short { display: inline; } }
@media (max-width: 767.98px) {
  /* Two rows on phones: let the header scroll away so it never covers the content (100px is an eighth of the screen). */
  .app-header { height: auto; position: relative; }
  html { scroll-padding-top: var(--space-4); }
  .app-header__inner { flex-wrap: wrap; row-gap: 0; padding-top: 0; }
  .app-header__inner > .app-mark { height: var(--size-header); }
  .app-tabs { order: 3; width: 100%; height: var(--control-h); margin-inline: calc(-1 * var(--space-3)); overflow-x: auto; scrollbar-width: none; }
  .app-tab { flex: 1 0 auto; justify-content: center; }
}
#theme-menu { position: fixed; }
#theme-menu:not(:popover-open) { display: none; }

/* ---------- Views ---------- */
.page--full { max-width: none; }
.view > .page { padding-top: var(--space-8); }
.view h1:focus { outline: none; }
/* .stack-lg comes from the design system (v0.4.3 second round: hidden children add no gap). */

/* ---------- Builder: steps | form | preview ---------- */
/* Columns are rounded to whole pixels so no box edge lands on a fraction (Testingralph MF3). */
.builder { display: grid; grid-template-columns: 224px round(down, calc((100% - 224px - 2 * var(--space-6)) / 2.05), 1px) minmax(0, 1fr); gap: var(--space-6); align-items: start; }
.builder > * { min-width: 0; }
@media (max-width: 1179.98px) { .builder { grid-template-columns: 200px minmax(0, 1fr); } .builder > .preview { grid-column: 1 / -1; position: static; max-height: none; } }
@media (max-width: 767.98px) { .builder { grid-template-columns: minmax(0, 1fr); } }
.rail { position: sticky; top: calc(var(--size-header) + var(--space-6)); }
@media (max-width: 767.98px) { .rail { position: static; } }
.rail-progress { height: var(--space-1); margin-bottom: var(--space-4); background: var(--secondary); border-radius: var(--radius-sm); overflow: hidden; }
.rail-progress > span { display: block; height: 100%; width: 0; background: var(--primary); border-radius: var(--radius-sm); transition: width var(--duration-base) var(--easing-out); }
.stepper button { display: flex; align-items: center; gap: var(--space-2); width: 100%; min-height: var(--item-h, var(--control-h)); padding-inline: var(--space-2); border: 0; border-radius: var(--radius-sm); background: none;
  color: var(--muted-foreground); text-align: left; font-size: var(--text-sm); line-height: var(--leading-sm); cursor: pointer; }
.stepper button:hover { background: var(--accent); color: var(--foreground); }
.stepper .done { color: var(--foreground); }
.stepper .done .stepper__num { background: var(--primary); border-color: var(--primary); color: var(--primary-foreground); }
.stepper button[aria-current="step"] { background: var(--primary-soft); color: var(--primary-soft-foreground); font-weight: var(--font-weight-semibold); }
.stepper button[aria-current="step"] .stepper__num { border-color: var(--primary); border-width: var(--border-strong); color: var(--primary-soft-foreground); background: transparent; }
.stepper .warn-dot { margin-left: auto; width: var(--size-dot); height: var(--size-dot); border-radius: var(--radius-full); background: var(--warning); flex: none; }
.rail-note { display: flex; gap: var(--space-2); align-items: flex-start; margin-top: var(--space-4); font-size: var(--text-xs); line-height: var(--leading-xs); color: var(--muted-foreground); }
.rail-note .icon { color: var(--success); flex: none; width: var(--size-icon-sm); height: var(--size-icon-sm); }
@media (max-width: 767.98px) {
  .stepper { display: flex; overflow-x: auto; gap: var(--space-1); padding-bottom: var(--space-1); scrollbar-width: none; position: relative; }
  .stepper li { flex: none; }
  .stepper button:not([aria-current="step"]) .t { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .rail-note { display: none; }
}

.stage > .panel__body { padding: var(--space-6); }
@media (max-width: 767.98px) { .stage > .panel__body { padding: var(--space-4); } }
.step-footer { align-items: center; border-radius: 0 0 var(--radius-lg) var(--radius-lg); }
.step-count { font-size: var(--text-sm); line-height: var(--leading-sm); color: var(--muted-foreground); font-variant-numeric: tabular-nums; }
.step-head { margin-bottom: var(--space-6); }
.step-head p { color: var(--muted-foreground); margin-top: var(--space-2); }
.step-view > .state { padding-inline: 0; }

/* Questions: fieldsets separated by one hairline, no nested cards. */
.q { border: 0; padding: 0; margin: 0; min-width: 0; }
.q + .q, .group + .q, .q + .group { margin-top: var(--space-6); padding-top: var(--space-6); border-top: var(--border-hairline) solid var(--border); }
.q legend { float: left; width: 100%; padding: 0; font-size: var(--text-base); line-height: var(--leading-base); font-weight: var(--font-weight-semibold); }
.q legend + * { clear: both; }
.q .prompt { color: var(--muted-foreground); margin: var(--space-1) 0 var(--space-3); font-size: var(--text-sm); line-height: var(--leading-sm); }
.q .help { color: var(--muted-foreground); font-size: var(--text-sm); line-height: var(--leading-sm); margin-top: var(--space-2); }
.q.flagged legend::after { content: ""; display: inline-block; width: var(--size-dot); height: var(--size-dot); margin-left: var(--space-2); border-radius: var(--radius-full); background: var(--warning); vertical-align: middle; }
.opts { display: grid; gap: var(--space-2); }
.opt { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--space-3); align-items: start; padding: var(--space-3); border: var(--border-hairline) solid var(--border); border-radius: var(--radius-md); background: var(--card); cursor: pointer; }
.opt:hover { border-color: var(--input); }
.opt:has(input:checked) { border-color: var(--primary); background: var(--primary-soft); box-shadow: inset 0 0 0 var(--border-hairline) var(--primary); }
.opt input { margin-top: var(--space-0-5); }
.opt .label { font-size: var(--text-sm); line-height: var(--leading-sm); font-weight: var(--font-weight-medium); }
.opt .sub, .opt .seen { display: block; font-size: var(--text-sm); line-height: var(--leading-sm); color: var(--muted-foreground); }
.opt .seen a, .choice-card .seen a { color: var(--muted-foreground); }
.opt .seen a:hover, .choice-card .seen a:hover { color: var(--foreground); }

/* Stance and venue cards: DS choice cards with a visible radio. */
.cards { display: grid; gap: var(--space-3); grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr)); grid-auto-rows: 1fr; }
.cards.two-col { grid-template-columns: repeat(auto-fit, minmax(min(180px, 100%), 1fr)); }
.choice-card { min-width: 0; height: 100%; }
.choice-card > .radio, .choice-card > .check { margin-top: var(--space-0-5); flex: none; }
.choice-card__body { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.choice-card .seen { margin-top: auto; padding-top: var(--space-1); font-size: var(--text-xs); line-height: var(--leading-xs); color: var(--muted-foreground); }

.field-row { display: grid; gap: var(--space-4); }
.field-row + .field-row { margin-top: var(--space-4); }

/* Review step */
.review { display: grid; }
.review-row { display: grid; grid-template-columns: 180px minmax(0, 1fr) auto; gap: var(--space-3); align-items: baseline; padding: var(--space-3) 0; border-bottom: var(--border-hairline) solid var(--border); }
.review-row:first-child { border-top: var(--border-hairline) solid var(--border); }
.review-row .k { font-size: var(--text-sm); line-height: var(--leading-sm); font-weight: var(--font-weight-medium); }
.review-row .v { font-size: var(--text-sm); line-height: var(--leading-sm); color: var(--muted-foreground); max-width: none; }
@media (max-width: 599.98px) { .review-row { grid-template-columns: minmax(0, 1fr) auto; } .review-row .v { grid-column: 1 / -1; } }
.linkish { border: 0; background: none; padding: 0 var(--space-1); min-height: var(--size-target-min); color: var(--link); font-size: var(--text-sm); line-height: var(--leading-sm); font-weight: var(--font-weight-medium); cursor: pointer; text-decoration: underline; text-underline-offset: 0.2em; }
.edit-cta { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; margin-top: var(--space-6); padding: var(--space-4); border-radius: var(--radius-md); background: var(--primary-soft); border: var(--border-hairline) solid var(--border); }
.edit-cta > div { flex: 1 1 280px; }
.edit-cta p { max-width: none; color: var(--muted-foreground); font-size: var(--text-sm); line-height: var(--leading-sm); }
.files { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(250px, 100%), 1fr)); grid-auto-rows: 1fr; gap: var(--space-3); margin-top: var(--space-6); }
.file-card { display: flex; justify-content: space-between; align-items: center; gap: var(--space-2); padding: var(--space-3) var(--space-4); border: var(--border-hairline) solid var(--border); border-radius: var(--radius-md); background: var(--card); min-width: 0; }
.file-card > span { min-width: 0; overflow-wrap: anywhere; font-size: var(--text-sm); line-height: var(--leading-sm); font-weight: var(--font-weight-medium); }
.file-card code { display: block; font-family: var(--font-mono); font-size: var(--text-xs); line-height: var(--leading-xs); color: var(--muted-foreground); font-weight: var(--font-weight-regular); overflow-wrap: anywhere; }
.file-card .btn { flex-shrink: 0; }
#panel-builder .row { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-6); }
.legal-note { margin-top: var(--space-4); font-size: var(--text-sm); line-height: var(--leading-sm); color: var(--muted-foreground); max-width: none; }

/* ---------- Preview panels (builder and statement) ---------- */
.preview { position: sticky; top: calc(var(--size-header) + var(--space-6)); display: flex; flex-direction: column; max-height: calc(100vh - var(--size-header) - var(--space-12)); overflow: hidden; }
.preview-head { padding: 0 var(--space-2); border-bottom: var(--border-hairline) solid var(--border); }
.file-tabs { border-bottom: 0; }
.file-tabs button { background: none; border: 0; cursor: pointer; }
/* The select that stands in for the file tabs when they do not fit (see fitTabs in app.js). */
.preview-head.is-narrow { padding: var(--space-2) var(--space-4); }
.tab-select { display: block; width: 100%; max-width: none; }
.file-tabs[hidden] { display: none; }
.tab-select[hidden] { display: none; }
.tab-select > select { width: 100%; }
.preview-bar { display: flex; justify-content: space-between; align-items: center; gap: var(--space-2); padding: var(--space-3) var(--space-4); }
.file-name { font-family: var(--font-mono); font-size: var(--text-xs); line-height: var(--leading-xs); color: var(--muted-foreground); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.actions { display: flex; gap: var(--space-2); flex: none; }
.doc-wrap { position: relative; flex: 1; min-height: 0; margin: 0 var(--space-4) var(--space-4); }
.doc { margin: 0; height: 100%; max-height: calc(100vh - 260px); overflow: auto; padding: var(--space-4); background: var(--muted); color: var(--foreground); border: var(--border-hairline) solid var(--border); border-radius: var(--radius-md);
  font-family: var(--font-mono); font-size: var(--text-xs); line-height: var(--leading-sm); white-space: pre-wrap; word-break: break-word; }
@media (max-width: 1179.98px) { .doc { max-height: 70vh; } }
.doc .h { color: var(--syntax-keyword); font-weight: var(--font-weight-semibold); }
.doc .box { color: var(--syntax-string); }
.doc .cm { color: var(--syntax-comment); }
.doc .flash { animation: flash 1.1s var(--easing-out); border-radius: var(--radius-sm); }
@keyframes flash { 0% { background: var(--selection); } 100% { background: transparent; } }
.doc-wrap > .state { padding: var(--space-6) var(--space-4); border: var(--border-hairline) dashed var(--border); border-radius: var(--radius-md); }
.issues { display: grid; gap: var(--space-2); padding: 0 var(--space-4); }
.issues:not(:empty) { padding-top: var(--space-3); }
.issue { display: flex; gap: var(--space-3); align-items: baseline; justify-content: space-between; }
.issue p { max-width: none; }
.issue .linkish { color: inherit; flex: none; }

/* ---------- Edit and export: full width under the header ---------- */
.ed-head { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--space-4) var(--space-6); flex-wrap: wrap; margin-bottom: var(--space-6); }
.ed-head .page-header__text p { color: var(--muted-foreground); margin-top: var(--space-2); }
.file-switch { border-bottom: 0; max-width: 100%; position: relative; }
.file-switch button { background: none; border: 0; cursor: pointer; }
.file-dot { width: var(--size-dot); height: var(--size-dot); border-radius: var(--radius-full); background: var(--primary); flex: none; }
.file-dot.stale { background: var(--warning); }
@media (max-width: 559.98px) {
  .file-switch .long { display: none; } .file-switch .short { display: inline; }
  .file-switch { display: flex; width: 100%; }
  .file-switch button { flex: 1 1 0; justify-content: center; padding-inline: var(--space-2); }
}

.sync { display: grid; gap: var(--space-2); margin-bottom: var(--space-4); }
.sync:empty { display: none; }
/* PR 13 review MF4: while the editor code loads, the sync banner's slot is held at the height of
   the default one ("Matches your builder answers"), so the editor grid does not move down when it
   arrives: one line from 1280 px, two from 768 px, and on phones the text wraps under the icon. */
#panel-editor:has(#ed-loading:not([hidden])) .sync:empty { display: block; block-size: calc(2 * var(--space-3) + 2 * var(--border-hairline) + var(--leading-sm)); }
@media (max-width: 1279.98px) { #panel-editor:has(#ed-loading:not([hidden])) .sync:empty { block-size: calc(2 * var(--space-3) + 2 * var(--border-hairline) + 2 * var(--leading-sm)); } }
@media (max-width: 767.98px) { #panel-editor:has(#ed-loading:not([hidden])) .sync:empty { block-size: calc(2 * var(--space-3) + 2 * var(--border-hairline) + 4.5 * var(--leading-sm)); } }
.ed-loading__bar.is-pending { visibility: hidden; }
.sync-card { display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: flex-start; }
.sync-card > .icon { flex: none; margin-top: var(--space-0-5); }
.sync-body { flex: 1 1 320px; min-width: 0; }
.sync-body p, .sync-body li { max-width: none; }
.sync-actions { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.sync-card .missing { margin-top: var(--space-2); padding-left: var(--space-4); list-style: disc; }
.diff { flex-basis: 100%; background: var(--card); border: var(--border-hairline) solid var(--border); border-radius: var(--radius-md); padding: var(--space-3) var(--space-4); max-height: 280px; overflow: auto; position: relative; }
.diff pre { margin: 0; font-family: var(--font-mono); font-size: var(--text-xs); line-height: var(--leading-sm); white-space: pre-wrap; word-break: break-word; }
.diff .add { display: block; background: var(--success-soft); border-radius: var(--radius-sm); padding: 0 var(--space-2); }
.diff .del { display: block; background: var(--destructive-soft); border-radius: var(--radius-sm); padding: 0 var(--space-2); text-decoration: line-through; text-decoration-thickness: 1px; }

.ed-grid { display: grid; grid-template-columns: round(down, calc((100% - var(--space-6)) * 0.545), 1px) minmax(0, 1fr); gap: var(--space-6); align-items: start; }
.ed-grid > * { min-width: 0; }
@media (max-width: 1100px) { .ed-grid { grid-template-columns: minmax(0, 1fr); } .ed-preview { position: static; max-height: none; } }
.paper-shell { overflow: clip; }
.edit-bar { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: thin; }
.edit-bar .btn--icon { width: var(--size-control-sm); height: var(--size-control-sm); min-height: var(--size-control-sm); flex: none; }
@media (max-width: 767.98px) { .edit-bar .btn--icon { width: var(--size-target-touch); height: var(--size-target-touch); } }
/* PR 13 review MF5: on phones the text style select is as tall as the 44 px icon buttons beside it. */
@media (max-width: 767.98px) { .edit-bar .select--sm select { height: var(--size-target-touch); min-height: var(--size-target-touch); } }
.edit-bar .btn[aria-pressed="true"] { background: var(--primary-soft); color: var(--primary-soft-foreground); }
.edit-bar .btn:disabled { opacity: 0.4; }
.edit-bar .select { width: auto; flex: none; }
.tb-sep { width: var(--border-hairline); align-self: stretch; margin: var(--space-1); background: var(--border); flex: none; }
@media (max-width: 559.98px) {
  .edit-bar { flex-wrap: wrap; overflow-x: visible; row-gap: var(--space-1); }
  .edit-bar .tb-sep { display: none; }
}
.linkbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-3); background: var(--muted); border-bottom: var(--border-hairline) solid var(--border); }
.linkbar .input { flex: 1 1 220px; width: auto; min-width: 0; }
.link-error { flex-basis: 100%; color: var(--destructive); font-size: var(--text-sm); line-height: var(--leading-sm); font-weight: var(--font-weight-medium); }
.link-error:empty { display: none; }
.paper-scroll { background: var(--background); }
.paper { min-height: 480px; border-radius: 0; }
.paper.is-blank { min-height: 0; }
/* While the editor code loads (or failed), the box fits the skeleton or the message: no blank band. */
.paper:not(:has(.ProseMirror)) { min-height: 0; }
@media (max-width: 767.98px) { .paper { min-height: 360px; } }
.ed-loading { max-width: var(--size-prose-max); margin-inline: auto; padding: var(--space-6) var(--space-4); }
@media (min-width: 768px) { .ed-loading { padding-inline: var(--space-8); } }
.ed-loading .skeleton:first-child { height: var(--space-6); margin-bottom: var(--space-4); }
.paper .ProseMirror { min-height: 480px; font-variant-ligatures: none; font-feature-settings: "liga" 0; position: relative; }
.paper.is-blank .ProseMirror { min-height: 0; }
@media (max-width: 767.98px) { .paper .ProseMirror { min-height: 360px; } }
.ProseMirror pre { white-space: pre-wrap; font-family: var(--font-mono); font-size: var(--text-sm); line-height: var(--leading-sm); background: var(--muted); padding: var(--space-3) var(--space-4); border-radius: var(--radius-md); margin-top: var(--space-3); }
.ProseMirror pre code { background: none; padding: 0; }
.ProseMirror code { font-family: var(--font-mono); font-size: 0.875em; }
.ProseMirror li { position: relative; }
.ProseMirror h4 { font-size: var(--text-base); line-height: var(--leading-base); margin-top: var(--space-4); }
.ProseMirror a { color: var(--link); text-decoration: underline; cursor: text; }
.ProseMirror hr { border: 0; border-top: var(--border-hairline) solid var(--border); margin: var(--space-6) 0; }
.ProseMirror p, .ProseMirror li, .ProseMirror dd { max-width: none; }
.ProseMirror-hideselection *::selection { background: transparent; }
.ProseMirror-hideselection { caret-color: transparent; }
.pm-doc li.task-item { list-style: none; padding-left: var(--space-0-5); }
.pm-doc li.task-item::before { content: ""; position: absolute; left: calc(-1 * var(--space-6)); top: var(--space-1); width: var(--size-icon-sm); height: var(--size-icon-sm); border: var(--border-hairline) solid var(--input); border-radius: var(--radius-sm); background: var(--card); cursor: pointer; }
.pm-doc li.task-item[data-checked="true"]::before { background: var(--primary); border-color: var(--primary); }
.pm-doc li.task-item[data-checked="true"]::after { content: ""; position: absolute; left: calc(-1 * var(--space-6) + 5px); top: calc(var(--space-1) + 2px); width: 5px; height: 9px; border: solid var(--primary-foreground); border-width: 0 2px 2px 0; transform: rotate(45deg); pointer-events: none; }
.md-html { font-family: var(--font-mono); font-size: var(--text-xs); line-height: var(--leading-sm); color: var(--muted-foreground); background: var(--muted); border: var(--border-hairline) dashed var(--input); border-radius: var(--radius-md); padding: var(--space-2) var(--space-3); margin-top: var(--space-3); white-space: pre-wrap; user-select: none; }
.doc-empty .state__title { font-size: var(--text-base); }
.ed-status { align-items: center; font-size: var(--text-sm); line-height: var(--leading-sm); }
.ed-status #ed-reset { margin-left: auto; }
#ed-state:empty { display: none; }
#ed-state.edited { background: var(--primary-soft); color: var(--primary-soft-foreground); }
#ed-empty { margin: var(--space-4); }

/* Paste notice: a floating layer fixed to the bottom of the window until dismissed. */
.paste-notice.alert { position: fixed; left: 50%; bottom: var(--space-5); transform: translateX(-50%); z-index: var(--z-toast); display: flex; align-items: center; gap: var(--space-3);
  width: max-content; max-width: min(600px, calc(100vw - 2 * var(--space-4))); box-shadow: var(--shadow-2); }
.paste-notice p { min-width: 0; max-width: none; }
.paste-notice .btn { flex: none; }
/* Wide screens: over the editor column only (1.2 of 2.2 parts of the full-width page), never the preview and its exports. */
@media (min-width: 1101px) {
  .paste-notice.alert { left: var(--gutter); transform: none; max-width: calc((100vw - 2 * var(--gutter) - var(--space-6)) * 0.545 - var(--space-4)); }
}
html.has-notice:has(#panel-editor:not([hidden])) { scroll-padding-bottom: 104px; }
html.has-notice:has(#panel-editor:not([hidden])) body { padding-bottom: 104px; }
@media (max-width: 760px) {
  .paste-notice.alert { bottom: var(--space-2); max-width: calc(100vw - var(--space-4)); gap: var(--space-2); padding: var(--space-2) var(--space-2) var(--space-2) var(--space-3); }
  html.has-notice:has(#panel-editor:not([hidden])) { scroll-padding-bottom: 140px; }
  html.has-notice:has(#panel-editor:not([hidden])) body { padding-bottom: 140px; }
}

/* GitHub-like preview of the edited file */
.ed-preview { top: calc(var(--size-header) + var(--space-6)); }
.gh-bar { border-bottom: var(--border-hairline) solid var(--border); }
/* The preview header matches the editor toolbar next to it (a small control, 4 px above and below, one rule). */
.ed-preview .gh-bar { box-sizing: border-box; min-height: calc(var(--size-control-sm) + 2 * var(--space-1) + var(--border-hairline)); padding-block: var(--space-1); }
.pv-title { display: flex; align-items: center; gap: var(--space-2); min-width: 0; color: var(--muted-foreground); }
.pv-title .icon { flex: none; }
.pv-note { margin: var(--space-3) var(--space-4) 0; font-size: var(--text-sm); line-height: var(--leading-sm); color: var(--muted-foreground); }
.pv-note:empty { display: none; }
.gh-wrap { flex: 1; min-height: 0; overflow: auto; position: relative; }
.gh { padding: var(--space-2) var(--space-6) var(--space-6); font-size: var(--text-sm); line-height: var(--leading-base); color: var(--foreground); word-wrap: break-word; max-height: calc(100vh - 290px); overflow: auto; outline: none; position: relative; }
.gh:focus-visible { box-shadow: inset 0 0 0 var(--focus-width) var(--ring); }
@media (max-width: 1100px) { .gh { max-height: none; } }
.gh p, .gh li, .gh dd { max-width: none; }
.gh > :first-child { margin-top: var(--space-3); }
.gh h1, .gh h2 { padding-bottom: var(--space-1); border-bottom: var(--border-hairline) solid var(--border); }
.gh h1 { font-size: var(--text-xl); line-height: var(--leading-xl); margin: var(--space-6) 0 var(--space-3); }
.gh h2 { font-size: var(--text-lg); line-height: var(--leading-lg); margin: var(--space-6) 0 var(--space-3); }
.gh h3, .gh h4 { font-size: var(--text-base); line-height: var(--leading-base); margin: var(--space-5) 0 var(--space-2); }
.gh p, .gh ul, .gh ol, .gh blockquote, .gh pre { margin: 0 0 var(--space-3); }
.gh ul, .gh ol { padding-left: var(--space-8); }
.gh ul { list-style: disc; } .gh ol { list-style: decimal; }
.gh li + li { margin-top: var(--space-1); }
.gh li > p { margin: 0; }
.gh a { color: var(--link); }
.gh code { font-family: var(--font-mono); font-size: 0.875em; background: var(--muted); padding: 0 var(--space-1); border-radius: var(--radius-sm); }
.gh pre { font-family: var(--font-mono); font-size: var(--text-xs); line-height: var(--leading-sm); background: var(--muted); padding: var(--space-3); border-radius: var(--radius-md); overflow: auto; }
.gh pre code { background: none; padding: 0; }
.gh blockquote { padding: 0 var(--space-4); color: var(--muted-foreground); box-shadow: inset var(--border-strong) 0 0 var(--border); }
.gh hr { height: var(--border-strong); border: 0; background: var(--border); margin: var(--space-5) 0; }
.gh ul.contains-task-list { list-style: none; padding-left: var(--space-2); }
.gh .task-list-item { display: flex; gap: var(--space-2); align-items: flex-start; }
.gh .task-list-item-checkbox { appearance: none; -webkit-appearance: none; margin: var(--space-1) 0 0; width: var(--size-icon-sm); height: var(--size-icon-sm); flex: none; border: var(--border-hairline) solid var(--input); border-radius: var(--radius-sm); background: var(--card); opacity: 1; }
.gh .task-list-item-checkbox:checked { background: var(--primary); border-color: var(--primary); box-shadow: inset 0 0 0 2px var(--card); }
.gh .task-body { min-width: 0; }
.gh .raw-html { font-size: var(--text-xs); color: var(--muted-foreground); }
.export-bar { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; padding: var(--space-3) var(--space-4); border-top: var(--border-hairline) solid var(--border); }
/* v0.4.3 round 4: the label box is wide enough for the busy note ("Making .zip\2026", 71 px at 12 px) on one line, so
   the note never wraps or shrinks at 375 and nothing moves when it shows. */
.export-label { font-size: var(--text-xs); line-height: var(--leading-xs); font-weight: var(--font-weight-medium); color: var(--muted-foreground); margin-right: var(--space-1); min-inline-size: 6.5em; }
.export-bar .btn--primary { margin-left: auto; }
/* When the preview is too narrow for the whole export row on one line (it needs about 570 px: 1101 to 1380 px
   wide screens and phones), the row is laid out on purpose in two rows, so no button ever wraps alone:
   "Save as", Markdown, Word and PDF on the first, the zip button and Copy Markdown on the second. PR 13 re-check
   MF1: this stays a wrapping flex row (a zero-height break item starts the second row), so the buttons keep
   their own widths and a gap, and can never overlap however narrow the phone is. */
.ed-preview { container: ed-preview / inline-size; }
@container ed-preview (max-width: 569.98px) {
  .export-bar { row-gap: 0; }
  .export-bar > * { order: 1; }
  .export-bar::after { content: ""; order: 2; flex-basis: 100%; height: 0; margin-top: var(--space-2); }
  .export-bar > .zip-slot { order: 3; }
  .export-bar > .btn--primary { order: 4; }
  .export-bar > .zip-note { order: 5; flex-basis: 100%; margin-top: var(--space-2); }
}
/* While the zip is made, Cancel sits in the zip button's place: same slot, same width, so nothing moves. */
.zip-slot { display: inline-grid; width: calc-size(fit-content, round(up, size, 1px)); }
.export-bar .zip-slot > .btn { grid-area: 1 / 1; width: 100%; }
.zip-slot.is-busy > #ed-zip { visibility: hidden; }
.s-export { border-top: 0; padding-top: 0; }

/* ---------- Policy browser ---------- */
.filters { display: grid; grid-template-columns: minmax(0, 1fr) 200px 200px auto; gap: var(--space-3); align-items: end; padding: var(--space-4); border-bottom: var(--border-hairline) solid var(--border); }
.filter { display: grid; gap: var(--space-1); min-width: 0; }
.filter--end { display: flex; align-items: center; gap: var(--space-3); justify-content: flex-end; min-height: var(--control-h); }
.filter-count { font-size: var(--text-sm); line-height: var(--leading-sm); color: var(--muted-foreground); white-space: nowrap; font-variant-numeric: tabular-nums; max-width: none; }
@media (max-width: 899.98px) { .filters { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } .filter--search { grid-column: 1 / -1; } .filter--end { grid-column: 1 / -1; justify-content: space-between; } }
@media (max-width: 559.98px) { .filters { grid-template-columns: minmax(0, 1fr); } .filter--search .kbd { display: none; } }
.browser .table-wrap { overflow: auto; position: relative; }
.browser .table td { max-width: none; }
.browser td.name a { font-weight: var(--font-weight-medium); color: var(--foreground); text-decoration: none; }
.browser td.name a:hover { text-decoration: underline; }
.browser td.t-summary { color: var(--muted-foreground); }
/* Loading skeleton: the build writes the real header and rows under the bars (design system v0.4.3
   .table--ghost), so the columns need no fixed widths to match the loaded table. */
/* The cell text sits in .skel-src, which the design system hides (visibility), so it cannot be selected or found. */
.browser td.date { white-space: nowrap; color: var(--muted-foreground); font-variant-numeric: tabular-nums; }
.browser td .badge { margin: 0 var(--space-1) var(--space-1) 0; }
/* Long values wrap inside their cell instead of widening the table. The answer columns are sized so every real
   answer fits on one line; only a value longer than its whole column wraps, and a long word breaks rather than
   pushing the last column out of view. */
#t-table td { overflow-wrap: anywhere; }
#t-table td .badge { max-width: 100%; height: auto; min-height: var(--space-6); padding-block: var(--space-0-5); white-space: normal; }
.cell-label { display: none; }
.browser-foot { justify-content: space-between; align-items: center; }
.browser-foot p { font-size: var(--text-sm); line-height: var(--leading-sm); color: var(--muted-foreground); max-width: 80ch; }
/* Wide screens (1280px and up): each policy is one grid row with the name, the four answers and the date on the
   first line and the summary under them across the row. The answer columns have fixed widths that fit the
   longest answer on one line, the name takes the rest, so the table always fits its panel. The header row uses
   the same columns; its Summary label is kept for screen readers only. */
@media (min-width: 1280px) {
  #t-table, #t-table thead, #t-table tbody { display: block; width: auto; }
  #t-table tr {
    display: grid; align-items: start;
    grid-template-columns:
      [name] minmax(0, 1fr) [stance] 11.75rem [disclosure] 12rem [autonomous_agents] 15.5rem
      [licensing_copyright] 20.5rem [checked] calc(5.5rem + var(--space-3) + var(--space-4)) [end];
    border-bottom: var(--border-hairline) solid var(--border);
  }
  #t-table tbody tr:last-child { border-bottom: 0; }
  #t-table th, #t-table td { height: auto; border-bottom: 0; min-width: 0; grid-row: 1; }
  /* Header cells fill the header row, so its background has no gaps, with the labels on the bottom line. */
  #t-table thead tr { align-items: stretch; }
  #t-table thead th { white-space: normal; display: flex; flex-direction: column; justify-content: flex-end; }
  #t-table .col-name, #t-table td.name { grid-column: name; }
  #t-table .col-stance, #t-table td.ans-stance { grid-column: stance; }
  #t-table .col-disclosure, #t-table td.ans-disclosure { grid-column: disclosure; }
  #t-table .col-autonomous_agents, #t-table td.ans-autonomous_agents { grid-column: autonomous_agents; }
  #t-table .col-licensing_copyright, #t-table td.ans-licensing_copyright { grid-column: licensing_copyright; }
  #t-table .col-checked, #t-table td.date { grid-column: checked; padding-right: var(--space-4); }
  #t-table thead th.col-summary { position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  #t-table td.t-summary { grid-row: 2; grid-column: name / end; padding: 0 var(--space-4) var(--space-3); max-width: 100ch; }
}
/* Below 1280px each policy becomes a stacked card instead of a table that scrolls sideways. */
@media (max-width: 1279.98px) {
  #t-table, #t-table tbody, #t-table tr, #t-table td { display: block; width: auto; }
  #t-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  #t-table tr { padding: var(--space-3) var(--space-4); border-bottom: var(--border-hairline) solid var(--border); }
  #t-table tbody tr:last-child { border-bottom: 0; }
  #t-table td { height: auto; padding: var(--space-1) 0; border: 0; min-width: 0; max-width: none; }
  #t-table td.t-summary { padding-bottom: var(--space-2); }
  #t-table .cell-label { display: block; margin-bottom: var(--space-1); font-size: var(--text-xs); line-height: var(--leading-xs); color: var(--muted-foreground); }
  #t-table.table--ghost .skel-cell { inset: var(--space-1) 0; }
}
/* Tablets and small laptops: the date sits on the name's line, the summary spans the card, and the answers
   flow side by side, each as wide as its longest answer, wrapping to a new line only when the card is full. */
@media (min-width: 561px) and (max-width: 1279.98px) {
  #t-table tr { display: flex; flex-wrap: wrap; align-items: flex-start; column-gap: var(--space-6); }
  #t-table td.name { order: 0; flex: 1 1 0; }
  #t-table td.date { order: 1; flex: 0 0 auto; text-align: right; }
  #t-table td.t-summary { order: 2; flex: 1 1 100%; }
  #t-table td.answer { order: 3; flex: 0 1 auto; }
}
/* Phones: one column, and the loading skeleton shows only the first three cards. */
@media (max-width: 560px) {
  #t-table.table--skeleton tbody tr:nth-child(n+4) { display: none; }
}

/* ---------- Statement ---------- */
.two { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-6); align-items: start; }
.two > * { min-width: 0; }
@media (max-width: 979.98px) { .two { grid-template-columns: minmax(0, 1fr); } .two .preview { position: static; max-height: none; } }
.group { border: 0; padding: 0; margin: 0; min-width: 0; }
.group + .group, .group + .toggle { margin-top: var(--space-6); }
.group > legend { padding: 0; margin-bottom: var(--space-3); font-size: var(--text-base); line-height: var(--leading-base); font-weight: var(--font-weight-semibold); }
.uses { display: grid; gap: var(--space-2); }
.use { border: var(--border-hairline) solid var(--border); border-radius: var(--radius-md); background: var(--card); }
.use:has(> label input:checked) { border-color: var(--primary); }
.use > label { display: flex; gap: var(--space-3); align-items: center; min-height: var(--control-h); padding: var(--space-2) var(--space-4); cursor: pointer; font-size: var(--text-sm); line-height: var(--leading-sm); font-weight: var(--font-weight-medium); }
.use .details { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-3); padding: 0 var(--space-4) var(--space-3); }
.use .details .field { gap: var(--space-1); }
@media (max-width: 519.98px) { .use .details { grid-template-columns: minmax(0, 1fr); } }
.toggle { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--control-h); font-size: var(--text-sm); line-height: var(--leading-sm); cursor: pointer; position: relative; }
.toggle input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.toggle__track { position: relative; width: var(--size-switch-width); height: var(--space-5); flex: none; border-radius: var(--radius-full); background: var(--card); border: var(--border-hairline) solid var(--input); transition: background-color var(--duration-fast) var(--easing-out); }
.toggle__track::after { content: ""; position: absolute; top: var(--border-hairline); left: var(--border-hairline); width: var(--size-icon-sm); height: var(--size-icon-sm); border-radius: var(--radius-full); background: var(--input); transition: translate var(--duration-fast) var(--easing-out); }
.toggle input:checked + .toggle__track { background: var(--primary); border-color: var(--primary); }
.toggle input:checked + .toggle__track::after { translate: var(--size-icon-sm) 0; background: var(--primary-foreground); }
.toggle input:focus-visible + .toggle__track { outline: var(--focus-width) solid var(--ring); outline-offset: var(--focus-offset); }
.s-status { margin: var(--space-3) var(--space-4) 0; }
.s-status:empty { display: none; }
.s-status p, .s-status li { max-width: none; }
.s-status p + p { margin-top: var(--space-2); }
.s-legal { margin: var(--space-2) var(--space-4) 0; }
.notes { padding: 0 var(--space-4) var(--space-4); font-size: var(--text-sm); line-height: var(--leading-sm); color: var(--muted-foreground); overflow: auto; position: relative; }
.notes ul { padding-left: var(--space-4); list-style: disc; display: grid; gap: var(--space-1); }
.notes li { max-width: none; }

/* ---------- Templates and help (deeper pages, with breadcrumbs) ---------- */
/* The design system reset keeps list padding; breadcrumbs line up with the page title. */
.grid-cards { display: grid; gap: var(--space-4); grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr)); grid-auto-rows: 1fr; }
.tpl { display: flex; flex-direction: column; }
.tpl .panel__body { flex: 1 1 auto; display: grid; align-content: start; gap: var(--space-2); }
.tpl .panel__body p { font-size: var(--text-sm); line-height: var(--leading-sm); color: var(--muted-foreground); }
.tpl .panel__footer { justify-content: flex-start; }
/* PR 13 review MF2: the "Your stance" badge sits on the title line, so every card's header is one
   control tall and the header rules and body text line up across the row. */
.tpl > .panel__header { flex-wrap: nowrap; min-block-size: calc(var(--control-h) + 2 * var(--space-3) + var(--border-hairline)); }
.tpl > .panel__header > .panel__title { min-width: 0; }
.tpl > .panel__header > .badge { flex: none; }
/* v0.4.3 self-review: a long title can still take two lines in a narrow card, so each card is three rows of a
   subgrid and every header, body and footer in a row of cards shares one height. */
#tpl-grid { grid-auto-rows: auto; }
#tpl-grid > .tpl { display: grid; grid-row: span 3; grid-template-rows: subgrid; row-gap: 0; }
.help h2 { font-size: var(--text-lg); line-height: var(--leading-lg); margin-bottom: var(--space-3); }
.help p { color: var(--muted-foreground); }
.help code { font-family: var(--font-mono); font-size: var(--text-sm); background: var(--muted); padding: 0 var(--space-1); border-radius: var(--radius-sm); overflow-wrap: anywhere; }
.help-list { display: grid; grid-template-columns: minmax(0, 12rem) minmax(0, 1fr); gap: var(--space-3) var(--space-4); }
.help-list dt { font-weight: var(--font-weight-medium); font-size: var(--text-sm); line-height: var(--leading-sm); }
.help-list dd { color: var(--muted-foreground); font-size: var(--text-sm); line-height: var(--leading-sm); }
@media (max-width: 559.98px) { .help-list { grid-template-columns: minmax(0, 1fr); row-gap: var(--space-1); } .help-list dd { margin-bottom: var(--space-3); } }

/* ---------- Footer ---------- */
.foot { display: grid; gap: var(--space-3); padding-block: var(--space-6) var(--space-8); color: var(--muted-foreground); font-size: var(--text-sm); line-height: var(--leading-sm); }
.app-footer { border-top: var(--border-hairline) solid var(--border); }
.foot p, .foot li { max-width: 80ch; }
.foot strong, .foot summary { color: var(--foreground); }
.foot summary { cursor: pointer; font-weight: var(--font-weight-medium); min-height: var(--size-target-min); display: inline-flex; align-items: center; gap: var(--space-1); list-style: none; }
/* v0.4.3 cross-app fix (health PR 5 MF1): a flex summary loses the native marker, so it draws a chevron that turns
   when the section opens. */
.foot summary::-webkit-details-marker { display: none; }
.disclosure { flex: none; transition: transform var(--duration-fast) var(--easing-out); }
details[open] > summary > .disclosure { transform: rotate(90deg); }
@media (prefers-reduced-motion: reduce) { .disclosure { transition: none; } }
.foot ul { margin-top: var(--space-2); padding-left: var(--space-4); list-style: disc; }
.foot nav { display: flex; gap: var(--space-4); }
.foot nav a { color: var(--muted-foreground); min-height: var(--size-target-min); display: inline-flex; align-items: center; }

/* ---------- Motion ---------- */
.view:not([hidden]) { animation: fade var(--duration-base) var(--easing-out); }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .view:not([hidden]), .doc .flash { animation: none; } }

/* Scroll boxes hold visually hidden text; keep it inside them so the page never scrolls sideways. */
.table-wrap, .file-tabs, .file-switch, .notes, .diff, .gh-wrap, .gh { position: relative; }

/* ---------- Print: only the exported document, clean black on white ---------- */
.print-root { display: none; }
@media print {
  html.printing body > *:not(#print-root) { display: none !important; }
  html.printing .print-root { display: block; }
  html.printing, html.printing body { background: #fff !important; color: #000 !important; }
  .print-doc { max-height: none; overflow: visible; padding: 0; font: 11pt/1.5 Georgia, "Times New Roman", serif; color: #000; }
  .print-doc p, .print-doc li { max-width: none; }
  .print-doc h1, .print-doc h2, .print-doc h3, .print-doc h4 { font-family: var(--font-sans); color: #000; break-after: avoid; page-break-after: avoid; }
  .print-doc h1, .print-doc h2 { border-bottom: 1px solid #999; }
  .print-doc a { color: #000; text-decoration: underline; }
  .print-doc a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; color: #333; word-break: break-all; }
  .print-doc code, .print-doc pre { background: #f2f2f2; color: #000; }
  .print-doc li, .print-doc p, .print-doc pre, .print-doc blockquote { break-inside: avoid; page-break-inside: avoid; }
  .print-doc .task-list-item-checkbox { border-color: #000; background: #fff; }
  .print-doc .task-list-item-checkbox:checked { background: #000; box-shadow: inset 0 0 0 2px #fff; }
  @page { margin: 18mm 16mm; }
}

/* Buttons whose position depends on their text width are rounded up to a whole pixel, so the
   edges next to them stay on the pixel grid (Testingralph MF3). Browsers without calc-size ignore it. */
.step-footer > .btn { flex-shrink: 0; }
.step-footer { flex-wrap: wrap; row-gap: var(--space-2); }
.step-footer > .step-count { flex: 1 1 auto; min-width: 0; text-align: center; }
.step-footer > .btn, .export-bar .btn, .ed-status .btn, .preview-bar .btn, .panel__footer .btn, .app-header__end .btn {
  width: calc-size(fit-content, round(up, size, 1px));
}
/* A centered state sits on an even width from a whole-pixel left edge, so its centered
   actions never land on a half pixel. */
.state--center { width: round(down, 100%, 2px); margin-inline: 0; }
/* Centered actions use even widths, so centering never lands on a half pixel. */
.state__actions > .btn { width: calc-size(fit-content, round(up, size, 2px)); }
/* Editor loading: the line with Cancel sits above the skeleton lines. */
.ed-loading__bar { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); max-width: var(--size-prose-max); margin-inline: auto; padding: var(--space-4) var(--space-4) 0; }
@media (min-width: 768px) { .ed-loading__bar { padding-inline: var(--space-8); } }
/* Until the editor code is in, there is nothing to preview: the loading or error box takes the
   full width instead of sitting next to an empty preview panel. */
.ed-grid:has(#ed-loading:not([hidden]), #ed-load-error) { grid-template-columns: minmax(0, 1fr); }
.ed-grid:has(#ed-loading:not([hidden]), #ed-load-error) > .ed-preview { display: none; }
.step-footer > #next { margin-left: auto; }
/* PR 13 review SF3: on phones Back and Next share one row; the stepper above already shows the step. */
@media (max-width: 479.98px) { .step-footer > .step-count { display: none; } }

/* Keys in a row sit in a flex row, so the space between them is a whole-pixel gap, not a text space. */
.help-list--keys dt { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--space-1); }

/* Zip busy note (design system v0.4.3 third round, busy note "status" mode): the visible busy label is muted text laid
   over the export row's own label, which is hidden meanwhile and keeps its box (.is-busy-host), so no control moves
   and none is covered. Centred on the row, one line, the label's own size (round 4); it wraps only below 375. */
.export-label.is-busy-host { position: relative; }
.zip-busy-note { inset-block-start: 50%; transform: translateY(-50%); }
.zip-busy-note.busy-note--wrap { inline-size: max-content; }

/* Zip note (design system v0.4.3 second round, like the .zip menu item's second line): when a file is blank it is
   left out of the .zip, and this visible line under the buttons says how many files go in and names the empty ones.
   It takes its own row in the export bar, a 20px line over a 16px muted line. */
.zip-note { flex-basis: 100%; order: 1; display: grid; margin: 0; max-width: none; font-size: var(--text-sm); line-height: var(--leading-sm); color: var(--foreground); }
.zip-note[hidden] { display: none; }
.zip-note__sub { font-size: var(--text-xs); line-height: var(--leading-xs); color: var(--muted-foreground); text-wrap: pretty; }

/* Cards sit on the 4px grid: the hairline border is taken out of the block padding, so border plus padding
   is 24px and the card height stays a multiple of 4 (the text inside is set in 4px multiples). */
.choice-card, .file-card { padding-block: calc(var(--space-3) - var(--border-hairline)); }
/* Review rows hold text and an Edit button on a shared baseline, so their natural height is not a 4px multiple;
   round it up to the next one. Browsers without calc-size keep the natural height. */
.review-row { block-size: calc-size(auto, round(up, size, 4px)); }
