/* ───────────────────────────────────────────────────────────────────────
   robin — shared design system
   Palette read off the two licensed common-robin photographs in assets/:
   the glossy near-black head, the chocolate body, the marigold eye patch.
   See brand-spec.md. Six tokens below are the ONLY place colour is authored.

   The accent is a FILL, never a text colour — marigold on paper is ~1.9:1.
   ─────────────────────────────────────────────────────────────────────── */

:root {
  --bg:      oklch(98.2% 0.006 85);
  --surface: oklch(100% 0 0);
  --fg:      oklch(23% 0.020 55);
  --muted:   oklch(46% 0.022 50);   /* 4.8:1 on --bg — L*52 measured only 3.9:1 */
  --border:  oklch(90% 0.008 70);
  --accent:  oklch(78% 0.155 78);

  /* Two tokens for the places WCAG 1.4.11 asks 3:1 of a non-text thing:
     a control's own boundary, and a graphic that carries meaning. Measured
     on --surface in this theme:

       --border  1.35:1   fine for a decorative hairline, short of 3:1 for
                          the edge of an input, which is the only thing
                          saying where the field is.
       --accent  2.04:1   fine as a wash behind text, short of 3:1 for a
                          filled dot or a progress bar that IS the
                          information.

     So the plain tokens keep their jobs (dividers, panel edges, soft
     accent washes) and these two take over wherever the shape has to be
     seen. Darkening --border or --accent outright would have dragged every
     hairline on every screen along with it. Dark mode already passes
     (--border 1.46:1 is still a hairline; --accent is 7.17:1 there), so
     the dark block aliases --accent-strong straight back to --accent. */
  --border-strong: oklch(64% 0.008 70);   /* 3.37:1 on --surface */
  --accent-strong: oklch(62% 0.155 78);   /* 3.70:1 on --surface */

  /* derived — never author new colour */
  --accent-soft: color-mix(in oklch, var(--accent) 22%, transparent);
  --accent-deep: color-mix(in oklch, var(--accent) 88%, var(--fg));
  --fg-soft:     color-mix(in oklch, var(--fg) 5%, transparent);
  --fg-line:     color-mix(in oklch, var(--fg) 14%, transparent);

  --font-display: 'Iowan Old Style', 'Charter', 'Palatino Linotype', 'Book Antiqua', Georgia, serif;
  --font-body:    -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  --font-mono:    ui-monospace, 'JetBrains Mono', 'SF Mono', Menlo, monospace;

  --fs-h1: clamp(40px, 5.2vw, 64px);
  --fs-h2: clamp(28px, 3.4vw, 40px);
  --fs-h3: 20px;
  --fs-lead: 18px;
  --fs-body: 16px;
  --fs-meta: 13px;

  --gap-xs: 8px;
  --gap-sm: 12px;
  --gap-md: 20px;
  --gap-lg: 32px;
  --gap-xl: 56px;
  --gap-2xl: 96px;
  --container: 1120px;
  --gutter: 32px;

  --radius: 10px;
  --radius-lg: 16px;
  --rail: 264px;
  /* Text on marigold fills stays the dark head colour in both themes.
     Inverting --fg for dark mode would put light type on --accent (~1.9:1). */
  --on-accent: oklch(23% 0.020 55);
}

:root[data-theme="dark"] {
  --bg:      oklch(22% 0.014 55);
  --surface: oklch(28% 0.012 55);
  --fg:      oklch(96% 0.008 85);
  --muted:   oklch(82% 0.018 50);
  --border:  oklch(38% 0.012 55);
  --accent:  oklch(78% 0.155 78);
  /* --accent is already 7.17:1 on --surface here, so the strong variant is
     the same colour. --border-strong still has work to do: 1.46:1. */
  --border-strong: oklch(60% 0.012 55);   /* 3.69:1 on --surface */
  --accent-strong: var(--accent);
  --accent-soft: color-mix(in oklch, var(--accent) 22%, transparent);
  --accent-deep: color-mix(in oklch, var(--accent) 88%, oklch(23% 0.020 55));
  --fg-soft:     color-mix(in oklch, var(--fg) 8%, transparent);
  --fg-line:     color-mix(in oklch, var(--fg) 16%, transparent);
  --on-accent: oklch(23% 0.020 55);
}

/* ─── reset & base ─────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; overflow-x: clip; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.55;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}
img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; cursor: pointer; }
p { text-wrap: pretty; }
h1, h2, h3, h4 { text-wrap: balance; }

/* Focus rings are --fg. A marigold ring would fail the 3:1 non-text floor
   against both --bg and --surface. */
:focus-visible {
  outline: 2px solid var(--fg);
  outline-offset: 2px;
  border-radius: 6px;
}

/* Off-screen until focused, then the first thing in the tab order. The rail
   holds the whole agenda, so without this reaching the screen itself meant
   tabbing through every meeting in the list. */
.skip-link {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 200;
  transform: translateY(-200%);
  padding: 10px 16px;
  border: 1px solid var(--fg);
  border-radius: var(--radius, 10px);
  background: var(--surface);
  color: var(--fg);
  font-weight: 550;
  text-decoration: none;
}

.skip-link:focus-visible { transform: translateY(0); }

@media (prefers-reduced-motion: no-preference) {
  .skip-link { transition: transform 0.12s ease; }
}

/* An icon is 1em so it scales with whatever text it sits beside, and never
   shrinks below that when a flex row runs out of room. Every icon is
   aria-hidden, so none of this affects what is announced. */
.icon {
  width: 1em;
  height: 1em;
  flex: none;
  vertical-align: -0.125em;
}

/* Icon plus label: the gap belongs to the pairing, not to every button. */
.btn .icon,
summary .icon,
dt .icon,
h1 .icon, h2 .icon, h3 .icon {
  margin-right: 0.45em;
}

.btn .icon:last-child {
  margin-right: 0;
  margin-left: 0.45em;
}

