/* Faculty Twin: shared styles for the student page and the settings page.
   The look is Ben's collier.phd field notebook (bcollier/ben.collier.phd, css/site.css): grid paper,
   index cards, a legal-pad caption strip, highlighter tags and sticky notes. Colors are tokens on :root
   with a dark-mode override (the lab bench). docs/SPEC.md, "Look and feel". No framework. */

:root {
  /* collier.phd tokens, copied from site.css */
  --paper: #fbf8f1;
  --card: #fffefa;
  --legal: #fff2ad;
  --pen: #2447a6;
  --red: #b8352a;
  --margin: #e7a2a0;
  --rule: rgba(64, 120, 168, .28);
  --hl-yellow: #ffe56b;
  --hl-green: #b9f0a0;
  --hl-pink: #ffc0d2;
  --hl-blue: #bfe3ff;
  --sticky: #ffe17a;
  --sticky-pink: #ffbdcc;
  --tape: rgba(232, 220, 186, .82);
  --bench: #22302b;
  --bench-ink: #efe8d6;
  --tab-1: #f6c453; --tab-2: #9ccbea; --tab-3: #a9d8a1; --tab-4: #f3a391;
  --tab-5: #cdb8e8; --tab-6: #8ed3c7; --tab-7: #f5b5c8; --tab-8: #e9dfc4;
  --serif-d: "Young Serif", Georgia, serif;
  --serif: "Literata", Georgia, serif;
  --mono: "IBM Plex Mono", ui-monospace, monospace;
  --hand: "Kalam", "Comic Sans MS", cursive;

  /* the page's roles, mapped onto those tokens */
  --bg: var(--paper);
  --surface: var(--card);
  --surface-2: #f3eee1;
  --ink: #1d2633;
  --ink-2: #4a5463;
  --ink-3: #555d6a;
  --paper-ink: #1d2633;          /* ink on paper objects (sticky notes, tabs, highlighter tags) in both themes */
  --line: #d9cfba;
  --line-strong: #8c8270;
  --accent: var(--pen);
  --accent-hover: #1b3785;
  --accent-ink: #fffefa;
  --accent-soft: #e4eafb;
  --mark: var(--hl-yellow);
  --mark-edge: #c99700;
  --danger: var(--red);
  --danger-soft: #fbe4df;
  --ok: #2f6b3e;
  --ok-soft: #e3f4d9;
  --warn: #855200;
  --warn-soft: #fff6c8;
  --slide-bg: #ffffff;
  --code-bg: var(--card);
  --paper-grid: rgba(64, 120, 168, .09);
  --legal-bg: var(--legal);
  --legal-rule: rgba(64, 120, 168, .3);
  --legal-margin: rgba(184, 53, 42, .5);
  --note-bg: var(--sticky);
  --note-pink: var(--sticky-pink);
  --shadow: 0 1px 2px rgba(0, 0, 0, .14), 0 12px 22px -14px rgba(0, 0, 0, .4);
  --shadow-ink: 3px 4px 0 rgba(29, 38, 51, .16);
  --focus: 0 0 0 2px var(--bg), 0 0 0 5px var(--accent);

  --font-serif: var(--serif-d);
  --font-sans: var(--serif);
  --font-mono: var(--mono);

  --radius: 4px;
  --radius-sm: 3px;
  --sketch: 14px 4px 12px 4px / 4px 12px 4px 14px;   /* the site's hand-cut corners */
  --tap: 44px;
  --gutter: 16px;
  color-scheme: light;
}

/* Dark mode: the lab bench the notebook sits on (collier.phd has no dark mode of its own). */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #1c2723; --surface: #263530; --surface-2: #2f3f39;
    --ink: #efe8d6; --ink-2: #d4cdba; --ink-3: #b9b29f; --line: #3e514a; --line-strong: #84958c;
    --accent: #9db4ff; --accent-hover: #bccbff; --accent-ink: #14201b; --accent-soft: #2d3a5c;
    --mark: #4d4420; --mark-edge: #e3bf3a; --danger: #f4a597; --danger-soft: #45281f;
    --ok: #a8dc96; --ok-soft: #23392a; --warn: #f0cf6a; --warn-soft: #3b3620;
    --slide-bg: #ffffff; --code-bg: #20302a;
    --paper-grid: rgba(239, 232, 214, .045);
    --legal-bg: #393423; --legal-rule: rgba(157, 180, 255, .2); --legal-margin: rgba(240, 130, 118, .6);
    --note-bg: #e8cd63; --note-pink: #eab0bf;
    --hl-yellow: #e9d35f; --hl-green: #a6d98f; --hl-pink: #eeb0c2; --hl-blue: #a9d1f0;
    --shadow: 0 1px 2px rgba(0, 0, 0, .45), 0 12px 22px -14px rgba(0, 0, 0, .8);
    --shadow-ink: 3px 4px 0 rgba(0, 0, 0, .35);
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --bg: #1c2723; --surface: #263530; --surface-2: #2f3f39;
  --ink: #efe8d6; --ink-2: #d4cdba; --ink-3: #b9b29f; --line: #3e514a; --line-strong: #84958c;
  --accent: #9db4ff; --accent-hover: #bccbff; --accent-ink: #14201b; --accent-soft: #2d3a5c;
  --mark: #4d4420; --mark-edge: #e3bf3a; --danger: #f4a597; --danger-soft: #45281f;
  --ok: #a8dc96; --ok-soft: #23392a; --warn: #f0cf6a; --warn-soft: #3b3620;
  --slide-bg: #ffffff; --code-bg: #20302a;
  --paper-grid: rgba(239, 232, 214, .045);
  --legal-bg: #393423; --legal-rule: rgba(157, 180, 255, .2); --legal-margin: rgba(240, 130, 118, .6);
  --note-bg: #e8cd63; --note-pink: #eab0bf;
  --hl-yellow: #e9d35f; --hl-green: #a6d98f; --hl-pink: #eeb0c2; --hl-blue: #a9d1f0;
  --shadow: 0 1px 2px rgba(0, 0, 0, .45), 0 12px 22px -14px rgba(0, 0, 0, .8);
  --shadow-ink: 3px 4px 0 rgba(0, 0, 0, .35);
  color-scheme: dark;
}

/* ---------- base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background-color: var(--bg);
  background-image:
    linear-gradient(var(--paper-grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--paper-grid) 1px, transparent 1px);
  background-size: 24px 24px;
  background-position: -1px -1px;
  color: var(--ink);
  font: 17px/1.55 var(--font-sans);
  min-height: 100vh;
  min-height: 100dvh;
}
[hidden] { display: none !important; }
img, video { max-width: 100%; display: block; }
h1, h2, h3 { font-family: var(--font-serif); font-weight: 400; line-height: 1.12; letter-spacing: -.01em; margin: 0 0 .4em; text-wrap: balance; }
p { margin: 0 0 .75em; }
a { color: var(--accent); text-decoration-thickness: 1.5px; text-underline-offset: 3px; }
button, input, select, textarea { font: inherit; color: inherit; }
:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }

.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; left: -9999px; top: 8px; z-index: 50; padding: 0 14px; min-height: var(--tap); display: inline-flex; align-items: center;
  background: var(--note-bg); color: var(--paper-ink); font: 500 14px var(--font-mono);
}
.skip-link:focus { left: 8px; }
.muted { color: var(--ink-3); }
.small { font-size: .875rem; }
/* a kicker, as on collier.phd: small mono capitals */
.eyebrow { font: 500 .75rem/1.4 var(--font-mono); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-2); margin-bottom: .6rem; }
/* the logo line: "Faculty Twin" in the hand font, like the site's name in its header */
.eyebrow.logo {
  font: 700 1.45rem/1.1 var(--hand); letter-spacing: 0; text-transform: none; color: var(--accent);
  display: inline-block; transform: rotate(-2deg); margin-bottom: .5rem;
}
.title { font-size: clamp(2.1rem, 4.6vw, 3.2rem); letter-spacing: -.02em; }
.title-sm { font-size: 1.45rem; }
.lede { font-size: 1.12rem; color: var(--ink-2); }
.hint { color: var(--ink-3); font-size: .9rem; margin: .1rem 0 .5rem; }
/* notes and warnings: a strip of legal pad with the red margin line */
.note {
  background: var(--legal-bg); color: var(--ink); padding: .55rem .8rem .55rem 1.1rem; border-radius: var(--radius-sm);
  background-image: linear-gradient(90deg, transparent 6px, var(--legal-margin) 6px 8px, transparent 8px);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .12);
}
.error-text { color: var(--danger); min-height: 1.5em; margin: .5rem 0 0; font-size: .95rem; }
.field-label { display: block; font-weight: 600; margin-top: .75rem; }

