:root {
  color-scheme: light dark;
  --bg: #fbfaf8;
  --panel: #ffffff;
  --line: #e5e1da;
  --ink: #1c1a17;
  --muted: #6f6a62;
  --accent: #b4531f;
  --accent-soft: #fbeee5;
  --teacher: #b4531f;
  --student: #2f6f6a;
  --ok: #2f6f4a;
  --bad: #a32c2c;
  --radius: 10px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #14130f;
    --panel: #1c1a17;
    --line: #302c26;
    --ink: #ece7de;
    --muted: #9a938a;
    --accent: #e08a53;
    --accent-soft: #2a1e15;
    --teacher: #e08a53;
    --student: #6cbdb4;
    --ok: #74c39a;
    --bad: #e08585;
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 15px/1.55 ui-sans-serif, system-ui, "Segoe UI", Roboto, sans-serif;
}

.wrap { max-width: 940px; margin: 0 auto; padding: 32px 20px 80px; }

/* Links in prose. Set once, globally: a default-blue link inside a warm
   palette reads as an artefact of an unfinished page. */
a { color: var(--accent); }
a:hover { text-decoration: none; }

header.top {
  display: flex; align-items: baseline; gap: 14px;
  flex-wrap: wrap; margin-bottom: 6px;
}
header.top h1 { font-size: 21px; margin: 0; letter-spacing: -0.01em; }
header.top .sub { color: var(--muted); font-size: 13px; }
header.top a { color: var(--accent); text-decoration: none; font-size: 13px; }
header.top a:hover { text-decoration: underline; }

.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 20px;
  margin-top: 20px;
}
.panel h2 {
  font-size: 12px; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--muted); margin: 0 0 14px; font-weight: 600;
}

/* upload */
.drop {
  border: 1.5px dashed var(--line); border-radius: var(--radius);
  padding: 30px 20px; text-align: center; cursor: pointer;
  transition: border-color .15s, background .15s;
}
.drop:hover, .drop.over { border-color: var(--accent); background: var(--accent-soft); }
.drop strong { display: block; font-size: 15px; margin-bottom: 4px; }
.drop span { color: var(--muted); font-size: 13px; }

.opts {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 14px; margin-top: 18px;
}
label.field { display: block; font-size: 12px; color: var(--muted); }
label.field span { display: block; margin-bottom: 5px; }
select, input[type="number"], input[type="text"] {
  width: 100%; padding: 7px 9px; font: inherit; font-size: 14px;
  color: var(--ink); background: var(--bg);
  border: 1px solid var(--line); border-radius: 6px;
}
.checkline { display: flex; align-items: center; gap: 8px; font-size: 13px; margin-top: 14px; }

button {
  font: inherit; font-size: 14px; font-weight: 500;
  padding: 9px 18px; border-radius: 7px; cursor: pointer;
  border: 1px solid var(--accent); background: var(--accent); color: #fff;
}
button:hover { filter: brightness(1.08); }
button:disabled { opacity: .5; cursor: not-allowed; }
button.ghost { background: transparent; color: var(--accent); }

/* jobs */
table { width: 100%; border-collapse: collapse; font-size: 14px; }
th {
  text-align: left; font-size: 11px; text-transform: uppercase;
  letter-spacing: .06em; color: var(--muted); font-weight: 600;
  padding: 0 10px 8px 0; border-bottom: 1px solid var(--line);
}
td { padding: 11px 10px 11px 0; border-bottom: 1px solid var(--line); vertical-align: middle; }
tr:last-child td { border-bottom: none; }
td a { color: var(--accent); text-decoration: none; font-weight: 500; }
td a:hover { text-decoration: underline; }

.pill {
  display: inline-block; font-size: 11px; padding: 2px 8px;
  border-radius: 999px; border: 1px solid var(--line); color: var(--muted);
  text-transform: capitalize;
}
.pill.done { color: var(--ok); border-color: var(--ok); }
.pill.failed { color: var(--bad); border-color: var(--bad); }
.pill.running { color: var(--accent); border-color: var(--accent); }
.pill.cancelled { color: var(--muted); border-color: var(--muted); }

.bar { height: 5px; background: var(--line); border-radius: 3px; overflow: hidden; min-width: 80px; }
.bar i { display: block; height: 100%; background: var(--accent); transition: width .4s; }

.empty { color: var(--muted); font-size: 14px; padding: 8px 0; }
.err {
  color: var(--bad); font-size: 13px; margin-top: 12px;
  padding: 10px 12px; border: 1px solid var(--bad); border-radius: 7px;
  background: color-mix(in srgb, var(--bad) 8%, transparent);
}
.mono { font-family: ui-monospace, "Cascadia Code", Consolas, monospace; font-size: 12.5px; }