/* ─── layout primitives ────────────────────────────────────────────── */
.container { max-width: var(--container); margin-inline: auto; padding-inline: var(--gutter); }
.section { padding-block: clamp(48px, 7vw, var(--gap-2xl)); }
.section + .section { border-top: 1px solid var(--border); }
.stack { display: flex; flex-direction: column; }
.stack > * + * { margin-top: var(--gap-md); }
.row { display: flex; align-items: center; gap: var(--gap-md); }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: var(--gap-md); }
.grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--gap-lg); }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--gap-lg); }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--gap-md); }
.grid-2-1 { display: grid; grid-template-columns: 2fr 1fr; gap: var(--gap-xl); align-items: start; }
.grid-1-2 { display: grid; grid-template-columns: 1fr 2fr; gap: var(--gap-xl); align-items: start; }
@media (max-width: 920px) {
  .grid-2, .grid-3, .grid-4, .grid-2-1, .grid-1-2 { grid-template-columns: 1fr; }
}

/* ─── type ─────────────────────────────────────────────────────────── */
/* Display is a serif — warmer tracking than a grotesque wants. */
.h1, h1 { font-family: var(--font-display); font-size: var(--fs-h1); line-height: 1.06; letter-spacing: -0.016em; margin: 0; font-weight: 600; }
.h2, h2 { font-family: var(--font-display); font-size: var(--fs-h2); line-height: 1.14; letter-spacing: -0.012em; margin: 0; font-weight: 600; }
.h3, h3 { font-family: var(--font-display); font-size: var(--fs-h3); font-weight: 600; line-height: 1.32; letter-spacing: -0.006em; margin: 0; }
.lead { font-size: var(--fs-lead); line-height: 1.55; color: var(--muted); max-width: 60ch; margin: 0; }
.eyebrow {
  font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--muted); margin: 0 0 var(--gap-md);
}
.eyebrow-quiet { color: var(--muted); }
.meta { font-family: var(--font-mono); font-size: var(--fs-meta); color: var(--muted); }
.num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.mono-path { font-family: var(--font-mono); font-size: 12px; color: var(--muted); }

/* ─── chrome ───────────────────────────────────────────────────────── */
.topnav {
  position: sticky; top: 0; z-index: 20;
  background: color-mix(in oklch, var(--bg) 88%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border);
}
.topnav-inner { display: flex; align-items: center; justify-content: space-between; padding-block: 14px; gap: var(--gap-md); }
.topnav nav { display: flex; gap: var(--gap-lg); }
.topnav nav a { font-size: 14px; color: var(--muted); }
.topnav nav a:hover { color: var(--fg); }
.pagefoot { padding-block: var(--gap-xl); color: var(--muted); font-size: 13px; border-top: 1px solid var(--border); }
.pagefoot .row-between { flex-wrap: wrap; gap: var(--gap-md); }
.pagefoot a:hover { color: var(--fg); }

/* wordmark — the one flourish: the robin's marigold eye patch, abstracted.
   An eye with the bare patch streaming behind it, on the bird's near-black. */
.logo { display: inline-flex; align-items: center; gap: 9px; font-family: var(--font-display); font-size: 19px; font-weight: 600; letter-spacing: -0.012em; }
.logo-mark { width: 24px; height: 24px; flex: none; }
.logo-mark svg { width: 100%; height: 100%; display: block; }
.logo-mark img { width: 100%; height: 100%; display: block; object-fit: cover; border-radius: 7px; }

/* ─── buttons ──────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 44px; padding: 11px 18px;
  border-radius: var(--radius); border: 1px solid transparent;
  font-size: 15px; font-weight: 500; letter-spacing: -0.006em;
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.06s ease;
}
.btn:active { transform: translateY(1px); }
/* Marigold fill carries --fg text, not white — the pair measures well past
   4.5:1, and hover deepens the fill so contrast only ever rises. */
.btn-primary { background: var(--accent); color: var(--on-accent); border-color: var(--accent); font-weight: 550; }
.btn-primary:hover { background: var(--accent-deep); border-color: var(--accent-deep); color: var(--on-accent); }
.btn-secondary { background: var(--surface); color: var(--fg); border-color: var(--border); }
.btn-secondary:hover { background: var(--fg-soft); border-color: var(--fg-line); color: var(--fg); }
.btn-ghost { background: transparent; color: var(--fg); border-color: transparent; padding-inline: 10px; }
.btn-ghost:hover { background: var(--fg-soft); color: var(--fg); }
.btn-sm { min-height: 34px; padding: 6px 12px; font-size: 13px; border-radius: 8px; }
.btn[disabled] { opacity: 0.45; cursor: not-allowed; }
.btn-arrow::after { content: '→'; transition: transform 0.15s ease; }
.btn-arrow:hover::after { transform: translateX(2px); }
.btn-block { width: 100%; }

/* ─── surfaces ─────────────────────────────────────────────────────── */
.card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 28px; }
.card-flat { background: transparent; border: 0; padding: 0; }
.card-rule { background: transparent; border: 0; border-top: 1px solid var(--fg); padding: 22px 0 0; border-radius: 0; }
.rule { border: 0; border-top: 1px solid var(--border); margin: 0; }
.rule-strong { border: 0; border-top: 1px solid var(--fg); margin: 0; }

/* ─── content imagery ──────────────────────────────────────────────── */
/* Full frame, never cropped. One axis bounded and the other left automatic,
   so an unusually tall or wide file can't run away with the page. */
.content-img {
  display: block;
  width: 100%;
  height: auto;
  max-height: min(72vh, 720px);
  object-fit: contain;
  border-radius: var(--radius-lg);
  background: var(--fg-soft);
}
.figure { margin: 0; }
.figure figcaption {
  font-family: var(--font-mono); font-size: 11px; line-height: 1.5;
  color: var(--muted); margin-top: 10px; letter-spacing: 0.01em;
}
.figure figcaption a { text-decoration: underline; text-underline-offset: 2px; }
.figure figcaption a:hover { color: var(--fg); }

/* ─── layered illustration + parallax background wash ──────────────── */
/* Two independent images: .illo-bg (a soft watercolour wash whose own edges
   fade to full transparency, generated via vignette_fade) sits behind
   .illo-fg (the actual ink illustration, fully transparent so the wash
   reads through the negative space). Both images are decorative, so
   .illo-fg must not inherit .content-img's var(--fg-soft) loading-
   placeholder tint — that tint is exactly what showed as a stray grey box
   behind the transparent illustration.
   .illo-bg is NOT oversized and the stack does NOT clip: the wash's alpha
   is already 0 at its own outer edge, so a flush 100%-sized image blends
   into the page with no visible boundary. An earlier version scaled it to
   124% with a -12% inset for parallax headroom and clipped the stack with
   overflow:hidden — that pushed the already-faded outer ring outside the
   visible box, leaving only the opaque centre showing, hard-cropped into a
   visible rectangle. The fix is to let the fade itself do the blending and
   never clip it. */