/* ---------- controls ---------- */
/* Buttons: an inked box with hand-cut corners; the main action is sticky-note yellow (site.css .btn). */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .45rem;
  min-height: var(--tap); padding: 0 1.1rem; border-radius: var(--sketch);
  border: 2px solid var(--ink); background: var(--surface); color: var(--ink); box-shadow: var(--shadow-ink);
  cursor: pointer; font: 600 .875rem/1.2 var(--font-mono); letter-spacing: .02em; white-space: nowrap; text-decoration: none;
  transition: transform .15s ease, box-shadow .15s ease, background-color .15s ease;
}
.btn:hover { background: var(--surface-2); transform: translateY(-2px) rotate(-.6deg); }
.btn:focus-visible { outline: none; box-shadow: var(--focus); }
.btn-primary { background: var(--note-bg); color: var(--paper-ink); border-color: var(--paper-ink); }
.btn-primary:hover { background: var(--hl-yellow); color: var(--paper-ink); }
.btn-ghost { background: transparent; border-color: transparent; color: var(--accent); padding: 0 .75rem; box-shadow: none; }
.btn-ghost:hover { background: var(--accent-soft); transform: none; }
.btn-small { min-height: var(--tap); padding: 0 .75rem; font-size: .8rem; }
.btn[disabled], .icon-btn[disabled] { opacity: .45; cursor: not-allowed; transform: none; }

input[type="text"], input[type="password"], input[type="search"], input[type="number"], input[type="date"], textarea, select {
  min-height: var(--tap); padding: .5rem .75rem; border-radius: var(--radius-sm);
  border: 1.5px solid var(--line-strong); background: var(--surface); width: 100%;
}
input::placeholder, textarea::placeholder { color: var(--ink-3); opacity: 1; }
textarea { resize: vertical; line-height: 1.45; }
/* Safari ignores min-height on a native select (it drew the dock's course picker 23 px tall),
   so draw our own: no native chrome, a chevron, and room for it on the right. */
select {
  -webkit-appearance: none; appearance: none; padding-right: 2.25rem; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5l5 5 5-5' fill='none' stroke='%23888' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right .8rem center; background-size: 12px 8px;
}
input:focus-visible, textarea:focus-visible, select:focus-visible { outline: none; border-color: var(--accent); box-shadow: var(--focus); }

.row { display: flex; gap: .5rem; align-items: stretch; }
.row > input { flex: 1; min-width: 0; }

.icon-btn {
  width: var(--tap); height: var(--tap); flex: none; display: inline-grid; place-items: center;
  border-radius: 50%; border: 2px solid var(--ink); background: var(--surface); color: var(--ink); cursor: pointer; padding: 0;
}
.icon-btn svg { width: 22px; height: 22px; }
.icon-btn:hover { background: var(--surface-2); }
.icon-btn:focus-visible { outline: none; box-shadow: var(--focus); }
.icon-btn-primary { background: var(--note-bg); border-color: var(--paper-ink); color: var(--paper-ink); width: 54px; height: 54px; box-shadow: var(--shadow-ink); }
.icon-btn-primary:hover { background: var(--hl-yellow); }

/* an index card */
.card { background: var(--surface); border: 0; border-radius: var(--radius-sm); padding: 1.6rem; box-shadow: var(--shadow); }
.narrow { width: min(460px, 100%); }

/* ---------- screens ---------- */
.screen-center { min-height: 100vh; min-height: 100dvh; display: grid; place-items: center; padding: var(--gutter); }

/* chips: inked tags with hand-cut corners (site.css .chips li) */
.chips { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .55rem; }
.chip {
  min-height: var(--tap); padding: .45rem .95rem; border-radius: var(--sketch); border: 1.5px solid var(--ink);
  background: var(--surface); color: var(--ink); cursor: pointer; text-align: left; line-height: 1.3; font-size: .95rem;
  transition: background-color .15s ease, transform .15s ease;
}
.chip:hover { background: var(--hl-yellow); color: var(--paper-ink); }
.chip:hover .chip-course { color: var(--paper-ink); }
.chip:focus-visible { outline: none; box-shadow: var(--focus); }
.chip .chip-course { color: var(--ink-3); font: 500 .75rem var(--font-mono); margin-left: .4rem; white-space: nowrap; }
.chips-label { font: 400 1.15rem/1.2 var(--hand); color: var(--accent); margin: 0 0 .6rem; }

/* ---------- app shell ---------- */
.app { min-height: 100vh; min-height: 100dvh; }
.app[data-view="idle"] .stage, .app[data-view="idle"] .dock { display: none; }
.app[data-view="presenting"] .idle { display: none; }

/* idle: a page of the notebook, with the red margin rule where the hand-off frame drew it (x = 64px) */
.idle { min-height: 100vh; min-height: 100dvh; display: grid; place-items: center; padding: 2rem var(--gutter); outline: none; }
.idle, #screen-login, #screen-offline {
  background-image: linear-gradient(90deg, transparent 64px, var(--margin) 64px, var(--margin) 66px, transparent 66px);
}
.idle-inner { width: min(740px, 100%); text-align: center; }
.idle-inner .lede { margin-bottom: 1.6rem; }
/* the course filter: index tabs standing on the question card */
.course-filter { border: 0; padding: 0 0 0 14px; margin: 0; display: flex; flex-wrap: wrap; justify-content: flex-start; gap: 5px; }
.course-filter label { position: relative; }
.course-filter input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.course-filter label > span {
  display: inline-flex; align-items: center; gap: .3em; min-height: var(--tap); padding: 0 1rem;
  border-radius: 9px 9px 0 0; background: var(--tab, var(--tab-8)); color: var(--paper-ink);
  font: 500 .84rem var(--font-mono); letter-spacing: -.01em; cursor: pointer;
  box-shadow: inset 0 -8px 10px -8px rgba(0, 0, 0, .28), inset 0 1px 0 rgba(255, 255, 255, .5);
  transform: translateY(4px); transition: transform .18s ease;
}
.course-filter label:nth-child(2) > span { --tab: var(--tab-1); }
.course-filter label:nth-child(3) > span { --tab: var(--tab-2); }
.course-filter label:nth-child(4) > span { --tab: var(--tab-3); }
.course-filter label:hover > span { transform: translateY(0); }
.course-filter input:checked + span {
  transform: translateY(0); background: var(--surface); color: var(--ink); font-weight: 600; box-shadow: none;
}
.course-filter input:focus-visible + span { box-shadow: var(--focus); }
.ask-form {
  view-transition-name: ask-box; position: relative;
  background: var(--surface); border: 2px solid var(--accent); border-radius: 6px;
  padding: .55rem; box-shadow: var(--shadow); text-align: left;
}
/* these boxes already wear a pen border, so focus adds a soft pen halo instead of a second ring */
.ask-form:focus-within, .dock-form input:focus-visible, #passcode:focus-visible {
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 32%, transparent);
}
.ask-form textarea { border: 0; box-shadow: none !important; font-size: 1.12rem; min-height: 3.3rem; background: transparent; }
.ask-row { display: flex; align-items: center; justify-content: space-between; gap: .5rem; padding: 0 .25rem .1rem .5rem; }
.count { font: .78rem var(--font-mono); color: var(--ink-3); }
#idle-privacy { margin-top: .6rem; }
.chips-block { margin-top: 1.6rem; }
.chips-block .chips { justify-content: center; }
.ai-label { display: inline-flex; gap: .4rem; align-items: flex-start; margin-top: 2rem; font-size: .85rem; color: var(--ink-3); text-align: left; max-width: 34rem; }
.ai-label svg { flex: none; margin-top: .2rem; }
/* A quiet way in to Settings for me; the page behind it asks for the admin passcode. */
.settings-link { margin-top: 1rem; font: 500 .75rem/1.4 var(--font-mono); letter-spacing: .06em; }
.settings-link a { color: var(--ink-3); display: inline-block; padding: .75rem .25rem; text-decoration: underline; text-underline-offset: 3px; }
.settings-link a:hover { color: var(--pen); }