/* ---------------------------------------------------------------------
   Speaker palette. Both modes validated with the dataviz palette checker
   (lightness band, chroma floor, CVD separation, normal-vision floor,
   contrast vs surface). Slot 1 is always the teacher; students take
   slots 2..5 in descending talk time, so a speaker keeps its colour when
   the transcript is re-read or the teacher is corrected by hand.
   --------------------------------------------------------------------- */
:root {
  --sp1: #b4531f;
  --sp2: #1668c4;
  --sp3: #3f7d2a;
  --sp4: #8b46b0;
  --sp5: #8a6d00;
}
@media (prefers-color-scheme: dark) {
  :root {
    --sp1: #cf6f3b;
    --sp2: #4f8cd9;
    --sp3: #529f3d;
    --sp4: #a86ed0;
    --sp5: #9e881c;
  }
}

/* stat tiles */
.tiles {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 1px; background: var(--line);
  border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden;
}
.tile { background: var(--panel); padding: 14px 16px; }
.tile .k {
  font-size: 11px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--muted); font-weight: 600;
}
.tile .v {
  font-size: 25px; font-weight: 600; letter-spacing: -0.02em;
  margin-top: 5px; font-variant-numeric: tabular-nums;
}
.tile .n { font-size: 12px; color: var(--muted); margin-top: 2px; }

/* proportion bar + timeline share the 2px surface gap between fills */
.prop { display: flex; gap: 2px; height: 26px; margin: 4px 0 10px; }
.prop div { border-radius: 3px; min-width: 2px; }
.legend {
  display: flex; flex-wrap: wrap; gap: 14px;
  font-size: 12.5px; color: var(--muted); margin-top: 10px;
}
.legend span { display: inline-flex; align-items: center; gap: 6px; }
.legend i { width: 10px; height: 10px; border-radius: 2px; display: inline-block; }

.timeline {
  position: relative; height: 34px; margin-top: 6px;
  background: var(--line); border-radius: 4px; overflow: hidden;
}
.timeline i {
  position: absolute; top: 0; bottom: 0; display: block;
  box-shadow: 0 0 0 1px var(--panel);
}
.axis {
  display: flex; justify-content: space-between;
  font-size: 11px; color: var(--muted); margin-top: 5px;
  font-variant-numeric: tabular-nums;
}

#tip {
  position: fixed; z-index: 20; pointer-events: none;
  background: var(--panel); color: var(--ink);
  border: 1px solid var(--line); border-radius: 7px;
  padding: 7px 10px; font-size: 12.5px; line-height: 1.4;
  box-shadow: 0 4px 14px rgba(0,0,0,.14); max-width: 280px;
}
#tip b { font-weight: 600; }

/* teacher verdict */
.verdict { display: flex; gap: 16px; align-items: flex-start; flex-wrap: wrap; }
.verdict .who { font-size: 19px; font-weight: 600; }
.verdict ul { margin: 8px 0 0; padding-left: 18px; color: var(--muted); font-size: 13.5px; }
.warnbox {
  border: 1px solid var(--line); border-left: 3px solid var(--accent);
  border-radius: 6px; padding: 11px 13px; font-size: 13.5px;
  background: var(--accent-soft); margin-top: 14px;
}

/* review */
.review h3 { font-size: 15px; margin: 22px 0 6px; }
.review h3:first-child { margin-top: 0; }
.review p { margin: 0 0 8px; }
.review ul { margin: 6px 0 0; padding-left: 20px; }
.review li { margin-bottom: 6px; }
.tags { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 6px; }
.tag {
  font-size: 12.5px; padding: 3px 10px; border-radius: 999px;
  border: 1px solid var(--line); color: var(--muted);
}
.moment {
  border-left: 2px solid var(--line); padding: 2px 0 2px 12px; margin-bottom: 12px;
}
.moment .t { font-size: 12px; color: var(--accent); font-weight: 600;
             font-variant-numeric: tabular-nums; }

/* transcript */
.filters { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; align-items: center; }
.filters button {
  background: transparent; color: var(--muted); border-color: var(--line);
  padding: 5px 12px; font-size: 13px;
}
.filters button.on { color: #fff; background: var(--accent); border-color: var(--accent); }

.utt { display: flex; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--line); }
.utt:last-child { border-bottom: none; }
.utt .t {
  font-size: 12px; color: var(--muted); min-width: 44px;
  font-variant-numeric: tabular-nums; padding-top: 2px;
}
.utt .who { font-size: 12.5px; font-weight: 600; min-width: 82px; padding-top: 1px; }
.utt .tx { flex: 1; }
.utt.low .tx { opacity: .62; }
.utt.low .tx::after {
  content: " ~"; color: var(--muted); font-size: 11px;
}

