/* Parchment and ink. Every value here comes from docs/05-design-system.md;
   none is invented at the point of use. Dark mode is required, not optional. */

/* Self-hosted, not CDN (docs/05-design-system.md). Latin subsets only: the
   platform is English-only (ADR-0028), so the Devanagari face that file names
   is not carried until there is Hindi to set. */
@font-face {
  font-family: Inter;
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("../fonts/inter-400-600.260c81a4759b.woff2") format("woff2");
}
@font-face {
  font-family: "STIX Two Text";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/stix-two-text-400.50787b9fd0c0.woff2") format("woff2");
}
@font-face {
  font-family: "STIX Two Text";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/stix-two-text-600.50787b9fd0c0.woff2") format("woff2");
}
/* The name, and only the name. Geometric, so the wordmark reads as a mark
   rather than as a sentence — the shape a product logo has (ADR-0061). */
@font-face {
  font-family: Poppins;
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/poppins-500.a09f2fccfee3.woff2") format("woff2");
}
@font-face {
  font-family: Poppins;
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/poppins-600.72993dddf88a.woff2") format("woff2");
}

/* Light is parchment and ink; dark is the same at night. Either follows the
   system until the teacher picks one with the switch, which sets
   `data-theme` on the page before it paints (spec 022). */
:root {
  --bg: #f2ece0;
  --surface: #fbf7ee;
  --border: #e0d6c4;
  --border-strong: #cfc2ab;
  --text: #241f18;
  --text-muted: #6d6455;
  --text-placeholder: #767060;
  --accent: #8c3a2b;
  /* A destructive action, and only that (docs/05's error colour). Measured
     against both backgrounds: 6.1:1 and 5.6:1. */
  --danger: #a33a2c;

  --space-1: 4px;  --space-2: 8px;  --space-3: 12px; --space-4: 16px;
  --space-6: 24px; --space-8: 32px; --space-12: 48px; --space-16: 64px;

  --radius: 6px;
  --radius-card: 8px;
  /* Every control a teacher presses or types into. A card is not a
     control and keeps `--radius-card`. */
  --radius-control: 999px;

  /* The browser's own parts — scrollbars, checkboxes, file pickers — follow
     the scheme and the accent instead of staying white and blue. */
  color-scheme: light;
  accent-color: var(--accent);

  --ui: Inter, system-ui, -apple-system, "Segoe UI", sans-serif;
  --serif: "STIX Two Text", Georgia, serif;
  --brand: Poppins, Inter, system-ui, sans-serif;
}

/* The dark tokens twice: once for a system that asks for dark and a teacher
   who has not said otherwise, once for a teacher who chose it. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #1a1713;
    --surface: #232019;
    --border: #3a342b;
    --border-strong: #4a4238;
    --text: #efe8db;
    --text-muted: #a19785;
    --text-placeholder: #a19785;
    --accent: #d98d76;
    --danger: #e0806f;  /* 6.4:1 and 5.8:1 */
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --bg: #1a1713;
  --surface: #232019;
  --border: #3a342b;
  --border-strong: #4a4238;
  --text: #efe8db;
  --text-muted: #a19785;
  --text-placeholder: #a19785;
  --accent: #d98d76;
  --danger: #e0806f;
  color-scheme: dark;
}

/* The switch shows what pressing it does: the sun in the dark, the moon in
   the light. */
.to-light { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .to-light { display: contents; }
  :root:not([data-theme="light"]) .to-dark { display: none; }
}
:root[data-theme="dark"] .to-light { display: contents; }
:root[data-theme="dark"] .to-dark { display: none; }

/* An icon sits on the text's line and takes its colour. */
.icon { flex: none; vertical-align: -0.2em; }

*, *::before, *::after { box-sizing: border-box; }
* { scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }

/* Moving between pages fades rather than flashes (spec 022; the motion rule
   in docs/05). Chrome and Edge; elsewhere a page simply arrives. */
@view-transition { navigation: auto; }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: 150ms; }

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

h1, h2 { font-family: var(--serif); font-weight: 600; line-height: 1.2; margin: 0; }
h1 { font-size: 30px; letter-spacing: -0.01em; }
h2 { font-size: 20px; }

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

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

/* The wordmark: the nib, then the name. Used on the sign-in page and in the
   masthead, at two sizes. */
.mark { display: flex; align-items: center; gap: var(--space-3); }
.mark svg { flex: none; color: var(--accent); }
.mark span { font-family: var(--brand); font-weight: 600; letter-spacing: -0.02em;
             white-space: nowrap; }
.mark-stacked { flex-direction: column; gap: var(--space-4); }

.centred {
  position: relative;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-12);
  padding: var(--space-6);
}

.masthead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-6);
  border-bottom: 1px solid var(--border);
}

main { max-width: 640px; margin: 0 auto; padding: var(--space-12) var(--space-6); }
main.wide { max-width: 1000px; }

.crumbs { display: flex; align-items: center; gap: var(--space-3); min-width: 0; }
.crumbs .sep { color: var(--border-strong); }
.crumbs .here { font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.state { font-size: 14px; color: var(--text-muted); white-space: nowrap; }
/* "Typesetting" at the head of the chat only while the paper is put away:
   with it open, the sheet setting itself says so. */
.app:not(.doc-closed).has-doc .chat-head .state { visibility: hidden; }

.titlerow { display: flex; justify-content: space-between; align-items: flex-end;
            gap: var(--space-4); margin-bottom: var(--space-8); }
.titlerow p { margin: var(--space-2) 0 0; }

.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
         gap: var(--space-6); }