/* presenting: chat docks right, about 30% */
.app[data-view="presenting"] {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(300px, 30%, 440px);
  height: 100vh; height: 100dvh;
}
.stage { overflow-y: auto; min-width: 0; }
.stage-inner { max-width: 1180px; margin: 0 auto; padding: 1.4rem clamp(1rem, 2.5vw, 2rem) 2rem; }

.stage-message { min-height: 60vh; display: grid; place-items: center; text-align: center; }
.stage-message-body { max-width: 36rem; }
.stage-message-body .title-sm { font-size: 1.7rem; }
.stage-actions { display: flex; gap: .6rem; justify-content: center; flex-wrap: wrap; margin: .6rem 0 1.1rem; }
.stage-message .chips { justify-content: center; }
/* answer labels are highlighter tags: From Canvas blue, from the web pink, AI-drawn slide green */
.stage-label {
  display: inline-block; padding: .2rem .65rem .15rem; margin-bottom: .8rem; letter-spacing: .1em;
  color: var(--paper-ink); background: var(--hl-blue); border-radius: 2px 6px 3px 7px; transform: rotate(-1.2deg);
  box-decoration-break: clone; -webkit-box-decoration-break: clone;
}
.stage-label.web-label { background: var(--hl-pink); }
.stage-extra { text-align: left; margin: .5rem 0 1rem; display: grid; gap: 1rem; }
.stage-extra h3 { font: 400 1.15rem/1.2 var(--hand); margin: 0 0 .35rem; color: var(--accent); }
.web-sources { list-style: none; margin: 0; padding: 0; display: grid; gap: .4rem; }
.web-sources a {
  display: block; padding: .5rem .75rem; min-height: var(--tap); border: 0; border-radius: var(--radius-sm);
  background: var(--surface); color: var(--accent); text-decoration: none; overflow-wrap: anywhere; box-shadow: var(--shadow);
  border-left: 4px solid var(--hl-pink);
}
.web-sources a:hover { text-decoration: underline; }
.web-sources a:focus-visible { outline: none; box-shadow: var(--focus); }
.web-sources .host { display: block; font: .75rem var(--font-mono); color: var(--ink-3); }
.web-listen { display: flex; gap: .6rem; align-items: center; flex-wrap: wrap; }
.web-listen .small { color: var(--ink-3); font-size: .85rem; }
.related-slides { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: .6rem; }
.related-slides .source-btn { flex-direction: column; align-items: stretch; height: 100%; }
.related-slides .source-btn img { width: 100%; }

/* AI-drawn helper slide: a dashed frame and its own green highlighter tag, so it never reads as a course slide. */
.helper-slot { margin-top: 1.2rem; }
.helper-slide { margin: 0; padding: .8rem; border: 0; border-radius: 2px; background: var(--surface); box-shadow: var(--shadow); }
.helper-label {
  display: inline-block; margin: 0 0 .6rem; padding: .2rem .65rem .15rem; border-radius: 2px 6px 3px 7px;
  font: 500 .75rem var(--font-mono); letter-spacing: .1em; text-transform: uppercase;
  color: var(--paper-ink); background: var(--hl-green); transform: rotate(-1.2deg);
}
.helper-svg { display: block; width: 100%; height: auto; border-radius: var(--radius-sm); }
.helper-cap { margin-top: .4rem; font-size: .85rem; color: var(--ink-2); }
.helper-sources { list-style: none; margin: .3rem 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: .35rem .9rem; font-size: .85rem; }
.helper-sources a { color: var(--accent); }
.spinner {
  width: 38px; height: 38px; margin: 0 auto 1rem; border-radius: 50%;
  border: 3px solid var(--line); border-top-color: var(--accent); animation: spin 1s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.media { display: grid; gap: 1rem; }
.media.has-code .slide-frame { width: min(100%, calc(44vh * 16 / 9)); justify-self: center; }
/* the slide: a white print on the page, as large as before */
.slide-frame {
  position: relative;
  margin: 0; background: var(--slide-bg); border: 0; border-radius: 2px;
  overflow: hidden; aspect-ratio: 16 / 9; display: grid; place-items: center;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .15), 0 22px 34px -18px rgba(0, 0, 0, .5);
  transition: transform .45s cubic-bezier(.2, .8, .2, 1), box-shadow .45s cubic-bezier(.2, .8, .2, 1);
}
/* Read-along: the slide being talked about is lifted into a soft highlighter spotlight while it is narrated,
   and sits back a little while paused. */