.illo-stack { position: relative; display: block; width: 100%; }
.illo-stack .illo-bg {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; background: transparent; border-radius: 0;
  pointer-events: none; will-change: transform;
  transition: transform 0.5s cubic-bezier(.22, .61, .36, 1);
}
.illo-stack .illo-fg { position: relative; background: transparent; }
@media (prefers-reduced-motion: reduce) {
  .illo-stack .illo-bg { transition: none; }
}

/* ─── bird cross-fade (plate ↔ sprite) ──────────────────────────────── */
/* At rest the bird IS the painting: .illo-plate (the full original artwork,
   branch included) shows at full opacity and .illo-sprite (the cut-out bird
   alone, transparent background) sits at opacity 0 in the exact same box,
   via grid stacking rather than absolute positioning — both images share
   the same intrinsic size and object-fit, so grid-area: 1/1 keeps them
   pixel-locked without needing to hardcode a position. The sprite exists
   only while the bird is actually moving; toggling .is-flying swaps which
   layer is visible. Both cross-fade over the same 420ms so the handoff
   reads as the bird settling into or lifting out of the paper, never as a
   layer toggle. The sprite sits outside .illo-plate, so nothing that masks
   or clips the painting (a card radius, a reveal clip) can ever crop it. */
.illo-crossfade { display: grid; position: relative; aspect-ratio: 1248 / 832; }
.illo-crossfade .illo-plate,
.illo-crossfade .illo-sprite,
.illo-crossfade .illo-plate-empty {
  grid-area: 1 / 1;
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  transition: opacity 420ms ease;
}
.illo-crossfade .illo-sprite { opacity: 0; pointer-events: none; }
.illo-crossfade.is-flying .illo-plate { opacity: 0; }
.illo-crossfade.is-flying .illo-sprite { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .illo-crossfade .illo-plate,
  .illo-crossfade .illo-sprite,
  .illo-crossfade .illo-plate-empty { transition: none; }
}

/* Hero-only variant: the branch is a single permanent layer (hero doesn't
   use .illo-plate at all) — .illo-sprite just fades in on top of it once
   the bird lands. Earlier this cross-faded to a second, separately-
   generated full-painting asset on settle, but that image's branch was
   redrawn slightly differently by the model than plate-empty's, so the
   swap read as the branch itself visibly changing. Keeping one branch
   asset the whole time removes the mismatch instead of trying to match
   two independently-generated renderings pixel-for-pixel. Scoped to
   .has-empty-plate so sign-in's simpler two-layer crossfade is untouched. */
.illo-crossfade.has-empty-plate.is-settled .illo-sprite { opacity: 1; }

/* ─── click-to-call ──────────────────────────────────────────────────── */
/* .illo-call (pose-calling, transparent cut-out) overlays the settled
   painting on click — same alignment trick as the sprite cross-fade, since
   pose-calling was cut from the same source at the same size/angle as the
   plate's bird. Only the head changes, so it reads as the resting bird
   briefly opening its beak, not a layer swap. Clickable only once settled
   — see is-settled in JS. */
.illo-crossfade .illo-call {
  grid-area: 1 / 1; width: 100%; height: 100%; object-fit: contain;
  display: block; opacity: 0; pointer-events: none;
  transition: opacity 160ms ease;
}
.illo-crossfade.is-calling .illo-call { opacity: 1; }
/* the resting closed-beak bird must fully hand off to pose-calling during
   a call — leaving both at opacity 1 together is what showed as two
   overlapping birds */
.illo-crossfade.has-empty-plate.is-calling .illo-sprite { opacity: 0; }
.illo-crossfade.is-settled { cursor: pointer; }
@media (prefers-reduced-motion: reduce) {
  .illo-crossfade .illo-call { transition: none; }
}

/* A small hand-drawn ink swoosh near the beak — a visual echo of the
   chirp, not a literal waveform. Positioned by percentage of the crossfade
   box; approximate, since it only needs to read as "near the beak", not
   register pixel-perfect. Ink tone (--fg), never the accent — the
   illustration carries no accent marks of its own, per brand-spec. */
.illo-crossfade .song-mark {
  position: absolute; left: 21%; top: 12%; width: 34px; height: 34px;
  opacity: 0; transform: translateY(0) scale(0.7);
  pointer-events: none; color: var(--fg);
  transition: opacity 200ms ease, transform 200ms ease;
}
.illo-crossfade.is-calling .song-mark {
  opacity: 0.8; transform: translateY(-10px) scale(1.05);
  transition: opacity 550ms ease-out, transform 550ms ease-out;
}
@media (prefers-reduced-motion: reduce) {
  .illo-crossfade .song-mark { display: none; }
}

/* ─── feature cell ─────────────────────────────────────────────────── */
.feature .feature-mark {
  width: 34px; height: 34px; display: grid; place-items: center;
  border: 1px solid var(--border); border-radius: 9px; color: var(--fg);
  margin-bottom: var(--gap-md);
}
.feature .feature-mark svg { width: 17px; height: 17px; }
.feature h3 { margin-bottom: 6px; }
.feature p { margin: 0; color: var(--muted); font-size: 15px; }

/* ─── pill / tag ───────────────────────────────────────────────────── */
.pill {
  display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px;
  background: var(--fg-soft); color: var(--fg); border-radius: 999px;
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.05em; text-transform: uppercase;
}
.tag {
  display: inline-flex; align-items: center; padding: 3px 9px;
  color: var(--muted); border: 1px solid var(--border); border-radius: 999px;
  font-size: 12px; background: var(--surface);
}

/* ─── forms ────────────────────────────────────────────────────────── */
.field { display: flex; flex-direction: column; gap: 6px; }
.field label { font-size: 13px; color: var(--muted); }
/* --border-strong, not --border: this edge is the only thing showing where
   the field is, which puts it under the 3:1 non-text floor. A panel divider
   is decoration and keeps the lighter --border. */
