/* Consilyn — Direction 1, single focus.
   UI contract: 03-decisions.md. The governing idea is one second of glance, so
   exactly one thing owns the screen and everything else is peripheral until it
   earns promotion.

   **Dressed like consilyn.com** (user, 2026-10-09): the site's paper, ink and teal,
   Inter for the interface and Newsreader for headings, rounded cards and pill
   buttons, so the app and the site read as one product. What is read aloud keeps
   its own faces and colours - the answer's fonts and looks were gated for reading
   cold (hard rule 5) and its colours are provenance (hard rule 4), so the theme
   stops at the edge of the answer. Teal is the brand on buttons and chrome; on an
   answer it still means only "your own words". */

@font-face {
  font-family: "Inter"; font-style: normal; font-weight: 100 900; font-display: swap;
  src: url("fonts/inter.woff2") format("woff2");
}
@font-face {
  font-family: "Newsreader"; font-style: normal; font-weight: 200 800; font-display: swap;
  src: url("fonts/newsreader.woff2") format("woff2");
}

:root {
  --ground: #F6F4EF;   /* the site's paper */
  --surface: #FFFFFF;
  --surface-2: #EEEAE1;
  --ink: #0E1A24;
  --ink-2: #44515E;
  --ink-3: #5F6A76;   /* 4.59 on --surface-2, 5.01 on --ground (AA) */
  /* Said already, no longer to be read. Far enough from --ink-2 that an unverified
     answer cannot be mistaken for it (user, 2026-09-22), and 3.09 on --surface-2,
     which is the AA floor for text this size. */
  --ink-said: #77828F;
  /* The answer changes its look on every new one, so a replacement is visible
     without reading a word (user, 2026-09-22). Look "a" is --ink / --ink-2. */
  --look-b-ink: #132A45;  --look-b-soft: #33506E;   /* cool */
  --look-c-ink: #2C1B0F;  --look-c-soft: #5E4630;   /* warm */
  --line: #E0DBD0;
  --line-strong: #C9C2B4;
  --verified: #0B6E62;
  --verified-bg: #DCEEE9;
  --unverified: #8A5A05;
  --unverified-bg: #F7EBD3;
  --clash: #A32118;
  --clash-bg: #F8E2E0;
  --live: #B3261E;
  --focus: #0B6E62;
  --brand: #0B6E62;
  --brand-hover: #095B51;
  --brand-ink: #FFFFFF;   /* 6.14 on --brand */
  --brand-soft: #DCEEE9;
  --shadow: 0 1px 2px rgba(14, 26, 36, .06), 0 12px 32px -12px rgba(14, 26, 36, .22);
  --shadow-lg: 0 2px 4px rgba(14, 26, 36, .05), 0 32px 64px -24px rgba(14, 26, 36, .35);
  --radius: 14px;
  --radius-sm: 10px;

  --font-ui: "Inter", "Segoe UI", system-ui, -apple-system, sans-serif;
  --font-display: "Newsreader", Georgia, "Times New Roman", serif;
  /* The sans face an answer can be set in (look b) stays the one it was gated in. */
  --font-sans-read: "Segoe UI", system-ui, -apple-system, sans-serif;
  --font-read: Georgia, "Times New Roman", serif;
  --font-read-alt: Cambria, Constantia, "Palatino Linotype", Georgia, serif;
  --font-data: "Cascadia Mono", Consolas, ui-monospace, monospace;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ground: #0B1117;
    --surface: #141C25;
    --surface-2: #1F2731;
    --ink: #E8ECF1;
    --ink-2: #A9B4C0;
    --ink-3: #8C99A6;   /* 5.19 on --surface-2 */
    --ink-said: #6B7886;   /* 3.34 on --surface-2 */
    --look-b-ink: #D3E7FA;  --look-b-soft: #93B4D4;
    --look-c-ink: #F6E7D2;  --look-c-soft: #C9B393;
    --line: #222E3A;
    --line-strong: #34414F;
    --verified: #5FCFBC;
    --verified-bg: #12332F;
    --unverified: #E3B25C;
    --unverified-bg: #33280F;
    --clash: #F0928A;
    --clash-bg: #3A1A17;
    --live: #F0928A;
    --focus: #5FCFBC;
    --brand: #5FCFBC;
    --brand-hover: #7DDBCB;
    --brand-ink: #06231F;   /* 8.78 on --brand */
    --brand-soft: #12332F;
    --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 12px 32px -12px rgba(0, 0, 0, .7);
    --shadow-lg: 0 2px 4px rgba(0, 0, 0, .4), 0 32px 64px -24px rgba(0, 0, 0, .8);
  }
}