.slide-frame.is-speaking {
  transform: translateY(-2px);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--hl-yellow) 70%, transparent),
    0 0 26px 6px color-mix(in srgb, var(--hl-yellow) 38%, transparent),
    0 1px 2px rgba(0, 0, 0, .15), 0 26px 38px -18px rgba(0, 0, 0, .55);
}
.player.is-paused .slide-frame img { filter: saturate(.85) brightness(.97); transition: filter .3s; }
/* highlighter marks over the slide words being said: drawn on the picture's own box (app.js layoutMarks) */
.slide-marks { position: absolute; pointer-events: none; z-index: 1; }
.slide-mark {
  position: absolute; border-radius: 3px 6px 4px 7px / 6px 3px 7px 4px;
  background: #ffe56b; mix-blend-mode: multiply; opacity: .62;
  box-shadow: 0 0 0 1px rgba(201, 151, 0, .25);
  animation: mark-in .32s cubic-bezier(.2, .8, .2, 1) both;
}
.mark-group { transition: opacity .42s ease-out; }
.mark-group.out { opacity: 0; }
@keyframes mark-in { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
.slide-frame img, .slide-frame video { width: 100%; height: 100%; object-fit: contain; }
.slide-frame video { background: #000; }
/* While the next slide loads, show the empty frame rather than the previous slide under the new caption. */
.slide-frame img.is-loading { visibility: hidden; }
.media:not(.has-code) .slide-frame { width: min(100%, calc(64vh * 16 / 9)); justify-self: center; }

.code-panel { background: var(--code-bg); border: 0; border-radius: var(--radius-sm); min-width: 0; overflow: hidden; box-shadow: var(--shadow); }
.code-head {
  display: flex; justify-content: space-between; gap: .5rem; padding: .5rem .8rem; border-bottom: 2px solid var(--legal-margin);
  font: 400 1.1rem/1.2 var(--hand); color: var(--accent);
}
.code-head .small { font: .78rem var(--font-mono); align-self: center; }
.code { margin: 0; padding: .5rem 0; overflow: auto; max-height: 32vh; font: .82rem/1.6 var(--font-mono); tab-size: 4; }
.code:focus-visible { outline: 3px solid var(--accent); outline-offset: -3px; }
.code code { display: block; min-width: max-content; }
.code .ln { display: block; padding: 0 .9rem 0 0; white-space: pre; border-left: 3px solid transparent; }
.code .ln::before { content: attr(data-n); display: inline-block; width: 2.6em; padding-right: .8em; text-align: right; color: var(--ink-3); user-select: none; }
.code .ln.marked { background: var(--mark); border-left-color: var(--mark-edge); }

.clip-row { display: flex; align-items: center; flex-wrap: wrap; gap: .5rem; margin-top: .5rem; min-height: 0; }
.clip-row:has(> :not([hidden])) { min-height: var(--tap); }
#clip-note { font: 400 1.05rem/1.3 var(--hand); color: var(--ink-2); }

/* The narration box (read-along): a hand-lettered "Narration" tag and the voice in mono, over the legal pad. */
.narration { margin: .9rem 0 0; }
.narration-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: .2rem .8rem; padding: 0 0 .25rem 4px; }
.narration-tag {
  margin: 0; font: 700 1.2rem/1.1 var(--hand); color: var(--accent); letter-spacing: 0;
  display: inline-block; transform: rotate(-1.5deg);
}
.narration-voice { font: 500 .72rem/1.4 var(--font-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); }
.narration-note { font: 400 1rem/1.3 var(--hand); color: var(--ink-2); margin-left: auto; }
/* the caption: a strip of legal pad, red double margin line, the text written on 32px rules */
.caption {
  margin: 0; padding: 12px 18px 12px 66px; color: var(--ink);
  background-color: var(--legal-bg);
  background-image:
    linear-gradient(90deg, transparent 40px, var(--legal-margin) 40px 42px, transparent 42px 46px, var(--legal-margin) 46px 48px, transparent 48px),
    repeating-linear-gradient(transparent 0 31px, var(--legal-rule) 31px 32px);
  background-position: 0 0, 0 12px;
  background-size: 100% 100%, 100% calc(100% - 12px);
  background-repeat: no-repeat;
  border: 0; border-radius: 2px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .14), 0 10px 18px -12px rgba(0, 0, 0, .35);
  font-size: 1.1rem; line-height: 32px; min-height: 88px;
  /* the whole narration, four ruled lines at a time; the spoken line scrolls into view */
  max-height: calc(4 * 32px + 24px); overflow-y: auto; overscroll-behavior: contain;
  background-attachment: local;
}
.caption:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
/* words still to come are lighter, words said are in ink, the word being said gets a highlighter sweep */
.caption .w { opacity: .62; transition: opacity .25s, color .25s; border-radius: 2px; }
.caption .w.said { opacity: 1; }
.caption .w.now {
  opacity: 1; color: var(--paper-ink);
  /* a deeper yellow than the pad itself, so the sweep reads on the legal-pad yellow */
  --sweep: color-mix(in srgb, var(--hl-yellow) 55%, var(--mark-edge));
  background: linear-gradient(var(--sweep), var(--sweep)) 0 55% / 0% 78% no-repeat;
  animation: sweep .18s cubic-bezier(.2, .8, .2, 1) forwards;
}
@keyframes sweep { to { background-size: 100% 78%; } }
/* reduced motion: the sentence being read is highlighted as a whole, nothing sweeps */
.caption.reduce .w.now { animation: none; background: none; }
.caption.reduce .w.in-sentence {
  --sweep: color-mix(in srgb, var(--hl-yellow) 55%, var(--mark-edge));
  opacity: 1; color: var(--paper-ink);
  background: linear-gradient(var(--sweep), var(--sweep)) 0 55% / 100% 78% no-repeat;
}

.controls { display: flex; align-items: center; gap: .55rem; margin-top: .9rem; flex-wrap: wrap; }
.icon-btn .i-play, .icon-btn .i-muted { display: none; }
.player.is-paused #btn-play .i-pause { display: none; }
.player.is-paused #btn-play .i-play { display: block; }
#btn-mute[aria-pressed="true"] .i-sound { display: none; }
#btn-mute[aria-pressed="true"] .i-muted { display: block; }
.dots { list-style: none; margin: 0; padding: 0; display: flex; flex: 1; flex-wrap: wrap; justify-content: center; min-width: 0; }
.dots button {
  width: var(--tap); height: var(--tap); border: 0; background: transparent; cursor: pointer; display: grid; place-items: center; padding: 0; border-radius: 50%;
}
.dots button::before { content: ""; width: 11px; height: 11px; border-radius: 50%; background: transparent; border: 2px solid var(--line-strong); transition: transform .15s, background .15s; }
.dots button.done::before { background: var(--line-strong); }
.dots button[aria-current="step"]::before { background: var(--accent); border-color: var(--accent); transform: scale(1.35); }
.dots button:focus-visible { outline: none; box-shadow: var(--focus); }
.dots button { position: relative; }
.dots button::before { position: relative; z-index: 1; }
.player:not(.is-paused) .dots button[aria-current="step"]::after {
  content: ""; position: absolute; inset: 0; margin: auto; width: 15px; height: 15px; border-radius: 50%;
  background: color-mix(in srgb, var(--hl-yellow) 75%, transparent); z-index: 0;
  animation: dot-glow 1.6s ease-in-out infinite;
}
@keyframes dot-glow { 0%, 100% { transform: scale(1.3); opacity: .9; } 50% { transform: scale(2); opacity: .35; } }
/* The other course answered (the course filter had nothing): said plainly above the slide. */
.cross-note {
  margin: 0 0 .7rem; font-size: .95rem; color: var(--ink); padding: .45rem .75rem .45rem 1.1rem; border-radius: var(--radius-sm);
  background: var(--legal-bg) linear-gradient(90deg, transparent 6px, var(--legal-margin) 6px 8px, transparent 8px);
}
.audio-note {
  margin: .6rem 0 0; font-size: .88rem; color: var(--ink); padding: .45rem .75rem .45rem 1.1rem; border-radius: var(--radius-sm);
  background: var(--legal-bg) linear-gradient(90deg, transparent 6px, var(--legal-margin) 6px 8px, transparent 8px);
}

/* Where this is in the course: an index card, its title in pen above a red rule, a strip of tape on top */
.source-card {
  position: relative; margin-top: 1.4rem; border: 0; border-radius: 2px; padding: .7rem 1.1rem 1rem;
  background: var(--surface); box-shadow: var(--shadow);
}
.source-card::before {
  content: ""; position: absolute; top: -11px; right: 48px; width: 76px; height: 22px;
  background: var(--tape); transform: rotate(4deg); box-shadow: 0 1px 2px rgba(0, 0, 0, .12); pointer-events: none;
}
.card-h {
  font: 400 1.3rem/1.25 var(--hand); letter-spacing: 0; text-transform: none; color: var(--accent);
  margin: 0 -1.1rem .7rem; padding: 0 1.1rem .45rem; border-bottom: 2px solid var(--legal-margin);
}
.source-card-body { display: flex; gap: 1.1rem; align-items: flex-start; }
.thumb {
  width: 136px; aspect-ratio: 16 / 9; object-fit: contain; background: var(--slide-bg); border: 4px solid #fff; border-radius: 1px; flex: none;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .25); transform: rotate(-1.5deg);
}
.source-meta { margin: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: .4rem 1.25rem; flex: 1; min-width: 0; }
.source-meta dt { font: 500 .7rem var(--font-mono); color: var(--danger); text-transform: uppercase; letter-spacing: .1em; }
.source-meta dd { margin: 0; font-weight: 500; }