.input, .textarea, .select {
  width: 100%; padding: 12px 14px; min-height: 44px;
  border: 1px solid var(--border-strong); border-radius: var(--radius);
  background: var(--surface); color: var(--fg); font: inherit; font-size: 15px;
}
.input::placeholder, .textarea::placeholder { color: var(--muted); }
.input:focus, .textarea:focus, .select:focus {
  outline: 0; border-color: var(--fg);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.textarea { min-height: 96px; resize: vertical; line-height: 1.55; }
.field-error { font-size: 13px; color: var(--fg); font-weight: 500; display: none; }
.field.invalid .input { border-color: var(--fg); }
.field.invalid .field-error { display: block; }

/* toggle switch — "on" is --fg, keeping the accent budget for one action */
.switch { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch .track {
  width: 38px; height: 22px; border-radius: 999px; background: var(--border);
  border: 1px solid var(--border); position: relative; transition: background 0.15s ease;
  flex: none;
}
.switch .track::after {
  content: ''; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px;
  border-radius: 50%; background: var(--surface); transition: transform 0.15s ease;
  box-shadow: 0 1px 2px var(--fg-line);
}
.switch input:checked + .track { background: var(--fg); border-color: var(--fg); }
.switch input:checked + .track::after { transform: translateX(16px); }
.switch input:focus-visible + .track { outline: 2px solid var(--fg); outline-offset: 2px; }
.switch .switch-label { font-size: 14px; }

/* ─── tabs ─────────────────────────────────────────────────────────── */
.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); }
.tab {
  appearance: none; background: transparent; border: 0; border-bottom: 2px solid transparent;
  padding: 10px 12px; min-height: 44px; font-size: 14px; color: var(--muted);
  transition: color 0.15s ease, border-color 0.15s ease;
}

/* pin 1. Links waiting for a verdict, counted on the tab that can settle them.
   Not a dot: a number says how much work it is, and a dot only says there is
   some. */
.tab-badge {
  display: inline-block;
  margin-left: 5px;
  padding: 0 6px;
  border-radius: 20px;
  background: color-mix(in oklch, var(--accent) 30%, transparent);
  font-family: var(--font-mono);
  font-size: 9.5px;
  color: var(--fg);
  vertical-align: 1px;
}
.tab:hover { color: var(--fg); }
.tab[aria-selected="true"] { color: var(--fg); border-bottom-color: var(--fg); font-weight: 550; }

/* ─── table ────────────────────────────────────────────────────────── */
.ds-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.ds-table th, .ds-table td { padding: 12px 14px; text-align: left; border-bottom: 1px solid var(--border); vertical-align: middle; }
.ds-table th { color: var(--muted); font-weight: 500; font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; }
.ds-table tbody tr:hover { background: var(--fg-soft); }
.ds-table .num-col { font-family: var(--font-mono); font-variant-numeric: tabular-nums; text-align: right; }

/* ─── filled bar (index coverage) ──────────────────────────────────── */
.bar { height: 8px; border-radius: 999px; background: var(--fg-soft); overflow: hidden; }
.bar-fill { height: 100%; background: var(--fg); border-radius: 999px; display: block; }
.bar-fill.is-partial { background: color-mix(in oklch, var(--fg) 42%, var(--bg)); }

/* ─── log row ──────────────────────────────────────────────────────── */
.log-row { display: grid; grid-template-columns: 130px 1fr 110px; gap: var(--gap-lg); padding: 22px 0; border-top: 1px solid var(--border); align-items: baseline; }
.log-row h3 { font-size: 18px; }
.log-row .pull { text-align: right; }
@media (max-width: 920px) { .log-row { grid-template-columns: 1fr; gap: 6px; } .log-row .pull { text-align: left; } }

/* ─── hero ─────────────────────────────────────────────────────────── */
.hero { padding-block: clamp(64px, 10vw, 132px); }
.hero-center { text-align: center; max-width: 34ch; margin-inline: auto; }
.hero h1 { margin-bottom: var(--gap-md); }
.hero .lead { margin-bottom: var(--gap-lg); }
.hero-cta { display: inline-flex; gap: var(--gap-sm); flex-wrap: wrap; align-items: center; }
.hero-center .hero-cta { justify-content: center; }
.hero-split { display: grid; grid-template-columns: 0.85fr 1.25fr; gap: var(--gap-xl); align-items: center; }
@media (max-width: 920px) { .hero-split { grid-template-columns: 1fr; gap: var(--gap-lg); } }