.card {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  color: inherit;
  text-decoration: none;
  transition: border-color 150ms ease-out;
}
.card:hover { border-color: var(--border-strong); text-decoration: none; }
.card:hover .cardname { color: var(--accent); }
.cardname { font-weight: 500; }

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  min-height: 44px;
  padding: 0 var(--space-6);
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-control);
  font: 500 15px var(--ui);
  white-space: nowrap;
  cursor: pointer;
  transition: background 150ms ease-out, border-color 150ms ease-out;
}
.button:hover { background: var(--bg); border-color: var(--text-muted); }
.button:active { background: var(--border); }
.button[disabled] { opacity: 0.5; cursor: not-allowed; }
/* `hidden` is a UA `display: none`, and any author `display` beats it — which
   is every button here, since they are all `inline-flex`. Without this the
   Download button stayed on screen when the tab it belongs to had nothing to
   download. */
[hidden] { display: none !important; }

.button-quiet {
  background: none;
  border-color: var(--border);
  padding: 0 var(--space-4);
  font-size: 14px;
  color: var(--text-muted);
}
.button-quiet:hover { color: var(--text); background: var(--surface); }

/* The only destructive control in the product. It was the filled accent,
   which is what every primary button is — "Delete this chat" looked exactly
   like "Send" (spec 022). Now it is the palette's error colour, outlined, and
   filled only when pointed at: never the thing the eye lands on first. */
.button-danger { background: none; color: var(--danger); border-color: var(--danger); }
.button-danger:hover { background: var(--danger); border-color: var(--danger); color: var(--surface); }

/* The one thing a new teacher is asked. Sized to the sign-in page beside it,
   because it is the same moment continued. */
.onboard { width: 100%; max-width: 26rem; display: flex;
           flex-direction: column; gap: var(--space-4); }
.onboard .decide { justify-content: flex-start; }

/* A page that asks one question and takes one answer. */
.narrow { max-width: 42rem; margin: 0 auto; padding: var(--space-8) var(--space-6); }
.going { margin: 0; padding-left: var(--space-6); display: flex;
         flex-direction: column; gap: var(--space-2); font-size: 15px; }


.field { display: flex; flex-direction: column; gap: var(--space-2); }
.field label { font-size: 14px; font-weight: 500; color: var(--text-muted); }

/* A pill, like the composer. The horizontal padding grows with the curve —
   text set hard against a rounded edge reads as a mistake. */
input[type="text"] {
  min-height: 44px;
  padding: 0 var(--space-4);
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-control);
  font: 400 16px var(--ui);
}
input[type="file"] {
  min-height: 44px; padding: var(--space-2) var(--space-4);
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border-strong); border-radius: var(--radius-control);
  font: 400 15px var(--ui); width: 100%;
}
/* The browser's own button inside it, which is square by default and looks it
   next to everything else here. */
input[type="file"]::file-selector-button {
  margin-right: var(--space-3); min-height: 30px; padding: 0 var(--space-4);
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border-strong); border-radius: var(--radius-control);
  font: 500 14px var(--ui); cursor: pointer;
}
input[type="file"]::file-selector-button:hover { border-color: var(--text-muted); }
input[type="text"]::placeholder { color: var(--text-placeholder); }


.muted { color: var(--text-muted); font-size: 14px; }

.notice {
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border-strong);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  background: var(--surface);
  font-size: 14px;
}

@media (prefers-reduced-motion: reduce) {
  /* Animations as well as transitions: the sign-in page writes itself with
     keyframes, and clamping only `transition-duration` would have left the
     whole of it running for someone who asked for no motion. */
  * { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important;
      animation-delay: 0ms !important; animation-iteration-count: 1 !important; }
  @view-transition { navigation: none; }
}

/* --- Signing in ----------------------------------------------------------- */
/* Static. There was a nib that wrote the name a stroke at a time; it went
   because the letterforms it needed were a single-stroke plotter face from the
   1960s, and no font a wordmark would actually want can be drawn that way —
   an ordinary font is filled contours, not the path of a pen (ADR-0061). */

.beta {
  position: absolute; top: var(--space-4); left: 0; right: 0;
  margin: 0; text-align: center;
  font: 500 12px var(--ui); letter-spacing: .1em; text-transform: uppercase;
  color: var(--text-muted);
}

.signature { display: flex; flex-direction: column; align-items: center; gap: var(--space-4); }
.signature .resting { color: var(--accent); }

/* Sized against the one on google.com, measured rather than guessed: 270x82px
   of ink there. 82px of Poppins gives 83px of ink — the same wordmark height,
   though a longer word so a wider one. `clamp` because a fixed 82px is most of
   a phone’s width. */
.wordmark {
  margin: 0; font-family: var(--brand); font-weight: 600;
  font-size: clamp(44px, 10vw, 82px); line-height: 1.05;
  letter-spacing: -0.035em; color: var(--text); white-space: nowrap;
}
.tagline {
  margin: 0; font-family: var(--ui); font-weight: 400;
  font-size: clamp(15px, 3.4vw, 19px); color: var(--text-muted);
}

/* --- The application shell ------------------------------------------------ */
/* A side menu, a conversation, and the paper being read. The conversation sits
   in the middle of the window until there is something to read, and moves
   aside when there is — the paper is the point, and it should be on screen
   while the teacher talks about it rather than downloaded and opened. */

.app {
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr);
  height: 100vh;
  overflow: hidden;
}
.app.sidebar-closed { grid-template-columns: 0 minmax(0, 1fr); }

.sidebar {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-4);
  background: var(--surface);
  border-right: 1px solid var(--border);
  overflow: hidden;
  min-width: 0;
  white-space: nowrap;
}
.app.sidebar-closed .sidebar { padding: 0; border-right: none; }
.sidebar-top { margin-bottom: var(--space-4); }
.side-list {
  flex: 1; overflow-y: auto; margin-top: var(--space-4);
  display: flex; flex-direction: column; gap: 1px;
}

/* A chat is a link, a rename control and the form that renames it, sharing one
   slot. The pencil appears on hover or when the row is focused within, so the
   menu stays a list of names rather than a list of controls. */