/* dock */
.dock { border-left: 0; background: var(--surface); display: flex; flex-direction: column; min-height: 0; view-transition-name: dock; box-shadow: -1px 0 0 var(--line), -12px 0 24px -20px rgba(0, 0, 0, .35); }
.dock-head { display: flex; gap: .5rem; padding: .75rem; border-bottom: 1px solid var(--line); align-items: center; }
.dock-head select { flex: 1; font: 500 .85rem var(--font-mono); }
.dock-toggle { display: none; }
.dock-log { flex: 1; overflow-y: auto; padding: .85rem; outline: none; }
.log { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .8rem; }
.msg { max-width: 100%; }
.msg-user {
  align-self: flex-end; background: var(--accent-soft); color: var(--ink); padding: .55rem .85rem;
  border-radius: 14px 14px 3px 14px; max-width: 90%;
}
.msg-twin { color: var(--ink); }
.msg-twin p { margin: 0 0 .5rem; }
.msg-error { color: var(--ink-2); font-size: .95rem; }
.sources-h { font: 500 .72rem var(--font-mono); letter-spacing: .12em; text-transform: uppercase; color: var(--ink-2); margin: .8rem 0 .45rem; }
.sources { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .4rem; }
.source-btn {
  width: 100%; display: flex; gap: .65rem; align-items: center; text-align: left; padding: .4rem; min-height: var(--tap);
  border: 1.5px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); cursor: pointer; font-size: .88rem;
}
.source-btn:hover { border-color: var(--accent); }
.source-btn:focus-visible { outline: none; box-shadow: var(--focus); }
.source-btn[aria-current="true"] { border-color: var(--accent); background: var(--accent-soft); }
.source-btn img { width: 64px; aspect-ratio: 16 / 9; object-fit: contain; background: var(--slide-bg); border-radius: 1px; flex: none; border: 2px solid #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, .25); }
.source-btn .src-l1 { font-weight: 600; display: block; }
.source-btn .src-l2 { color: var(--ink-3); display: block; }
/* follow-up questions are sticky notes, yellow and pink, tilted a little until you point at one */
.followups { padding: .6rem .85rem .8rem; border-top: 1px solid var(--line); }
.followups .chips { gap: .7rem; }
.followups .chip {
  font-size: .92rem; border: 0; border-radius: 1px; background: var(--note-bg); color: var(--paper-ink);
  padding: .6rem .9rem; box-shadow: 0 1px 1px rgba(0, 0, 0, .12), 0 10px 14px -10px rgba(0, 0, 0, .45); transform: rotate(-1.5deg);
}
.followups li:nth-child(2n) .chip { background: var(--note-pink); transform: rotate(1.2deg); }
.followups .chip:hover, .followups .chip:focus-visible { transform: rotate(0) translateY(-2px); background: var(--note-bg); }
.followups li:nth-child(2n) .chip:hover, .followups li:nth-child(2n) .chip:focus-visible { background: var(--note-pink); }
.dock-form { display: flex; gap: .5rem; padding: .75rem; border-top: 1px solid var(--line); view-transition-name: ask-box; }
.dock-form input { flex: 1; min-width: 0; border-color: var(--accent); border-width: 2px; }
.ai-label-dock { margin: 0; padding: 0 .75rem .6rem; font-size: .75rem; }

.slide-dialog { border: 0; border-radius: var(--radius-sm); background: var(--surface); color: var(--ink); padding: .8rem; width: min(960px, 94vw); box-shadow: 0 30px 60px -20px rgba(0, 0, 0, .6); }
.slide-dialog::backdrop { background: rgba(28, 39, 35, .7); }
.dialog-head { display: flex; justify-content: space-between; align-items: center; gap: .5rem; margin-bottom: .5rem; }
.slide-dialog img { width: 100%; background: var(--slide-bg); border-radius: 1px; }
.contact-dialog { width: min(420px, 92vw); }
.contact-body p { margin: .25rem 0; overflow-wrap: anywhere; }
.contact-name { font-weight: 600; }
.contact-note { color: var(--ink-2, inherit); font-size: .9rem; margin-top: .75rem !important; }
#stage-message-text { white-space: pre-line; }

/* ---------- phone ---------- */
@media (max-width: 760px) {
  body { font-size: 16px; }
  /* no margin rule on a phone: the column is too narrow for it */
  .idle, #screen-login, #screen-offline { background-image: none; }
  .app[data-view="presenting"] { display: block; height: auto; }
  .stage { overflow: visible; }
  /* --dock-h is measured in app.js, so the bottom bar never covers the end of the stage */
  .stage-inner { padding: .75rem .75rem calc(var(--dock-h, 8.5rem) + 1rem); }
  .media:not(.has-code) .slide-frame, .media.has-code .slide-frame { width: 100%; }
  .code { max-height: 28vh; font-size: .78rem; }
  .caption { font-size: 1rem; padding: 12px 12px 12px 46px; min-height: 0;
    background-image:
      linear-gradient(90deg, transparent 24px, var(--legal-margin) 24px 26px, transparent 26px 30px, var(--legal-margin) 30px 32px, transparent 32px),
      repeating-linear-gradient(transparent 0 31px, var(--legal-rule) 31px 32px); }
  /* spec: on a phone the source card sits directly under the slide, above the caption */
  .player { display: flex; flex-direction: column; }
  .player > .cross-note { order: -1; }
  .player > .media { order: 0; }
  .player > .clip-row { order: 1; }
  .player > .source-card { order: 2; margin-top: .8rem; }
  .player > .narration { order: 3; }
  .narration-note { margin-left: 0; flex-basis: 100%; }
  .caption { max-height: calc(5 * 32px + 24px); }
  .player > .controls { order: 4; }
  .player > .audio-note { order: 5; }
  .source-card { padding: .55rem .8rem .7rem; }
  .source-card::before { right: 24px; width: 56px; height: 18px; top: -9px; }
  .card-h { font-size: 1.15rem; margin: 0 -.8rem .55rem; padding: 0 .8rem .35rem; }
  .source-card-body { gap: .75rem; }
  .source-card-body { flex-direction: row; }
  .thumb { width: 92px; border-width: 3px; }
  /* compact: the values read on their own, so the labels are kept for screen readers only */
  .source-meta { grid-template-columns: auto 1fr; gap: .15rem .9rem; font-size: .92rem; line-height: 1.35; }
  .source-meta > div:nth-child(-n+2) { grid-column: 1 / -1; }
  .source-meta dt { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .source-meta > div:nth-child(1) dd { font-weight: 600; }
  /* prev, play, next, mute on one row; the progress dots get their own row */
  .controls { gap: .5rem; }
  .controls #btn-mute { margin-left: auto; }
  .dots { order: 10; flex-basis: 100%; }
  .course-filter { padding-left: 8px; }
  .course-filter label > span { padding: 0 .8rem; }
  .course-filter .cf-title { display: none; }

  .dock {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 20; border-left: 0; border-top: 1px solid var(--line);
    box-shadow: 0 -4px 18px rgba(0, 0, 0, .14); max-height: 80dvh; padding-bottom: env(safe-area-inset-bottom);
  }
  .dock-head { padding: .5rem .75rem; }
  .dock-toggle { display: inline-flex; }
  .dock-log { display: none; }
  .dock.expanded .dock-log { display: block; max-height: 55dvh; }
  .followups { max-height: 30dvh; overflow-y: auto; }
  .dock-form { padding: .5rem .75rem; }
  .ai-label-dock { display: none; }
  .stage-message { min-height: 50vh; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
  ::view-transition-group(*) { animation: none !important; }
  .slide-frame.is-speaking { transform: none; }
  .slide-mark { animation: none; }
  .player:not(.is-paused) .dots button[aria-current="step"]::after { animation: none; }
  /* nothing tilts or lifts when pointed at */
  .btn:hover, .followups .chip:hover, .followups .chip:focus-visible,
  .followups li:nth-child(2n) .chip:hover, .followups li:nth-child(2n) .chip:focus-visible { transform: none; }
}

/* ---------- settings page ---------- */
.admin { max-width: 1040px; margin: 0 auto; padding: 1.5rem var(--gutter) 4rem; }
.admin-head { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; flex-wrap: wrap; margin-bottom: 1rem; }
/* the section menu: the site's index tabs on a strip of lab bench, full width */
.admin-nav {
  position: sticky; top: 0; z-index: 5; margin: 0 calc(-1 * var(--gutter)) 1.4rem; padding: .55rem var(--gutter) 0;
  background: var(--bench); box-shadow: 0 0 0 100vmax var(--bench); clip-path: inset(0 -100vmax);
  overflow-x: auto; scrollbar-width: none;
}
.admin-nav::-webkit-scrollbar { display: none; }
.admin-nav ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 4px 5px; }
@media (max-width: 760px) {
  /* a phone scrolls the tabs sideways inside the strip, as collier.phd does */
  .admin-nav ul { flex-wrap: nowrap; padding-right: 40px; }
}
.admin-nav li { flex: none; }
.admin-nav li:nth-child(8n+1) a { --tab: var(--tab-1); } .admin-nav li:nth-child(8n+2) a { --tab: var(--tab-2); }
.admin-nav li:nth-child(8n+3) a { --tab: var(--tab-3); } .admin-nav li:nth-child(8n+4) a { --tab: var(--tab-4); }
.admin-nav li:nth-child(8n+5) a { --tab: var(--tab-5); } .admin-nav li:nth-child(8n+6) a { --tab: var(--tab-6); }
.admin-nav li:nth-child(8n+7) a { --tab: var(--tab-7); } .admin-nav li:nth-child(8n+8) a { --tab: var(--tab-8); }
.admin-nav a {
  display: inline-flex; align-items: center; min-height: var(--tap); padding: 0 .85rem; border-radius: 9px 9px 0 0;
  background: var(--tab, var(--tab-8)); color: var(--paper-ink); text-decoration: none; white-space: nowrap;
  font: 500 .8rem var(--font-mono); letter-spacing: -.01em;
  box-shadow: inset 0 -8px 10px -8px rgba(0, 0, 0, .28), inset 0 1px 0 rgba(255, 255, 255, .5);
  transform: translateY(4px); transition: transform .18s ease;
}
.admin-nav a:hover { transform: translateY(0); color: var(--paper-ink); }
.admin-nav a[aria-current="true"] { transform: translateY(0); background: var(--bg); color: var(--ink); font-weight: 600; box-shadow: none; }
.admin-nav a:focus-visible { outline: 3px solid var(--accent); outline-offset: -5px; }
.panel { background: var(--surface); border: 0; border-radius: var(--radius-sm); padding: 1.4rem; margin-bottom: 1.5rem; scroll-margin-top: 4.5rem; box-shadow: var(--shadow); }
.panel > h2 { font-size: 1.75rem; }
.panel-intro { color: var(--ink-2); margin-bottom: 1rem; }
.grid-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 1rem; }
.field { display: flex; flex-direction: column; gap: .3rem; margin-bottom: .9rem; }
.field > label, .field > .label { font-weight: 600; font-size: .92rem; }
.actions { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; }
.status-line { font-size: .9rem; color: var(--ink-2); min-height: 1.4em; margin: .5rem 0 0; }
.status-line.ok { color: var(--ok); }
.status-line.err { color: var(--danger); }

.kv { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: .5rem; margin: 0; }
.kv > div { background: var(--surface-2); border-radius: var(--radius-sm); padding: .55rem .75rem; }
.kv dt { font: 500 .7rem var(--font-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); }
.kv dd { margin: 0; font-weight: 600; font-variant-numeric: tabular-nums; }

.pill { display: inline-flex; align-items: center; gap: .3rem; font: 600 .72rem/1.5 var(--font-mono); letter-spacing: .02em; padding: .1rem .5rem; border-radius: 10px 3px 9px 3px; background: var(--surface-2); color: var(--ink-2); white-space: nowrap; }
.pill.ok { background: var(--ok-soft); color: var(--ok); }
.pill.warn { background: var(--warn-soft); color: var(--warn); }
.pill.err { background: var(--danger-soft); color: var(--danger); }
.pill.info { background: var(--accent-soft); color: var(--accent); }
.pill.off { background: transparent; border: 1px dashed var(--line-strong); color: var(--ink-3); }

.model-list { border: 1.5px solid var(--line); border-radius: var(--radius-sm); max-height: 320px; overflow-y: auto; margin: .25rem 0 0; padding: 0; list-style: none; }
.model-list li + li { border-top: 1px solid var(--line); }
.model-opt { width: 100%; text-align: left; background: transparent; border: 0; padding: .55rem .75rem; cursor: pointer; display: grid; gap: .1rem; min-height: var(--tap); }
.model-opt:hover { background: var(--surface-2); }
.model-opt[aria-pressed="true"] { background: var(--accent-soft); box-shadow: inset 3px 0 0 var(--accent); }
.model-opt:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.model-opt .m-id { font-family: var(--font-mono); font-size: .85rem; }
.model-opt .m-meta { font-size: .8rem; color: var(--ink-3); }
pre.json { background: var(--code-bg); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: .75rem; overflow: auto; max-height: 360px; font: .8rem/1.5 var(--font-mono); margin: .5rem 0 0; white-space: pre-wrap; word-break: break-word; }

.voice-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: .5rem; }
.voice { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: .6rem .75rem; display: flex; align-items: center; gap: .5rem; }
.voice.selected { border-color: var(--accent); background: var(--accent-soft); }
.voice label { flex: 1; display: flex; gap: .5rem; align-items: center; cursor: pointer; min-height: var(--tap); }
.voice input { width: 18px; height: 18px; accent-color: var(--accent); }
.voice .v-name { font-weight: 600; display: block; }
.voice .v-cat { font-size: .78rem; color: var(--ink-3); display: block; }
.voice-group + .voice-group { margin-top: .75rem; }
.voice-group .h-sub { display: flex; align-items: center; gap: .5rem; margin-bottom: .1rem; }
.voice-custom { flex-wrap: wrap; }
.voice-custom input[type="text"] { flex: 1 1 12rem; min-width: 0; }