/* metric glossary
   The brief asks each metric to carry its formula, its logic and how to read
   it. Rendering that beside the numbers is cheaper than asking anyone to
   trust a tile. */
.metricdef { padding: 16px 0; border-bottom: 1px solid var(--line); }
.metricdef:last-child { border-bottom: none; padding-bottom: 0; }
.metricdef h3 { font-size: 15px; margin: 0 0 8px; }
.metricdef p { margin: 0 0 7px; font-size: 14px; }
.metricdef p:last-child { margin-bottom: 0; }
.metricdef .formula {
  background: var(--bg); border: 1px solid var(--line); border-radius: 6px;
  padding: 8px 11px; margin-bottom: 9px; overflow-x: auto; white-space: nowrap;
}
.metricdef .reading { color: var(--muted); }

/* static demo: the session picker
   A list of the actual recordings, named as they are named in the dataset.
   Deliberately not a drag-and-drop zone: this page computes nothing, and a
   control that implies otherwise would be a lie about what it does. */
.picker { display: flex; flex-direction: column; gap: 8px; }
.sessionbtn {
  display: flex; flex-direction: column; align-items: stretch; gap: 9px;
  width: 100%; text-align: left; font: inherit; font-size: 14px;
  padding: 13px 15px; border-radius: var(--radius);
  border: 1px solid var(--line); background: var(--panel); color: var(--ink);
}
.sessionbtn:hover { border-color: var(--accent); background: var(--accent-soft); filter: none; }
.sessionbtn.on { border-color: var(--accent); background: var(--accent-soft); }
.sessionbtn .name {
  font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
  font-size: 13px; font-weight: 600; word-break: break-all;
}
.sessionbtn .row { display: flex; gap: 7px; align-items: center; flex-wrap: wrap; }
.sessionbtn .meta { color: var(--muted); font-size: 12.5px; margin-left: auto; }
.sessionbtn.on .meta { color: var(--ink); }

/* The settings a session was produced with, on the card rather than one click
   in. Two runs of one lesson differ only by these, and a number computed over
   the wrong language is worth nothing - so which language and which model is
   not detail, it is the first thing you need to know about a result. */
.chip {
  font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
  font-size: 11.5px; line-height: 1.7; white-space: nowrap;
  padding: 1px 9px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--bg); color: var(--muted);
}
.chip.lang { color: var(--ink); border-color: var(--accent); font-weight: 600; }

footer.note {
  margin-top: 30px; padding-top: 18px; border-top: 1px solid var(--line);
  color: var(--muted); font-size: 12.5px; line-height: 1.6;
}
footer.note code {
  font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
  font-size: 12px; background: var(--panel);
  border: 1px solid var(--line); border-radius: 4px; padding: 1px 5px;
}

/* server home page: the session library
   Same card as the static picker, but a link - each session has its own URL
   so one can be sent to someone. */
a.sessionbtn { text-decoration: none; }
a.sessionbtn:hover .name { color: var(--accent); }

nav.tabs { display: flex; gap: 6px; margin: 18px 0 0; }
nav.tabs a {
  font-size: 13px; text-decoration: none; padding: 7px 13px;
  border: 1px solid var(--line); border-radius: 999px;
  color: var(--muted); background: var(--panel);
}
nav.tabs a.on { color: #fff; background: var(--accent); border-color: var(--accent); }
nav.tabs a:hover:not(.on) { border-color: var(--accent); color: var(--accent); }

/* A recording sitting in assets/in that has not been processed. Muted, and
   never a link: there is nothing to open yet. */
.waiting {
  display: flex; gap: 14px; align-items: baseline; flex-wrap: wrap;
  padding: 10px 15px; border: 1px dashed var(--line);
  border-radius: var(--radius); margin-bottom: 8px; color: var(--muted);
}
.waiting .name {
  font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
  font-size: 13px; flex: 1; min-width: 240px; word-break: break-all;
}

/* The note on /process explaining why inference is not hosted. Body text is
   muted and the claims inside it are not, so the paragraphs can be skimmed for
   the numbers and read properly only if you want the reasoning. */
p.why {
  margin: 0 0 11px; color: var(--muted);
  font-size: 13.5px; line-height: 1.68; max-width: 74ch;
}
p.why:last-child { margin-bottom: 0; }
p.why b { color: var(--ink); font-weight: 600; }
p.why .mono { color: var(--ink); }

.cmd {
  font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
  font-size: 12.5px; background: var(--bg); border: 1px solid var(--line);
  border-radius: 6px; padding: 9px 12px; margin: 10px 0 0;
  overflow-x: auto; white-space: pre;
}