:root[data-theme="dark"] {
  --ground: #0B1117;
  --surface: #141C25;
  --surface-2: #1F2731;
  --ink: #E8ECF1;
  --ink-2: #A9B4C0;
  --ink-3: #8C99A6;   /* 5.19 on --surface-2 */
  --ink-said: #6B7886;   /* 3.34 on --surface-2 */
  --look-b-ink: #D3E7FA;  --look-b-soft: #93B4D4;
  --look-c-ink: #F6E7D2;  --look-c-soft: #C9B393;
  --line: #222E3A;
  --line-strong: #34414F;
  --verified: #5FCFBC;
  --verified-bg: #12332F;
  --unverified: #E3B25C;
  --unverified-bg: #33280F;
  --clash: #F0928A;
  --clash-bg: #3A1A17;
  --live: #F0928A;
  --focus: #5FCFBC;
  --brand: #5FCFBC;
  --brand-hover: #7DDBCB;
  --brand-ink: #06231F;   /* 8.78 on --brand */
  --brand-soft: #12332F;
  --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 12px 32px -12px rgba(0, 0, 0, .7);
  --shadow-lg: 0 2px 4px rgba(0, 0, 0, .4), 0 32px 64px -24px rgba(0, 0, 0, .8);
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }

/* The site's buttons, a size smaller: an app is used at arm's length all day,
   a landing page is read once. Pills for actions, so they never look like fields. */
button {
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  min-height: 34px;
  padding: 6px 16px;
  cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
button:hover { background: var(--surface-2); border-color: var(--ink-3); }
button:active { transform: translateY(1px); }
button:disabled { opacity: .55; cursor: default; transform: none; }
button.primary { background: var(--brand); color: var(--brand-ink); border-color: var(--brand); }
button.primary:hover { background: var(--brand-hover); border-color: var(--brand-hover); }
button.danger { color: var(--clash); border-color: var(--clash); background: transparent; }

textarea, input[type="text"], input[type="password"] {
  font-family: inherit;
  font-size: 14px;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  padding: 9px 12px;
  width: 100%;
  transition: border-color .15s ease, box-shadow .15s ease;
}
textarea:focus, input[type="text"]:focus, input[type="password"]:focus, input[type="email"]:focus, select:focus {
  outline: none; border-color: var(--brand);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 22%, transparent);
}
textarea { font-family: var(--font-read); line-height: 1.5; resize: vertical; }

.hidden { display: none !important; }

/* ---------------------------------------------------------------- app shell */

#app { height: 100%; display: flex; flex-direction: column; }

.topbar {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  min-height: 60px; padding: 10px 20px;
  background: var(--ground);
  border-bottom: 1px solid var(--line);
}
.brand {
  /* An h1, so the page has a top-level heading for a screen reader (Stage 6).
     Every visual property below is what the span had. */
  margin: 0; display: inline-flex; align-items: center; gap: 10px;
  font: 600 20px/1 var(--font-display); letter-spacing: -.01em; }
.brand span { font: 400 14px/1 var(--font-ui); color: var(--ink-3); letter-spacing: 0; }
/* The site's mark: an ink tile, two lines of text, the second in "your own words" teal. */
.brand .mark {
  width: 26px; height: 26px; border-radius: 7px; background: var(--ink); position: relative; flex: none;
}
.brand .mark::before, .brand .mark::after { content: ""; position: absolute; left: 6.5px; height: 3px; border-radius: 2px; }
.brand .mark::before { top: 8px; width: 13px; background: var(--brand-soft); }
.brand .mark::after { top: 15px; width: 8.5px; background: #5FCFBC; }
.topbar .spacer { flex: 1; }

.client-name { font-weight: 600; font-size: 14px; }
.client-name em { font-style: normal; font-weight: 400; color: var(--ink-2); }

.live-dot {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--font-data); font-size: 11px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3);
}
.live-dot::before {
  content: ""; width: 8px; height: 8px; border-radius: 50%;
  background: var(--ink-3);
}
.live-dot.on { color: var(--live); }
.live-dot.on::before { background: var(--live); }