.chatrow { position: relative; display: flex; align-items: center; }
.chatrow .side-chat {
  flex: 1; min-width: 0; font-size: 13px; color: var(--text-muted);
  display: flex; flex-direction: column; gap: 1px;
}
.chatname { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chatmeta { font-size: 11px; color: var(--text-muted); overflow: hidden;
            text-overflow: ellipsis; white-space: nowrap; }
/* Today, This week: headed; Earlier is the fold below them. */
.side-group {
  padding: var(--space-3) var(--space-3) var(--space-1);
  font-size: 11px; font-weight: 500; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--text-muted);
}
.chatrow.on .side-chat { background: var(--bg); color: var(--text); }
.chatrow:hover .side-chat { background: var(--bg); }

/* Rename and delete sit over the end of the row and appear on hover, so a
   sidebar at rest is a list of names and nothing else. Delete is the inner of
   the two: the outer edge is where a hand lands by default, and that should
   not be the irreversible one. */
.rowaction {
  position: absolute;
  width: 26px; height: 26px; display: none; place-items: center;
  background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-control);
  color: var(--text-muted); font-size: 12px; cursor: pointer;
  text-decoration: none;
}
.rename-open { right: 4px; }
.chat-delete { right: 34px; }
.chatrow:hover .rowaction, .chatrow:focus-within .rowaction { display: grid; }
.rowaction:hover { color: var(--text); border-color: var(--border-strong); }
.chat-delete:hover { color: var(--accent); border-color: var(--accent); }

.rename { display: none; width: 100%; gap: 2px; }
.chatrow.naming .rename { display: flex; }
.chatrow.naming .side-chat, .chatrow.naming .rowaction { display: none; }
.rename input[type="text"] {
  flex: 1; min-width: 0; min-height: 30px; font-size: 13px;
  padding: 0 var(--space-2);
}
.rename-save {
  width: 30px; display: grid; place-items: center;
  background: var(--bg); border: 1px solid var(--border-strong);
  border-radius: var(--radius-control); color: var(--text-muted); cursor: pointer;
}
/* No JavaScript: the form is the row, and renaming still works. */
.no-js .rename { display: flex; }
.no-js .rename-open { display: none; }

/* The older chats, folded away. `<details>` rather than a script — the browser
   already has this control and it is keyboard-operable for free. */
.earlier { margin-top: var(--space-3); }
.earlier > summary {
  list-style: none; cursor: pointer;
  padding: var(--space-2) var(--space-3); border-radius: var(--radius-control);
  font-size: 12px; font-weight: 500; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--text-muted);
}
.earlier > summary::-webkit-details-marker { display: none; }
.earlier > summary::before { content: "▸ "; }
.earlier[open] > summary::before { content: "▾ "; }
.earlier > summary:hover { color: var(--text); background: var(--bg); }

/* Every paper this chat produced, switchable. Nothing generated is lost by
   asking for something else. */
.artefacts { display: flex; gap: var(--space-1); margin-right: var(--space-3); }

.side-item {
  display: block;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-control);
  color: var(--text);
  font-size: 14px;
  text-decoration: none;
}
.side-item:hover { background: var(--bg); text-decoration: none; }
/* A row with an icon: New paper, the switch, Account, Sign out. */
.side-foot .side-item { display: flex; align-items: center; gap: var(--space-3); }
.side-foot .side-item .icon { color: var(--text-muted); }

/* The light/dark switch where there is no side menu: the pages before
   signing in. */
.corner { position: absolute; top: var(--space-3); right: var(--space-3); z-index: 2; }
/* The one thing a teacher comes to do, as a button across the menu, in the
   accent Send uses (Prateek, 30 Sep 2026). */
.side-new { width: 100%; min-height: 40px; text-decoration: none; }
.side-new:hover { text-decoration: none; }
.side-left { margin: var(--space-2) 0 0; text-align: center; font-size: 12px;
             color: var(--text-muted); }
/* Sign out is a button in a form and Account is a link; `display: block` and a
   full width make the pair sit as two rows of the same shape. */
.side-button {
  display: block; width: 100%; text-align: left;
  background: none; border: none;
  font-family: var(--ui); cursor: pointer; color: var(--text-muted);
}
.side-foot { margin: 0; display: flex; flex-direction: column; }
.side-foot form { margin: 0; }

.stage {
  position: relative;
  display: flex;
  min-width: 0;
  overflow: hidden;
}

.sidebar-toggle {
  position: absolute; top: var(--space-3); left: var(--space-3); z-index: 2;
}
.iconbutton {
  width: 32px; height: 32px; display: grid; place-items: center;
  background: none; border: 1px solid transparent; border-radius: var(--radius-control);
  color: var(--text-muted); font-size: 15px; cursor: pointer;
}
.iconbutton:hover { background: var(--surface); border-color: var(--border); color: var(--text); }

/* The conversation. Centred and narrow on its own; a fixed, draggable width
   once there is a paper beside it. */
.chat {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1;
  max-width: 780px;
  margin: 0 auto;
  padding: var(--space-6);
  gap: var(--space-6);
}
.has-doc .chat {
  flex: 0 0 var(--chat-width, 44%);
  max-width: none;
  margin: 0;
}