.table-wrap { overflow-x: auto; border: 1.5px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); }
table.data { width: 100%; border-collapse: collapse; font-size: .9rem; }
table.data th, table.data td { padding: .5rem .65rem; text-align: left; vertical-align: top; border-bottom: 1px solid var(--line); }
table.data th { font: 500 .7rem var(--font-mono); color: var(--ink-2); text-transform: uppercase; letter-spacing: .08em; background: var(--surface-2); position: sticky; top: 0; }
table.data tr:last-child td { border-bottom: 0; }
table.data td.num { font-variant-numeric: tabular-nums; text-align: right; }
table.data tr.is-hidden td { color: var(--ink-3); }
.pills { display: flex; flex-wrap: wrap; gap: .25rem; list-style: none; margin: 0; padding: 0; }
.course-block { margin-top: 1rem; }
.course-block > h3 { font-size: 1.1rem; display: flex; gap: .5rem; align-items: baseline; flex-wrap: wrap; }
.subform { border: 1px dashed var(--line-strong); border-radius: var(--radius-sm); padding: .9rem; margin-top: .75rem; }
.subform legend { font-weight: 600; padding: 0; margin-bottom: .5rem; }
.subform .grid-2 { gap: 0 1rem; }
.grid-2.top { align-items: start; }
input[type="file"] { width: 100%; font-size: .9rem; }
input[type="file"]::file-selector-button {
  min-height: var(--tap); margin-right: .75rem; padding: 0 1rem; border-radius: var(--sketch);
  border: 2px solid var(--ink); background: var(--surface); color: var(--ink); font: 600 .85rem var(--font-mono); cursor: pointer;
}
input[type="file"]:focus-visible { outline: none; }
input[type="file"]:focus-visible::file-selector-button { box-shadow: var(--focus); }
.table-wrap:focus-visible { outline: none; box-shadow: var(--focus); }