/* ═══ APP SHELL ════════════════════════════════════════════════════ */
.app { display: grid; grid-template-columns: var(--rail) 1fr; min-height: 100vh; }
.rail {
  border-right: 1px solid var(--border); background: var(--bg);
  display: flex; flex-direction: column; gap: var(--gap-md);
  padding: 18px 14px; position: sticky; top: 0; height: 100vh; overflow: hidden;
}
.rail-head { padding-inline: 6px; }
.rail-close { display: none; }
.rail-toggle { display: none; flex: none; align-items: center; gap: 6px; }
.rail-toggle svg { display: block; }
.rail-backdrop {
  display: none;
  position: fixed; inset: 0; z-index: 35;
  background: color-mix(in oklch, var(--fg) 34%, transparent);
  border: 0; padding: 0; cursor: pointer;
}
.rail-backdrop:not([hidden]) { display: block; }
.side-label {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--muted); padding: 0 8px 6px;
}
.side-nav { display: flex; flex-direction: column; gap: 2px; flex: none; }
.side-nav a {
  display: flex; align-items: center; gap: 10px; padding: 9px 10px;
  border-radius: 8px; font-size: 14px; color: var(--muted); min-height: 40px;
  border-left: 2px solid transparent; transition: background 0.15s ease, color 0.15s ease;
}
.side-nav a svg { width: 16px; height: 16px; flex: none; }
.side-nav a:hover { background: var(--fg-soft); color: var(--fg); }
.side-nav a[aria-current="page"] { background: var(--fg-soft); color: var(--fg); font-weight: 550; border-left-color: var(--fg); border-radius: 4px 8px 8px 4px; }
.thread-list { display: flex; flex-direction: column; gap: 1px; }
.thread {
  appearance: none; background: transparent; border: 0; text-align: left;
  padding: 8px 10px; border-radius: 8px; font-size: 13.5px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-height: 36px;
}
.thread:hover { background: var(--fg-soft); color: var(--fg); }
.thread[aria-current="true"] { background: var(--fg-soft); color: var(--fg); font-weight: 550; }
.meeting-row[aria-current="true"] { background: var(--fg); color: var(--bg); }
.meeting-row[aria-current="true"] .meeting-time { color: var(--bg); opacity: 0.7; }
.meeting-row[aria-current="true"] .meeting-title { color: var(--bg); }
.meeting-row[aria-current="true"] .meeting-dot { border-color: var(--bg); }
.meeting-row[aria-current="true"] .meeting-dot-active,
.meeting-row[aria-current="true"] .meeting-dot-past { background: var(--bg); border-color: var(--bg); }
.rail-hide-sm { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.meeting-search-section { display: flex; flex-direction: column; gap: var(--gap-sm); flex: none; }
.meeting-search-form { display: flex; align-items: center; gap: var(--gap-xs); margin: 0; }
.meeting-search-form .input { font-size: 13px; padding: 8px 12px; min-height: 36px; width: auto; flex: 1; min-width: 0; }
.meeting-search-form .btn { flex: none; }
/* The rail's four filters are one control, not four loose pills. As pills
   they wrapped onto a second line in a rail this narrow, which read as two
   unrelated groups; as equal segments of a single track they fit on one
   line and say plainly that picking one drops the others. */
.chip-row {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 2px;
  padding: 2px; border: 1px solid var(--border); border-radius: 999px;
  background: var(--surface);
}
.chip {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 5px 2px; min-width: 0;
  border: 0; border-radius: 999px;
  font-size: 10.5px; color: var(--muted); background: transparent;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  text-decoration: none; transition: background 0.15s ease, color 0.15s ease;
}
.chip:hover { color: var(--fg); background: var(--fg-soft); }
.chip-active, .chip[aria-current="true"] {
  background: var(--fg-soft); color: var(--fg); font-weight: 600;
}
.meeting-list-container {
  display: flex; flex-direction: column; gap: var(--gap-sm);
  flex: 1; min-height: 0; overflow-y: auto;
}
.meeting-agenda,
.meeting-day-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--gap-sm);
}
.meeting-day-list { gap: 1px; }
.meeting-agenda > li { display: flex; flex-direction: column; gap: 1px; }