.chat-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--space-4); padding-left: 40px; min-height: 32px;
}
.chat-head .here { font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 17px, not the 16px the rest of the chrome uses. The transcript is the one
   thing on this screen a teacher reads rather than scans, and it is what the
   product sounds like. */
.transcript {
  font-size: 17px; line-height: 1.55;
  flex: 1; min-height: 0; overflow-y: auto;
  display: flex; flex-direction: column; gap: var(--space-6);
  padding-right: var(--space-2);
}
/* An empty chat is a greeting and somewhere to type, sitting together rather
   than pinned to the top and bottom of the space.

   Together, but **above** the middle, not on it. Measured against google.com,
   which is the same screen — a mark and one box to type in: its logo sits at
   33% of the viewport and its search box at 43%. Ours centred the pair, which
   put the box at 60%, low enough that Prateek noticed before any of this was
   measured. The padding is on the bottom because the group is centred in what
   is left, so half of it is how far the pair rises. */
.chat.blank .transcript { flex: 0 1 auto; justify-content: flex-end; overflow: visible; }
.chat.blank { justify-content: center; padding-bottom: 33vh; }


.greeting {
  display: flex; align-items: center; justify-content: center;
  gap: var(--space-4); padding: var(--space-8) 0 var(--space-4);
  color: var(--accent);
}
/* The nib centred on the capitals of the greeting, not on its line box: the
   line box carries the descenders' room, which set the nib 0.1em low
   (measured, 30 Sep 2026). Sized in the heading's own units, so it holds at
   every width the heading takes. */
.greeting-mark {
  display: flex; font-size: clamp(34px, 5.2vw, 46px);
  transform: translateY(-0.1em);
}
.greeting h1 {
  margin: 0; font-family: var(--serif); font-weight: 600;
  font-size: clamp(34px, 5.2vw, 46px);
  letter-spacing: -0.015em; color: var(--text);
}

.said {
  align-self: flex-end; max-width: 30rem; margin: 0;
  white-space: pre-line;  /* the lines they typed with Shift+Enter */
  padding: var(--space-3) var(--space-4);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-card);
}
.reply { margin: 0; max-width: 40rem; }
/* "Thinking", with light passing over it, until the first words arrive and
   take its place (spec 022). With reduced motion it is simply the word. */
.reply.waiting {
  width: fit-content;
  background: linear-gradient(90deg, var(--text-muted) 0%, var(--text) 50%, var(--text-muted) 100%);
  background-size: 200% 100%;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: shimmer 1.6s linear infinite;
}
@keyframes shimmer { from { background-position: 100% 0; } to { background-position: -100% 0; } }

/* The answers to the last reply's question, as buttons (spec 020): under the
   reply they answer, in the same quiet chips as the sheet options, wrapping
   on a phone. The first is the likely one and carries the accent. */
.answers { display: flex; flex-wrap: wrap; gap: var(--space-2); max-width: 40rem; }
.answers form { margin: 0; }
.answers form:first-child .chip { color: var(--accent); border-color: var(--accent); }

/* The one place a teacher types a sentence, so it is shaped like somewhere to
   type a sentence rather than like a form field. Measured on google.com, the
   same screen doing the same job: a 686x50px shell at a 26px radius, which is
   half its height plus a hair — a pill. `999px` gets that at any height rather
   than pinning it to this one.

   **The form is the box; the input inside it has no box of its own.** Send
   sits inside on the right, where a thumb goes and where every chat a teacher
   already uses puts it. That means the border, the background and the focus
   ring all belong to the form — and the focus ring has to be `:focus-within`,
   or typing would light nothing up at all.

   Only here. `--radius: 6px` still governs every other field and button
   (docs/05-design-system.md); a product where everything is a pill has no way
   left to say that this is the thing to type in. */
/* A pill while it is one line — the radius is half its 52px — that grows into
   a rounded box as Shift+Enter adds lines (Prateek, 29 Sep 2026), rather than
   a stadium whose curve would cut into the text. Send stays at the foot,
   beside the line being typed. */
.composer {
  display: flex; align-items: flex-end; gap: var(--space-2);
  min-height: 52px; padding: 5px var(--space-2) 5px var(--space-6);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: 26px;
  transition: border-color 150ms ease-out;
}
.composer:focus-within { border-color: var(--accent); }
/* The field keeps the form's shape and gives up its own. It is as tall as
   what is typed (`field-sizing`; app.js does it where that is missing), up to
   about eight lines, then scrolls. */
.composer textarea {
  flex: 1; min-width: 0; min-height: 0;
  font: inherit; font-size: 17px; line-height: 1.5; padding: 8px 0;
  max-height: 14rem; overflow-y: auto; resize: none;
  field-sizing: content;
  background: none; border: none; border-radius: 0; color: inherit;
}
/* The ring is the form's, so the field must not draw a second one inside it. */
.composer textarea:focus-visible { outline: none; }
.composer textarea:disabled { opacity: 0.6; }
/* Compact, because it sits inside rather than beside — and `flex: none`, or
   the input's `flex: 1` squeezes it until the word inside it is clipped by its
   own curve. */
.composer .button {
  flex: none; min-height: 40px; padding: 0 var(--space-4); border-radius: 999px;
}

.button-accent { background: var(--accent); border-color: var(--accent); color: var(--surface); }
.button-accent:hover { background: var(--accent); border-color: var(--text); }

/* The partition. A real control: draggable, focusable, and it moves with the
   arrow keys. */
.splitter {
  flex: 0 0 9px;
  cursor: col-resize;
  background: var(--border);
  background-clip: content-box;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  transition: background-color 150ms ease-out;
}
.splitter:hover, .splitter:focus-visible { background-color: var(--accent); }
body.dragging { cursor: col-resize; user-select: none; }
/* --- putting the paper away ----------------------------------------------- */
/* The panel closes and the conversation takes the window back, exactly as it
   looks before a paper exists. Nothing about the paper changes: the files are
   on disk, a render in flight finishes, and the poller keeps watching — this
   is a teacher deciding how much of the screen they want.

   The state lives on `.app`, which the poller never replaces. Putting it on
   the panel would lose it every two seconds. */
.app.doc-closed .viewer-shell,
.app.doc-closed .splitter { display: none; }
/* With the panel away, **the column narrows but the head does not**. The head
   is a bar across the top of the pane — the paper's name at one end, the way
   back at the other — and centring it with the messages moved the title into
   the middle of the window, a hand's width from where it sits when the panel
   is open.

   So the chat takes the full width and the three things a teacher reads and
   types into are centred inside it. 44rem, not the 780px the panel leaves:
   given the whole window the line would otherwise set far wider than anyone
   reads comfortably. */