@media (max-width: 760px) {
  .panel { padding: 1rem; }
  .kv { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* tables become one card per row on a phone */
  table.data.stack thead { display: none; }
  table.data.stack, table.data.stack tbody, table.data.stack tr, table.data.stack td { display: block; }
  table.data.stack tr { display: grid; grid-template-columns: auto 1fr; gap: .3rem .75rem; padding: .7rem .75rem; border-bottom: 1px solid var(--line); }
  table.data.stack tr:last-child { border-bottom: 0; }
  table.data.stack td { padding: 0; border: 0; text-align: left; }
  table.data.stack td.full { grid-column: 1 / -1; }
  table.data.stack td[data-label]::before { content: attr(data-label) ": "; color: var(--ink-3); font-size: .8rem; }
  table.data.stack td.num { text-align: left; }
}
.progress { width: 100%; height: 8px; border-radius: 4px; background: var(--surface-2); overflow: hidden; margin-top: .35rem; }
.progress > span { display: block; height: 100%; background: var(--accent); width: 0; transition: width .15s; }
.upload-list { list-style: none; margin: .5rem 0 0; padding: 0; display: flex; flex-direction: column; gap: .5rem; }
.upload-item { font-size: .88rem; }
.src-path { font-family: var(--font-mono); font-size: .8rem; word-break: break-all; }
.bare { border: 0; padding: 0; margin: 0; min-width: 0; }
.h-sub { font-size: 1rem; margin-top: 1rem; }

/* ---------------- Settings: prompts (prompt editor) ---------------- */
.prompt-layout { display: grid; grid-template-columns: minmax(220px, 280px) minmax(0, 1fr); gap: 1.25rem; align-items: start; margin-top: 1rem; }
.prompt-list { border: 1px solid var(--line); border-radius: var(--radius-sm); margin: .25rem 0 0; padding: 0; list-style: none; }
.prompt-list li + li { border-top: 1px solid var(--line); }
.prompt-opt { width: 100%; text-align: left; background: transparent; border: 0; padding: .6rem .75rem; cursor: pointer; display: grid; gap: .25rem; min-height: var(--tap); }
.prompt-opt:hover { background: var(--surface-2); }
.prompt-opt[aria-pressed="true"] { background: var(--accent-soft); box-shadow: inset 3px 0 0 var(--accent); }
.prompt-opt:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.prompt-opt .m-id { font-weight: 600; }
.prompt-opt .m-meta { font-size: .8rem; color: var(--ink-3); display: flex; flex-wrap: wrap; gap: .3rem; align-items: center; }
.pe-title { font-size: 1.1rem; margin: 0 0 .25rem; }
textarea.mono { font-family: var(--font-mono); font-size: .82rem; line-height: 1.5; min-height: 18rem; tab-size: 2; }
.review { border: 1px solid var(--line-strong); border-radius: var(--radius-sm); padding: .75rem; margin-top: .75rem; background: var(--surface-2); }
.review h4 { margin: 0 0 .25rem; font-size: 1rem; }
.review h4:focus { outline: none; }
.diff { max-height: 420px; overflow: auto; background: var(--code-bg); border: 1px solid var(--line); border-radius: var(--radius-sm); margin: .5rem 0 .75rem; }
.diff:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.diff-text { margin: 0; padding: .75rem; font: .8rem/1.55 var(--font-mono); white-space: pre-wrap; word-break: break-word; }
.diff-text ins { background: var(--ok-soft); color: var(--ok); text-decoration: underline; text-decoration-thickness: 2px; }
.diff-text del { background: var(--danger-soft); color: var(--danger); text-decoration: line-through; }
.after-save { display: flex; flex-wrap: wrap; gap: .5rem 1rem; align-items: center; margin-top: .75rem; }
.after-save p { margin: 0; flex: 1 1 260px; }
.after-save .btn { text-decoration: none; }
.history-list { list-style: none; margin: .25rem 0 0; padding: 0; display: grid; gap: .5rem; }
.history-item { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: .55rem .75rem; display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; justify-content: space-between; }
.history-item.live { border-color: var(--ok); }
.history-item .v-name { font-weight: 600; }
@media (max-width: 760px) {
  .prompt-layout { grid-template-columns: minmax(0, 1fr); }
}
/* ---------- settings: evals ---------- */
/* Chart series colors: the dataviz reference palette, fixed order, assigned per model (never by rank).
   Checked with the dataviz palette validator against --surface in both modes (adjacent pairs). Light slots 3 to 5
   sit under 3:1 on white, so the chart always ships direct labels, a legend and a table view. */
:root {
  --series-1: #2a78d6; --series-2: #eb6834; --series-3: #1baf7a; --series-4: #eda100;
  --series-5: #e87ba4; --series-6: #008300; --series-7: #4a3aa7; --series-8: #e34948;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --series-1: #3987e5; --series-2: #d95926; --series-3: #199e70; --series-4: #c98500;
    --series-5: #d55181; --series-6: #008300; --series-7: #9085e9; --series-8: #e66767;
  }
}
:root[data-theme="dark"] {
  --series-1: #3987e5; --series-2: #d95926; --series-3: #199e70; --series-4: #c98500;
  --series-5: #d55181; --series-6: #008300; --series-7: #9085e9; --series-8: #e66767;
}
.ev-row { display: flex; flex-wrap: wrap; gap: .5rem .75rem; align-items: flex-end; }
.ev-row > .field { margin-bottom: .5rem; }
.ev-row > select { width: auto; min-width: 9rem; }
.ev-row > input { flex: 1 1 12rem; min-width: 0; width: auto; }
.ev-grow { flex: 1 1 14rem; min-width: 0; }
.ev-end { justify-content: flex-end; }
.ev-chips { margin-top: .4rem; min-height: 1.6rem; }
.ev-chips .pill { font-size: .85rem; padding: .2rem .25rem .2rem .6rem; }
/* a 44px target that only looks 28px wide: the negative margins keep the chip compact */
.ev-chips button { border: 0; background: transparent; color: inherit; cursor: pointer; min-width: var(--tap); min-height: var(--tap); margin: -8px -8px -8px -4px; border-radius: 50%; font-size: 1rem; line-height: 1; }
.ev-chips button:hover { background: var(--surface); }
.ev-chips button:focus-visible { outline: none; box-shadow: var(--focus); }
.ev-cats { margin: .5rem 0; }
.ev-catpick { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: .1rem .75rem; font-size: .88rem; }
.ev-catpick label, label.check { display: flex; gap: .45rem; align-items: center; min-height: var(--tap); font-weight: 400; }
.ev-details { margin: .5rem 0 1rem; }
.ev-details > summary { cursor: pointer; min-height: var(--tap); display: flex; align-items: center; color: var(--accent); font-weight: 600; }
.ev-details > summary:focus-visible { outline: none; box-shadow: var(--focus); border-radius: var(--radius-sm); }
.ev-scroll { max-height: 420px; overflow: auto; }
.ev-scroll-lg { max-height: 640px; overflow: auto; }
.ev-estimate { margin-top: .75rem; background: var(--surface-2); border-radius: var(--radius-sm); padding: .75rem .9rem; font-size: .92rem; }
.ev-estimate ul { margin: .35rem 0 0; padding-left: 1.1rem; }
.ev-warn { background: var(--warn-soft); border-left: 3px solid var(--warn); padding: .45rem .7rem; border-radius: var(--radius-sm); margin: .5rem 0; font-size: .9rem; }
.ev-active { border: 1px solid var(--line-strong); border-radius: var(--radius-sm); padding: .9rem; margin: 1rem 0; }
.ev-active-title { font-weight: 600; margin: 0; }
.ev-h4 { font-size: 1.05rem; margin: 1rem 0 .4rem; }
.ev-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); gap: .75rem; margin-top: .6rem; }
.ev-card { border: 0; border-top: 6px solid var(--tab-2); border-radius: 2px; padding: .8rem .9rem; display: flex; flex-direction: column; gap: .35rem; background: var(--surface); box-shadow: var(--shadow); }
.ev-card.is-excluded { opacity: .8; border-top-color: var(--line-strong); outline: 1.5px dashed var(--line-strong); }
.ev-card h4 { margin: 0; font-size: 1rem; }
.ev-card .meta { font-size: .82rem; color: var(--ink-3); }
.ev-card dl { display: grid; grid-template-columns: 1fr auto; gap: .1rem .75rem; margin: .2rem 0; font-size: .86rem; }
.ev-card dt { color: var(--ink-2); }
.ev-card dd { margin: 0; font-weight: 600; font-variant-numeric: tabular-nums; text-align: right; }
.ev-card .gen { font-size: .84rem; font-weight: 600; margin-top: .25rem; display: flex; align-items: center; gap: .4rem; word-break: break-word; }
.ev-card .actions { margin-top: auto; padding-top: .3rem; }
.ev-note { font-size: .82rem; color: var(--ink-2); background: var(--surface-2); border-radius: var(--radius-sm); padding: .35rem .55rem; margin: 0; }
.ev-key { display: inline-block; width: 14px; height: 3px; border-radius: 2px; flex: none; }
.ev-chart { margin: .5rem 0 0; position: relative; }
.ev-legend { display: flex; flex-wrap: wrap; gap: .25rem 1rem; font-size: .85rem; color: var(--ink-2); margin: .25rem 0 .5rem; }
.ev-legend span { display: inline-flex; align-items: center; gap: .4rem; }
.ev-plot svg { display: block; width: 100%; height: auto; overflow: visible; }
.ev-plot .grid { stroke: var(--line); stroke-width: 1; }
.ev-plot .axis { stroke: var(--line-strong); stroke-width: 1; }
.ev-plot text { fill: var(--ink-3); font: 11px var(--font-mono); }
.ev-plot text.lbl { fill: var(--ink-2); font-size: 11.5px; }
.ev-plot .hit { fill: transparent; cursor: pointer; }
.ev-plot .hit:focus { outline: none; }
.ev-plot .hit:focus-visible + .dot, .ev-plot .hit:hover + .dot { r: 6; }
.ev-plot .empty { fill: var(--ink-3); font-size: 13px; }
.ev-tip { position: absolute; z-index: 4; pointer-events: none; background: var(--surface); border: 1px solid var(--line-strong); border-radius: var(--radius-sm); box-shadow: var(--shadow); padding: .45rem .6rem; font-size: .82rem; max-width: 260px; }
.ev-tip strong { display: block; font-size: 1rem; font-variant-numeric: tabular-nums; color: var(--ink); }
.ev-tip span { color: var(--ink-2); display: block; }
.ev-detail { margin-top: 1.25rem; border-top: 1px solid var(--line); padding-top: .5rem; }
.ev-detail:focus { outline: none; }
.ev-results td { font-size: .86rem; }
.ev-results .q { max-width: 28rem; }
.ev-results details summary { cursor: pointer; color: var(--accent); font-size: .82rem; margin-top: .3rem; }
.ev-results .narr { white-space: pre-wrap; background: var(--surface-2); border-radius: var(--radius-sm); padding: .4rem .55rem; margin: .3rem 0; }
.ev-jv { display: flex; flex-direction: column; gap: .35rem; min-width: 13rem; }
.ev-legend-list { list-style: none; margin: .5rem 0 1rem; padding: 0; font-size: .8rem; color: var(--ink-2); display: flex; flex-direction: column; gap: .15rem; }
.ev-legend-list li { padding-left: .9rem; text-indent: -.9rem; }
.ev-legend-list li::before { content: "· "; color: var(--ink-3); }
.ev-legend-list strong { color: var(--ink); font-weight: 600; }
.ev-plot text.axis-title { fill: var(--ink-2); font-size: 11.5px; font-weight: 600; }
.ev-jv .scores { font-size: .78rem; color: var(--ink-3); font-variant-numeric: tabular-nums; }