.meeting-day-group { display: flex; flex-direction: column; gap: 1px; }
.meeting-row {
  display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 8px;
  padding: 8px 10px; border-radius: 8px; color: var(--fg); min-height: 36px;
}
.meeting-row:hover { background: var(--fg-soft); }
.meeting-row[aria-current="true"]:hover { background: var(--fg); }
.meeting-row-past { color: var(--muted); }
.meeting-dot {
  width: 6px; height: 6px; border-radius: 50%; flex: none; justify-self: end;
  border: 1px solid var(--fg); background: transparent;
}
.meeting-row-past .meeting-dot { border-color: var(--muted); }
.meeting-dot-active { background: var(--accent); border-color: var(--accent); }
.meeting-dot-past { width: 4px; height: 4px; border-width: 0; background: var(--muted); }
.meeting-title { font-size: 13.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
/* Demo only: what a seeded meeting is in the rail to show. Dropped into the
   title's column on a second grid row rather than wrapped around the title, so
   any row without a caption keeps the three-cell single-row grid unchanged. */
.meeting-use-case {
  grid-column: 2; grid-row: 2;
  font-size: 11px; line-height: 1.3; color: var(--muted);
  min-width: 0;
  /* Wraps to two lines rather than ellipsing on one. The title truncates
     because a long meeting name is still recognisable from its first words;
     this caption is a whole short sentence and "Ended today - prep, live and
     r..." explains nothing, which is the entire job it has. Two lines is the
     cap so a row cannot grow without bound. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.meeting-row-past .meeting-use-case { color: var(--muted); }
.meeting-row[aria-current="true"] .meeting-use-case { color: var(--bg); opacity: 0.72; }
.meeting-time {
  font-family: var(--font-mono); font-size: 11px; color: var(--muted);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.meeting-row-past .meeting-time, .meeting-row-past .meeting-title { color: var(--muted); }
.meeting-list-empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 32px 16px; gap: 8px;
}
.meeting-list-empty-title { font-size: 14px; font-weight: 550; margin: 0; color: var(--fg); }
.meeting-list-empty-text { font-size: 12px; margin: 0; line-height: 1.4; color: var(--muted); }
.meeting-list-empty a { text-decoration: underline; text-underline-offset: 2px; }
.meeting-list-cap {
  font-size: 12px; color: var(--muted); text-align: center;
  margin: 12px 0 0; padding: 0;
}
.rail-foot { margin-top: auto; border-top: 1px solid var(--border); padding-top: 12px; flex: none; }
.rail-foot-inner { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.rail-foot-inner .btn { flex: none; white-space: nowrap; }
.account { display: flex; align-items: center; gap: 10px; padding: 6px; min-width: 0; flex: 1; }
.account-text { min-width: 0; flex: 1; }
.account-name { font-family: var(--font-display); font-size: 13.5px; font-weight: 550; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.account-email { font-size: 11px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.avatar {
  width: 30px; height: 30px; border-radius: 50%; flex: none;
  background: var(--fg); color: var(--bg); display: grid; place-items: center;
  font-family: var(--font-mono); font-size: 12px;
}
.sign-out-error {
  font-size: 12px; margin-top: 8px; color: var(--fg); font-weight: 500;
  display: none;
}
.sign-out-error.is-visible { display: block; }

.app-main { display: flex; flex-direction: column; min-width: 0; }
.app-bar {
  position: sticky; top: 0; z-index: 15;
  display: flex; align-items: center; justify-content: space-between; gap: var(--gap-md);
  padding: 14px 28px; border-bottom: 1px solid var(--border);
  background: color-mix(in oklch, var(--bg) 88%, transparent); backdrop-filter: blur(12px);
}
/* A bar carrying nothing but the rail toggle, which is itself hidden above
   920px. Left as an ordinary .app-bar it drew an empty strip with a rule under
   it across the whole width. Collapsed to nothing where the toggle is hidden;
   the 920px block further down restores real padding where it is not. */
.app-bar-bare { padding: 0; border-bottom: 0; background: none; backdrop-filter: none; }
.meeting-ctx { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.meeting-ctx-title { font-family: var(--font-display); font-size: 16px; font-weight: 550; letter-spacing: -0.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* The topic describes the meeting, so it sits directly under the name of
   it, above the clock -- not sharing a row with the date. */
.meeting-ctx-topic-row { display: flex; align-items: center; min-width: 0; margin-top: 2px; }

/* The clock line and (Prep-only) the two counts worth carrying up here. */
.meeting-ctx-meta-row { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 12px; margin-top: 3px; }

.meeting-ctx-sub {
  font-size: 11px; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* pin 5. What the meeting is about, under the title that does not say. */
.meeting-ctx-topic {
  display: flex; align-items: baseline; gap: 6px;
  font-size: 11.5px; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.meeting-ctx-topic-label {
  font-size: 9.5px; letter-spacing: 0.06em;
  text-transform: uppercase; flex: none;
}
.meeting-ctx-topic-edit {
  flex: none; padding: 0; border: 0; background: none; font: inherit;
  color: var(--muted); text-decoration: underline; text-underline-offset: 2px;
  cursor: pointer;
}
.meeting-ctx-topic-edit:hover { color: var(--fg); }

.meeting-topic-pop {
  width: min(28rem, calc(100vw - 32px));
  padding: 14px 16px;
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--surface); color: var(--fg);
  box-shadow: 0 16px 40px color-mix(in oklch, var(--fg) 18%, transparent);
}
.meeting-topic-pop::backdrop {
  background: color-mix(in oklch, var(--fg) 28%, transparent);
}
.meeting-topic-lbl {
  display: block; margin-bottom: 6px;
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--muted);
}
.meeting-topic-pop .input { width: 100%; }
.meeting-topic-acts { display: flex; gap: 6px; margin-top: 10px; }
.meeting-topic-error { margin: 8px 0 0; font-size: 12px; color: #A2432A; }

.golive-form { margin: 0; flex: none; }
.golive-dot {
  width: 7px; height: 7px; border-radius: 50%; flex: none;
  border: 1px solid var(--fg); background: transparent;
}
.golive-btn.is-recording .golive-dot { background: var(--accent); border-color: var(--accent); }
.golive-error {
  font-size: 12px; margin: 0; padding: 8px 28px; color: var(--fg); font-weight: 500;
  visibility: hidden; opacity: 0;
  transition: opacity 0.2s;
}
.golive-error.is-visible { visibility: visible; opacity: 1; }
.golive-switch-actions {
  display: inline-flex;
  gap: 8px;
  margin-left: 10px;
  vertical-align: middle;
}
.golive-offer-root {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 40;
  max-width: min(360px, calc(100vw - 32px));
}
.golive-offer {
  background: var(--surface);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 16px;
  box-shadow: 0 10px 30px var(--fg-soft);
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.golive-offer-text {
  margin: 0;
  font-size: 14px;
  line-height: 1.4;
}
.golive-offer-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.tab { text-decoration: none; }
.tab[aria-current="page"] { color: var(--fg); border-bottom-color: var(--fg); font-weight: 550; }
.tab-empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 32px 16px; gap: 8px;
}
.tab-empty-title { font-size: 16px; font-weight: 550; margin: 0; color: var(--fg); }
.tab-empty-text { font-size: 14px; margin: 0; line-height: 1.4; color: var(--muted); max-width: 46ch; }
.tab-empty .btn { margin-top: 8px; }
.app-body { padding: 32px 28px 48px; flex: 1; min-width: 0; }

/* ── the calendar page fills the window, and does not scroll ──
   A month grid is a fixed amount of information: five or six rows the library
   distributes with flex. Handing it a pixel height made the document 1210px
   tall inside an 817px window, so the whole page scrolled -- past the grid, to
   reveal the chat box and the last week row. Constrained to the viewport, the
   rows share whatever height there is: taller on a big screen, and no page
   scrollbar on any.

   :has() rather than a modifier class because .app and .app-main come from
   base_app.html, which every screen shares -- this keeps the rule next to the
   one page it is about instead of adding a hook to all of them.

   Only above the rail's breakpoint. Below it the rail is a fixed overlay and
   the column really is taller than the window, so scrolling is correct there. */
@media (min-width: 921px) {
  .app:has(#cal-root) { height: 100vh; }
  .app:has(#cal-root) .app-main { min-height: 0; }
  .app:has(#cal-root) .app-body {
    display: flex; flex-direction: column; min-height: 0; overflow: hidden;
    padding-bottom: 28px;
  }
  .app:has(#cal-root) #cal-root { flex: 1 1 auto; min-height: 0; display: flex; }
  .app:has(#cal-root) #cal-root > section { max-width: 100%; }
}
.app-body-narrow { max-width: 780px; }
.app-bar-actions { display: flex; align-items: center; gap: 10px; flex: none; }

.settings-wrap {
  display: grid; grid-template-columns: 178px 1fr;
  flex: 1; min-height: 0;
}
.settings-nav {
  border-right: 1px solid var(--border); background: var(--surface);
  padding: 12px 10px 32px; display: flex; flex-direction: column; gap: 1px;
}
.settings-nav-group {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--muted); padding: 12px 6px 5px; margin: 0;
}
.settings-nav-group:first-child { padding-top: 0; }
.settings-nav a {
  display: block; font-size: 13px; padding: 6px 8px; border-radius: 6px;
  color: var(--fg); text-decoration: none;
}
.settings-nav a:hover { background: var(--fg-soft); }
.settings-nav a[aria-current="page"] { background: var(--fg-soft); font-weight: 550; }
.settings-main { padding: 16px 20px 32px; min-width: 0; }
.settings-pane-heading { font-size: 20px; margin: 0 0 8px; letter-spacing: -0.01em; }
.settings-pane-description { font-size: 14px; color: var(--muted); margin: 0 0 20px; max-width: 60ch; }
.settings-pane-body { font-size: 14.5px; max-width: 60ch; }
.settings-pane-body p { margin: 0; }
.settings-pane-body:has(.settings-all),
.settings-pane-body:has(.settings-manage) { max-width: none; }
.settings-all { max-width: none; display: flex; flex-direction: column; gap: 28px; }
.settings-block { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); padding: 14px 16px 16px; }
.settings-block-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-bottom: 10px;
}
.settings-block-label {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted); margin: 0;
}
.settings-source {
  display: grid; grid-template-columns: 12px 1fr auto auto; gap: 10px; align-items: center;
  padding: 8px 0; border-top: 1px solid var(--border); font-size: 13.5px;
}
.settings-source:first-of-type { border-top: 0; }
.settings-dot {
  width: 8px; height: 8px; border-radius: 50%; background: var(--fg); justify-self: center;
}
.settings-source.is-disconnected .settings-dot,
.settings-source.is-failed .settings-dot {
  background: transparent; border: 1px solid var(--fg);
}
.settings-source.is-failed .settings-dot { border-style: dashed; }
.settings-source-name { min-width: 0; }
.settings-source-detail { font-family: var(--font-mono); font-size: 11px; color: var(--muted); }
.settings-source.is-failed .settings-source-detail { color: var(--fg); }
.settings-source.is-disconnected .settings-source-name { color: var(--muted); }
.settings-stale { font-size: 12.5px; color: var(--muted); margin: 10px 0 0; }
.settings-pane-body .settings-stale,
.settings-pane-body .settings-note { margin: 10px 0 0; }
.settings-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 8px 0; border-top: 1px solid var(--border); font-size: 13.5px;
}
.settings-row:first-of-type { border-top: 0; }

/* pin 6. Where each kind of data goes, checkable in Settings rather than only
   readable as a label during a call. No path is drawn where there is no path:
   a fake folder under a dead Open button would claim local-only storage that
   is not happening. */
.settings-storage { margin: 0; padding: 0; list-style: none; }
.settings-storage-row {
  display: flex; flex-wrap: wrap; gap: 6px 16px;
  align-items: baseline; justify-content: space-between;
  padding: 9px 0; border-top: 1px solid var(--border);
}
.settings-storage-row:first-child { border-top: 0; }
.settings-storage-what { font-size: 14px; }
.settings-storage-detail {
  font-size: 12px; color: var(--muted); margin-top: 2px; max-width: 46ch;
}
.settings-storage-where {
  font-family: var(--font-mono); font-size: 11px; color: var(--muted);
  white-space: nowrap;
}
.settings-storage-path {
  font-family: var(--font-mono); font-size: 11px;
  padding: 2px 7px; border: 1px solid var(--border); border-radius: 5px;
  overflow-wrap: anywhere;
}
.settings-row .meta { font-size: 12px; }
.settings-connect-menu { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.settings-ical-form { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
/* An author `display` beats the UA stylesheet's [hidden] { display: none },
   so without these the connect menus and the iCal form were permanently
   expanded and their "+ connect" / "+ add" triggers toggled an attribute with
   no visual effect. */
.settings-connect-menu[hidden],
.settings-ical-form[hidden] { display: none; }
.settings-ical-form .input { min-height: 38px; padding-block: 8px; font-size: 14px; }
.settings-ical-error { font-size: 13px; color: var(--fg); font-weight: 500; margin: 0; }
.settings-note { font-size: 12.5px; color: var(--muted); margin: 10px 0 0; }
.settings-empty { font-size: 13.5px; color: var(--muted); margin: 0; }
.settings-manage { display: flex; flex-direction: column; gap: 14px; max-width: none; }
.settings-manage .input { min-height: 38px; padding-block: 8px; font-size: 14px; }
.settings-manage-toolbar {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
}
.settings-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.settings-chip {
  font-size: 12px; padding: 4px 10px; border: 1px solid var(--border); border-radius: 999px;
  background: transparent; color: var(--fg); cursor: pointer;
}
.settings-chip.is-on { background: var(--fg); color: var(--bg); border-color: var(--fg); }
.settings-bulk { display: flex; align-items: center; gap: 8px; }
.settings-bulk-count { font-size: 12px; color: var(--muted); }
.settings-file-table {
  border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface);
  overflow-x: auto; max-width: 100%;
}
.settings-filerow {
  display: grid; grid-template-columns: 28px minmax(120px, 1fr) 88px 64px 88px auto;
  gap: 10px; align-items: center; padding: 8px 12px; font-size: 13px;
  border-top: 1px solid var(--border); min-width: 520px;
}
.settings-filerow.is-head {
  border-top: 0; font-family: var(--font-mono); font-size: 10px;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted);
}
.settings-filerow.is-failed .settings-file-name { color: var(--muted); }
.settings-check { display: grid; place-items: center; }
.settings-file-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.settings-file-tag {
  font-size: 11px; border: 1px solid var(--border); border-radius: 999px;
  padding: 1px 8px; text-align: center;
}
.settings-file-tag.is-failed { border-style: dashed; color: var(--fg); }
.settings-file-mono { font-family: var(--font-mono); font-size: 11px; color: var(--muted); }
.settings-file-acts { display: flex; gap: 4px; justify-content: flex-end; }
.settings-drop {
  border: 1px dashed var(--border); border-radius: var(--radius); padding: 18px;
  text-align: center; font-size: 13.5px; color: var(--muted);
}
.settings-drop.is-over { border-color: var(--fg); color: var(--fg); }
.settings-drop-browse {
  background: none; border: 0; padding: 0; color: var(--fg);
  text-decoration: underline; text-underline-offset: 2px; cursor: pointer; font: inherit;
}

@media (max-width: 920px) {
  .app { grid-template-columns: 1fr; overflow-x: clip; }
  .app-main, .app-body, .settings-wrap, .settings-main { min-width: 0; max-width: 100%; }
  .rail {
    position: fixed; top: 0; left: 0; bottom: 0;
    width: min(var(--rail), 88vw); height: 100vh; z-index: 40;
    overflow: hidden; border-right: 1px solid var(--border); border-bottom: 0;
    transform: translateX(-105%);
    transition: transform 0.2s ease;
    visibility: hidden; pointer-events: none;
  }
  .rail.is-open {
    transform: translateX(0);
    visibility: visible; pointer-events: auto;
  }
  body.rail-open { overflow: hidden; }
  .rail-close, .rail-toggle { display: inline-flex; }
  /* The toggle is visible here, so the bare bar has something to hold. */
  .app-bar-bare { padding: 14px 28px; border-bottom: 1px solid var(--border); }
  .app-bar, .app-body { padding-inline: 20px; }
  .app-bar { flex-wrap: wrap; }
  .composer-foot { flex-wrap: wrap; }
  .settings-wrap { grid-template-columns: 1fr; }
  .settings-nav { border-right: 0; border-bottom: 1px solid var(--border); }
  #cal-root { overflow-x: auto; max-width: 100%; -webkit-overflow-scrolling: touch; }
}
@media (prefers-reduced-motion: reduce) {
  .rail { transition: none; }
}

/* ═══ CONVERSATION ═════════════════════════════════════════════════ */
.chat { display: flex; flex-direction: column; gap: 28px; max-width: 760px; }
.turn { display: grid; grid-template-columns: 30px 1fr; gap: 14px; align-items: start; }
.turn-mark {
  width: 30px; height: 30px; border-radius: 8px; display: grid; place-items: center;
  font-family: var(--font-mono); font-size: 11px; border: 1px solid var(--border); color: var(--muted);
}
.turn-user .turn-mark { background: var(--fg); border-color: var(--fg); color: var(--bg); }
.turn-body { min-width: 0; }
.turn-body p { margin: 0 0 12px; }
.turn-body p:last-child { margin-bottom: 0; }
.turn-user .turn-body { font-weight: 500; }
.cite {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 20px; padding: 0 6px; margin-left: 3px;
  border: 1px solid var(--border); border-radius: 5px; background: var(--surface);
  font-family: var(--font-mono); font-size: 11px; color: var(--muted);
  vertical-align: baseline; transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.cite:hover, .cite[aria-pressed="true"] { background: var(--fg); border-color: var(--fg); color: var(--bg); }
.turn-tools { display: flex; gap: 6px; margin-top: 14px; flex-wrap: wrap; }
.thinking { display: inline-flex; align-items: center; gap: 8px; color: var(--muted); font-size: 14px; }
.thinking .dot { width: 5px; height: 5px; border-radius: 50%; background: var(--muted); animation: pulse 1.1s ease-in-out infinite; }
.thinking .dot:nth-child(2) { animation-delay: 0.15s; }
.thinking .dot:nth-child(3) { animation-delay: 0.3s; }
@keyframes pulse { 0%, 100% { opacity: 0.25; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .thinking .dot { animation: none; opacity: 0.6; } }

.composer-wrap { position: sticky; bottom: 0; padding: 16px 28px 24px; background: linear-gradient(to top, var(--bg) 65%, transparent); }
.composer { max-width: 760px; border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface); padding: 12px 12px 10px; }
.composer:focus-within { border-color: var(--fg); box-shadow: 0 0 0 3px var(--accent-soft); }
.composer textarea {
  width: 100%; border: 0; outline: 0; resize: none; background: transparent;
  color: var(--fg); font: inherit; font-size: 15.5px; line-height: 1.5; min-height: 46px; padding: 4px 4px 8px;
}
.composer textarea::placeholder { color: var(--muted); }
.composer-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--gap-sm); }
.kbd {
  font-family: var(--font-mono); font-size: 11px; color: var(--muted);
  border: 1px solid var(--border); border-radius: 5px; padding: 1px 5px; background: var(--bg);
}
.starter {
  appearance: none; text-align: left; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 14px 16px; font-size: 14.5px; color: var(--fg); min-height: 44px;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.starter:hover { background: var(--fg-soft); border-color: var(--fg-line); }
.starter span { display: block; color: var(--muted); font-size: 13px; margin-top: 3px; }

/* ═══ SOURCE DRAWER ════════════════════════════════════════════════ */
.with-drawer { display: grid; grid-template-columns: 1fr 0; transition: grid-template-columns 0.22s ease; min-height: 0; }
.with-drawer.open { grid-template-columns: 1fr 360px; }
.drawer { border-left: 1px solid var(--border); background: var(--surface); overflow: hidden; min-width: 0; }
.drawer-inner { width: 360px; padding: 20px; height: 100%; overflow-y: auto; }
.drawer-quote { border-left: 2px solid var(--fg); padding-left: 14px; margin: 14px 0 0; font-size: 14.5px; color: var(--fg); }
@media (max-width: 920px) {
  .with-drawer, .with-drawer.open { grid-template-columns: 1fr; }
  .with-drawer:not(.open) .drawer { display: none; }
  .drawer { border-left: 0; border-top: 1px solid var(--border); }
  .drawer-inner { width: 100%; }
}
@media (prefers-reduced-motion: reduce) { .with-drawer { transition: none; } }

/* ═══ MODAL ════════════════════════════════════════════════════════ */
.modal[hidden] { display: none; }
.modal {
  position: fixed; inset: 0; z-index: 60;
  background: color-mix(in oklch, var(--fg) 34%, transparent);
  display: grid; place-items: center; padding: 20px;
}
.modal-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
  width: min(460px, 100%); max-height: 88vh; overflow-y: auto; padding: 26px;
  box-shadow: 0 24px 60px color-mix(in oklch, var(--fg) 18%, transparent);
}
.modal-card h2 { font-size: 22px; letter-spacing: -0.018em; }

/* ═══ MISC ═════════════════════════════════════════════════════════ */
.scope-row { display: flex; align-items: flex-start; gap: 12px; padding: 14px 0; border-top: 1px solid var(--border); }
.scope-row .scope-copy { flex: 1; min-width: 0; }
.scope-row h3 { font-size: 15px; }
.scope-row p { margin: 2px 0 0; color: var(--muted); font-size: 13.5px; }
.notice { border: 1px solid var(--border); border-radius: var(--radius); padding: 14px 16px; background: var(--surface); font-size: 13.5px; color: var(--muted); }
.notice strong { color: var(--fg); font-weight: 550; }
.center-page { min-height: 100vh; display: grid; grid-template-columns: 1fr 1fr; }
@media (max-width: 920px) { .center-page { grid-template-columns: 1fr; } }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* Demo-mode notice in Settings. Uses the accent at its usual soft strength so
   it reads as information, not as an error. */
.settings-demo-note {
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  background: var(--accent-soft);
  color: var(--fg);
  padding: var(--gap-sm) var(--gap-md);
  border-radius: var(--radius);
  margin-bottom: var(--gap-md);
  max-width: 68ch;
}