.app.doc-closed .chat { flex: 1; max-width: none; margin: 0; }
.app.doc-closed .transcript,
.app.doc-closed .composer,
.app.doc-closed .sheetoptions {
  width: 100%; max-width: 44rem; margin-left: auto; margin-right: auto;
}

/* The way back, and it names the paper it goes back to — the panel is shut, so
   the title is otherwise the only thing on screen saying which paper this chat
   is about. Rendered whenever there is a paper and shown only when the panel is
   away, because that choice is local to the teacher's own browser and the
   server has no idea. */
.chat-head .showdoc { display: none; }
/* The bar's other end, whatever is or is not beside it. */
.app.doc-closed .chat-head .showdoc { margin-left: auto; }
.app.doc-closed .chat-head .showdoc {
  display: inline-flex; align-items: center; gap: var(--space-2);
  max-width: 60%; min-height: 34px; padding: 0 var(--space-2) 0 var(--space-3);
  background: var(--surface); color: var(--text-muted);
  border: 1px solid var(--border); border-radius: var(--radius-control);
  font: 500 13px var(--ui); cursor: pointer;
  transition: border-color 150ms ease-out, color 150ms ease-out;
}
.showdoc:hover { color: var(--text); border-color: var(--border-strong); }
.showdoc-mark { display: flex; color: var(--accent); flex: none; }
.showdoc-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.showdoc-verb {
  flex: none; padding: 0 var(--space-3); min-height: 26px;
  display: inline-flex; align-items: center;
  background: var(--bg); border-radius: var(--radius-control);
  color: var(--text); font-weight: 500;
}


.viewer-shell {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column;
  background: var(--bg);
  border-left: 1px solid var(--border);
}
.viewer-bar {
  display: flex; align-items: center;
  gap: var(--space-3); padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border); background: var(--surface);
}
/* The papers and the tabs scroll inside the bar on a narrow screen; the bar
   itself does not, or it would clip the Download menu (spec 022). */
.viewer-bar .artefacts, .viewer-bar .tabs {
  min-width: 0; overflow-x: auto; scrollbar-width: none;
}
/* The tabs take the slack, so what follows is pinned to the right end
   however many of them there are. `space-between` spread them evenly
   instead, which left Download stranded in the middle. */
.tabs { display: flex; gap: var(--space-1); margin-right: auto; }

/* A menu of downloads: each document, or all three (spec 022). `<details>`,
   so it opens with no script and from the keyboard. */
.menu { position: relative; }
.menu > summary { list-style: none; }
.menu > summary::-webkit-details-marker { display: none; }
.menu-list {
  position: absolute; right: 0; top: calc(100% + var(--space-2)); z-index: 10;
  min-width: 200px; display: flex; flex-direction: column; padding: var(--space-1);
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: var(--radius-card); box-shadow: 0 8px 24px rgb(0 0 0 / 0.16);
}
.menu-list a {
  padding: var(--space-2) var(--space-3); border-radius: var(--radius);
  color: var(--text); font-size: 14px; white-space: nowrap;
}
.menu-list a:hover { background: var(--bg); text-decoration: none; }
.viewer-end { display: flex; align-items: center; gap: var(--space-2); flex: none; }
.tab {
  padding: var(--space-2) var(--space-3);
  white-space: nowrap;
  background: none; border: 1px solid transparent; border-radius: var(--radius-control);
  font: 500 14px var(--ui); color: var(--text-muted); cursor: pointer;
}
.tab:hover { color: var(--text); background: var(--bg); }
.tab.on { color: var(--text); background: var(--bg); border-color: var(--border); }

/* The pages (spec 022): white sheets on the chrome's own background, in
   either theme, as the paper is white in either. `--zoom` is on `.app`, which
   the poller never replaces, so a new render keeps the teacher's size. */
.reader { position: relative; flex: 1; min-height: 0; overflow: auto; background: var(--bg); }
.pages {
  display: none; flex-direction: column; align-items: safe center;
  gap: var(--space-4); padding: var(--space-6) var(--space-4) var(--space-16);
}
.pages.on { display: flex; }
.page {
  display: block; flex: none; height: auto; max-width: none;
  width: calc(min(100%, 860px) * var(--zoom, 1));
  background: #fff; border-radius: 2px;
  box-shadow: 0 1px 3px rgb(0 0 0 / 0.12), 0 8px 24px rgb(0 0 0 / 0.08);
}
/* Where in the document the teacher is, and how large it is shown: a small
   bar that floats at the foot of the pages as they scroll. */
.reader-tools {
  position: sticky; bottom: var(--space-4); z-index: 2;
  width: fit-content; margin: calc(-1 * var(--space-12)) auto 0;
  display: flex; align-items: center; gap: 2px;
  padding: 4px 6px 4px var(--space-4);
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: var(--radius-control); box-shadow: 0 4px 16px rgb(0 0 0 / 0.14);
}
.pageof { font-size: 13px; color: var(--text-muted); font-variant-numeric: tabular-nums;
          min-width: 4.5em; }
.fit {
  min-height: 32px; padding: 0 var(--space-3); background: none; border: none;
  border-radius: var(--radius-control); font: 500 13px var(--ui); color: var(--text-muted);
  cursor: pointer;
}
.fit:hover { background: var(--bg); color: var(--text); }
.viewer-empty { flex: 1; display: flex; flex-direction: column; align-items: center;
                justify-content: center; gap: var(--space-4); padding: var(--space-8); }
/* A sheet setting itself while the paper is typeset: white, because the paper
   is white in either theme, and its lines inked in one after another. At rest
   — or with reduced motion — every line is there. */