/* Settings > Draft slides */
.hs-list { list-style: none; margin: .5rem 0 0; padding: 0; display: grid; gap: 1.25rem; }
.hs-item { border: 0; border-radius: 2px; padding: .8rem; background: var(--surface); display: grid; gap: .6rem; box-shadow: var(--shadow); }
.hs-head { display: flex; gap: .6rem; align-items: center; flex-wrap: wrap; }
.hs-edit { width: 100%; font: .85rem/1.45 var(--font-mono); }
#hs-preview { margin-top: .75rem; display: grid; gap: .5rem; }

/* ---------- arriving from collier.phd (public/handoff.js; the frame itself is in handoff.css) ---------- */
/* The legal page slides up and fades, showing the passcode or idle screen underneath. It starts gently
   (the page lifts off, then goes), so the first frames of the reveal still read as the legal pad. */
html.handoff-out .handoff-frame {
  transform: translateY(-100%); opacity: 0;
  transition: transform var(--ho-reveal-ms) cubic-bezier(.45, 0, .2, 1), opacity var(--ho-reveal-ms) cubic-bezier(.6, 0, .4, 1);
}
/* The question box (or the passcode field) draws its border in pen, edge by edge. */
#passcode { border: 2px solid var(--accent); border-radius: 6px; }
.ho-host { position: relative; }
.ho-drawing { border-color: transparent !important; }
.ask-form.ho-drawing, #passcode.ho-drawing { box-shadow: var(--shadow) !important; }
.ho-draw { position: absolute; pointer-events: none; overflow: visible; z-index: 1; }
.ho-draw rect {
  fill: none; stroke: var(--accent); stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 1 1; stroke-dashoffset: 1;
  animation: ho-draw var(--ho-reveal-ms) var(--ho-ease) 60ms forwards;
}
@keyframes ho-draw { to { stroke-dashoffset: 0; } }
/* Reduced motion: no movement, a 150 ms crossfade (this outranks the global reduced-motion rule above). */
@media (prefers-reduced-motion: reduce) {
  html.handoff-out .handoff-frame {
    transform: none;
    transition: opacity var(--ho-reduced-ms) linear !important;
    transition-duration: var(--ho-reduced-ms) !important;
  }
}

/* ---------- my cartoon avatars (added Oct 8) ---------- */
/* the waving sticker greets on the passcode and idle screens, stuck on slightly crooked like the site's notes */
.twin-greet {
  display: block; width: 150px; height: auto; margin: 0 auto .4rem; transform: rotate(-3deg);
  filter: drop-shadow(0 3px 6px rgba(0, 0, 0, .18));
}
#login-form .twin-greet { width: 120px; }
/* the small round avatar at the head of the chat dock */
.dock-avatar { width: 34px; height: 34px; border-radius: 50%; flex: none; box-shadow: 0 0 0 1.5px var(--line); }
@media (max-width: 760px) {
  .twin-greet { width: 110px; }
  #login-form .twin-greet { width: 96px; }
  .dock-avatar { width: 28px; height: 28px; }
}