.timer {
  font-family: var(--font-data); font-size: 12px;
  color: var(--ink-2); font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------ intake screen */

.intake {
  flex: 1; overflow-y: auto;
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 16px; padding: 16px 20px 20px; background: var(--ground);
}
.intake > section {
  background: var(--surface); padding: 22px 24px; overflow-y: auto;
  border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow);
}

.panel-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; border-bottom: 1px solid var(--line);
  padding-bottom: 9px; margin-bottom: 16px;
}
.panel-head h2 { font: 500 22px/1.15 var(--font-display); letter-spacing: -.01em; margin: 0; }
.panel-head .hint { font-size: 12px; color: var(--ink-3); }

.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
.field label {
  font: 600 11px/1.3 var(--font-ui);
  letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3);
}

.row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
/* Not saved: the label and its note in the clash colour, which both themes define. */
.field.unsaved > label { color: var(--clash); }
.field.unsaved > label::after { content: " — not saved yet"; font-weight: 600; }
.field.unsaved > textarea { border-color: var(--clash); }
.hint.warn { color: var(--clash); font-weight: 600; }
.unsaved-dialog { max-width: 460px; border: 1px solid var(--clash); border-radius: var(--radius);
  background: var(--surface); color: var(--ink); padding: 22px 24px; box-shadow: var(--shadow-lg); }
.unsaved-dialog::backdrop { background: rgba(14, 26, 36, .45); }
.unsaved-head { color: var(--clash); font-weight: 700; margin: 0 0 8px; }
.plan-line { display: flex; gap: 12px; align-items: center; flex-wrap: wrap;
  padding: 10px 14px; margin: 0 0 12px; border: 1px solid var(--line-strong); border-radius: var(--radius-sm); }
.plan-line.refused { border-color: var(--clash); }
.plan-line.refused #plan-text { color: var(--clash); font-weight: 600; }
.setup-dialog { max-width: 580px; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--surface); color: var(--ink); padding: 26px 30px; box-shadow: var(--shadow-lg); }
.setup-dialog::backdrop { background: rgba(14, 26, 36, .45); }
.setup-head { padding-right: 44px; }
.setup-x { position: absolute; top: 14px; right: 14px; width: 36px; height: 36px; padding: 0;
  border-radius: 999px; border: 1px solid var(--line); background: transparent; color: var(--ink-2);
  font-family: inherit; font-size: 22px; line-height: 1; cursor: pointer; }