.setting {
  width: min(300px, 60%); aspect-ratio: 210 / 297;
  display: flex; flex-direction: column; gap: 5.5%; padding: 10% 9%;
  background: #fff; border-radius: 2px; box-shadow: 0 6px 24px rgb(0 0 0 / 0.14);
}
.setting span {
  height: 2.4%; min-height: 3px; border-radius: 2px; background: #e6e0d4;
  transform-origin: left; animation: ink 2.6s ease-out infinite;
  animation-delay: calc(var(--i) * 120ms);
}
.setting span:nth-child(1) { width: 45%; height: 4%; background: #d8d0c0; }
.setting span:nth-child(3n) { width: 70%; }
.setting span:nth-child(3n + 1):not(:first-child) { width: 92%; }
.setting span:nth-child(5n) { width: 55%; }
@keyframes ink { 0% { transform: scaleX(0); } 45%, 100% { transform: scaleX(1); } }

/* A change, shown in isolation and in the conversation, where the teacher is
   already looking (ADR-0048). */
.proposal {
  border: 1px solid var(--border-strong); border-radius: var(--radius-card);
  padding: var(--space-4); background: var(--surface);
  display: flex; flex-direction: column; gap: var(--space-4);
}
.label {
  font-size: 12px; font-weight: 500; letter-spacing: 0.06em;
  text-transform: uppercase; margin-bottom: var(--space-2);
}
.accented { color: var(--accent); }
.beforeafter { display: flex; flex-direction: column; gap: var(--space-4); }
.beforeafter .paper {
  margin: 0; font-family: var(--serif); font-size: 15px; line-height: 1.4;
  padding: var(--space-3); background: var(--bg);
  border-radius: var(--radius); border: 1px solid var(--border);
}
.decide { display: flex; gap: var(--space-3); flex-wrap: wrap; margin: 0; }

/* Questions offered against the paper, numbered as the teacher will name them
   ("swap 8 for extra 1"). The number is the whole interface, so it is the one
   thing that is not allowed to be subtle. */
.offered { margin: 0; padding-left: var(--space-6); display: flex;
           flex-direction: column; gap: var(--space-3); }
.offered li::marker { font-weight: 600; color: var(--accent); }
.offered .paper {
  margin: 0; font-family: var(--serif); font-size: 15px; line-height: 1.4;
  padding: var(--space-3); background: var(--bg);
  border-radius: var(--radius); border: 1px solid var(--border);
}

/* What goes on the sheet besides the questions, under the composer where the
   teacher is already looking. Quiet until wanted: they are choices about the
   paper, not the way to make one. */
/* `align-items: center` so a chip is its own height. Half of these are a
   button inside a form and half are a bare link, and a flex row stretches its
   children by default — which made the links taller than the buttons beside
   them for no reason a reader could see. */
.sheetoptions { display: flex; align-items: center; gap: var(--space-2);
                flex-wrap: wrap; padding: 0 var(--space-4) var(--space-3); }
.sheetoptions form { margin: 0; }

/* One rule, for the sheet options, the answers under a reply and the starters.
   There were two blocks called `.chip` two hundred lines apart, quietly
   overriding each other.

   `inline-flex` is the fix that matters: a `<button>` centres its own label
   and an `<a>` does not, so the same class on the two of them put one label in
   the middle of its pill and the other against the top of it. */
.chip {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 32px; padding: 0 var(--space-4);
  background: transparent; color: var(--text-muted);
  border: 1px solid var(--border); border-radius: var(--radius-control);
  font: 500 13px var(--ui); line-height: 1; white-space: nowrap;
  cursor: pointer; text-decoration: none;
  transition: color 150ms ease-out, border-color 150ms ease-out, background 150ms ease-out;
}
.chip:hover { color: var(--text); border-color: var(--border-strong); text-decoration: none; }
.chip.on { color: var(--accent); border-color: var(--accent); background: var(--surface); }

/* --- The account screen --------------------------------------------------- */
/* Who they are and what they have made, the name their papers carry, what
   they keep for their papers, and the way out (spec 022). Sections divided by
   a rule rather than boxed: it is one page about one person, not four
   unrelated cards. */

.mastactions { display: flex; align-items: center; gap: var(--space-2); }
.mastactions form { margin: 0; }

.account { max-width: 46rem; margin: 0 auto; padding: var(--space-12) var(--space-6) var(--space-16); }
.account-part { padding: var(--space-8) 0; border-top: 1px solid var(--border); }
.account-part .muted { margin: calc(-1 * var(--space-2)) 0 var(--space-4); }

.who { display: flex; align-items: center; gap: var(--space-4); padding-bottom: var(--space-8); }
.initial {
  flex: none; width: 64px; height: 64px; display: grid; place-items: center;
  background: var(--surface); border: 1px solid var(--border-strong); border-radius: 50%;
  font: 600 26px var(--brand); color: var(--accent); text-transform: uppercase;
}
.who-name { min-width: 0; flex: 1; }
.who-name h1 { font-size: 28px; }
.who-name p { margin: var(--space-1) 0 0; overflow: hidden; text-overflow: ellipsis; }
/* What they have made, beside who they are. */
.counts { display: flex; gap: var(--space-8); margin: 0; }
.counts div { display: flex; flex-direction: column-reverse; align-items: flex-end; }
.counts dd { margin: 0; font: 600 26px var(--brand); line-height: 1.1; color: var(--text); }
.counts dt { font-size: 12px; letter-spacing: 0.06em; text-transform: uppercase;
             color: var(--text-muted); }

.panelhead {
  margin: 0 0 var(--space-4); font: 500 12px var(--ui);
  letter-spacing: .08em; text-transform: uppercase; color: var(--text-muted);
}
.inline-field { display: flex; gap: var(--space-3); }
.inline-field input { flex: 1; min-width: 0; }

/* A saved name, read as the name; Edit opens the field beneath it. */
.institute { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); }
.institute-name { flex: 1; min-width: 0; margin: 0; font-size: 20px; font-weight: 500;
                  overflow-wrap: anywhere; }
