/* alisx.css · @alis-build/design-system. GENERATED from tokens.json and source/css/; do not edit by hand.
   Contents: tokens as custom properties, light and dark (rules/themes.md) · type classes · product base (resets * and body) · .app-* product components.
   Fonts are not loaded here: add fonts.css, or self-host Nunito Sans and Material Symbols Outlined. */

:root {
  color-scheme: light;
  --petrol-950: #161d22;
  --petrol-900: #1b242b;
  --petrol-850: #232d35;
  --petrol-800: #27323a;
  --petrol-700: #39444d;
  --petrol-500: #5d666d;
  --slate-500: #55636e;
  --blue-600: #2a5cbe;
  --mist-100: #dfe7ec;
  --paper-0: #ffffff;
  --paper-25: #fdfdfc;
  --paper-50: #fbfbfa;
  --paper-75: #f8f8f8;
  --paper-100: #f4f4f2;
  --paper-150: #f3f3f2;
  --grey-200: #e6e8eb;
  --grey-250: #e2e3e3;
  --grey-300: #cfd2d4;
  --grey-400: #c4c7ca;
  --grey-500: #909499;
  --grey-600: #74777c;
  --cyan-700: #004f68;
  --cyan-600: #006383;
  --cyan-200: #7fd4e8;
  --teal-600: #006b70;
  --teal-200: #7fd4c1;
  --violet-700: #473078;
  --violet-600: #584287;
  --violet-200: #c3b2f7;
  --amber-100: #ffd9a8;
  --amber-700: #b58200;
  --alis-red: #f02222;
  --red-700: #ba1a1a;
  --green-700: #1e6b3a;
  --primary: light-dark(var(--cyan-600), var(--cyan-200));
  --on-primary: light-dark(var(--paper-0), #00303f);
  --signal: var(--alis-red);
  --on-surface: light-dark(var(--petrol-800), var(--mist-100));
  --on-surface-variant: light-dark(var(--petrol-500), #9aa6ae);
  --background: light-dark(var(--paper-50), #192127);
  --surface: light-dark(var(--paper-0), #26313a);
  --surface-container-low: light-dark(var(--paper-150), #21292f);
  --surface-container-high: light-dark(var(--paper-0), #29343c);
  --surface-container-highest: light-dark(var(--grey-200), #2f3b45);
  --surface-variant: light-dark(var(--grey-200), #2f3b45);
  --shimmer: light-dark(var(--paper-0), #3d4a55);
  --secondary-container: light-dark(var(--grey-300), #34434e);
  --on-secondary-container: light-dark(var(--petrol-800), var(--mist-100));
  --selection-chrome: light-dark(var(--grey-250), #2a363f);
  --outline: light-dark(var(--grey-600), #77838c);
  --field-edge: light-dark(var(--grey-400), #46525b);
  --field-edge-hover: light-dark(var(--grey-500), #6f7b84);
  --outline-variant: light-dark(var(--grey-200), #34414a);
  --error: light-dark(var(--red-700), #ffb4ab);
  --on-error: light-dark(var(--paper-0), #690005);
  --warning: light-dark(var(--amber-700), #e9b443);
  --success: light-dark(var(--green-700), #7ccf95);
  --info: light-dark(var(--blue-600), #a9c1ff);
  --inverse-surface: light-dark(var(--petrol-800), var(--mist-100));
  --on-inverse-surface: light-dark(var(--paper-100), var(--petrol-800));
  --code-surface: light-dark(var(--paper-75), #2c353b);
  --machine-surface: light-dark(var(--petrol-800), #0f1418);
  --on-machine-surface: light-dark(var(--paper-100), var(--mist-100));
  --paper: var(--paper-0);
  --scrim: #000000;
  --shadow-key: light-dark(rgba(16, 24, 40, 0.16), rgba(0, 0, 0, 0.4));
  --shadow-ambient: light-dark(rgba(16, 24, 40, 0.2), rgba(0, 0, 0, 0.45));
  --highlight: light-dark(#fdecc8, #5b4614);
  --on-highlight: light-dark(var(--petrol-800), #fdecc8);
  --cat1: light-dark(#7860c4, #846cd1);
  --cat2: #19a289;
  --cat3: #c97409;
  --cat4: #0398cd;
  --cat5: light-dark(#b3487e, #c1548a);
  --cat6: #728d02;
  --on-cat: var(--paper-0);
  --cat1-container: light-dark(#ede9ff, #2f2752);
  --cat2-container: light-dark(#d2f6ec, #0f3a31);
  --cat3-container: light-dark(#ffe8d2, #43280a);
  --cat4-container: light-dark(#d3f2ff, #0b3446);
  --cat5-container: light-dark(#ffe2f0, #45192f);
  --cat6-container: light-dark(#e8f2d4, #2a3405);
  --on-cat1-container: light-dark(#443672, #ddd5ff);
  --on-cat2-container: light-dark(#004f41, #b5efdc);
  --on-cat3-container: light-dark(#653400, #ffd9b3);
  --on-cat4-container: light-dark(#00496a, #c2ecff);
  --on-cat5-container: light-dark(#682848, #ffd1e6);
  --on-cat6-container: light-dark(#3a4a00, #d6ea9f);
  --chart-neutral: #8c8e8e;
  --syntax-plain: light-dark(var(--petrol-800), var(--mist-100));
  --syntax-comment: light-dark(var(--petrol-500), #9aa6ae);
  --syntax-keyword: light-dark(#5f45a6, #cdb7ff);
  --syntax-string: light-dark(#006f58, #6de3c8);
  --syntax-number: light-dark(#914100, #ffb35e);
  --syntax-function: light-dark(#952c64, #ff9fd5);
  --ai-you: #0398cd;
  --ai-you-container: light-dark(#d3f2ff, #9fdcf0);
  --ai-alis: var(--signal);
  --ai-alis-container: light-dark(#ffece9, #f0a39b);
  --ai-tail: #19a289;
  --ai-ground-start: var(--cyan-600);
  --ai-ground-end: #004f41;
  --narrative-canvas: var(--paper-25);
  --narrative-surface-sunken: var(--paper-75);
  --narrative-ink-body: var(--petrol-700);
  --narrative-line: rgba(39, 50, 58, 0.12);
  --narrative-line-strong: rgba(39, 50, 58, 0.16);
  --narrative-line-inverse: rgba(255, 255, 255, 0.22);
  --narrative-link: var(--cyan-700);
  --narrative-tone-forge: var(--teal-600);
  --band-top: var(--petrol-850);
  --band-bottom: var(--petrol-900);
  --band-fg: rgba(253, 253, 252, 0.78);
  --band-surface: rgba(253, 253, 252, 0.05);
  --band-line: rgba(255, 255, 255, 0.12);
  --on-band-ideate: var(--cyan-200);
  --on-band-build: var(--violet-200);
  --on-band-forge: var(--amber-100);
  --on-band-spec: var(--teal-200);
  --term-bg: var(--petrol-950);
  --term-fg: var(--mist-100);
  --term-prompt: var(--teal-200);
  --term-reply: #ffc107;
  --term-ok: #4caf50;
  --field-grid-line: light-dark(rgba(39, 50, 58, 0.06), rgba(127, 212, 232, 0.055));
  --field-glow-1: light-dark(rgba(0, 99, 131, 0.12), rgba(127, 212, 232, 0.1));
  --field-glow-2: light-dark(rgba(88, 66, 135, 0.1), rgba(195, 178, 247, 0.08));
  --field-noise: light-dark(var(--petrol-800), var(--paper-0));
  --bench-grid-line: rgba(127, 212, 232, 0.055);
  --space-4: 4px;
  --space-8: 8px;
  --space-12: 12px;
  --space-16: 16px;
  --space-24: 24px;
  --space-32: 32px;
  --space-48: 48px;
  --card-padding-wide: 28px;
  --chat-row: 32px;
  --touch-target: 32px;
  --touch-target-coarse: 48px;
  --control-height: 36px;
  --titlebar-height-phone: 64px;
  --measure-prose: 710px;
  --nav-width: 256px;
  --detail-width: 360px;
  --breakpoint-compact: 600px;
  --breakpoint-medium: 840px;
  --breakpoint-expanded: 1200px;
  --breakpoint-large: 1600px;
  --container: 1280px;
  --radius-0: 0px;
  --radius-xs: 4px;
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 16px;
  --radius-xl: 28px;
  --radius-pill: 999px;
  --elevation-1: 0 1px 2px 0 var(--shadow-key), 0 2px 6px 0 var(--shadow-ambient);
  --elevation-2: 0 1px 2px 0 var(--shadow-key), 0 4px 12px 0 var(--shadow-ambient);
  --elevation-3: 0 1px 3px 0 var(--shadow-key), 0 12px 32px -4px var(--shadow-ambient);
  --dur-spatial: 220ms;
  --dur-effects: 160ms;
  --dur-tint: 140ms;
  --dur-ui: 200ms;
  --dur-panel: 320ms;
  --dur-arrive: 650ms;
  --stagger: 120ms;
  --blink: 1.1s;
  --motion-spatial: cubic-bezier(0.2, 0.8, 0.2, 1.15);
  --motion-effects: cubic-bezier(0.2, 0, 0, 1);
  --ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
  --ease-arrive: cubic-bezier(0.22, 1, 0.36, 1);
  --state-hover: 0.04;
  --state-focus: 0.04;
  --state-pressed: 0.12;
  --state-statement: 0.04;
  --state-dragged: 0.08;
  --font-sans: "Nunito Sans", "Inter", ui-sans-serif, system-ui, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

/* Themes: light unless asked. data-theme works on any element (rules/themes.md). */
[data-theme="light"] { color-scheme: light; }
[data-theme="dark"] { color-scheme: dark; }
[data-theme="system"] { color-scheme: light dark; }
@media print { :root, [data-theme], .app-machine *, .app-ai-ground * { color-scheme: light !important; } }
/* A browser without light-dark() gets the light theme, never unset colours, and machine speech stays dark. */
@supports not (color: light-dark(#000, #fff)) {
  :root {
    --primary: var(--cyan-600);
    --on-primary: var(--paper-0);
    --on-surface: var(--petrol-800);
    --on-surface-variant: var(--petrol-500);
    --background: var(--paper-50);
    --surface: var(--paper-0);
    --surface-container-low: var(--paper-150);
    --surface-container-high: var(--paper-0);
    --surface-container-highest: var(--grey-200);
    --surface-variant: var(--grey-200);
    --shimmer: var(--paper-0);
    --secondary-container: var(--grey-300);
    --on-secondary-container: var(--petrol-800);
    --selection-chrome: var(--grey-250);
    --outline: var(--grey-600);
    --field-edge: var(--grey-400);
    --field-edge-hover: var(--grey-500);
    --outline-variant: var(--grey-200);
    --error: var(--red-700);
    --on-error: var(--paper-0);
    --warning: var(--amber-700);
    --success: var(--green-700);
    --info: var(--blue-600);
    --inverse-surface: var(--petrol-800);
    --on-inverse-surface: var(--paper-100);
    --code-surface: var(--paper-75);
    --machine-surface: var(--petrol-800);
    --on-machine-surface: var(--paper-100);
    --shadow-key: rgba(16, 24, 40, 0.16);
    --shadow-ambient: rgba(16, 24, 40, 0.2);
    --highlight: #fdecc8;
    --on-highlight: var(--petrol-800);
    --cat1: #7860c4;
    --cat5: #b3487e;
    --cat1-container: #ede9ff;
    --cat2-container: #d2f6ec;
    --cat3-container: #ffe8d2;
    --cat4-container: #d3f2ff;
    --cat5-container: #ffe2f0;
    --cat6-container: #e8f2d4;
    --on-cat1-container: #443672;
    --on-cat2-container: #004f41;
    --on-cat3-container: #653400;
    --on-cat4-container: #00496a;
    --on-cat5-container: #682848;
    --on-cat6-container: #3a4a00;
    --syntax-plain: var(--petrol-800);
    --syntax-comment: var(--petrol-500);
    --syntax-keyword: #5f45a6;
    --syntax-string: #006f58;
    --syntax-number: #914100;
    --syntax-function: #952c64;
    --ai-you-container: #d3f2ff;
    --ai-alis-container: #ffece9;
    --field-grid-line: rgba(39, 50, 58, 0.06);
    --field-glow-1: rgba(0, 99, 131, 0.12);
    --field-glow-2: rgba(88, 66, 135, 0.1);
    --field-noise: var(--petrol-800);
  }
  .app-machine *, .app-ai-ground * {
    --primary: var(--cyan-200);
    --on-primary: #00303f;
    --on-surface: var(--mist-100);
    --on-surface-variant: #9aa6ae;
    --background: #192127;
    --surface: #26313a;
    --surface-container-low: #21292f;
    --surface-container-high: #29343c;
    --surface-container-highest: #2f3b45;
    --surface-variant: #2f3b45;
    --shimmer: #3d4a55;
    --secondary-container: #34434e;
    --on-secondary-container: var(--mist-100);
    --selection-chrome: #2a363f;
    --outline: #77838c;
    --field-edge: #46525b;
    --field-edge-hover: #6f7b84;
    --outline-variant: #34414a;
    --error: #ffb4ab;
    --on-error: #690005;
    --warning: #e9b443;
    --success: #7ccf95;
    --info: #a9c1ff;
    --inverse-surface: var(--mist-100);
    --on-inverse-surface: var(--petrol-800);
    --code-surface: #2c353b;
    --machine-surface: #0f1418;
    --on-machine-surface: var(--mist-100);
    --shadow-key: rgba(0, 0, 0, 0.4);
    --shadow-ambient: rgba(0, 0, 0, 0.45);
    --highlight: #5b4614;
    --on-highlight: #fdecc8;
    --cat1: #846cd1;
    --cat5: #c1548a;
    --cat1-container: #2f2752;
    --cat2-container: #0f3a31;
    --cat3-container: #43280a;
    --cat4-container: #0b3446;
    --cat5-container: #45192f;
    --cat6-container: #2a3405;
    --on-cat1-container: #ddd5ff;
    --on-cat2-container: #b5efdc;
    --on-cat3-container: #ffd9b3;
    --on-cat4-container: #c2ecff;
    --on-cat5-container: #ffd1e6;
    --on-cat6-container: #d6ea9f;
    --syntax-plain: var(--mist-100);
    --syntax-comment: #9aa6ae;
    --syntax-keyword: #cdb7ff;
    --syntax-string: #6de3c8;
    --syntax-number: #ffb35e;
    --syntax-function: #ff9fd5;
    --ai-you-container: #9fdcf0;
    --ai-alis-container: #f0a39b;
    --field-grid-line: rgba(127, 212, 232, 0.055);
    --field-glow-1: rgba(127, 212, 232, 0.1);
    --field-glow-2: rgba(195, 178, 247, 0.08);
    --field-noise: var(--paper-0);
  }
}

/* Rules on the tokens themselves, shipped in alisx.css and tokens.css alike. */
@media (pointer: coarse) { :root { --touch-target: var(--touch-target-coarse); --control-height: var(--touch-target-coarse); } }
@media (prefers-reduced-motion: reduce) { :root { --dur-spatial: 0ms; --dur-effects: 0ms; --dur-tint: 0ms; --dur-ui: 0ms; --dur-panel: 0ms; --dur-arrive: 0ms; --stagger: 0ms; } }

/* Type styles: one class per job (rules/type.md). */
.text-welcome-title { font-family: var(--font-sans); font-size: 40px; line-height: 48px; font-weight: 800; letter-spacing: -0.03em; }
.text-page-title { font-family: var(--font-sans); font-size: 28px; line-height: 36px; font-weight: 700; letter-spacing: -0.03em; }
.text-section-title { font-family: var(--font-sans); font-size: 18px; line-height: 24px; font-weight: 600; letter-spacing: -0.02em; }
.text-object-title { font-family: var(--font-sans); font-size: 16px; line-height: 24px; font-weight: 500; letter-spacing: 0; }
.text-body { font-family: var(--font-sans); font-size: 16px; line-height: 24px; font-weight: 400; letter-spacing: 0; }
.text-supporting { font-family: var(--font-sans); font-size: 14px; line-height: 20px; font-weight: 400; letter-spacing: 0; }
.text-meta { font-family: var(--font-sans); font-size: 12px; line-height: 16px; font-weight: 400; letter-spacing: 0; }
.text-label { font-family: var(--font-sans); font-size: 14px; line-height: 20px; font-weight: 500; letter-spacing: 0; }
.text-eyebrow { font-family: var(--font-sans); font-size: 12px; line-height: 16px; font-weight: 700; letter-spacing: 0.12em; }
.text-metric-value { font-family: var(--font-sans); font-size: 40px; line-height: 48px; font-weight: 700; letter-spacing: -0.03em; }
.narrative-h1 { font-family: var(--font-sans); font-size: 4.8rem; line-height: 1.03; font-weight: 800; letter-spacing: -0.04em; }
.narrative-h2 { font-family: var(--font-sans); font-size: 3.4rem; line-height: 1.08; font-weight: 780; letter-spacing: -0.03em; }
.narrative-h3 { font-family: var(--font-sans); font-size: 1.12rem; line-height: 1.35; font-weight: 700; letter-spacing: -0.01em; }
.narrative-lede { font-family: var(--font-sans); font-size: 1.22rem; line-height: 1.7; font-weight: 400; letter-spacing: 0; }
.narrative-deck { font-family: var(--font-sans); font-size: 1.12rem; line-height: 1.65; font-weight: 400; letter-spacing: 0; }
.narrative-body { font-family: var(--font-sans); font-size: 1rem; line-height: 1.55; font-weight: 400; letter-spacing: 0; }
.narrative-eyebrow { font-family: var(--font-sans); font-size: 0.76rem; line-height: 1.3; font-weight: 700; letter-spacing: 0.18em; }
.mono { font-family: var(--font-mono); font-size: 0.93rem; line-height: 1.5; font-weight: 400; letter-spacing: 0; }
.mono-sm { font-family: var(--font-mono); font-size: 0.82rem; line-height: 1.5; font-weight: 400; letter-spacing: 0; }
.mono-xs { font-family: var(--font-mono); font-size: 0.78rem; line-height: 1.4; font-weight: 700; letter-spacing: 0.12em; }
@media (max-width: 599px) {
  .text-welcome-title { font-size: 32px; line-height: 40px; }
  .text-page-title { font-size: 22px; line-height: 28px; font-weight: 500; letter-spacing: 0; }
}

/* Product base. A marketing page overrides it with <body class="ax-page">. */
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; background: var(--background); color: var(--on-surface); font-family: var(--font-sans); font-size: 16px; line-height: 24px; -webkit-font-smoothing: antialiased; }
button, input, textarea, select { font: inherit; }
/* A section that asks for a theme paints its own ground and ink, so it is right all the way down (rules/themes.md) */
[data-theme]:not(:root) { background-color: var(--background); color: var(--on-surface); }

/* Drafting field: the one marketing texture permitted in the product (entry screens and pane-filling empty states). */
:root {
  --rc-noise: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.4'/%3E%3C/svg%3E"); 
  --noise-opacity: 0.025; 
  --field-grid-size: 72px; 
  --field-grid: linear-gradient(var(--field-grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--field-grid-line) 1px, transparent 1px); 
  --field-glow: radial-gradient(52rem 26rem at 18% 118%, var(--field-glow-1), transparent 62%),
    radial-gradient(46rem 24rem at 82% 122%, var(--field-glow-2), transparent 60%); 
  --field-mask: radial-gradient(closest-side at 50% 30%, rgba(0, 0, 0, 0.9), transparent 80%); /* any-theme: a mask reads alpha only */
}
.ax-field{position:absolute;inset:0;pointer-events:none;z-index:0}
.ax-field__glow{position:absolute;inset:0;background:var(--field-glow)}
.ax-field__grid{position:absolute;inset:0;background-image:var(--field-grid);background-size:var(--field-grid-size) var(--field-grid-size);-webkit-mask-image:var(--field-mask);mask-image:var(--field-mask)}
/* The grain is drawn in field-noise through the noise as a mask, so it darkens a light ground and lightens a dark one */
.ax-field__noise{position:absolute;inset:0;background:var(--field-noise);-webkit-mask-image:var(--rc-noise);mask-image:var(--rc-noise);opacity:var(--noise-opacity)}

/* ══ Product register · .app-* ═════════════════════════════════════════
   Framework-neutral classes for working screens (Ideate, Build, Admin).
   Every value is a token. The React App* components are thin wrappers;
   any stack can write these classes directly. Rules: the Rules sections. */

/* ── Type-style completions the token classes can't carry ── */
.text-eyebrow{text-transform:uppercase}
.text-metric-value{font-variant-numeric:tabular-nums}

/* ── Face and weight, beside a role class: the role keeps the size ── */
.text-mono{font-family:var(--font-mono)}
.text-emphasis{font-weight:600}
.text-selected{font-weight:700}

/* ── Ink, for text whose role takes the second ink (rules/type.md) ── */
.text-on-surface{color:var(--on-surface)}
.text-on-surface-variant{color:var(--on-surface-variant)}

/* ── Icon · Material Symbols Outlined; alis_* names are capability marks ── */
.app-icon{font-family:"Material Symbols Outlined";font-weight:normal;font-style:normal;font-size:20px;line-height:1;letter-spacing:0;text-transform:none;white-space:nowrap;direction:ltr;display:inline-flex;align-items:center;justify-content:center;width:1em;height:1em;flex:none;font-variation-settings:"FILL" 0,"wght" 400,"GRAD" 0,"opsz" 20;-webkit-font-smoothing:antialiased}
.app-icon--24{font-size:24px;font-variation-settings:"FILL" 0,"wght" 400,"GRAD" 0,"opsz" 24}
.app-icon--filled,.is-selected .app-icon{font-variation-settings:"FILL" 1,"wght" 500,"GRAD" 0,"opsz" 20}
.app-icon--mark{width:20px;height:20px}
.app-icon--mark.app-icon--24{width:24px;height:24px}

/* ── State layer: hover / focus / pressed over any interactive element ── */
.app-state{position:relative;isolation:isolate;cursor:pointer;-webkit-tap-highlight-color:transparent}
.app-state::before{content:"";position:absolute;inset:0;border-radius:inherit;background:currentColor;opacity:0;pointer-events:none;z-index:-1;transition:opacity var(--dur-effects) var(--motion-effects)}
.app-state:hover::before{opacity:var(--state-hover)}
.app-state:focus-visible::before{opacity:var(--state-focus)}
.app-state:active::before{opacity:var(--state-pressed)}
.app-state:focus-visible{outline:2px solid var(--primary);outline-offset:1px}
.app-state:disabled,.app-state[aria-disabled="true"]{cursor:default;opacity:.38}
.app-state:disabled::before,.app-state[aria-disabled="true"]::before{display:none}
/* A loading control is busy, not disabled: full colour, a spinner, no presses */
.app-state.is-loading{opacity:1;cursor:progress;pointer-events:none}
/* The target (32px, 48 under a coarse pointer) projected around a smaller box, so rows don't grow */
.app-target::after{content:"";position:absolute;left:50%;top:50%;width:max(100%,var(--touch-target));height:max(100%,var(--touch-target));transform:translate(-50%,-50%)}

/* ── Button · text (default) or filled (one per surface) ── */
.app-btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--space-8);min-height:var(--control-height);padding:0 var(--space-24);border:0;border-radius:var(--radius-pill);background:transparent;color:var(--on-surface);font-family:var(--font-sans);font-size:14px;line-height:20px;font-weight:600;letter-spacing:0;text-decoration:none;white-space:nowrap}
.app-btn .app-icon{font-size:16px;margin-left:calc(var(--space-8) * -1)}
/* A trailing glyph (open_in_new, a menu's chevron) pulls into the end padding instead */
.app-btn .app-icon--trailing{margin-left:0;margin-right:calc(var(--space-8) * -1)}
.app-btn--filled{padding:0 var(--space-24);background:var(--primary);color:var(--on-primary);font-weight:700;transition:border-radius var(--dur-spatial) var(--motion-spatial),transform var(--dur-spatial) var(--motion-spatial),background-color var(--dur-effects) var(--motion-effects)}
.app-btn--outlined{border:1px solid var(--outline-variant);background:var(--surface)}
.app-btn--error{color:var(--error)}
.app-btn--filled.app-btn--error{background:var(--error);color:var(--on-error)}
.app-btn--quiet{color:var(--on-surface-variant)}
.app-btn--small{min-height:32px;padding:0 var(--space-12)}
.app-btn__spinner{width:16px;height:16px;border-radius:var(--radius-pill);border:2px solid currentColor;border-right-color:transparent;flex:none}
@media (prefers-reduced-motion:no-preference){.app-btn__spinner{animation:app-spin .8s linear infinite}}
@keyframes app-spin{to{transform:rotate(360deg)}}
.app-target--none::after{content:none}
@media (prefers-reduced-motion:no-preference){.app-btn--filled:not(:disabled):active{border-radius:12px;transform:scale(.97)}}
.app-btn-row{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:var(--space-8)}
.app-btn-row--start{justify-content:flex-start}
.app-btn-row__start{margin-inline-end:auto}

/* ── Icon button · 20px glyph in a 40px box, no fill unless a toggle is on ── */
.app-icon-btn{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;padding:0;border:0;border-radius:var(--radius-pill);background:transparent;color:var(--on-surface-variant)}
.app-icon-btn--small{width:32px;height:32px}
.app-icon-btn.is-selected{background:var(--secondary-container);color:var(--on-secondary-container)}

/* ── Chip · a container for a small fact ── */
.app-chip{display:inline-flex;align-items:center;gap:var(--space-8);min-height:32px;padding:0 var(--space-16);border:1px solid transparent;border-radius:var(--radius-pill);font-family:var(--font-sans);font-size:14px;line-height:20px;font-weight:400;letter-spacing:0;white-space:nowrap;color:var(--on-surface-variant);background:color-mix(in srgb,currentColor 12%,transparent)}
.app-chip .app-icon{font-size:16px;margin-left:calc(var(--space-8) * -1)}
.app-chip--small{min-height:26px;font-size:12px;line-height:16px}
.app-chip--error{color:var(--error)}
.app-chip--success{color:var(--success)}
.app-chip--info{color:var(--info)}
.app-chip--warning{color:var(--on-surface);background:var(--surface-container-highest)}
.app-chip--warning .app-icon{color:var(--warning)}
/* Category: tonal, the cat role at 12% behind the same role as ink */
.app-chip[class*="app-chip--cat"]::before{content:"";flex:none;width:8px;height:8px;margin-left:calc(var(--space-4) * -1);border-radius:var(--radius-pill);background:var(--cat)}
.app-chip--cat1{--cat:var(--cat1);color:var(--on-cat1-container);background:var(--cat1-container)}.app-chip--cat2{--cat:var(--cat2);color:var(--on-cat2-container);background:var(--cat2-container)}.app-chip--cat3{--cat:var(--cat3);color:var(--on-cat3-container);background:var(--cat3-container)}
.app-chip--cat4{--cat:var(--cat4);color:var(--on-cat4-container);background:var(--cat4-container)}.app-chip--cat5{--cat:var(--cat5);color:var(--on-cat5-container);background:var(--cat5-container)}.app-chip--cat6{--cat:var(--cat6);color:var(--on-cat6-container);background:var(--cat6-container)}
/* Icon only: the glyph in the container's ink stands in for the dot */
.app-chip--icon{min-height:0;padding:var(--space-4)}.app-chip--icon .app-icon{margin:0}.app-chip.app-chip--icon::before{content:none}
/* Opaque: only where a chip overlaps or straddles other content */
.app-chip--opaque[class*="app-chip--cat"]{color:var(--on-surface)}
.app-chip--opaque:not([class*="app-chip--cat"]){background:var(--surface-container-highest);color:var(--on-surface)}
.app-chip--outlined{background:transparent;border-color:var(--outline)}
.app-chip--outlined.is-selected{background:var(--secondary-container);border-color:transparent;color:var(--on-secondary-container);font-weight:700}
.app-chip__close{display:inline-flex;margin-right:calc(var(--space-8) * -1);padding:0;border:0;border-radius:var(--radius-pill);background:transparent;color:inherit}
.app-chip-group{display:flex;flex-wrap:wrap;gap:var(--space-8)}

/* ── Alert · a statement carrying one status ── */
.app-alert{display:grid;grid-template-columns:auto 1fr auto;align-items:start;column-gap:var(--space-12);padding:var(--space-16);border-radius:var(--radius-xs);color:var(--info);background:color-mix(in srgb,currentColor 12%,transparent)}
.app-alert--error{color:var(--error)}
.app-alert--success{color:var(--success)}
.app-alert--warning{color:var(--warning)}
.app-alert__body{color:var(--on-surface);font-family:var(--font-sans);font-size:14px;line-height:20px}
.app-alert__title{display:block;font-weight:500;font-size:16px;line-height:24px}
.app-alert__actions{align-self:center}
/* Stacked: the action under the message. Automatic in the detail pane; .app-alert--stacked anywhere narrow */
.app-alert--stacked .app-alert__actions,.app-shell__detail .app-alert__actions{grid-column:2;align-self:start;justify-self:start;margin:var(--space-8) 0 0 calc(var(--space-16) * -1)}
@media (max-width:599px){.app-alert__actions{grid-column:2;align-self:start;justify-self:start;margin:var(--space-8) 0 0 calc(var(--space-16) * -1)}}

/* ── Snackbar · a passing notice: level 3, light, one text action at most ── */
.app-snackbar{position:fixed;left:50%;bottom:var(--space-24);transform:translateX(-50%);z-index:4;display:flex;align-items:center;gap:var(--space-8);width:max-content;max-width:min(560px,calc(100vw - 2 * var(--space-16)));min-height:48px;padding:var(--space-4) var(--space-8) var(--space-4) var(--space-16);border-radius:var(--radius-lg);background:var(--surface-variant);color:var(--on-surface);box-shadow:var(--elevation-3);font-family:var(--font-sans);font-size:14px;line-height:20px}
.app-snackbar--inline{position:static;transform:none}
.app-snackbar__text{flex:1;padding:var(--space-8) 0}
.app-snackbar:not(:has(.app-btn)){padding-right:var(--space-16)}

/* ── Card · statement (flat, context) or instrument (white, acted on) ── */
.app-card{display:flex;flex-direction:column;gap:var(--space-8);padding:var(--space-24);border-radius:var(--radius-lg);color:var(--on-surface);text-align:left}
@media (min-width:600px){.app-card{padding:var(--card-padding-wide)}}
.app-card--statement{background:var(--surface-container-low)}
.app-card--instrument{background:var(--surface);border:1px solid var(--outline-variant)}
/* A shadow means above the page: on the drafting field a card is protected by elevation, not an edge */
.app-empty-field .app-card--instrument,:has(>.ax-field)>* .app-card--instrument{border-color:transparent;box-shadow:var(--elevation-2)}
/* A card or row being dragged lifts until it settles */
.app-card.is-dragged,.app-row.is-dragged{border-color:transparent;background:var(--surface-container-high);box-shadow:var(--elevation-3);cursor:grabbing}
.app-card--instrument .app-card__inset{padding:var(--space-16);border-radius:var(--radius-md);background:var(--surface-container-low)}
button.app-card{border:0;font:inherit;width:100%}
.app-card__title{margin:0}
.app-card>.app-btn-row{margin-top:var(--space-8)}
/* A statement over a gradient: the role at the statement opacity */
.app-statement-over-gradient{background:color-mix(in srgb,var(--on-surface) calc(var(--state-statement) * 100%),transparent)}
/* The AI identity: a drawing, from its own tokens, never a category */
.app-ai-text{background:linear-gradient(135deg,var(--signal),var(--primary) 30%,var(--ai-tail));-webkit-background-clip:text;background-clip:text;color:transparent}
.app-ai-ground{background:linear-gradient(135deg,var(--ai-ground-start),var(--ai-ground-end));color:var(--on-machine-surface);--shiki-background:transparent;--shiki-foreground:var(--on-machine-surface);scrollbar-color:color-mix(in srgb,var(--on-machine-surface) 40%,transparent) transparent}
/* Machine speech: a code block on the machine ground, a terminal. Dark in both themes, and everything inside takes its dark values */
/* On Shiki's own <pre> too: its inline background and foreground read these */
.app-machine{background:var(--machine-surface);color:var(--on-machine-surface);--shiki-background:var(--machine-surface);--shiki-foreground:var(--on-machine-surface);scrollbar-color:color-mix(in srgb,var(--on-machine-surface) 40%,transparent) transparent}
.app-machine *,.app-ai-ground *{color-scheme:dark}
@media print{.app-machine,.app-ai-ground{background:none;color:var(--on-surface)}}

/* ── Selection tile · a card chosen among others ── */
.app-tile{display:grid;grid-template-columns:1fr auto;align-items:start;gap:var(--space-4) var(--space-12);padding:var(--space-24);border:0;border-radius:var(--radius-lg);background:var(--surface-container-low);color:var(--on-surface);text-align:left;font:inherit}
@media (min-width:600px){.app-tile{padding:var(--card-padding-wide)}}
.app-tile__check{grid-column:2;grid-row:1;visibility:hidden}
.app-tile.is-selected .app-tile__check{visibility:visible}
.app-tile.is-selected{background:var(--secondary-container);color:var(--on-secondary-container)}
.app-tile.is-selected .app-tile__check{color:var(--on-secondary-container)}
.app-tile.is-selected .text-object-title{font-weight:700}
.app-tile .text-supporting{color:var(--on-surface-variant)}
.app-tile.is-selected .text-supporting{color:var(--on-secondary-container)}
.app-tile-group{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:var(--space-12)}

/* ── Segmented control · one track, one pill ── */
.app-seg{display:inline-flex;max-width:100%;min-height:var(--control-height);overflow-x:auto;scrollbar-width:none;gap:0;padding:var(--space-4);border:0;border-radius:var(--radius-pill);background:var(--surface-container-low)}
.app-seg__item{display:inline-flex;align-items:center;gap:var(--space-8);min-height:calc(var(--control-height) - 2 * var(--space-4));padding:0 var(--space-16);border:1px solid transparent;border-radius:var(--radius-pill);background:transparent;color:var(--on-surface-variant);font-family:var(--font-sans);font-size:14px;line-height:20px;font-weight:500;white-space:nowrap}
.app-seg__item.is-selected{border-color:var(--outline-variant);background:var(--surface);color:var(--on-surface);font-weight:700}

/* ── List row · content plane (full fill) or rail (chrome fill) ── */
.app-list{display:flex;flex-direction:column;margin:0;padding:0;list-style:none}
.app-row{display:flex;align-items:center;gap:var(--space-16);width:100%;min-height:max(48px,var(--touch-target));padding:var(--space-8) var(--space-16);border:0;background:transparent;color:var(--on-surface);text-align:left;font:inherit}
.app-row__icon{color:var(--on-surface-variant)}
.app-row__text{display:flex;flex-direction:column;min-width:96px;flex:1}
.app-row__text>*{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.app-row__meta{color:var(--on-surface-variant);flex:none}
.app-row__trailing{position:relative;z-index:1;display:flex;align-items:center;gap:var(--space-8);flex:none}
/* A trailing control never grows the row: 32px at most, no projected target */
.app-row__trailing .app-icon-btn{width:32px;height:32px}
.app-row__trailing .app-btn{min-height:32px;padding:0 var(--space-12)}
.app-row__trailing .app-target::after{content:none}
/* The hit: one button or link that names the row and stretches over it, so the
   trailing slot can hold its own controls without nesting one inside another */
.app-row__hit{display:block;min-width:0;padding:0;border:0;background:transparent;color:inherit;text-align:inherit;text-decoration:none;cursor:pointer;outline:none}
/* Inherit the row's font only where no role class sets one (zero specificity) */
:where(.app-row__hit){font:inherit}
.app-row__hit::after{content:"";position:absolute;inset:0;border-radius:inherit}
.app-row:has(.app-row__hit:focus-visible){outline:2px solid var(--primary);outline-offset:-2px}
.app-row:has(.app-row__hit:focus-visible)::before{opacity:var(--state-focus)}
a.app-row,a.app-card{text-decoration:none}
.app-row .text-supporting,.app-row .text-meta{color:var(--on-surface-variant)}
.app-row--divided+.app-row--divided{border-top:1px solid var(--outline-variant)}
/* Field: a saved setting read back, its name over its value; the row opens its edit. The list reaches
   16 into the gutter so the names meet the heading's edge and the state layer runs past them; the line
   between fields runs from the text's start to the glyph's end. Values wrap and stay in ink */
.app-list--fields{margin-inline:calc(var(--space-16) * -1)}
.app-row--field{position:relative;align-items:flex-start;padding:var(--space-16)}
.app-row--field .app-row__text{gap:var(--space-4)}
.app-row--field .app-row__text>*{overflow:visible;white-space:normal;overflow-wrap:anywhere}
.app-row--field .text-supporting{color:var(--on-surface)}
.app-row--field .text-supporting.text-on-surface-variant{color:var(--on-surface-variant)}
.app-row--field .app-row__trailing{min-height:24px;color:var(--on-surface-variant)}
.app-row--field+.app-row--field::after{content:"";position:absolute;top:0;left:var(--space-16);right:var(--space-16);border-top:1px solid var(--outline-variant);pointer-events:none}
.app-row--nav{min-height:max(36px,var(--touch-target));border-radius:var(--radius-pill);padding:0 var(--space-16)}
.app-row--nav .app-icon{font-size:24px;font-variation-settings:"FILL" 0,"wght" 400,"GRAD" 0,"opsz" 24}
.app-row--agent-chat{min-height:max(var(--chat-row),var(--touch-target));padding:0 var(--space-8) 0 var(--space-16);border-radius:var(--radius-pill)}
.app-row--agent-chat .app-row__trailing .app-icon-btn{width:24px;height:24px}
.app-row--agent-chat .app-row__trailing .app-icon{font-size:16px}
/* A heading over a group of rows in the navigation pane: sets its own type, sentence case */
.app-nav-heading{display:flex;align-items:center;min-height:24px;margin:var(--space-8) 0 var(--space-4);padding:0 var(--space-8);color:var(--on-surface-variant);font-family:var(--font-sans);font-size:12px;line-height:16px;font-weight:500;letter-spacing:0}
/* The navigation pane's one primary action: 56px, radius-lg, level 2 */
.app-row.is-selected{background:var(--secondary-container);color:var(--on-secondary-container)}
.app-row--nav.is-selected{background:var(--selection-chrome)}
.app-row.is-selected .app-row__icon,.app-row.is-selected .text-supporting,.app-row.is-selected .text-meta{color:var(--on-secondary-container)}
.app-row.is-selected .text-label,.app-row.is-selected .text-object-title{font-weight:700}
.app-row--nav.is-selected .app-icon{font-variation-settings:"FILL" 1,"wght" 500,"GRAD" 0,"opsz" 24}

/* ── Lattice · content you read: hairline, tick, eyebrow, no box ── */
.app-lattice{position:relative;padding-top:var(--space-16);border-top:1px solid var(--outline-variant);color:var(--on-surface)}
.app-lattice::before{content:"";position:absolute;left:0;top:-2px;width:44px;height:3px;background:var(--outline)}
.app-lattice__eyebrow{margin:0 0 var(--space-8);color:var(--on-surface-variant)}

/* ── Title bar and filter row ── */
.app-titlebar{display:flex;flex-direction:column;gap:var(--space-8);padding:var(--space-16) var(--space-24) 0}
.app-titlebar__row{display:flex;align-items:center;gap:var(--space-16);min-height:var(--control-height)}
.app-titlebar__name{display:flex;align-items:center;gap:var(--space-8);min-width:0;margin:0}
.app-titlebar__role{flex:none}
.app-titlebar__title{margin:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.app-titlebar__leading{margin-left:calc(var(--space-12) * -1)}
.app-titlebar__actions{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-8);margin-left:auto}
.app-titlebar.is-scrolled,.app-file-pane__bar.is-scrolled{box-shadow:inset 0 -1px 0 var(--outline-variant)}
@media (prefers-reduced-motion:no-preference){.app-titlebar,.app-file-pane__bar{transition:box-shadow var(--dur-effects) var(--motion-effects)}}
.app-search{display:flex;align-items:center;gap:var(--space-8);height:var(--control-height);padding:0 var(--space-16);border-radius:var(--radius-pill);background:var(--surface-container-highest);color:var(--on-surface-variant);font-family:var(--font-sans);font-size:14px}
.app-search__clear{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;margin-right:calc(var(--space-8) * -1);padding:0;border:0;border-radius:var(--radius-pill);background:transparent;color:var(--on-surface-variant)}
.app-search:focus-within{outline:2px solid var(--primary);outline-offset:1px}
.app-search__input{flex:1;min-width:0;height:100%;padding:0;border:0;background:transparent;color:var(--on-surface);font:inherit;outline:none}
.app-search__input::placeholder{color:var(--on-surface-variant);opacity:1}
.app-tabs{display:flex;gap:var(--space-4);border-bottom:1px solid var(--outline-variant);overflow-x:auto;scrollbar-width:none}
.app-tab{position:relative;flex:none;min-height:var(--control-height);padding:0 var(--space-32);border:0;background:transparent;color:var(--on-surface-variant);font-family:var(--font-sans);font-size:14px;line-height:20px;font-weight:500}
.app-tab.is-selected{color:var(--on-surface);font-weight:700}
.app-tab.is-selected::after{content:"";position:absolute;left:var(--space-32);right:var(--space-32);bottom:0;height:3px;border-radius:var(--radius-sm) var(--radius-sm) 0 0;background:var(--on-surface)}
/* Detail: the bar of a detail pane. The pane pads it; the name drops to section-title
   (one page-title per screen); the verbs take a row of their own under the name */
.app-titlebar--detail{padding:0}
.app-titlebar--detail .app-titlebar__row{flex-wrap:wrap;row-gap:0}
.app-titlebar--detail .app-titlebar__name{flex:1 1 100%}
/* The first verb's label meets the pane edge, as the close glyph does */
.app-titlebar--detail .app-titlebar__actions{flex-basis:100%;margin-left:calc(var(--space-24) * -1)}
/* One markup for both windows: a part that exists only on a phone, or only above one */
@media (min-width:600px){.app-compact-only{display:none!important}}
@media (max-width:599px){.app-wide-only{display:none!important}}
/* Compact window: one 56 bar. Menu or back, the name, the lead as its glyph alone, then ⋯ holding every other verb.
   Its 48 targets sit 4 in and its glyphs 16 in; a name with nothing before it starts on the content's 24 edge. A row's meta gives way to its title */
@media (max-width:599px){.app-titlebar:not(.app-titlebar--detail){gap:0;padding:env(safe-area-inset-top,0px) var(--space-8) 0}.app-titlebar:not(.app-titlebar--detail) .app-titlebar__row{flex-wrap:nowrap;gap:0;min-height:var(--titlebar-height-phone)}.app-titlebar:not(.app-titlebar--detail) .app-titlebar__name{flex:1;gap:var(--space-4)}.app-titlebar:not(.app-titlebar--detail) .app-titlebar__leading{margin-left:0}.app-titlebar:not(.app-titlebar--detail) .app-titlebar__name:not(:has(.app-titlebar__leading)) .app-titlebar__title{padding-left:var(--space-16)}.app-titlebar:not(.app-titlebar--detail) .app-titlebar__actions{flex-wrap:nowrap;gap:0;margin-left:0}.app-titlebar__lead{width:40px;min-width:0;height:40px;padding:0;gap:0;border-color:transparent;background:transparent;color:var(--on-surface)}.app-titlebar__lead .app-icon{margin:0;font-size:24px}.app-titlebar:not(.app-titlebar--detail) .app-tabs{margin:0 calc(var(--space-8) * -1);padding:0 var(--space-8)}.app-titlebar__lead .app-titlebar__label{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}.app-titlebar .app-icon-btn{color:var(--on-surface)}.app-row:not(.app-row--nav):not(.app-row--agent-chat) .app-row__meta{display:none}}
/* The filter row sits in .app-shell__content, which already pads the sides */
.app-filterrow{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-8)}
/* Search leads the row; the controls follow it; the count closes the row and answers them */
.app-filterrow__search{flex:1 1 200px;min-width:200px;max-width:360px}
.app-filterrow__summary{order:1;margin:0 0 0 auto;color:var(--on-surface-variant);font-variant-numeric:tabular-nums}
.app-filterrow__controls{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-8);min-width:0;max-width:100%}
@media (max-width:599px){.app-filterrow__search{flex-basis:100%;max-width:none}}
.app-filterrow__controls>.app-seg{max-width:100%;overflow-x:auto;scrollbar-width:none}

/* ── Dialog · white at level 3, text actions, affirmative last ── */
.app-scrim{position:fixed;inset:0;z-index:3;display:grid;place-items:center;padding:var(--space-24);background:color-mix(in srgb,var(--scrim) 32%,transparent)}
.app-scrim--inline{position:static;inset:auto}
.app-dialog{display:flex;flex-direction:column;gap:var(--space-16);width:min(560px,100%);padding:var(--space-24);border-radius:var(--radius-lg);background:var(--surface-container-high);color:var(--on-surface);box-shadow:var(--elevation-3)}
@media (min-width:600px){.app-dialog{padding:var(--card-padding-wide)}}
.app-dialog__title{margin:0}
.app-dialog:focus{outline:none}
.app-dialog__body{margin:0}

/* ── Skeleton · the layout with the words taken out ── */
.app-skel{display:flex;flex-direction:column;gap:var(--space-16)}
.app-skel__bar{display:block;height:12px;border-radius:var(--radius-xs);background:var(--surface-container-highest);position:relative;overflow:hidden}
.app-skel__bar--title{height:16px;width:40%}
.app-skel__bar--short{width:60%}
.app-skel__bar--block{height:96px;border-radius:var(--radius-lg)}
.app-skel__row{display:flex;align-items:center;gap:var(--space-16);min-height:max(48px,var(--touch-target))}
.app-skel__row--plain .app-skel__dot{display:none}
.app-skel__dot{width:24px;height:24px;border-radius:var(--radius-pill);background:var(--surface-container-highest);flex:none}
.app-skel__lines{display:flex;flex-direction:column;gap:var(--space-8);flex:1}
@media (prefers-reduced-motion:no-preference){.app-skel__bar::after{content:"";position:absolute;inset:0;transform:translateX(-100%);background:linear-gradient(90deg,transparent,var(--shimmer),transparent);opacity:.6;animation:app-shimmer 1.4s var(--motion-effects) infinite}}
@keyframes app-shimmer{to{transform:translateX(100%)}}

/* ── Loader · the Alis mark, in signal ── */
.app-loader{display:flex;flex-direction:column;align-items:center;gap:var(--space-16);color:var(--on-surface-variant)}
.app-loader--line{display:inline-flex;flex-direction:row;gap:var(--space-8)}
@media (prefers-reduced-motion:no-preference){.app-loader circle{animation:app-dot 1.2s var(--motion-effects) infinite both}}
.app-loader circle:nth-child(1){animation-delay:0s}.app-loader circle:nth-child(2){animation-delay:.08s}.app-loader circle:nth-child(3){animation-delay:.16s}.app-loader circle:nth-child(4){animation-delay:.24s}.app-loader circle:nth-child(5){animation-delay:.32s}.app-loader circle:nth-child(6){animation-delay:.4s}.app-loader circle:nth-child(7){animation-delay:.48s}.app-loader circle:nth-child(8){animation-delay:.56s}.app-loader circle:nth-child(9){animation-delay:.64s}.app-loader circle:nth-child(10){animation-delay:.72s}.app-loader circle:nth-child(11){animation-delay:.8s}
@keyframes app-dot{0%,100%{opacity:1}50%{opacity:.25}}

/* ── Text field · label above, outlined box, one supporting line ── */
.app-field{display:flex;flex-direction:column;gap:var(--space-4);min-width:0;color:var(--on-surface)}
.app-field__label{color:var(--on-surface)}
.app-field__box{display:flex;align-items:center;gap:var(--space-8);min-height:var(--control-height);padding:0 var(--space-16);border:1px solid var(--field-edge);border-radius:var(--radius-lg);background:var(--surface);color:var(--on-surface-variant)}
.app-field__box:hover{border-color:var(--field-edge-hover)}
.app-field__box:focus-within{border-color:var(--primary);box-shadow:inset 0 0 0 1px var(--primary)}
.app-field__input{flex:1;min-width:0;padding:var(--space-4) 0;border:0;background:transparent;color:var(--on-surface);font-family:var(--font-sans);font-size:16px;line-height:24px;outline:none;resize:vertical}
.app-field__input::placeholder{color:var(--on-surface-variant);opacity:1}
.app-field__support{display:flex;align-items:center;gap:var(--space-4);margin:0;color:var(--on-surface-variant)}
.app-field.is-error .app-field__box{border-color:var(--error);box-shadow:inset 0 0 0 1px var(--error)}
.app-field.is-error .app-field__support{color:var(--error)}
.app-field.is-disabled{opacity:.38}
.app-field.is-disabled .app-field__box{border-color:var(--field-edge)}
.app-form{display:flex;flex-direction:column;gap:var(--space-24);max-width:var(--measure-prose)}

/* ── App shell · navigation pane, content, optional detail pane, all on the ground ── */
.app-shell{display:grid;grid-template-columns:var(--nav-width) minmax(0,1fr);min-height:100vh;background:var(--background);color:var(--on-surface);font-family:var(--font-sans)}
.app-shell--detail{grid-template-columns:var(--nav-width) minmax(0,1fr) var(--detail-width)}
.app-shell__nav{display:flex;flex-direction:column;gap:0;padding:var(--space-16) var(--space-12);border-right:1px solid var(--outline-variant);min-width:0}
.app-shell__nav-foot{margin-top:auto;display:flex;flex-direction:column;gap:0}
.app-shell__main{display:flex;flex-direction:column;min-width:0}
.app-shell__content{flex:1;display:flex;flex-direction:column;gap:var(--space-24);padding:var(--space-24) var(--space-24) var(--space-32)}
.app-shell__detail{display:flex;flex-direction:column;gap:var(--space-24);padding:var(--space-16) var(--space-24);border-left:1px solid var(--outline-variant);min-width:0}
.app-shell__detail{overflow:auto}
/* breakpoint-medium (840): the detail pane slides over the content */
@media (max-width:839px){.app-shell--detail{grid-template-columns:var(--nav-width) minmax(0,1fr)}.app-shell__detail{position:fixed;top:0;right:0;bottom:0;width:min(var(--detail-width),100%);background:var(--surface-container-high);box-shadow:var(--elevation-3),0 0 0 100vmax color-mix(in srgb,var(--scrim) 32%,transparent);border-left:0;z-index:2}}
/* breakpoint-compact (600): the navigation pane collapses to a column of icons */
/* Compact window: the navigation pane fills the screen, the same pane opened by the title bar's menu button
   (app-shell--nav-open) on the ground: nothing shows behind it, so no scrim and no elevation. Its close sits in its head */
.app-shell__nav-close{display:none}
@media (max-width:599px){.app-shell,.app-shell--detail{grid-template-columns:minmax(0,1fr)}.app-shell__nav{display:none;position:fixed;inset:0;z-index:3;width:auto;padding:calc(var(--space-8) + env(safe-area-inset-top,0px)) calc(var(--space-12) + env(safe-area-inset-right,0px)) calc(var(--space-16) + env(safe-area-inset-bottom,0px)) calc(var(--space-12) + env(safe-area-inset-left,0px));overflow-y:auto;background:var(--background);border-right:0}.app-shell--nav-open .app-shell__nav{display:flex}.app-shell__nav-close{display:inline-flex;position:absolute;top:calc(var(--space-12) + env(safe-area-inset-top,0px));right:calc(var(--space-8) + env(safe-area-inset-right,0px));color:var(--on-surface)}.app-tab{padding:0 var(--space-16)}.app-tab.is-selected::after{left:var(--space-16);right:var(--space-16)}.app-shell__detail{width:100%}}

/* ── File pane · a file opened beside the conversation (AppFilePane): the detail pane, made wide ── */
/* breakpoint-expanded (1200): the content takes two parts and the file three; below it, the file takes the content's place */
.app-shell--file{grid-template-columns:var(--nav-width) minmax(0,2fr) minmax(0,3fr)}
/* Beside the conversation the file is an object Alis made: an instrument card, its edge and no shadow (nothing at rest lifts), inset from the content area; the gap to the chat is the conversation's own padding */
.app-shell--file .app-shell__detail{position:static;width:auto;padding:0;gap:0;overflow:hidden;margin:var(--space-8) var(--space-12) var(--space-12) 0;background:var(--surface);box-shadow:none;border:1px solid var(--outline-variant);border-radius:var(--radius-lg);z-index:auto}
.app-shell--file .app-shell__detail>.app-file-pane{background:transparent}
.app-shell--file-expanded{grid-template-columns:var(--nav-width) minmax(0,1fr)}
.app-shell--file-expanded .app-shell__main{display:none}
/* Expanded, the same card fills the content area, so its shape doesn't change mid-action */
.app-shell--file-expanded .app-shell__detail{margin:var(--space-12)}
/* breakpoint-expanded (1200): narrower, the file takes the content's place, flat and full-bleed */
@media (max-width:1199px){.app-shell--file{grid-template-columns:var(--nav-width) minmax(0,1fr)}.app-shell--file .app-shell__main,.app-file-pane__expand{display:none}.app-shell--file .app-shell__detail{margin:0;border:0;border-left:1px solid var(--outline-variant);border-radius:0;background:var(--background)}}
@media (max-width:599px){.app-shell--file,.app-shell--file-expanded{grid-template-columns:minmax(0,1fr)}.app-shell--file .app-shell__detail{border-left:0}}
/* With the content narrowed beside a file, its bar's lead shows its glyph alone, as on a phone */
.app-shell--file .app-shell__main .app-titlebar:not(.app-titlebar--detail) .app-titlebar__row{flex-wrap:nowrap}
.app-shell--file .app-shell__main .app-titlebar:not(.app-titlebar--detail) .app-titlebar__actions{flex-wrap:nowrap;gap:0}
.app-shell--file .app-shell__main .app-titlebar__lead{width:40px;min-width:0;height:40px;padding:0;gap:0;border-color:transparent;background:transparent}
.app-shell--file .app-shell__main .app-titlebar__lead .app-icon{margin:0}
.app-shell--file .app-shell__main .app-titlebar__lead .app-titlebar__label{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.app-file-pane{display:flex;flex-direction:column;gap:0;min-width:0;min-height:0;background:var(--background)}
.app-shell__detail>.app-file-pane{flex:1}
.app-file-pane__bar{flex:none;display:flex;align-items:center;gap:var(--space-8);min-height:64px;padding:var(--space-12)}
.app-file-pane__name{flex:1;min-width:0;display:flex;flex-direction:column}
.app-file-pane__name>*{margin:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.app-file-pane__name>.text-meta{color:var(--on-surface-variant)}
.app-file-pane__tools{flex:none;display:flex;align-items:center;gap:0}
.app-file-pane__tools>.app-seg{margin-right:var(--space-8)}
.app-file-pane__body{flex:1;min-height:0;overflow:auto;position:relative}
/* A page sets its own colours: its frame is white in every theme */
.app-file-pane__frame{display:block;width:100%;height:100%;border:0;background:var(--paper)}
.app-file-pane__body--prose{padding:var(--space-32) var(--space-24)}
.app-file-pane__body--prose>.prose{max-width:var(--measure-prose);margin:0 auto}
.app-file-pane__body--image{display:flex;align-items:center;justify-content:center;padding:var(--space-24)}
.app-file-pane__body--image>img{display:block;max-width:100%;max-height:100%;object-fit:contain}
.app-file-pane__body--paper{background:var(--paper)}
.app-file-pane__body--source{background:var(--surface-container-low)}
.app-file-pane__source{margin:0;padding:var(--space-16) 0;font-family:var(--font-mono);font-size:13px;line-height:20px;color:var(--on-surface);white-space:pre;counter-reset:app-ln}
.app-file-pane__source>span{display:block;padding-right:var(--space-24)}
.app-file-pane__source>span::before{counter-increment:app-ln;content:counter(app-ln);display:inline-block;width:48px;margin-right:var(--space-16);text-align:right;color:var(--on-surface-variant)}
.app-file-pane__body--table .app-table-wrap{border:0;border-radius:0}
.app-file-pane__body--table th,.app-file-pane__body--table td{white-space:nowrap}
.app-file-pane__line{flex:none;margin:0;padding:var(--space-8) var(--space-24);border-top:1px solid var(--outline-variant);color:var(--on-surface-variant)}
.app-file-pane__state{display:flex;flex-direction:column;min-height:100%}
.app-file-pane__body>.app-skel{max-width:var(--measure-prose);margin:0 auto;padding:var(--space-32) var(--space-24)}
@media (max-width:599px){.app-file-pane__bar{min-height:var(--titlebar-height-phone);padding:env(safe-area-inset-top,0px) var(--space-4) 0;gap:var(--space-4)}.app-file-pane__bar .app-icon-btn{color:var(--on-surface)}.app-file-pane__tools>.app-seg{margin-right:0}.app-file-pane__tools .app-seg__item{padding:0 var(--space-12)}.app-file-pane__word{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}}

/* ── Navigation pane · brand, account card, a place's switcher ── */
.app-brand{display:flex;align-items:center;min-height:48px;padding:0 var(--space-16);margin-bottom:var(--space-16)}
.app-brand__wordmark{display:block;width:auto}
.app-account{display:flex;align-items:center;gap:var(--space-12);width:100%;min-height:56px;margin-top:var(--space-8);padding:var(--space-8);border:1px solid var(--outline-variant);border-radius:var(--radius-lg);background:transparent;color:var(--on-surface);text-align:left;font:inherit}
.app-account__avatar{flex:none;width:36px;height:36px;border-radius:50%;object-fit:cover}
span.app-account__avatar{display:flex;align-items:center;justify-content:center;background:var(--surface-container-highest);color:var(--on-surface)}
.app-account__text{flex:1;min-width:0;display:flex;flex-direction:column}
.app-account__text>*{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.app-account>.app-icon{color:var(--on-surface-variant)}
.app-nav-switcher{display:flex;align-items:center;gap:var(--space-12);width:100%;min-height:56px;margin-bottom:var(--space-8);padding:var(--space-8) var(--space-8) var(--space-8) var(--space-16);border:1px solid var(--outline-variant);border-radius:var(--radius-lg);background:transparent;color:var(--on-surface);text-align:left;font:inherit}
.app-nav-switcher__text{flex:1;min-width:0;display:flex;flex-direction:column}
.app-nav-switcher__text>*{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.app-nav-switcher__kind,.app-nav-switcher>.app-icon{color:var(--on-surface-variant)}

/* ── Empty state · speaks to the user; may take the drafting field ── */
.app-empty{position:relative;flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-8);min-height:320px;padding:var(--space-48) var(--space-24);text-align:center;color:var(--on-surface)}
.app-empty__headline{margin:0;max-width:22ch}
/* The tile above the headline sits 16 clear of it */
.app-empty>.app-avatar{margin-bottom:var(--space-8)}
.app-empty__line{margin:0 0 var(--space-8);max-width:44ch;color:var(--on-surface-variant)}
.app-empty-line{margin:0;color:var(--on-surface-variant)}
/* Access line: a request's state where the control that sent it was (Request sent, Declined), in meta and in ink: nothing failed. rules/access.md */
.app-access-line{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-4);margin:0;color:var(--on-surface-variant)}
.app-access-line .app-icon{font-size:16px}
/* The drafting field around an empty state fills the pane with it */
.app-empty-field{position:relative;overflow:hidden;flex:1;display:flex;flex-direction:column}
.app-shell__content>.app-empty-field{margin:calc(var(--space-24) * -1) calc(var(--space-24) * -1) calc(var(--space-32) * -1)}
.app-empty-field>div:last-child{position:relative;z-index:1;flex:1;display:flex;flex-direction:column}
.app-shell__detail>.app-empty-field{margin:calc(var(--space-16) * -1) calc(var(--space-24) * -1)}

/* ── Sign-in · signing in, signing up, onboarding: one card on the plain ground. components/AppSignIn.md ── */
.app-signin{box-sizing:border-box;min-height:100dvh;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-16);padding:var(--space-48) var(--space-16);background:var(--background);color:var(--on-surface)}
.app-signin__card{width:min(440px,100%);max-width:none;gap:var(--space-24)}
.app-signin__lead{display:flex;flex-direction:column;align-items:center;gap:var(--space-8);text-align:center}
.app-signin__lead>h1,.app-signin__lead>h2,.app-signin__lead>p{margin:0}
.app-signin__card--steps .app-signin__lead{align-items:flex-start;text-align:start}
.app-signin__logo{display:block;max-width:200px;max-height:40px;margin-bottom:var(--space-8)}
/* With nothing to fill in, the empty-state block sits at its own height so the foot stays under it */
.app-signin>.app-empty{flex:none;min-height:0;padding:0}
.app-signin__action{width:100%}
.app-signin__foot{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--space-4) var(--space-8);margin:0;color:var(--on-surface-variant)}
.app-signin__foot a{color:inherit;text-decoration:none}
.app-signin__foot a:hover,.app-signin__foot a:focus-visible{text-decoration:underline;text-underline-offset:2px}

/* ── Transcript · a question and its answer, in pairs ── */
.app-qa{display:flex;flex-direction:column;gap:var(--space-24);margin:0}
.app-qa__pair{display:flex;flex-direction:column;gap:var(--space-8)}
.app-qa__q{margin:0;color:var(--on-surface-variant)}
.app-qa__a{margin:0;color:var(--on-surface)}

/* ── Field set, inline field action ── */
.app-fieldset{display:flex;flex-direction:column;gap:var(--space-8);min-width:0;margin:0;padding:0;border:0}
.app-fieldset__support{margin:0}
.app-fieldset__legend{margin:0 0 var(--space-4);padding:0;color:var(--on-surface)}
.app-field__row{display:flex;align-items:flex-start;gap:var(--space-8)}
.app-field__row>.app-field__box{flex:1}
.app-field__row>.app-btn{min-height:var(--control-height)}
/* Values a field has collected, as input chips, between the box and its supporting line */
.app-field__values{display:flex;flex-wrap:wrap;gap:var(--space-8);padding-top:var(--space-4)}

/* ── Select · a native select in the field box, a trailing chevron ── */
.app-field__box--select{position:relative;padding:0}
.app-field__select{flex:1;min-width:0;min-height:calc(var(--control-height) - 2px);padding:0 calc(var(--space-16) + 28px) 0 var(--space-16);border:0;border-radius:inherit;background:transparent;color:var(--on-surface);font-family:var(--font-sans);font-size:16px;line-height:24px;outline:none;appearance:none;-webkit-appearance:none;cursor:pointer}
.app-field__select:has(option[value=""]:checked){color:var(--on-surface-variant)}
.app-field__box--select>.app-icon{position:absolute;right:var(--space-12);pointer-events:none;color:var(--on-surface-variant)}

/* ── Switch · an on/off setting, applied at once; the row is the target ── */
.app-switch-row{position:relative;display:flex;align-items:center;gap:var(--space-16);min-height:max(48px,var(--touch-target));color:var(--on-surface);cursor:pointer}
.app-switch-row__text{display:flex;flex-direction:column;flex:1;min-width:0}
.app-switch-row__text .text-supporting{color:var(--on-surface-variant)}
.app-switch{position:relative;flex:none;width:52px;height:32px;margin:0;border:2px solid var(--outline);border-radius:var(--radius-pill);background:var(--surface-container-highest);appearance:none;-webkit-appearance:none;cursor:pointer;transition:background-color var(--dur-effects) var(--motion-effects),border-color var(--dur-effects) var(--motion-effects)}
.app-switch::before{content:"";position:absolute;top:50%;left:6px;width:16px;height:16px;border-radius:var(--radius-pill);background:var(--outline);transform:translateY(-50%);transition:left var(--dur-spatial) var(--motion-spatial),width var(--dur-spatial) var(--motion-spatial),height var(--dur-spatial) var(--motion-spatial),background-color var(--dur-effects) var(--motion-effects)}
.app-switch:checked{border-color:var(--primary);background:var(--primary)}
.app-switch:checked::before{left:22px;width:24px;height:24px;background:var(--on-primary)}
.app-switch:focus-visible{outline:2px solid var(--primary);outline-offset:1px}
.app-switch-row:hover .app-switch:not(:disabled){box-shadow:0 0 0 8px color-mix(in srgb,var(--on-surface) calc(var(--state-hover) * 100%),transparent)}
.app-switch-row:active .app-switch:not(:disabled){box-shadow:0 0 0 8px color-mix(in srgb,var(--on-surface) calc(var(--state-pressed) * 100%),transparent)}
.app-switch:disabled{cursor:default}
.app-switch-row.is-disabled{opacity:.38;cursor:default}

/* ── Progress · determinate, for work you can count ── */
.app-progress{display:flex;flex-direction:column;gap:var(--space-8);min-width:0}
.app-progress>.app-steps{margin-top:var(--space-8)}
.app-progress__head{display:flex;align-items:baseline;justify-content:space-between;gap:var(--space-16)}
.app-progress__value{color:var(--on-surface-variant);font-variant-numeric:tabular-nums}
.app-progress__track{position:relative;height:4px;border-radius:var(--radius-pill);background:var(--surface-container-highest);overflow:hidden}
.app-progress__fill{position:absolute;inset:0 auto 0 0;border-radius:inherit;background:var(--on-surface);transition:width var(--dur-effects) var(--motion-effects)}
.app-progress.is-error .app-progress__fill{background:var(--error)}

/* ── Steps · the stages of a long piece of work ── */
.app-steps{display:flex;flex-direction:column;gap:0;margin:0;padding:0;list-style:none}
.app-step{display:flex;align-items:center;gap:var(--space-12);min-height:32px;color:var(--on-surface-variant)}
.app-step.is-current,.app-step.is-done{color:var(--on-surface)}
.app-step.is-failed{color:var(--error)}

/* ── Stepper · a form a person moves through in named steps ──
   Our progress bar cut into one segment per step: done and current ink, next the
   track. The current step's name is 600; a done step is a button back. Narrower
   than 480 (the stepper's own width), the names leave and one caption names the
   current step and counts. */
.app-stepper{container-type:inline-size;min-width:0}
.app-stepper__steps{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);gap:var(--space-4);margin:0;padding:0;list-style:none}
.app-stepper__step{display:flex;flex-direction:column;gap:var(--space-8);width:100%;min-width:0;padding:0 0 var(--space-4);border:0;border-radius:var(--radius-xs);background:transparent;color:var(--on-surface-variant);font:inherit;text-align:left}
.app-stepper__bar{display:block;height:4px;border-radius:var(--radius-pill);background:var(--surface-container-highest)}
.app-stepper__label{display:flex;align-items:center;gap:var(--space-4);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.app-stepper__label>.app-icon{font-size:16px}
.app-stepper__step.is-done,.app-stepper__step.is-current{color:var(--on-surface)}
.app-stepper__step.is-done .app-stepper__bar,.app-stepper__step.is-current .app-stepper__bar{background:var(--on-surface)}
.app-stepper__step.is-current .app-stepper__label{font-weight:600}
.app-stepper__step.is-invalid{color:var(--error)}
.app-stepper__step.is-invalid .app-stepper__bar{background:var(--error)}
.app-stepper__caption{display:none;align-items:baseline;justify-content:space-between;gap:var(--space-16);margin-top:var(--space-8)}
.app-stepper__count{color:var(--on-surface-variant);font-variant-numeric:tabular-nums}
@container (max-width:479px){
.app-stepper__label{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}
.app-stepper__caption{display:flex}
}

/* ── Table · scanned, not read: full width, 40px rows, radius 0 ── */
.app-table-wrap{width:100%;overflow-x:auto}
.app-table{width:100%;border-collapse:collapse;border-radius:var(--radius-0);color:var(--on-surface);font-family:var(--font-sans)}
.app-table th{height:max(40px,var(--touch-target));padding:0 var(--space-16);border-bottom:1px solid var(--outline-variant);text-align:start;vertical-align:middle;white-space:nowrap}
.app-table td{height:max(40px,var(--touch-target));padding:var(--space-4) var(--space-16);border-bottom:1px solid var(--outline-variant);text-align:start;vertical-align:middle}
.app-table :is(th,td).is-numeric{text-align:end;font-variant-numeric:tabular-nums}
.app-table tbody tr{position:relative}
.app-table tr.is-interactive{cursor:pointer}
.app-table tr.is-interactive:hover>td{background-image:linear-gradient(color-mix(in srgb,currentColor calc(var(--state-hover) * 100%),transparent),color-mix(in srgb,currentColor calc(var(--state-hover) * 100%),transparent))}
/* Sticky header: opaque in the ground it sits on (white inside a card) */
.app-table--sticky th{position:sticky;top:0;z-index:1;background:var(--background)}
.app-card .app-table--sticky th{background:var(--surface)}
.app-table tr:has(.app-row__hit:focus-visible){outline:2px solid var(--primary);outline-offset:-2px}
.app-table tr.is-selected>td{background:var(--secondary-container);color:var(--on-secondary-container)}
.app-table tr.is-selected .app-table__primary{font-weight:700}
.app-table .app-row__hit::after{border-radius:0}
.app-table td .app-btn,.app-table td .app-icon-btn{position:relative;z-index:1}
.app-table td .app-target::after{content:none}
.app-table td .app-btn{min-height:32px;padding:0 var(--space-12)}
.app-table td .app-icon-btn{width:32px;height:32px}

/* ── Prose · rendered markdown on the type scale (rules/type.md) ── */
.prose-compact{--prose-body-size:14px;--prose-body-line:20px;--prose-gap:16px;--prose-item-gap:4px;--prose-h1-size:16px;--prose-h1-line:24px;--prose-h1-tracking:0;--prose-h1-weight:600;--prose-h1-above:24px;--prose-h1-below:8px;--prose-h2-size:14px;--prose-h2-line:20px;--prose-h2-weight:600;--prose-h2-above:24px;--prose-h3-above:16px;--prose-minor-ink:var(--on-surface-variant);--prose-code-size:12px}
.prose{max-width:100%;overflow-wrap:anywhere;font-family:var(--font-sans)}
.prose>:first-child{margin-top:0}.prose>:last-child{margin-bottom:0}
.prose :is(p,li){font-size:var(--prose-body-size,16px);line-height:var(--prose-body-line,24px);letter-spacing:0;font-weight:400}
.prose p{margin:0 0 var(--prose-gap,24px)}
.prose h1{font-size:var(--prose-h1-size,18px);line-height:var(--prose-h1-line,24px);letter-spacing:var(--prose-h1-tracking,-0.02em);font-weight:var(--prose-h1-weight,600);margin:var(--prose-h1-above,32px) 0 var(--prose-h1-below,12px)}
.prose :is(h2,h3,h4,h5,h6){font-size:var(--prose-h2-size,16px);line-height:var(--prose-h2-line,24px);letter-spacing:0;font-weight:var(--prose-h2-weight,600);margin:var(--prose-h3-above,24px) 0 var(--space-8)}
.prose h2{margin-top:var(--prose-h2-above,32px)}
.prose :is(h3,h4,h5,h6){color:var(--prose-minor-ink,inherit)}
.prose :is(strong,b){font-weight:600}
.prose a{color:var(--primary);text-decoration:underline;text-underline-offset:.15em}
.prose :is(ul,ol){margin:0 0 var(--prose-gap,24px);padding-inline-start:var(--space-24)}
.prose li{margin:0 0 var(--prose-item-gap,8px)}.prose li:last-child{margin-bottom:0}
.prose blockquote{margin:0 0 var(--prose-gap,24px);padding-inline-start:var(--space-16);border-inline-start:4px solid var(--outline-variant);color:var(--on-surface-variant)}
.prose blockquote p{margin:0 0 var(--space-8)}
.prose blockquote>:last-child{margin-bottom:0}
.prose blockquote :is(cite,footer){display:block;margin-top:var(--space-4);font-style:normal;font-size:14px;line-height:20px;color:var(--on-surface-variant)}
.prose hr{margin:var(--prose-gap,24px) 0;border:0;border-top:1px solid var(--outline-variant)}
:not(pre)>code{padding:0 var(--space-4);border-radius:var(--radius-xs);background:var(--surface-container-highest);color:var(--syntax-function);font-family:var(--font-mono)}
.prose code{font-size:var(--prose-code-size,14px)}
.prose pre{margin:0 0 var(--prose-gap,24px);padding:var(--space-12) var(--space-16);border-radius:var(--radius-md);background:var(--code-surface);box-shadow:inset 0 0 0 1px var(--outline-variant);overflow-x:auto;font-family:var(--font-mono)}
/* Syntax colours: Shiki's css-variables theme reads these, so code is highlighted once and follows the theme it sits in */
:where(:root){--shiki-foreground:var(--syntax-plain);--shiki-background:transparent;--shiki-token-keyword:var(--syntax-keyword);--shiki-token-string:var(--syntax-string);--shiki-token-string-expression:var(--syntax-string);--shiki-token-constant:var(--syntax-number);--shiki-token-function:var(--syntax-function);--shiki-token-comment:var(--syntax-comment);--shiki-token-parameter:var(--syntax-plain);--shiki-token-punctuation:var(--syntax-plain);--shiki-token-link:var(--syntax-string)}
.prose table{width:100%;border-collapse:collapse;margin:0 0 var(--prose-gap,24px)}
.prose :is(th,td){padding:var(--space-8) var(--space-12);border-bottom:1px solid var(--outline-variant);text-align:start;vertical-align:top;font-size:14px;line-height:20px}
.prose th{font-weight:500}
.prose li>p{margin:0}
.prose li>:is(ul,ol){margin:var(--prose-item-gap,8px) 0 0}
.prose table{table-layout:fixed}
.prose :is(th,td) :is(p,li){font-size:inherit;line-height:inherit;margin:0}
.prose img{max-width:100%;height:auto}
.prose sup{font-size:12px;line-height:0}
.prose pre code{padding:0;background:transparent;color:inherit;font:inherit;white-space:pre}

/* ── Code block · code to read or copy, edged on its own ground; a command to run, on the machine ground ── */
.app-code{position:relative;min-width:0;margin:0;border-radius:var(--radius-md);background:var(--code-surface);box-shadow:inset 0 0 0 1px var(--outline-variant);color:var(--syntax-plain)}
.prose .app-code{margin:0 0 var(--prose-gap,24px)}
.app-code__head{display:flex;align-items:center;gap:var(--space-8);min-height:40px;padding:var(--space-4) var(--space-4) 0 var(--space-16)}
.app-code__name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--on-surface-variant)}
.app-code .app-icon-btn{flex:none;width:32px;height:32px}
.app-code .app-code__body{margin:0;padding:var(--space-4) var(--space-16) var(--space-12);border-radius:0;background:none;box-shadow:none;overflow-x:auto;font-family:var(--font-mono);font-size:14px;line-height:20px;white-space:pre;tab-size:2}
.app-code__body code{padding:0;background:none;color:inherit;font:inherit}
.app-code.is-folded .app-code__body{max-height:calc(12 * 20px + var(--space-4));overflow-y:hidden;-webkit-mask-image:linear-gradient(to bottom,currentColor calc(100% - 40px),transparent);mask-image:linear-gradient(to bottom,currentColor calc(100% - 40px),transparent)}
.app-code__foot{padding:0 var(--space-8) var(--space-8)}
.app-code--command{display:flex;align-items:center;gap:var(--space-4);padding:var(--space-4) var(--space-4) var(--space-4) var(--space-16);background:var(--machine-surface);box-shadow:none;color:var(--on-machine-surface)}
.app-code--command .app-code__body{flex:1;padding:var(--space-8) 0}
.app-code__caret{color:var(--signal);-webkit-user-select:none;user-select:none}
.app-code--command .app-icon-btn{color:var(--on-machine-surface)}
@media print{.app-code{box-shadow:none}.app-code.is-folded .app-code__body{max-height:none;-webkit-mask-image:none;mask-image:none}.app-code .app-icon-btn,.app-code__foot{display:none}}

/* ── Hand-off · a task done in the person's own agent, and the way back ──
   The ask is a command's machine ground and signal caret; it is words, so it wraps.
   The context folds under one line and scrolls past 12 lines when opened. Back and a
   step's buttons are pulled to the text edge, as the detail title bar's are. */
.app-handoff{display:flex;flex-direction:column;gap:var(--space-16);min-width:0}
.app-handoff__choices{display:flex;flex-direction:column;min-width:0}
.app-handoff__back{margin-inline-start:calc(var(--space-24) * -1)}
.app-handoff__label,.app-handoff__body>p,.app-handoff>p{margin:0}
.app-handoff__status{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.app-handoff__head{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--space-8)}
.app-handoff__title{margin:0}
.app-handoff__steps{display:flex;flex-direction:column;gap:var(--space-24);margin:0;padding:0;list-style:none}
.app-handoff__step{display:flex;align-items:flex-start;gap:var(--space-12)}
.app-handoff__step>.app-icon{flex:none;color:var(--on-surface-variant)}
.app-handoff__body{display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-8);flex:1;min-width:0}
.app-handoff__body>.app-btn-row{align-self:stretch;margin-inline-start:calc(var(--space-24) * -1)}
.app-handoff__ask{align-self:stretch;margin:0;padding:var(--space-12) var(--space-16);border-radius:var(--radius-md);font-family:var(--font-mono);font-size:14px;line-height:20px;white-space:pre-wrap;overflow-wrap:anywhere}
.app-handoff__caret{color:var(--signal);-webkit-user-select:none;user-select:none}
.app-handoff__context{align-self:stretch;max-height:calc(12 * 20px + var(--space-24));overflow-y:auto;padding:var(--space-12) var(--space-16);border-radius:var(--radius-md);background:var(--code-surface);box-shadow:inset 0 0 0 1px var(--outline-variant);color:var(--on-surface);font-family:var(--font-mono);font-size:14px;line-height:20px;white-space:pre-wrap;overflow-wrap:anywhere}
.app-handoff__group{margin:var(--space-24) 0 var(--space-4);color:var(--on-surface-variant)}
.app-handoff__group:first-child{margin-top:0}
.app-handoff__no-mark{flex:none;width:20px;height:20px}
.app-btn .app-icon--mark{width:16px;height:16px}

/* ── Composer · where you write to Alis, an agent or a person: tray, editor, row; one line below ── */
.app-composer{position:relative;display:flex;flex-direction:column;gap:var(--space-8);width:100%;max-width:var(--measure-prose);margin-inline:auto}
.app-composer__box{position:relative;z-index:1;display:flex;flex-direction:column;padding:var(--space-8);border-radius:var(--radius-xl);background:var(--surface-container-high);box-shadow:var(--elevation-2);transition:background-color var(--dur-effects) var(--motion-effects),box-shadow var(--dur-effects) var(--motion-effects)}
/* Audience is a message property, kept above the draft even when its error line changes. */
.app-composer__audience{display:flex;flex-wrap:wrap;align-items:flex-end;gap:var(--space-12);padding:var(--space-8) var(--space-12) var(--space-12);border-bottom:1px solid var(--outline-variant)}
.app-composer__audience .app-field{flex:1 1 24ch;min-width:0;max-width:100%}
.app-composer__audience>.text-meta{margin:0;padding-block:var(--space-8);color:var(--on-surface-variant);overflow-wrap:anywhere}
.app-composer__tray{display:flex;flex-wrap:wrap;align-items:flex-start;gap:var(--space-8);padding:var(--space-4) var(--space-4) 0}
.app-composer__editor{min-height:24px;max-height:208px;overflow-y:auto;padding:var(--space-12) var(--space-12) var(--space-4);color:var(--on-surface);font-family:var(--font-sans);font-size:16px;line-height:24px;font-weight:400;overflow-wrap:anywhere}
.app-composer__input{display:block;width:100%;margin:0;padding:0;border:0;outline:0;resize:none;background:transparent;color:inherit;font:inherit}
.app-composer__input::placeholder{color:var(--on-surface-variant);opacity:1}
.app-composer__interim{color:var(--on-surface-variant)}
.app-composer__row{display:flex;align-items:center;gap:var(--space-4);min-height:40px}
.app-composer__spacer{flex:1;min-width:0}
.app-composer__row>.app-chip{min-width:0;max-width:240px;margin-left:var(--space-4)}
.app-composer__row>.app-chip>span:not(.app-icon){overflow:hidden;text-overflow:ellipsis}
/* The trailing button: the one filled icon button, concentric with the 28px corner (20 + 8) */
.app-composer__go{display:inline-flex;align-items:center;justify-content:center;flex:none;width:40px;height:40px;padding:0;border:0;border-radius:var(--radius-pill);background:var(--primary);color:var(--on-primary)}
/* A voice state carries its word: the only way into voice, and people meet it before they know the product. */
.app-composer__go:has(>.app-composer__go-label){width:auto;gap:var(--space-8);padding:0 var(--space-16) 0 var(--space-12)}
.app-composer__go-label{font-family:var(--font-sans);font-size:14px;line-height:20px;font-weight:600;white-space:nowrap}
@media (prefers-reduced-motion:no-preference){.app-composer__go{transition:transform var(--dur-spatial) var(--motion-spatial)}.app-composer__go:not(:disabled):active{transform:scale(.94)}}
/* Recording: the level wears ai-you, the voice light's "you're speaking" */
.app-composer__meter{flex:1;min-width:0;height:32px;display:flex;align-items:center;justify-content:center;gap:3px;overflow:hidden;color:var(--ai-you)}
.app-composer__meter>i{display:block;flex:none;width:3px;height:4px;border-radius:2px;background:currentColor}
.app-composer__rec{display:inline-flex;align-items:center;gap:var(--space-8);padding-inline:var(--space-8);color:var(--on-surface);white-space:nowrap}
/* A live microphone: the dot pulses in error beside "Recording" (rules/colour.md § The two reds); a call is not a recording */
.app-field__box--voice{flex-direction:column;align-items:stretch;gap:0;padding-top:var(--space-4)}
.app-field__voice{display:flex;align-items:center;gap:var(--space-4);margin:0 calc(var(--space-8) * -1) var(--space-4)}
.app-field__voice>:last-child{margin-left:auto}
.app-field__rec{display:inline-flex;align-items:center;gap:var(--space-8);color:var(--on-surface)}
.app-composer__rec::before,.app-field__rec::before{content:"";width:8px;height:8px;border-radius:var(--radius-pill);background:var(--error)}
@media (prefers-reduced-motion:no-preference){.app-composer__rec::before,.app-field__rec::before{animation:app-dot 1.2s var(--motion-effects) infinite both}}
.app-composer__timer{padding-inline:var(--space-8);font-variant-numeric:tabular-nums;color:var(--on-surface)}
/* A capture beside the conversation (a screen recording): a band docked on top of the box the way an ask docks, 20 in, a hairline under it. The editor stays writable; Send stays the one filled button, so Stop is error ink, unfilled (rules/buttons.md § Colour) */
.app-composer__capture{display:flex;align-items:center;gap:var(--space-4);min-height:40px;padding:0 0 var(--space-4) var(--space-12);margin-bottom:var(--space-4);border-bottom:1px solid var(--outline-variant)}
.app-composer__capture>.app-composer__rec{padding-inline:0 var(--space-4)}
.app-composer__capture>.app-composer__timer{padding-inline:var(--space-4)}
.app-composer__capture .app-btn{padding:0 var(--space-12)}
.app-composer__capture .app-btn .app-icon{margin-left:0}
.app-composer__capture.is-paused .app-composer__rec{color:var(--on-surface-variant)}
.app-composer__capture.is-paused .app-composer__rec::before{display:none}
/* What the capture sees: a live 16:9 thumbnail that leads the bar, quiet (no flash, no coloured edge); a button that opens the larger view. Paused, the picture freezes dimmed under pause; with no picture, desktop_access_disabled on its ground */
.app-capture-thumb{display:grid;place-items:center;flex:none;width:64px;height:36px;margin-right:var(--space-8);padding:0;overflow:hidden;border:1px solid var(--outline-variant);border-radius:var(--radius-sm);background:var(--surface-container-highest);color:var(--on-surface-variant)}
.app-capture-thumb>*{grid-area:1/1}
.app-capture-thumb>video,.app-capture-thumb>img,.app-capture-thumb>canvas{display:block;width:100%;height:100%;object-fit:cover}
.app-capture-thumb>.app-icon{color:var(--on-surface)}
.is-paused .app-capture-thumb>video,.is-paused .app-capture-thumb>img,.is-paused .app-capture-thumb>canvas{opacity:.35}
.app-capture-thumb.is-empty>.app-icon{color:var(--on-surface-variant)}
.app-capture-peek{display:flex;flex-direction:column;gap:var(--space-12);width:min(350px,calc(100vw - 32px));padding:var(--space-8) var(--space-16) var(--space-16);border-radius:var(--radius-lg);background:var(--surface-container-high);box-shadow:var(--elevation-2);color:var(--on-surface)}
.app-capture-peek[hidden]{display:none}
.app-capture-peek__head{display:flex;align-items:center;gap:var(--space-8);margin-right:calc(var(--space-8) * -1)}
.app-capture-peek__title{flex:1;min-width:0;margin:0}
.app-capture-peek__frame{display:grid;place-items:center;aspect-ratio:16/9;overflow:hidden;border:1px solid var(--outline-variant);border-radius:var(--radius-sm);background:var(--surface-container-highest);color:var(--on-surface-variant)}
.app-capture-peek__frame>*{grid-area:1/1}
.app-capture-peek__frame>video,.app-capture-peek__frame>img,.app-capture-peek__frame>canvas{display:block;width:100%;height:100%;object-fit:contain}
.app-capture-peek__note{margin:0;color:var(--on-surface-variant)}
/* On a phone, Pause and Stop show their glyph alone; Stop keeps its error ink */
@media (max-width:599px){.app-composer__capture .app-capture-thumb{display:none}.app-composer__capture .app-btn{width:40px;min-width:0;height:40px;min-height:0;padding:0;gap:0}.app-composer__capture .app-btn .app-icon{margin:0;font-size:20px}.app-composer__capture .app-btn:not(.app-btn--error){color:var(--on-surface-variant)}.app-composer__capture-label{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}}
/* In a call: the status word alone; the light behind says whose turn it is, and a red dot means only "recording" */
.app-composer__status{padding-inline:var(--space-8);color:var(--on-surface);white-space:nowrap}
.app-composer__line{position:relative;z-index:1;display:flex;align-items:center;gap:var(--space-4);min-height:16px;padding-inline:20px;color:var(--on-surface-variant)}
.app-composer__line .app-icon{font-size:16px}
.app-composer__line.is-error{color:var(--error)}
.app-composer__line-action{padding:0;border:0;background:none;color:var(--primary);font:inherit;font-weight:600;cursor:pointer}
/* On a phone the editor and the row share one row (56, a pill at radius-xl), unless the row holds chips or a bar.
   One markup for both: the switch is CSS alone, so the textarea is never re-rendered and the keyboard stays up. */
@media (max-width:599px){.app-composer__box:not(:has(>.app-composer__row>:is(.app-chip,.app-composer__rec,.app-composer__status,.app-composer__meter))){flex-direction:row;flex-wrap:wrap;align-items:flex-end;column-gap:var(--space-4)}.app-composer__box:not(:has(>.app-composer__row>:is(.app-chip,.app-composer__rec,.app-composer__status,.app-composer__meter)))>*{flex:0 0 100%}.app-composer__box:not(:has(>.app-composer__row>:is(.app-chip,.app-composer__rec,.app-composer__status,.app-composer__meter)))>.app-composer__editor{order:2;flex:1 1 0;min-width:0;padding:var(--space-8) var(--space-4)}.app-composer__box:not(:has(>.app-composer__row>:is(.app-chip,.app-composer__rec,.app-composer__status,.app-composer__meter)))>.app-composer__row{display:contents}.app-composer__box:not(:has(>.app-composer__row>:is(.app-chip,.app-composer__rec,.app-composer__status,.app-composer__meter)))>.app-composer__row>*{order:3}.app-composer__box:not(:has(>.app-composer__row>:is(.app-chip,.app-composer__rec,.app-composer__status,.app-composer__meter)))>.app-composer__row>:first-child:not(.app-composer__go){order:1}.app-composer__box:not(:has(>.app-composer__row>:is(.app-chip,.app-composer__rec,.app-composer__status,.app-composer__meter)))>.app-composer__row>.app-composer__spacer{display:none}.app-composer__input:placeholder-shown,.app-composer__input::placeholder{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}}
/* While the keyboard is up: five lines at most, and a note or hint on the line steps aside; an error stays. */
@media (max-width:599px) and (pointer:coarse){.app-composer:focus-within .app-composer__editor{max-height:136px}.app-composer:focus-within>.app-composer__line:not(.is-error){display:none}}
.app-composer__drop{display:flex;align-items:center;justify-content:center;width:100%;min-height:56px;border-radius:var(--radius-lg);color:var(--primary)}
/* Locked: drops to the ground, no shadow, no controls */
.app-composer.is-locked .app-composer__box{background:var(--surface-container-low);box-shadow:none}
.app-composer.is-locked .app-composer__editor{color:var(--on-surface-variant)}
/* The voice light, behind the composer in a call: cool while you speak, warm while Alis does */
.app-composer__light{position:absolute;z-index:0;inset:-40px -64px;pointer-events:none;filter:blur(28px)}
.app-composer__light::before,.app-composer__light::after,.app-voice__orb::before,.app-voice__orb::after{content:"";position:absolute;inset:0;border-radius:50%;transition:opacity var(--dur-panel) var(--ease-standard)}
.app-composer__light::before{background:radial-gradient(closest-side,color-mix(in srgb,var(--ai-you) 34%,var(--ai-you-container)) 55%,transparent)}
.app-composer__light::after{opacity:0;background:radial-gradient(closest-side,color-mix(in srgb,var(--ai-alis) 26%,var(--ai-alis-container)) 55%,transparent)}
.is-alis>.app-composer__light::before,.is-alis .app-voice__orb::before{opacity:0}
.is-alis>.app-composer__light::after,.is-alis .app-voice__orb::after{opacity:1}
.is-muted>.app-composer__light,.is-muted .app-voice__orb{opacity:.35}
@media (prefers-reduced-motion:no-preference){.app-composer__light,.app-voice__orb{animation:app-breathe 3.2s var(--ease-standard) infinite alternate}}
@keyframes app-breathe{from{transform:scale(.96)}to{transform:scale(1.04)}}

/* ── Attachment · a file, recording or queued message in the composer's tray, and in the sent message ── */
.app-attachment{position:relative;display:flex;align-items:center;gap:var(--space-12);width:232px;max-width:100%;height:56px;padding:var(--space-8);border-radius:var(--radius-lg);background:var(--surface-container-low)}
.app-attachment__glyph{display:flex;align-items:center;justify-content:center;flex:none;width:40px;height:40px;border-radius:var(--radius-sm);background:var(--surface);color:var(--on-surface-variant)}
.app-attachment__text{display:flex;flex-direction:column;flex:1;min-width:0}
.app-attachment__text>*{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.app-attachment__text>.text-meta{color:var(--on-surface-variant)}
/* Keep the visible control small; app-target supplies the pointer-sized hit area. */
.app-attachment .app-icon-btn.app-state{flex:none;width:24px;height:24px}
.app-attachment .app-icon-btn .app-icon{font-size:16px}
/* Recovery uses the lower line beneath the name and glyph, with room for words. */
.app-attachment:has(.app-attachment__retry){display:grid;grid-template-columns:16px minmax(0,1fr) 24px;grid-template-rows:20px 16px;row-gap:var(--space-4)}
.app-attachment:has(.app-attachment__retry)>.app-attachment__glyph{grid-column:1;grid-row:1;width:16px;height:16px;background:transparent}
.app-attachment:has(.app-attachment__retry)>.app-attachment__glyph .app-icon{font-size:16px}
.app-attachment:has(.app-attachment__retry)>.app-attachment__text{display:contents}
.app-attachment:has(.app-attachment__retry) .text-label{grid-column:2;grid-row:1}
.app-attachment:has(.app-attachment__retry) .app-attachment__status{grid-column:1 / 3;grid-row:2;overflow:visible}
.app-attachment:has(.app-attachment__retry)>.app-icon-btn{grid-column:3;grid-row:1 / 3}
.app-attachment__retry{padding:0;border:0;border-radius:var(--radius-xs);background:transparent;color:var(--primary);font:inherit;font-weight:600;text-decoration:none;cursor:pointer}
/* Centre the projected target on the tile, away from the row below. */
.app-attachment__retry.app-target::after{top:calc(50% - var(--space-12))}
.app-attachment__bar{pointer-events:none;position:absolute;left:var(--space-12);right:var(--space-12);bottom:var(--space-4);height:2px;background:var(--surface-container-highest);border-radius:var(--radius-pill);overflow:hidden}
.app-attachment__bar>span{display:block;height:100%;background:var(--on-surface)}
.app-attachment.is-error .app-attachment__glyph,.app-attachment.is-error .app-attachment__text>.text-meta{color:var(--error)}
.app-attachment--image{width:56px;height:56px;padding:0}
.app-attachment--image>img,.app-attachment--image>svg{display:block;width:100%;height:100%;object-fit:cover;border-radius:inherit}
.app-attachment--image .app-icon-btn{position:absolute;top:var(--space-4);right:var(--space-4);background:var(--surface);color:var(--on-surface)}
.app-attachment--message{width:100%;height:auto;min-height:56px}
.app-attachment--message>.app-icon-btn~.app-icon-btn{margin-left:max(0px,calc(var(--touch-target) - 36px))}
a.app-attachment{color:inherit;text-decoration:none}
.app-attachment__external{flex:none;font-size:16px;color:var(--on-surface-variant)}
button.app-attachment{border:0;color:inherit;font:inherit;text-align:left;cursor:pointer}
/* A file Alis made stands in her reply, wider for a title from her description */
.prose .app-attachment{width:320px;margin:0 0 var(--prose-gap,24px)}
@media (max-width:599px){.prose .app-attachment{width:100%}}
/* Open: its file is in the pane */
.app-attachment.is-selected{background:var(--secondary-container);color:var(--on-secondary-container)}
.app-attachment.is-selected .text-label{font-weight:700}
.app-attachment.is-selected .app-attachment__text>.text-meta{color:var(--on-secondary-container)}
/* Gone since: not pressable, the glyph on an outline */
.app-attachment.is-gone{color:var(--on-surface-variant)}
.app-attachment.is-gone .app-attachment__glyph{background:transparent;box-shadow:inset 0 0 0 1px var(--outline-variant)}

/* ── Voice view · a live call given the content area (focus) or the whole screen (phone) ── */
.app-voice{position:relative;display:flex;flex-direction:column;gap:var(--space-24);height:100%;min-height:0;padding:var(--space-16) var(--space-24) var(--space-32);background:var(--background);overflow:hidden}
.app-voice__top{display:flex;align-items:center;gap:var(--space-8)}
.app-voice__title{flex:1;min-width:0;overflow:hidden;text-align:center;text-overflow:ellipsis;white-space:nowrap;color:var(--on-surface)}
.app-voice__body{flex:1;min-height:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-24);text-align:center}
.app-voice__body>*{flex:none}
.app-voice__orb{position:relative;width:min(256px,60vw);aspect-ratio:1}
.app-voice__orb::before,.app-voice__orb::after{filter:blur(10px)}
.app-voice__orb::before{background:radial-gradient(circle at 50% 45%,color-mix(in srgb,var(--ai-you) 55%,var(--ai-you-container)) 0%,color-mix(in srgb,var(--ai-you) 24%,var(--ai-you-container)) 46%,transparent 71%)}
.app-voice__orb::after{opacity:0;background:radial-gradient(circle at 50% 45%,color-mix(in srgb,var(--ai-alis) 48%,var(--ai-alis-container)) 0%,color-mix(in srgb,var(--ai-alis) 20%,var(--ai-alis-container)) 46%,transparent 71%)}
.app-voice__caption{max-width:520px;color:var(--on-surface-variant);display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.app-voice__said{color:var(--on-surface)}
/* A capture running through the call: the thumbnail, the dot and Recording, the time, under the status word */
.app-voice__capture{display:flex;align-items:center;justify-content:center;gap:var(--space-4)}
.app-voice__capture>.app-composer__rec{padding-inline:0 var(--space-4)}
.app-voice__controls{display:flex;align-items:center;justify-content:center;gap:var(--space-16)}
.app-voice__round{display:inline-flex;align-items:center;justify-content:center;flex:none;width:56px;height:56px;padding:0;border:0;border-radius:var(--radius-pill);background:var(--surface-container-low);color:var(--on-surface)}
.app-voice__round .app-icon{font-size:24px;font-variation-settings:"FILL" 0,"wght" 400,"GRAD" 0,"opsz" 24}
.app-voice__round.is-selected{background:var(--secondary-container);color:var(--on-secondary-container)}
.app-voice__end{min-height:56px;padding:0 var(--space-32)}
@media (max-width:599px){.app-voice{padding:var(--space-12) var(--space-16) var(--space-24)}}

/* ── Thread and turns · you in a bubble, Alis as prose, anyone else in a bubble under a who-line ── */
.app-thread{display:flex;flex-direction:column;gap:var(--space-32);width:100%;max-width:var(--measure-prose);margin-inline:auto}
.app-turn{position:relative;display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-8);min-width:0}
.app-turn--you{align-items:flex-end}
.app-turn--alis{align-items:stretch}
.app-turn .app-icon-btn{width:32px;height:32px}
.app-turn__who{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-8);min-height:24px;color:var(--on-surface)}
.app-turn__who .text-meta{color:var(--on-surface-variant)}
.app-turn__audience{display:flex;align-items:center;gap:var(--space-4);margin:0;color:var(--on-surface-variant)}
.app-turn__audience .app-icon{font-size:16px}
.app-turn__avatar{display:inline-flex;align-items:center;justify-content:center;flex:none;width:24px;height:24px;border-radius:var(--radius-pill);background:var(--surface-container-highest);color:var(--on-surface);font-family:var(--font-sans);font-size:12px;line-height:16px;font-weight:600;overflow:hidden;object-fit:cover}
.app-turn__avatar--alis{background:transparent}
.app-turn__head{display:flex;align-items:center;gap:var(--space-12);min-height:32px}
.app-turn__mark{display:inline-flex;flex:none}
.app-turn__status{color:var(--on-surface-variant)}
.app-turn__worked{align-self:flex-start;display:inline-flex;align-items:center;gap:var(--space-4);min-height:32px;margin-left:calc(var(--space-8) * -1);padding:0 var(--space-8);border:0;border-radius:var(--radius-pill);background:transparent;color:var(--on-surface-variant);font-family:var(--font-sans);font-size:14px;line-height:20px;font-weight:400}
.app-turn__worked .app-icon{transition:transform var(--dur-effects) var(--motion-effects)}
.app-turn__worked[aria-expanded="true"] .app-icon{transform:rotate(180deg)}
.app-turn__steps{display:flex;flex-direction:column;gap:var(--space-8);margin:0 0 var(--space-8);padding:var(--space-4) 0 var(--space-4) var(--space-16);border-left:1px solid var(--outline-variant);list-style:none;color:var(--on-surface-variant)}
.app-turn__steps[hidden]{display:none}
.app-turn__step{display:flex;flex-direction:column;gap:var(--space-8);min-width:0}
.app-turn__step>span{display:flex;align-items:center;gap:var(--space-8)}
.app-turn__step .app-icon{font-size:16px}
.app-turn__output{margin:0;padding:var(--space-8) var(--space-12);border-radius:var(--radius-md);background:var(--surface-container-low);color:var(--on-surface);font-family:var(--font-mono);font-size:12px;line-height:16px;white-space:pre;overflow-x:auto;max-height:64px}
.app-turn__caret{display:inline-block;width:2px;height:20px;margin-left:2px;vertical-align:-4px;border-radius:1px;background:var(--signal)}
@media (prefers-reduced-motion:no-preference){.app-turn__caret{animation:app-dot 1s steps(1) infinite}}
.app-turn__row{display:flex;align-items:flex-end;justify-content:flex-end;gap:var(--space-4);width:100%}
.app-turn--them .app-turn__row{justify-content:flex-start}
.app-turn__bubble{min-width:0;max-width:80%;padding:var(--space-12) var(--space-16);border-radius:var(--radius-lg);background:var(--surface-container-low);color:var(--on-surface);font-family:var(--font-sans);font-size:16px;line-height:24px;font-weight:400;white-space:pre-line;overflow-wrap:anywhere}
.app-turn__bubble--voice{width:400px;padding:var(--space-8) var(--space-16) var(--space-12) var(--space-8);white-space:normal}
.app-turn__tools{display:flex;opacity:0;transition:opacity var(--dur-effects) var(--motion-effects)}
.app-turn:hover .app-turn__tools,.app-turn:focus-within .app-turn__tools{opacity:1}
.app-turn__files{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:flex-end;gap:var(--space-8);max-width:80%}
.app-turn--them .app-turn__files{justify-content:flex-start}
.app-turn__image{display:block;width:240px;max-width:100%;border-radius:var(--radius-lg);overflow:hidden;background:var(--surface-container-low)}
.app-turn__image img{display:block;width:100%;height:auto}
.app-turn__foot{display:flex;align-items:center;min-height:32px;margin-top:var(--space-4);transition:opacity var(--dur-effects) var(--motion-effects)}
.app-turn__foot .app-icon-btn:first-child{margin-left:-6px}
.app-turn--alis:not(.is-latest) .app-turn__foot{position:absolute;top:100%;left:0;margin:0;opacity:0}
.app-turn--alis:not(.is-latest):hover .app-turn__foot,.app-turn--alis:not(.is-latest):focus-within .app-turn__foot{opacity:1}
.app-turn__line{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-4);margin:0;color:var(--on-surface-variant)}
.app-turn__line .app-icon{font-size:16px}
.app-turn__line.is-error{color:var(--error)}
.app-turn__line-action,.app-empty-line__action,.app-access-line__action{margin-left:var(--space-4);padding:0;border:0;background:none;color:var(--primary);font:inherit;font-weight:600;cursor:pointer}
@media (hover:none){.app-turn__tools,.app-turn--alis:not(.is-latest) .app-turn__foot{display:none}}
/* What your message was about: the context chip as you sent it */
.app-turn__about{max-width:80%;color:var(--on-surface-variant);text-align:right}
@media (max-width:599px){.app-turn__bubble,.app-turn__files{max-width:85%}}

/* ── Voice note · a sent recording: play, the waveform, the time, then its transcript ── */
.app-voice-note{display:flex;flex-direction:column;gap:var(--space-4)}
.app-voice-note__player{display:flex;align-items:center;gap:var(--space-8)}
.app-voice-note__player .app-icon-btn{width:40px;height:40px;color:var(--on-surface)}
.app-voice-note__wave{flex:1;display:flex;align-items:center;gap:2px;height:32px;min-width:0}
.app-voice-note__wave i{flex:1;min-width:2px;max-width:3px;border-radius:var(--radius-pill);background:var(--outline)}
.app-voice-note__wave i.is-played{background:var(--primary)}
.app-voice-note__time{color:var(--on-surface-variant);font-variant-numeric:tabular-nums}
.app-voice-note__transcript{margin:0;padding-left:var(--space-8);display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.app-voice-note.is-open .app-voice-note__transcript{display:block}
.app-voice-note__more{align-self:flex-start;margin-left:var(--space-8);padding:0;border:0;background:none;color:var(--primary);font-family:var(--font-sans);font-size:14px;line-height:20px;font-weight:600;cursor:pointer}

/* ── Ask · when Alis needs you: the decision, docked on the composer above the editor ── */
.app-ask{display:flex;flex-direction:column;gap:var(--space-12);padding:var(--space-12) var(--space-12) var(--space-16);margin-bottom:var(--space-4);border-bottom:1px solid var(--outline-variant)}
.app-ask__head{display:flex;align-items:flex-start;gap:var(--space-8)}
.app-ask__title{flex:1;min-width:0;margin:0}
.app-ask__page{display:flex;align-items:center;flex:none;margin:-6px -8px -6px 0;color:var(--on-surface-variant)}
.app-ask__page .app-icon-btn{width:32px;height:32px}
.app-ask__page .text-meta{padding:0 2px;font-variant-numeric:tabular-nums}
.app-ask__body{margin:0;color:var(--on-surface-variant)}
.app-ask__grants{display:flex;flex-direction:column;gap:var(--space-4);margin:0;padding:0;list-style:none;color:var(--on-surface)}
.app-ask__grants li{display:flex;align-items:flex-start;gap:var(--space-8)}
.app-ask__grants .app-icon{font-size:16px;margin-top:2px;color:var(--on-surface-variant)}
.app-ask__note{margin:0;color:var(--on-surface-variant)}
.app-ask__options{display:flex;flex-direction:column;gap:var(--space-4);margin:0 calc(var(--space-8) * -1)}
.app-ask__option{display:grid;grid-template-columns:24px 1fr;align-items:start;column-gap:var(--space-12);width:100%;padding:var(--space-8);border:0;border-radius:var(--radius-md);background:transparent;color:var(--on-surface);font:inherit;text-align:left}
.app-ask__key{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:var(--radius-sm);background:var(--surface-container-low);color:var(--on-surface-variant);font-family:var(--font-sans);font-size:12px;line-height:16px;font-weight:600;font-variant-numeric:tabular-nums}
.app-ask__key .app-icon{font-size:16px}
.app-ask__option-text{display:flex;flex-direction:column;min-width:0;padding-top:2px}
.app-ask__option-text .text-supporting{color:var(--on-surface-variant)}
.app-ask__option.is-selected{background:var(--secondary-container);color:var(--on-secondary-container)}
.app-ask__option.is-selected .app-ask__key{background:var(--on-secondary-container);color:var(--secondary-container)}
.app-ask__option.is-selected .app-ask__option-text .text-supporting{color:inherit}
.app-ask__line{display:flex;align-items:center;gap:var(--space-4);margin:0;color:var(--on-surface-variant)}
.app-ask__line .app-icon{font-size:16px}
.app-ask__line.is-error{color:var(--error)}
.app-ask__actions{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:var(--space-8)}
.app-ask__actions .app-btn--quiet{margin-right:auto}
@media (max-width:599px){.app-ask__actions{flex-direction:column-reverse;align-items:stretch}.app-ask__actions .app-btn--quiet{margin-right:0}}
.app-composer__go--plain{background:transparent;color:var(--on-surface-variant)}
.app-turn__record{display:flex;align-items:center;gap:var(--space-4);margin:0;color:var(--on-surface-variant)}
.app-turn__record .app-icon{font-size:16px}
.app-thread__event{display:flex;align-items:center;justify-content:center;gap:var(--space-4);margin:0;color:var(--on-surface-variant);text-align:center}
.app-thread__event .app-icon{font-size:16px}
.app-thread__typing{margin:0;color:var(--on-surface-variant)}
.app-thread__status{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.app-turn__bubble.prose{white-space:normal;--prose-gap:12px;--prose-item-gap:4px;--prose-h1-size:16px;--prose-h1-line:24px;--prose-h1-tracking:0;--prose-h1-weight:600;--prose-h1-above:16px;--prose-h1-below:4px;--prose-h2-size:16px;--prose-h2-line:24px;--prose-h2-weight:600;--prose-h2-above:16px;--prose-h3-above:12px;--prose-code-size:14px}
.app-turn__request{display:flex;align-items:center;gap:var(--space-8);margin-bottom:var(--space-4);white-space:normal}
.app-turn__request .app-icon{font-size:20px;color:var(--on-surface-variant)}

/* ── Count · how many asks are waiting, on a rail row ── */
.app-count{display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:20px;padding:0 6px;border-radius:var(--radius-pill);background:var(--error);color:var(--on-error);font-family:var(--font-sans);font-size:12px;line-height:16px;font-weight:600;font-variant-numeric:tabular-nums}

/* ── Menu ── */
/* One surface, two behaviours: an action menu (role=menu, focus moves in) and a suggestion menu (role=listbox, focus stays in the editor) */
.app-menu{display:flex;flex-direction:column;min-width:200px;max-width:320px;max-height:min(400px,60vh);overflow-y:auto;overscroll-behavior:contain;margin:0;padding:var(--space-8);border-radius:var(--radius-lg);background:var(--surface-container-high);box-shadow:var(--elevation-2);color:var(--on-surface);list-style:none}
.app-menu[hidden]{display:none}
.app-menu__heading{display:block;padding:var(--space-8) var(--space-12) var(--space-4);color:var(--on-surface-variant)}
.app-menu__divider{flex:none;height:1px;margin:var(--space-4) calc(var(--space-8) * -1);border:0;background:var(--outline-variant)}
.app-menu__item{display:flex;align-items:center;gap:var(--space-12);flex:none;width:100%;min-height:40px;padding:var(--space-8) var(--space-12);border:0;border-radius:var(--radius-sm);background:transparent;color:var(--on-surface);font-family:var(--font-sans);font-size:14px;line-height:20px;font-weight:500;letter-spacing:0;text-align:left;text-decoration:none}
@media (pointer:coarse){.app-menu__item{min-height:var(--touch-target-coarse)}}
.app-menu__item>.app-icon{color:var(--on-surface-variant)}
.app-menu__text{display:flex;flex-direction:column;flex:1;min-width:0}
.app-menu__text>*{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.app-menu__support{color:var(--on-surface-variant);font-size:12px;line-height:16px;font-weight:400}
.app-menu__hint{flex:none;color:var(--on-surface-variant);font-size:12px;line-height:16px;font-weight:400;font-variant-numeric:tabular-nums}
.app-menu__avatar{display:inline-flex;align-items:center;justify-content:center;flex:none;width:24px;height:24px;border-radius:var(--radius-pill);background:var(--surface-container-highest);color:var(--on-surface);font-size:12px;line-height:16px;font-weight:600;object-fit:cover}
.app-menu__item:focus-visible,.app-menu__item.is-active{outline:2px solid var(--primary);outline-offset:-2px}
.app-menu__item.is-active::before{opacity:var(--state-hover)}
.app-menu__item.is-selected{background:var(--secondary-container);color:var(--on-secondary-container);font-weight:700}
.app-menu__item.is-selected>.app-icon,.app-menu__item.is-selected .app-menu__support{color:var(--on-secondary-container)}
.app-menu__item--danger,.app-menu__item--danger>.app-icon{color:var(--error)}
.app-menu__empty{padding:var(--space-8) var(--space-12);color:var(--on-surface-variant);font-size:14px;line-height:20px}
.app-menu__empty.app-loader--line{display:flex;justify-content:flex-start}
/* The suggestion menu in a composer: a band on its surface, above the editor, like an ask */
.app-menu--suggest{flex:none;min-width:0;max-width:none;max-height:min(272px,40vh);margin:0 0 var(--space-4);padding:var(--space-4) 0 var(--space-8);border-bottom:1px solid var(--outline-variant);border-radius:0;background:transparent;box-shadow:none}
.app-menu--suggest .app-menu__item{border-radius:var(--radius-md)}
.app-ask+.app-menu--suggest{padding-top:0}
/* A mention or a command, chosen: one token in the sentence */
.app-token{display:inline;padding:2px 6px;margin:0 1px;border-radius:var(--radius-sm);background:var(--surface-container-highest);color:var(--on-surface);font-weight:600;white-space:nowrap;text-decoration:none;-webkit-box-decoration-break:clone;box-decoration-break:clone;user-select:all}
.app-token>.app-icon{display:inline-block;font-size:1em;width:1em;height:1em;margin-right:var(--space-4);vertical-align:-0.125em;color:var(--on-surface-variant)}
a.app-token,button.app-token{border:0;font:inherit;font-weight:600;cursor:pointer}
/* ── Keys · a shortcut, one cap per key (rules/shortcuts.md) ── */
.app-keys{display:inline-flex;align-items:center;gap:var(--space-4);flex:none;margin:0;font:inherit;vertical-align:middle;white-space:nowrap}
.app-key{display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;min-width:20px;height:20px;padding:0 var(--space-4);border-radius:var(--radius-xs);background:var(--surface-container-highest);color:var(--on-surface-variant);font-family:var(--font-sans);font-size:12px;line-height:16px;font-weight:600;font-style:normal;font-variant-numeric:tabular-nums}
.app-keys__then{color:var(--on-surface-variant);font-family:var(--font-sans);font-size:12px;line-height:16px;font-weight:400}
/* What a screen reader says for caps it can't read aloud (⌘, ⇧): in the sheet and in prose */
.app-keys__said{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
/* On a grey field the cap lifts to white; the search field's key shows only while it is empty and unfocused */
.app-search .app-key{background:var(--surface)}
/* On a touch screen there is no keyboard to press them: the search field's cap and a menu row's keys leave */
@media (pointer:coarse){.app-search>.app-keys,.app-menu__hint>.app-keys{display:none}}
.app-search:focus-within>.app-keys,.app-search:has(>.app-search__input:not(:placeholder-shown))>.app-keys{display:none}
/* Single-key shortcuts off (set on the root): letter caps leave tooltips and menus, and dim in the sheet */
[data-single-keys="off"] .app-keys--single{display:none}
[data-single-keys="off"] .app-shortcuts .app-keys--single{display:inline-flex;opacity:.38}
.app-shortcuts[data-single-keys="off"] .app-keys--single{display:inline-flex;opacity:.38}
/* ── Tooltip · names a control and carries its keys: inverse, below, after 200ms ── */
.app-tooltip{position:fixed;z-index:40;display:inline-flex;align-items:center;gap:var(--space-8);max-width:240px;min-height:28px;box-sizing:border-box;margin:0;padding:var(--space-4) var(--space-8);border-radius:var(--radius-sm);background:var(--inverse-surface);color:var(--on-inverse-surface);font-family:var(--font-sans);font-size:12px;line-height:16px;font-weight:500;pointer-events:none}
.app-tooltip[hidden]{display:none}
.app-tooltip:has(>.app-keys:last-child){padding-right:var(--space-4)}
.app-tooltip .app-key{background:color-mix(in srgb,var(--on-inverse-surface) 16%,transparent);color:var(--on-inverse-surface)}
.app-tooltip .app-keys__then{color:inherit;opacity:.72}
[data-single-keys="off"] .app-tooltip:has(>.app-keys--single:last-child){padding-right:var(--space-8)}
/* ── Shortcut sheet · the keys of this screen, then everywhere; in the detail pane's place ── */
.app-shortcuts{display:flex;flex-direction:column;gap:var(--space-24);flex:1;min-height:0}
.app-shortcuts__group{display:flex;flex-direction:column;margin:0}
.app-shortcuts__heading{margin:0 0 var(--space-4);color:var(--on-surface-variant)}
.app-shortcuts__note{margin:0 0 var(--space-4);color:var(--on-surface-variant)}
.app-shortcuts__row{display:flex;align-items:center;justify-content:space-between;gap:var(--space-16);min-height:36px}
.app-shortcuts__group>dl{margin:0}
.app-shortcuts__row>dt,.app-shortcuts__row>dd{margin:0}
.app-shortcuts__note[hidden]{display:none}
/* The foot stays in view while the groups scroll under it */
.app-shortcuts__foot{position:sticky;bottom:0;margin-top:auto;padding-top:var(--space-16);border-top:1px solid var(--outline-variant);background:var(--background)}
/* ── Avatar · someone or something with a name: a person is round, a thing is a square tile ── */
.app-avatar{display:inline-flex;align-items:center;justify-content:center;flex:none;vertical-align:middle;width:36px;height:36px;border-radius:var(--radius-pill);background:var(--surface-container-highest);color:var(--on-surface);font-family:var(--font-sans);font-size:14px;line-height:20px;font-weight:600;letter-spacing:0;overflow:hidden;object-fit:cover;user-select:none}
.app-avatar--small{width:24px;height:24px;font-size:12px;line-height:16px}
.app-avatar--large{width:80px;height:80px;font-size:28px;line-height:36px}
.app-avatar--thing{border-radius:var(--radius-sm)}
.app-avatar--thing.app-avatar--small{border-radius:var(--radius-xs)}
.app-avatar--thing.app-avatar--large{border-radius:var(--radius-lg)}
.app-avatar--large>.app-icon{font-size:40px;font-variation-settings:"FILL" 0,"wght" 400,"GRAD" 0,"opsz" 40}
/* A logo and the Alis mark arrive with their own ground (rules/chips-alerts.md) */
.app-avatar--logo,.app-avatar--alis{background:transparent}
.app-avatar--logo{object-fit:contain}
.app-avatar--cat1{background:var(--cat1-container);color:var(--on-cat1-container)}.app-avatar--cat2{background:var(--cat2-container);color:var(--on-cat2-container)}.app-avatar--cat3{background:var(--cat3-container);color:var(--on-cat3-container)}.app-avatar--cat4{background:var(--cat4-container);color:var(--on-cat4-container)}.app-avatar--cat5{background:var(--cat5-container);color:var(--on-cat5-container)}.app-avatar--cat6{background:var(--cat6-container);color:var(--on-cat6-container)}
/* Several people: side by side, never overlapped, so no ring has to guess the ground under it */
.app-avatar-group{display:inline-flex;align-items:center;gap:var(--space-4)}
.app-avatar-group__more{font-variant-numeric:tabular-nums}
/* An avatar inside a button: the button is the control, and its state layer lies over the picture */
.app-avatar-btn{display:inline-flex;flex:none;padding:0;border:0;border-radius:var(--radius-pill);background:transparent;color:var(--on-surface)}
.app-avatar-btn:has(>.app-avatar--thing){border-radius:var(--radius-sm)}
.app-avatar-btn:has(>.app-avatar--thing.app-avatar--small){border-radius:var(--radius-xs)}
.app-avatar-btn:has(>.app-avatar--thing.app-avatar--large){border-radius:var(--radius-lg)}
.app-avatar-btn::before{z-index:1}

/* ── Checkbox and radio · native inputs; the row is the target ── */
.app-check-group{display:flex;flex-direction:column}
.app-check-row{position:relative;display:flex;align-items:flex-start;gap:var(--space-12);min-height:var(--control-height);padding:6px 0;color:var(--on-surface);cursor:pointer}
@media (pointer:coarse){.app-check-row{min-height:var(--touch-target-coarse);padding:var(--space-12) 0}}
.app-check-row__text{display:flex;flex-direction:column;flex:1;min-width:0}
.app-check-row__text .text-supporting{color:var(--on-surface-variant)}
.app-checkbox,.app-radio{position:relative;flex:none;width:18px;height:18px;margin:3px;border:2px solid var(--on-surface-variant);background:transparent;appearance:none;-webkit-appearance:none;cursor:pointer;transition:background-color var(--dur-effects) var(--motion-effects),border-color var(--dur-effects) var(--motion-effects),box-shadow var(--dur-effects) var(--motion-effects)}
.app-checkbox{border-radius:var(--radius-xs)}
.app-radio{width:20px;height:20px;margin:2px;border-radius:var(--radius-pill)}
.app-checkbox:checked,.app-checkbox:indeterminate,.app-checkbox.is-checked{border-color:var(--primary);background:var(--primary)}
.app-checkbox:checked::before,.app-checkbox.is-checked::before{content:"";position:absolute;left:4.5px;top:1px;width:5px;height:10px;border:solid var(--on-primary);border-width:0 2px 2px 0;transform:rotate(45deg)}
.app-checkbox:indeterminate::before{content:"";position:absolute;left:2px;right:2px;top:6px;height:2px;background:var(--on-primary)}
.app-radio:checked{border-color:var(--primary)}
.app-radio:checked::before{content:"";position:absolute;inset:3px;border-radius:inherit;background:var(--primary)}
.app-checkbox:focus-visible,.app-radio:focus-visible{outline:2px solid var(--primary);outline-offset:1px}
.app-check-row:hover :is(.app-checkbox,.app-radio):not(:disabled),:is(.app-checkbox,.app-radio):hover:not(:disabled){box-shadow:0 0 0 8px color-mix(in srgb,var(--on-surface) calc(var(--state-hover) * 100%),transparent)}
.app-check-row:active :is(.app-checkbox,.app-radio):not(:disabled){box-shadow:0 0 0 8px color-mix(in srgb,var(--on-surface) calc(var(--state-pressed) * 100%),transparent)}
.app-field.is-error :is(.app-checkbox,.app-radio):not(:checked),.app-fieldset.is-error :is(.app-checkbox,.app-radio):not(:checked){border-color:var(--error)}
.app-fieldset.is-error .app-fieldset__support{color:var(--error)}
:is(.app-checkbox,.app-radio):disabled{cursor:default}
.app-check-row.is-disabled{opacity:.38;cursor:default}

/* ── Combobox · the select's box opens a menu with a search at its head ── */
.app-combo{position:relative}
.app-combo__trigger{width:100%;font-family:var(--font-sans);font-size:16px;line-height:24px;text-align:left;cursor:pointer;outline:none}
.app-combo__trigger:focus-visible,.app-combo__trigger[aria-expanded="true"]{border-color:var(--primary);box-shadow:inset 0 0 0 1px var(--primary)}
.app-combo__trigger>.app-icon{flex:none;transition:transform var(--dur-effects) var(--motion-effects)}
.app-combo__trigger[aria-expanded="true"]>.app-icon{transform:rotate(180deg)}
.app-combo__value{display:flex;align-items:center;gap:var(--space-8);flex:1;min-width:0;color:var(--on-surface)}
.app-combo__value.is-placeholder{color:var(--on-surface-variant)}
.app-combo__text{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.app-combo__panel{position:absolute;top:calc(100% + var(--space-4));left:0;right:0;z-index:2;min-width:240px;max-width:none;max-height:none;padding:0;overflow:visible}
/* The search is the menu's first line: no box of its own, its glyph on the rows' leading edge */
.app-combo__search{display:flex;align-items:center;gap:var(--space-12);flex:none;min-height:48px;padding:0 var(--space-16) 0 calc(var(--space-8) + var(--space-12));border-bottom:1px solid var(--outline-variant);color:var(--on-surface-variant)}
.app-combo__input{flex:1;min-width:0;padding:0;border:0;background:transparent;color:var(--on-surface);font-family:var(--font-sans);font-size:14px;line-height:20px;outline:none}
.app-combo__input::placeholder{color:var(--on-surface-variant);opacity:1}
@media (pointer:coarse){.app-combo__input{font-size:16px;line-height:24px}}
.app-combo__list{display:flex;flex-direction:column;max-height:min(280px,40vh);overflow-y:auto;overscroll-behavior:contain;margin:0;padding:var(--space-8);list-style:none}
/* Several: each option leads with a drawn checkbox, and the box alone says it is chosen */
.app-menu__item>.app-checkbox{margin:1px;cursor:inherit}

/* ── Disclosure · detail most people don't need, folded under its title ── */
.app-disclosure{min-width:0;color:var(--on-surface)}
.app-disclosure__summary{display:flex;align-items:center;gap:var(--space-12);min-height:max(48px,var(--touch-target));margin:0 calc(var(--space-8) * -1);padding:var(--space-4) var(--space-8);border-radius:var(--radius-sm);list-style:none}
.app-disclosure__summary::-webkit-details-marker{display:none}
.app-disclosure__text{display:flex;flex-direction:column;flex:1;min-width:0}
.app-disclosure__text .text-supporting{color:var(--on-surface-variant)}
.app-disclosure__summary>.app-icon:last-child{flex:none;color:var(--on-surface-variant);transition:transform var(--dur-effects) var(--motion-effects)}
.app-disclosure[open]>.app-disclosure__summary>.app-icon:last-child{transform:rotate(180deg)}
.app-disclosure__body{padding:var(--space-4) 0 var(--space-16)}
.app-disclosure-group{display:flex;flex-direction:column}
.app-disclosure-group>.app-disclosure+.app-disclosure{border-top:1px solid var(--outline-variant)}

/* ── Drop target, while something is dragged over it ── */
.drop-target{outline:2px dashed var(--primary);outline-offset:-2px;background-color:color-mix(in srgb,var(--primary) calc(var(--state-dragged) * 100%),transparent)}

/* ── Scrollbars · one treatment for the app ── */
*{scrollbar-width:thin;scrollbar-color:var(--outline-variant) transparent}