.setup-x:hover { color: var(--ink); border-color: var(--ink-2); }
.setup-dialog a { color: var(--brand); }
.setup-dialog .row { align-items: center; }
.setup-dialog .grow { flex: 1; }
.setup-head { font: 500 28px/1.1 var(--font-display); letter-spacing: -.015em; margin: 0 0 14px; }
.setup-step { font: 600 16px/1.3 var(--font-ui); margin: 22px 0 8px; }
/* What is already saved, said before anything asks for it again (user, 2026-10-09). */
.saved-box {
  margin: 0 0 12px; padding: 14px 16px; border-radius: var(--radius-sm);
  background: var(--brand-soft); border: 1px solid color-mix(in srgb, var(--brand) 35%, transparent);
}
.saved-box p { margin: 0 0 6px; }
.saved-box p b { color: var(--ink); }
.saved-box .row { margin-top: 8px; }
.setup-list { margin: 0; padding-left: 18px; }
.setup-list li { margin-bottom: 6px; }
.kind-pick { display: flex; gap: 16px; margin-bottom: 10px; font-size: 13px; }
.kind-pick label { display: flex; gap: 6px; align-items: center; cursor: pointer; }
.kind-tag { font-size: 11px; color: var(--ink-3); border: 1px solid var(--line-strong); border-radius: 999px; padding: 0 7px; margin-left: 8px; }
.attach { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.attach .hint { font-size: 12px; color: var(--ink-3); }

.client-list { list-style: none; margin: 0 0 16px; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.client-list li {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  transition: border-color .15s ease, background-color .15s ease;
}
.client-list li:hover { border-color: var(--line-strong); }
.client-list li.active { border-color: var(--brand); background: var(--brand-soft); }
.client-list .grow { flex: 1; min-width: 0; }
.client-list .meta { font-family: var(--font-data); font-size: 11px; color: var(--ink-3); }

/* parsed items */
.items { display: flex; flex-direction: column; gap: 12px; }
.item {
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 12px 14px; display: flex; flex-direction: column; gap: 7px;
}
.item.gap { border-left: 3px solid var(--unverified); }
.item.uncertain { border-left: 3px dashed var(--ink-3); }
.item-head { display: flex; align-items: center; gap: 9px; }
.item-num {
  font-family: var(--font-data); font-size: 11px; color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
.item input.q { font-weight: 600; }
.item textarea.a { min-height: 54px; }

/* ------------------------------------------------------- chips & provenance */

.chip {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--font-data); font-size: 10.5px;
  letter-spacing: .07em; text-transform: uppercase;
  padding: 3px 9px; border-radius: 6px; white-space: nowrap;
}
.chip-verified { background: var(--verified-bg); color: var(--verified); border: 1px solid var(--verified); }
.chip-solid { background: var(--verified); color: var(--surface); }
.chip-unverified { background: var(--unverified-bg); color: var(--unverified); border: 1px dashed var(--unverified); }
.chip-clash { background: var(--clash-bg); color: var(--clash); border: 1px solid var(--clash); }
.chip-muted { background: var(--surface-2); color: var(--ink-3); border: 1px solid var(--line); }

/* ---------------------------------------------------------- the live screen */

/* Rail is on the LEFT. A Zoom window occupies the right of a laptop screen more
   often than not, and the rail is the one element that must never be covered. */
.live { flex: 1; display: grid; grid-template-columns: minmax(0, 1fr); min-height: 0; }

.heard-label, .foot-item b {
  font-family: var(--font-data); font-size: 10px; font-weight: 500;
  letter-spacing: .13em; text-transform: uppercase; color: var(--ink-3);
  margin: 0;
}

.stage { display: flex; flex-direction: column; min-width: 0; min-height: 0; }

.heard {
  padding: 11px 22px; border-bottom: 1px solid var(--line);
  display: flex; gap: 12px; align-items: flex-start; background: var(--surface);
}
.heard-label { padding-top: 4px; white-space: nowrap; }
.heard-text { font-family: var(--font-read); font-size: 16px; color: var(--ink-2); margin: 0; }

/* Absent by default. Full width, only when there is genuinely a second thing
   worth knowing (M5: a figure said on the call disagrees with the consultant's
   screening answer). It lies over the heard line, so the card below never moves. */
.heard-slot { position: relative; }
.clash-bar {
  position: absolute; top: 0; left: 0; right: 0; min-height: 100%; z-index: 2;
  display: flex; align-items: center; gap: 12px; box-sizing: border-box;
  background: var(--clash-bg); border-bottom: 1px solid var(--clash);
  color: var(--clash); padding: 10px 22px; font-size: 16px; line-height: 1.4;
}
.clash-bar.hidden { display: none; }
.clash-text { margin: 0; flex: 1; }
.clash-bar b { font-weight: 700; }
.clash-close {
  border: 1px solid var(--clash); background: transparent; color: var(--clash);
  font-size: 18px; line-height: 1; padding: 2px 8px; cursor: pointer;
}

/* Quiet on purpose: it sits above a card being read aloud, so it must be
   readable at a glance and never pull the eye off the words. */
/* Two sections, asked for by the user on 2026-09-22: a line to say at once, then
   the answer under it when it arrives. The filler is set in the reading font
   because it is read aloud, and smaller than the card so the eye knows which is
   which. Once the answer lands it goes quiet rather than vanishing - a line
   disappearing out of the mouth of someone reading it is hard rule 5's failure. */
.working {
  padding: 10px 28px 12px; background: var(--surface-2); color: var(--ink-2);
  font-size: 13px; letter-spacing: 0.02em;
}
.working-head { display: flex; align-items: center; gap: 9px; }
.working-say {
  font-family: var(--font-read); font-size: 21px; line-height: 1.38;
  color: var(--ink); margin: 6px 0 0; max-width: 40ch; letter-spacing: 0;
}
/* Its own background, not the card's and not the heard line's, so the two sections
   are two blocks at a glance rather than one column of text (user, 2026-09-22: the
   difference in ink alone was not enough).

   **The line itself does not change when the answer lands.** Same words, same size,
   same colour - only the "Read this" label moves down to the answer. A set is one
   colour across both sections, so nothing here may repaint it, and resizing text
   someone is halfway through saying is the stumble hard rule 5 is about. */
.working.answered { background: var(--ground); }
.working.answered .dot { animation: none; opacity: 0.3; }
.working .dot {
  width: 8px; height: 8px; border-radius: 50%; background: var(--ink-3);
  animation: working-pulse 1.1s ease-in-out infinite;
}
@keyframes working-pulse { 0%, 100% { opacity: 0.25; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .working .dot { animation: none; opacity: 0.7; } }

/* M6. No transition on purpose (03-decisions.md): the change must be visible in
   the one-second glance of someone reading aloud, not fade in under their eye. */
.cut-in {
  padding: 8px 28px; background: var(--ink); color: var(--surface);
  font-size: 14px; font-weight: 600; letter-spacing: 0.02em;
}
.card.stale { opacity: 0.35; transition: none; }
.card {
  flex: 1; min-height: 0; overflow-y: auto;
  background: var(--surface);
  padding: 24px 28px 20px;
  display: flex; flex-direction: column; gap: 16px;
}
.prov { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }

/* **The answer names itself when it arrives.** With an opening line above it the
   card is no longer the only thing on screen, and the consultant has to see which
   block to switch to without reading either (user, 2026-09-22). The rule and the
   label appear only with a real answer, never over the empty state. */
/* **Structure, in the structure colour.** Not the verified green and not the
   unverified amber: those two say what an answer rests on (hard rule 4), and a
   green marker over an unverified answer would quietly contradict its own chip. */
.card.answered { border-top: 3px solid var(--ink); }
/* The same label in both sections, so "Read this" looks identical wherever it is
   and the eye can find it without reading it (user, 2026-09-22). */
.working-head.read-this, .answer-label {
  display: flex; align-items: center; gap: 9px;
  font-family: var(--font-data); font-size: 10.5px;
  letter-spacing: .14em; text-transform: uppercase; color: var(--ink);
}
.answer-label::before {
  content: ""; width: 9px; height: 9px; border-radius: 2px; background: var(--ink);
}
/* The band's own dot doubles as the label's square once there are words to read. */
.working-head.read-this .dot { border-radius: 2px; background: var(--ink); animation: none; opacity: 1; }
.working-head.read-this { color: var(--ink); }

/* Nothing on screen may exceed this in size or weight. It is read aloud, so it
   is set as prose rather than as UI text. */
.answer {
  font-family: var(--font-read);
  font-size: 27px; line-height: 1.42; letter-spacing: -.005em;
  /* 40ch, not 34: with one sentence to a line (2026-09-26) the narrower measure made a
     ninety-word card a third taller; at 40 it is about a tenth taller, still within a
     comfortable line length for reading aloud. */
  margin: 0; color: var(--ink); max-width: 40ch;
}
.answer.unverified { border-left: 3px dashed var(--unverified); padding-left: 14px; color: var(--ink-2); }

/* **Every new answer wears a different one of these**, so a card that has been
   replaced looks replaced before a word of it is read (user, 2026-09-22). The
   cycle is in app.js. Three rules hold them together: each is a face that can be
   read aloud cold at this size, none is lighter than the AA floor on the card
   (`tests/test_screen_looks.py` measures every one), and none borrows the
   verified green or the unverified amber, which mean something here. The soft
   variant keeps the unverified answer softer than a cited one in every look. */
.answer.look-b { font-family: var(--font-sans-read); color: var(--look-b-ink); letter-spacing: -.012em; }
.answer.unverified.look-b { color: var(--look-b-soft); }
.answer.look-c { font-family: var(--font-read-alt); color: var(--look-c-ink); }
.answer.unverified.look-c { color: var(--look-c-soft); }
/* The opening line wears the same look as the answer under it: one question, one
   colour, across both sections. */
.working.look-b .working-say { font-family: var(--font-sans-read); color: var(--look-b-ink); }
.working.look-c .working-say { font-family: var(--font-read-alt); color: var(--look-c-ink); }
/* One sentence to a line with a gap between them, so a wrapped line never reads as a
   new sentence and the eye can find its place after looking up (user, 2026-09-26).
   The first sentence is the direct answer, so it is a little heavier. Weight only:
   colour on the answer is provenance. */
.answer .sent, .working-say .sent { display: block; text-wrap: pretty; }   /* no one-word last lines */
.answer .sent + .sent { margin-top: .5em; }
.working-say .sent + .sent { margin-top: .3em; }
.answer .sent.lead { font-weight: 600; }
.answer .q { display: block; font-family: var(--font-ui); font-size: 13px; color: var(--ink-3); margin-bottom: 10px; }

.empty {
  font-family: var(--font-read); font-size: 20px; color: var(--ink-2);
  max-width: 40ch; margin: 0;
}
.empty .why { display: block; font-family: var(--font-ui); font-size: 13px; color: var(--ink-3); margin-top: 10px; }

.card-foot {
  margin-top: auto; border-top: 1px solid var(--line); padding-top: 12px;
  display: flex; gap: 26px; flex-wrap: wrap;
}
.foot-item { font-size: 12.5px; color: var(--ink-2); max-width: 36ch; }
.foot-item b { display: block; margin-bottom: 2px; }

.keys {
  border-top: 1px solid var(--line); background: var(--surface-2);
  padding: 7px 22px; display: flex; gap: 18px; flex-wrap: wrap;
  font-family: var(--font-data); font-size: 11px; color: var(--ink-3);
}
.keys kbd {
  font-family: inherit; background: var(--surface); border: 1px solid var(--line-strong);
  border-bottom-width: 2px; border-radius: 3px; padding: 1px 5px; color: var(--ink-2);
}

/* ------------------------------------------------------- the consent gate */

/* Deliberately a whole screen, not a checkbox. Listening cannot be reached from
   anywhere else, so this is the last thing between a client's voice and a
   microphone (CLAUDE.md hard rule 2). */
.gate {
  flex: 1; overflow-y: auto;
  display: flex; align-items: flex-start; justify-content: center;
  padding: 48px 24px;
}
.gate-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 30px 32px; max-width: 62ch; width: 100%; box-shadow: var(--shadow);
}
.gate-card h2 { font: 500 28px/1.15 var(--font-display); letter-spacing: -.015em; margin: 0 0 18px; }

/* Set in the reading face because it is a sentence about what you have said to
   another person, not a piece of interface. */
.gate-lead {
  font-family: var(--font-read); font-size: 19px; line-height: 1.45;
  margin: 0 0 14px; color: var(--ink);
  border-left: 3px solid var(--verified); padding-left: 14px;
}
.gate-note { margin: 0 0 20px; color: var(--ink-2); font-size: 13.5px; max-width: 54ch; }
.gate-actions { margin-top: 20px; }
.gate-mic {
  margin: 12px 0 0; font-size: 13px; color: var(--ink-2);
}
.gate-mic b { font-weight: 600; color: var(--ink); }
/* Folded away: the default is to follow the call, and a picker in plain sight
   reads as a question that has to be answered before every call. */
.gate-pick { margin: 10px 0 0; font-size: 13px; color: var(--ink-2); }
.gate-pick summary { cursor: pointer; color: var(--ink-3); }
.gate-pick label { display: block; margin: 12px 0 4px; }
.gate-pick select { width: 100%; max-width: 46ch; font-size: 13px; padding: 5px 6px; }
/* Amber, not red: something to fix before starting, not something broken. */
.gate-warning {
  margin: 0 0 18px; padding: 10px 12px; font-size: 13.5px; line-height: 1.45;
  background: var(--unverified-bg); border: 1px solid var(--unverified);
  color: var(--unverified); border-radius: var(--radius-sm); max-width: 58ch;
}
.gate-error {
  margin: 14px 0 0; padding: 10px 12px; font-size: 13.5px;
  background: var(--clash-bg); border: 1px solid var(--clash); color: var(--clash);
  border-radius: var(--radius-sm);
}

select {
  font-family: inherit; font-size: 14px; color: var(--ink);
  background: var(--surface); border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm); padding: 8px 12px; width: 100%;
}

/* Shown only when audio was actually lost. A permanent "0 dropped" teaches the
   eye to skip the whole strip, and then a real one goes unread. */
.keys .grow { flex: 1; }
.drops { color: var(--unverified); }

/* ------------------------------------------------------------- empty states */

.blank {
  flex: 1; display: flex; flex-direction: column; justify-content: center;
  align-items: flex-start; gap: 10px; padding: 40px 48px; max-width: 56ch;
}
.blank h2 { font: 500 30px/1.15 var(--font-display); letter-spacing: -.015em; margin: 0; }
.blank p { margin: 0; color: var(--ink-2); }

.toast {
  position: fixed; bottom: 18px; left: 50%; transform: translateX(-50%);
  background: var(--ink); color: var(--ground);
  padding: 10px 18px; border-radius: 999px; font-size: 13.5px; z-index: 20; box-shadow: var(--shadow);
}

@media (max-width: 1100px) {
  /* Stacked, each card is as tall as it needs and the page scrolls - two small
     scrolling boxes inside one window is the thing nobody can use. */
  .intake { grid-template-columns: 1fr; grid-auto-rows: max-content; }
  .intake > section { overflow: visible; }
}
/* A narrow window - Consilyn squeezed beside the call app, or a small screen (user,
   2026-10-09). Same screens, less chrome: the room goes to the words being read. The
   answer itself keeps its faces and colours; only the space around it shrinks. */
@media (max-width: 600px) {
  .topbar { padding: 8px 12px; gap: 6px 10px; min-height: 0; }
  .brand { font-size: 18px; }
  #mode-note { display: none; }
  /* "Not listening" and the clock mean nothing before a call; on a call both stay. */
  .live-dot:not(.on), .live-dot:not(.on) + .timer { display: none; }
  .topbar button { min-height: 32px; padding: 5px 12px; }
  .intake { padding: 10px; gap: 10px; }
  .intake > section { padding: 16px 14px; border-radius: 12px; }
  .panel-head { flex-wrap: wrap; }
  .panel-head h2 { font-size: 20px; }
  .heard { padding: 9px 14px; }
  .clash-bar { padding: 9px 14px; }
  .working { padding: 8px 14px 10px; }
  .cut-in { padding: 8px 14px; }
  .card { padding: 14px 14px 12px; gap: 12px; }
  .keys { padding: 6px 14px; }
  .gate { padding: 14px 10px; }
  .gate-card { padding: 20px 16px; }
  .gate-card h2 { font-size: 24px; }
  .setup-dialog { width: calc(100% - 16px); padding: 20px 16px; }
  .setup-head { font-size: 24px; }
  .fb-card { margin: 10px; padding: 14px 14px 12px; }
}
@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}