.institute-edit > summary { list-style: none; gap: var(--space-2); }
.institute-edit > summary::-webkit-details-marker { display: none; }
/* Open: Edit goes, and the field, Save and Cancel take the row. */
.institute-edit[open] { flex-basis: 100%; }
.institute-edit[open] > summary { display: none; }
.institute:has(.institute-edit[open]) .institute-name { display: none; }

/* Header, cover and watermark: a tile each, the picture or an empty place. */
.kept { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-4); }
.kept-tile { display: flex; flex-direction: column; gap: var(--space-2); }
.kept-picture {
  aspect-ratio: 4 / 3; display: grid; place-items: center; padding: var(--space-3);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-card);
  overflow: hidden;
}
.kept-picture img { max-width: 100%; max-height: 100%; object-fit: contain; }
.kept-tile.empty .kept-picture {
  background: none; border-style: dashed; border-color: var(--border-strong);
  color: var(--text-muted); font-size: 13px;
}
.kept-foot { display: flex; align-items: center; justify-content: space-between;
             min-height: 30px; font-size: 14px; font-weight: 500; }
.kept-foot form { margin: 0; }
.kept-remove {
  width: 30px; height: 30px; display: grid; place-items: center;
  background: none; border: 1px solid transparent; border-radius: var(--radius-control);
  color: var(--text-muted); cursor: pointer;
}
.kept-remove:hover { color: var(--danger); border-color: var(--danger); }

/* The way out, as a button in the danger colour (Prateek, 30 Sep 2026). It
   only opens the page that asks for the address to be typed, so the press
   it invites cannot close anything by itself. */
.leaving { padding-bottom: 0; }
.button-danger:hover { text-decoration: none; }

@media (max-width: 640px) {
  .account { padding-top: var(--space-8); }
  .who { flex-wrap: wrap; }
  .counts { width: 100%; justify-content: flex-start; padding-left: 80px; }
  .counts div { align-items: flex-start; }
  .kept { grid-template-columns: 1fr; }
  .kept-picture { aspect-ratio: 3 / 1; }
}

.savedmark { margin: 0; padding: var(--space-4); background: var(--bg);
             border: 1px solid var(--border); border-radius: var(--radius);
             display: grid; place-items: center; }
.savedmark img { max-width: 200px; max-height: 96px; }
.remember { display: flex; align-items: center; gap: var(--space-2);
            font-size: 14px; color: var(--text-muted); }

/* "In use": which of the choices is on the paper now (spec 022). */
.inuse {
  margin-left: var(--space-2); padding: 1px var(--space-2);
  border: 1px solid var(--accent); border-radius: var(--radius-control);
  color: var(--accent); font-size: 11px; letter-spacing: 0.04em; vertical-align: 1px;
}

/* Header, cover and watermark, over the paper rather than on a page of their
   own (spec 022). A card on the right; the whole width at the foot on a
   phone. */
.sheet-panel {
  position: fixed; top: var(--space-3); right: var(--space-3); bottom: var(--space-3);
  z-index: 20; width: min(420px, calc(100vw - 2 * var(--space-3)));
  display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: var(--radius-card); box-shadow: 0 12px 40px rgb(0 0 0 / 0.22);
  animation: slide-in 250ms ease-out;
}
@keyframes slide-in { from { transform: translateX(24px); opacity: 0; } }
.sheet-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--space-3) var(--space-3) var(--space-3) var(--space-6);
  border-bottom: 1px solid var(--border);
}
.sheet-head h2 { font-size: 20px; }
.sheet-body { flex: 1; overflow-y: auto; padding: var(--space-4); }
.sheet-body .proposal { border: none; padding: var(--space-2); background: none; }
/* The pages move aside for it, so what the settings change is seen whole —
   on a screen wide enough to hold both. */
@media (min-width: 861px) {
  .app.panel-open .reader { margin-right: calc(min(420px, 100vw - 24px) + 12px); }
}

/* The watermark as it will print, laid over the page while it is typed. */
.pages { position: relative; }
.wm-preview {
  position: absolute; z-index: 1; pointer-events: none;
  transform: translate(-50%, -50%) rotate(-30deg);
  font: 700 1em Inter, Arial, sans-serif; line-height: 1.1;
  letter-spacing: .06em; text-transform: uppercase; white-space: nowrap;
  text-align: center; color: rgb(0 0 0 / 0.12);
}