/* ------------------------------------- notices and the feedback card (2026-10-08)
   Intake only: hidden whenever the intake screen is, so nothing new can appear on
   the consent or live screens. */
#app:has(#screen-intake.hidden) .notices { display: none; }
/* Never more than about half the window: the intake below stays usable. */
.notices { display: flex; flex-direction: column; flex-shrink: 0; max-height: 52vh; overflow-y: auto; }
.banner {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 20px; font-size: 13.5px;
  background: var(--brand-soft); color: var(--ink); border-bottom: 1px solid var(--line);
}
.banner .grow { flex: 1; min-width: 220px; }
.fb-card {
  position: relative; margin: 12px 16px; padding: 16px 18px 14px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  max-width: 760px; box-shadow: var(--shadow);
}
.fb-card h2 { font: 500 22px/1.2 var(--font-display); margin: 0 28px 12px 0; }
.fb-close {
  position: absolute; top: 8px; right: 8px; border: none; background: transparent;
  font-size: 20px; line-height: 1; padding: 4px 8px; color: var(--ink-3);
}
.fb-choices { display: flex; gap: 8px; flex-wrap: wrap; }
.fb-choice {
  display: inline-flex; flex-direction: column; align-items: center; gap: 4px;
  min-width: 96px; padding: 8px 10px; font-weight: 600; border-radius: var(--radius-sm);
}
.fb-choice .face { font-size: 26px; line-height: 1; }
.fb-choice .label { font-size: 12px; font-weight: 600; color: var(--ink-2); }
.fb-choice[aria-pressed="true"] { border-color: var(--verified); background: var(--verified-bg); }
.fb-choice[aria-pressed="true"] .label { color: var(--verified); }
@media (prefers-reduced-motion: no-preference) {
  .fb-choice:hover .face { transform: scale(1.15); transition: transform .12s; }
}
.fb-q { margin: 14px 0 6px; font-size: 13px; font-weight: 600; color: var(--ink-2); }
.fb-tags { display: flex; gap: 6px; flex-wrap: wrap; }
.fb-tag { font-weight: 500; border-radius: 999px; padding: 5px 12px; }
.fb-tag[aria-pressed="true"] { border-color: var(--verified); background: var(--verified-bg); color: var(--verified); }
.fb-more { margin-top: 12px; display: grid; gap: 8px; }
@media (min-width: 900px) {
  .fb-more { grid-template-columns: 1fr 1fr; }
  .fb-more > .row, .fb-more > #fb-email-wrap { grid-column: 1 / -1; }
  .fb-more:has(#fb-idea-wrap.hidden) #fb-comment-wrap { grid-column: 1 / -1; }
}
.fb-more .field { margin: 0; }
.fb-more textarea { font-family: var(--font-ui); font-size: 13px; }
.fb-thanks { margin: 6px 0 0; font-size: 14px; }
input[type="email"] {
  font-family: inherit; font-size: 14px; color: var(--ink); background: var(--surface);
  border: 1px solid var(--line-strong); border-radius: var(--radius-sm); padding: 9px 12px; width: 100%;
}
.check { display: flex; gap: 8px; align-items: flex-start; font-size: 13px; margin: 4px 0 10px; }

/* M4: prepared answers on the client page. Quiet: it is preparation, not the call. */
.prepare { margin-top: 24px; }
.prepare .hint { display: block; }
#prepare-status { display: inline; }
.prepared-list { list-style: none; margin: 8px 0 0; padding: 0; border-top: 1px solid var(--line); }
.prepared-list li { padding: 10px 0; border-bottom: 1px solid var(--line); }
.prepared-q { display: flex; justify-content: space-between; gap: 12px; font-weight: 600; }
.prepared-a { margin: 4px 0 0; color: var(--ink-2); line-height: 1.45; }
.prepared-del {
  border: 1px solid var(--line-strong); background: transparent; color: var(--ink-2);
  font-size: 16px; line-height: 1; padding: 1px 7px; cursor: pointer; flex: none;
}
#prepared-list-wrap summary { cursor: pointer; color: var(--ink-2); }
/* Advice before the call, not an answer: neutral, so it borrows neither provenance colour. */
.readiness { margin: 0 0 12px; padding: 12px 14px; background: var(--surface-2); border-left: 3px solid var(--line-strong); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.readiness-head { margin: 0 0 4px; font-weight: 600; color: var(--ink); }
.readiness ul { margin: 0; padding-left: 18px; color: var(--ink); line-height: 1.45; }
.readiness li + li { margin-top: 4px; }