/* What the last change did, with Undo, for a few seconds. */
.toast {
  position: fixed; left: 50%; bottom: var(--space-6); z-index: 40;
  transform: translateX(-50%);
  display: flex; align-items: center; gap: var(--space-4);
  padding: var(--space-2) var(--space-2) var(--space-2) var(--space-4);
  background: var(--text); color: var(--bg);
  border-radius: var(--radius-control); box-shadow: 0 8px 24px rgb(0 0 0 / 0.25);
  font-size: 14px; animation: rise 250ms ease-out;
}
@keyframes rise { from { transform: translate(-50%, 12px); opacity: 0; } }
.toast form { margin: 0; }
.toast-undo {
  display: inline-flex; align-items: center; gap: var(--space-1);
  min-height: 32px; padding: 0 var(--space-3);
  background: none; border: 1px solid transparent; border-radius: var(--radius-control);
  color: inherit; font: 500 14px var(--ui); cursor: pointer;
}
.toast-undo:hover { border-color: currentColor; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* Narrow windows: the paper goes under the conversation rather than beside it,
   and the partition has nothing to divide. */
@media (max-width: 860px) {
  .app, .app.sidebar-closed { grid-template-columns: minmax(0, 1fr); }
  /* The side menu was hidden here with nothing to open it: no chats, no
     Account, no Sign out on a phone (spec 022). It slides in from ☰. */
  .sidebar, .app.sidebar-closed .sidebar {
    position: fixed; top: 0; bottom: 0; left: 0; z-index: 30;
    width: min(82vw, 300px); padding: var(--space-4);
    border-right: 1px solid var(--border);
    transform: translateX(-105%); transition: transform 250ms ease-out;
  }
  .app.menu-open .sidebar { transform: none; box-shadow: 0 0 40px rgb(0 0 0 / 0.3); }
  .app.menu-open::after {
    content: ""; position: fixed; inset: 0; z-index: 29; background: rgb(0 0 0 / 0.45);
  }
  .masthead { padding: var(--space-3) var(--space-4); }
  /* Name, switch, Back and Sign out on one line of a phone. */
  .mastactions { gap: var(--space-1); }
  .mastactions .button { padding: 0 var(--space-3); }
  /* The viewer's bar on two rows: its buttons, then the documents across the
     full width, so no tab is cut off at its edge. */
  .viewer-bar { flex-wrap: wrap; row-gap: var(--space-2); }
  .viewer-bar .tabs { order: 2; flex-basis: 100%; margin-right: 0; }
  .viewer-end { margin-left: auto; }
  .sheet-panel { top: auto; left: var(--space-2); right: var(--space-2); bottom: 0;
                 width: auto; max-height: 85vh; border-radius: var(--radius-card) var(--radius-card) 0 0; }
  .stage { flex-direction: column; overflow-y: auto; }
  .has-doc .chat { flex: none; }
  .splitter { display: none; }
  .viewer-shell { min-height: 70vh; border-left: none; border-top: 1px solid var(--border); }
}

/* --- The terms ------------------------------------------------------------- */
/* Read, not used: a column of text at a reading measure (spec 024). */
.legal { max-width: 42rem; padding: var(--space-12) var(--space-6) var(--space-16); }
.legal h1 { margin-bottom: var(--space-1); }
.legal h2 { font-size: 18px; margin: var(--space-8) 0 var(--space-2); }
.legal p, .legal li { font-size: 15px; }
.legal ul { padding-left: var(--space-6); }
.legal li + li { margin-top: var(--space-2); }
.marklink { color: inherit; }
.marklink:hover { text-decoration: none; }
.legal-links { display: flex; justify-content: center; gap: var(--space-6); margin: 0;
               font-size: 13px; }
.legal-links a { color: var(--text-muted); }
.centred + .legal-links { position: absolute; bottom: var(--space-4); left: 0; right: 0; }
.leaving .legal-links { justify-content: flex-start; margin-top: var(--space-8); }
.agree { display: flex; align-items: flex-start; gap: var(--space-3); font-size: 15px; cursor: pointer; }
.agree input { width: 18px; height: 18px; margin: 3px 0 0; flex: none; }

/* --- The founder's dashboard (spec 024) ------------------------------------ */
main.founder { max-width: 1100px; padding-top: var(--space-8); }
.founder-part { padding: var(--space-8) 0; border-top: 1px solid var(--border); }
.parthead { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-4); }

.stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-6);
         padding-bottom: var(--space-8); }
.stat-group { padding: var(--space-4) var(--space-6) var(--space-6); background: var(--surface);
              border: 1px solid var(--border); border-radius: var(--radius-card); }
.stat-group dl { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4) var(--space-6); margin: 0; }
.stat-group dl div { display: flex; flex-direction: column-reverse; gap: var(--space-1); }
.stat-group dd { margin: 0; font: 600 26px var(--brand); line-height: 1.1; }
.stat-group dd small { display: block; margin-top: 2px; font: 400 13px var(--ui); color: var(--text-muted); }
.stat-group dt { font-size: 13px; color: var(--text-muted); }

.windows { display: flex; gap: var(--space-1); }
.windows a { padding: 2px var(--space-3); border-radius: var(--radius-control); font-size: 13px;
             color: var(--text-muted); }
.windows a[aria-current] { background: var(--surface); border: 1px solid var(--border-strong); color: var(--text); }
.windows a:hover { text-decoration: none; color: var(--text); }

.health { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.health li { padding: var(--space-2) var(--space-4); border-left: 3px solid var(--border-strong);
             background: var(--surface); border-radius: var(--radius); font-size: 15px; }
.health li.bad { border-left-color: var(--danger); }
.health li.warn { border-left-color: var(--accent); }
.health b { font-weight: 600; }
.bad { color: var(--danger); }
.subhead { margin: var(--space-6) 0 var(--space-2); font: 500 14px var(--ui); }

.tablewrap { overflow-x: auto; }
.datatable { width: 100%; border-collapse: collapse; font-size: 14px; }
.datatable th { text-align: left; font-weight: 500; color: var(--text-muted); font-size: 13px;
                padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--border-strong); }
.datatable td { padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--border);
                vertical-align: top; }
.datatable td .muted { display: block; font-size: 13px; }
.datatable .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.datatable .num .muted { display: inline; }
.datatable .when { white-space: nowrap; color: var(--text-muted); }
.footnote { margin: var(--space-6) 0 0; }

.replay { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-3); }
.replay-turn { padding: var(--space-3) var(--space-4); border: 1px solid var(--border); border-radius: var(--radius-card); }
.replay-teacher { background: var(--surface); margin-left: 15%; }
.replay-assistant { margin-right: 15%; }
.replay-failed { border-color: var(--danger); }
.replay-meta { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-3); font-size: 12px;
             color: var(--text-muted); margin-bottom: var(--space-1); }
.replay-text { font-size: 15px; overflow-wrap: anywhere; }
.draft { margin: var(--space-3) 0 0; padding: var(--space-4); background: var(--surface);
         border: 1px solid var(--border); border-radius: var(--radius); font-size: 12px;
         overflow-x: auto; }
details > summary.panelhead { cursor: pointer; margin: 0; }

@media (max-width: 860px) {
  .stats { grid-template-columns: 1fr; }
  .replay-teacher { margin-left: 0; }
  .replay-assistant { margin-right: 0; }
}
