/* Idioma styles. Bright, rounded and chunky, in the manner of the big
   language apps, but in orange rather than green. Every colour is a token
   on :root, so the whole theme is one block to retune, and the dark scheme
   at the bottom is nothing but a token swap.

   The Spanish is still meant to be the loudest thing on the screen; the
   furniture around it is friendly, not shouty. */

:root {
  /* Sandy paper, olive drab, burnt orange and brick: the palette of a
     screen-printed film poster left in the sun. Every value below was
     checked for contrast rather than chosen by eye, because a muted desert
     palette is exactly how you ship something unreadable. The two that
     failed on the first pass, --muted against the page and the label on an
     accent button, were solved for rather than nudged. */

  /* paper */
  --bg: #efe3c8;
  --panel: #f8f0dc;
  --panel2: #ebdec0;
  --line: #d8c7a4;
  --line2: #c2ac84;

  /* ink */
  --text: #2e2a1c;
  --muted: #6e6349;

  /* burnt orange, off the poster's title lettering */
  --accent: #b05423;
  --accent-deep: #8d4217;   /* accent as text, read on a pale tint */
  --accent-edge: #6f3411;   /* the slab under a button, always darker */
  --accent-soft: #f1dcba;
  --on-accent: #fdf7e8;

  /* verdicts, in the same dust: olive, ochre, brick */
  --good: #6b7a33;
  --good-deep: #46521c;
  --good-edge: #3a4416;
  --good-soft: #e6e6c2;
  --bad: #a8472a;
  --bad-deep: #78301a;
  --bad-edge: #5e2413;
  --bad-soft: #f3dac9;
  --warn: #c1912b;
  --warn-deep: #725209;
  --warn-edge: #8a6209;
  --warn-soft: #f6e8bd;

  /* the fox */
  --fur: #e08a3c;
  --tip: #2b332e;
  --snout: #f0e2c0;
  --sclera: #f6eeda;
  --eye: #7e8f6e;
  --coat: #c9a86a;
  --coat-line: #a9884a;
  --shirt: #ece1c2;
  --ink: #26261a;

  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --round: ui-rounded, "SF Pro Rounded", "Varela Round", "Quicksand",
           "Nunito", "Trebuchet MS", system-ui, -apple-system, sans-serif;
  /* A warm old serif for the wordmark and the headings only. The poster's
     display face is a western slab nobody has installed, and Georgia is on
     effectively every machine; used sparingly it reads period without
     costing any legibility where it matters. */
  --display: Georgia, "Iowan Old Style", "Palatino Linotype", Palatino,
             "Book Antiqua", serif;
  color-scheme: light;
}

* { box-sizing: border-box; }

/* An author display rule outranks the user-agent [hidden] one, and several
   panels here set display, so say it once and mean it. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  min-height: 100%;
  background-color: var(--bg);
  /* Paper grain, generated rather than an image so nothing is downloaded.
     Deliberately faint: enough to feel like stock, not enough to fight the
     text sitting on it. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23g)' opacity='0.05'/%3E%3C/svg%3E");
  color: var(--text);
  font: 15px/1.55 var(--round);
  -webkit-text-size-adjust: 100%;
}

/* ------------------------------ mascot ------------------------------ */

.sprite { position: absolute; }

.fox { display: block; flex: none; overflow: visible; }
.fox-sm { width: 32px; height: 32px; --fox-detail: 0; }
.fox-md { width: 46px; height: 46px; }
.fox-lg { width: 88px; height: 88px; }

/* Faces. The symbol reads --fox-idle / --fox-happy / --fox-sad as the
   opacity of each face group, and custom properties inherit into the
   shadow tree a <use> builds, so setting one here swaps the expression. */
.fox.happy { --fox-idle: 0; --fox-happy: 1; }
.fox.sad   { --fox-idle: 0; --fox-sad: 1; }
.card.correct .verdict .fox { --fox-idle: 0; --fox-happy: 1; }
.card.wrong   .verdict .fox { --fox-idle: 0; --fox-sad: 1; }
/* Amber leaves him on his idle face: not pleased, not sorry, waiting. */

.bob { animation: bob 3.4s ease-in-out infinite; }
@keyframes bob {
  0%, 100% { transform: translateY(0) rotate(-2deg); }
  50%      { transform: translateY(-6px) rotate(2deg); }
}

/* ------------------------------ chrome ------------------------------ */

.top {
  display: flex; align-items: center; gap: 12px;
  padding: 0 14px; height: 60px;
  background: var(--panel); border-bottom: 2px solid var(--line);
  position: sticky; top: 0; z-index: 20;
}
.brand {
  display: flex; align-items: center; gap: 9px;
  font: 700 21px var(--display); letter-spacing: 0.01em; user-select: none;
  color: var(--accent-deep);
}
.spacer { flex: 1; }

.tabs { display: flex; gap: 4px; overflow-x: auto; scrollbar-width: none; }
.tabs::-webkit-scrollbar { display: none; }
.tab {
  background: none; border: 2px solid transparent; color: var(--muted);
  font: 800 12px var(--round); letter-spacing: 0.06em; text-transform: uppercase;
  padding: 7px 14px; border-radius: 999px;
  cursor: pointer; white-space: nowrap; transition: color .15s, background .15s;
}
.tab:hover { color: var(--accent-deep); background: var(--accent-soft); }
.tab.on {
  color: var(--accent-deep); background: var(--accent-soft);
  border-color: var(--accent);
}

.menu {
  position: sticky; top: 60px; z-index: 19;
  background: var(--panel); border-bottom: 2px solid var(--line);
  padding: 14px; display: flex; flex-direction: column; gap: 12px;
}
.menu-row { display: flex; gap: 8px; flex-wrap: wrap; }

/* The bottom padding clears the home indicator on a notchless iPhone. */
main { max-width: 760px; margin: 0 auto;
       padding: 18px 14px calc(60px + env(safe-area-inset-bottom)); }

.screen { display: none; }
.screen.on { display: block; }

.pane {
  background: var(--panel); border: 2px solid var(--line);
  border-radius: 20px; padding: 18px; margin-bottom: 16px;
}
.pane h2 { font: 700 17px var(--display); margin: 0 0 12px; letter-spacing: 0; }
.pane-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.pane-head h2 { margin: 0; flex: 1; }

/* ------------------------------ atoms ------------------------------ */

/* The button is the piece that carries the whole feel: fat radius, all
   caps, and a solid slab of colour underneath that the press squashes. */
.btn {
  background: var(--panel); border: 2px solid var(--line2); color: var(--muted);
  border-radius: 16px; font: 800 13px var(--round);
  letter-spacing: 0.06em; text-transform: uppercase;
  padding: 11px 18px; cursor: pointer;
  box-shadow: 0 4px 0 var(--line2);
  transition: transform .06s, box-shadow .06s, filter .12s;
}
.btn:hover { filter: brightness(0.97); }
.btn:active { transform: translateY(4px); box-shadow: 0 0 0 var(--line2); }
.btn.primary {
  background: var(--accent); border-color: var(--accent); color: var(--on-accent);
  box-shadow: 0 4px 0 var(--accent-edge);
}
.btn.primary:hover { filter: brightness(1.05); }
.btn.primary:active { box-shadow: 0 0 0 var(--accent-edge); }
.btn.danger {
  border-color: var(--bad); color: var(--bad); box-shadow: 0 4px 0 var(--bad);
  background: var(--panel);
}
.btn.danger:active { box-shadow: 0 0 0 var(--bad); }
.btn.ghost {
  background: none; border: none; box-shadow: none; color: var(--muted);
  font-size: 22px; line-height: 1; padding: 4px 10px; letter-spacing: 0;
}
.btn.ghost:active { transform: none; }

/* The sound switch in the header. On, it is the speaker in the accent
   colour; off, it greys out and a line strikes through it, so the state reads
   at a glance without a label. */
.btn.sound-toggle { position: relative; display: inline-flex; align-items: center;
  justify-content: center; width: 40px; height: 40px; padding: 0; color: var(--accent-deep); }
.sound-toggle svg { width: 22px; height: 22px; display: block; }
.sound-toggle .sound-off { display: none; position: absolute; left: 50%; top: 50%;
  width: 26px; height: 2.5px; border-radius: 2px; background: currentColor;
  transform: translate(-50%, -50%) rotate(-45deg); }
.btn.sound-toggle[aria-pressed="false"] { color: var(--muted); opacity: 0.75; }
.sound-toggle[aria-pressed="false"] .sound-off { display: block; }
.btn.big { width: 100%; padding: 15px; font-size: 15px; }
.btn:disabled { opacity: 0.45; cursor: default; }
.btn:disabled:active { transform: none; box-shadow: 0 4px 0 var(--line2); }

.muted { color: var(--muted); }
.small { font-size: 12.5px; }
.mono { font-family: var(--mono); }

.field { display: flex; flex-direction: column; gap: 6px; }
.field > span {
  font: 800 11px var(--round); color: var(--muted);
  letter-spacing: 0.07em; text-transform: uppercase;
}
.field input, .field select, .filter, #answer {
  background: var(--panel); border: 2px solid var(--line); border-radius: 14px;
  color: var(--text); font: 500 14px var(--round); padding: 12px 13px;
  outline: none; width: 100%; transition: border-color .12s, background .12s;
}
.field input:focus, .field select:focus, .filter:focus, #answer:focus {
  border-color: var(--accent); background: var(--panel);
}
.field input::placeholder, .filter::placeholder, #answer::placeholder { color: #c4b2a2; }
.field.inline { flex-direction: row; align-items: center; gap: 10px; }
.field.inline input { width: 90px; }

.toggle { display: flex; align-items: center; gap: 10px; cursor: pointer; font-size: 14px; }
.toggle em { color: var(--muted); font-style: normal; font-size: 12.5px; display: block; }
.toggle input { width: 20px; height: 20px; accent-color: var(--accent); }

.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; align-items: end; }
.grid .wide, .grid button { grid-column: 1 / -1; }

/* Sync lives in the menu with the other housekeeping: four fields nobody
   should have to look at twice. */
.sync {
  background: var(--panel2); border: 2px solid var(--line);
  border-radius: 16px; padding: 14px; display: flex; flex-direction: column; gap: 10px;
}
.sync-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.sync-head b { font: 800 14px var(--round); }
.sync-head .small { margin-left: auto; }
.sync .menu-row .btn { flex: 1 1 auto; }
#sync-state.on { color: var(--good-deep); }
#sync-state.bad { color: var(--bad-deep); }
#sync-code { letter-spacing: 0.06em; }

/* The attribution the sentence licence asks for. Small, in the menu where
   the other housekeeping lives, and not on the card where it would be noise. */
.credit { line-height: 1.6; max-width: 62ch; }
.credit a { color: var(--accent-deep); }

.toast {
  position: fixed; left: 50%; bottom: calc(22px + env(safe-area-inset-bottom)); transform: translateX(-50%);
  background: var(--text); border: none; border-radius: 14px; color: #fff;
  padding: 12px 18px; font: 600 13.5px var(--round); z-index: 50; max-width: 90vw;
  box-shadow: 0 10px 24px rgba(75, 54, 38, 0.28);
}
.toast.bad { background: var(--bad); }

/* A new version waiting. A strip under the header rather than a toast,
   because it stays until it is answered. */
.update-bar {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px 8px 16px;
  background: var(--accent-soft); border-bottom: 2px solid var(--accent);
  color: var(--accent-deep); font: 700 13.5px var(--round);
  position: sticky; top: 60px; z-index: 18;
}
.update-bar span { flex: 1; }
.update-bar .btn.primary { padding: 8px 14px; }
.update-bar .btn.ghost { color: var(--accent-deep); }
#app-version-row { align-items: center; }

/* ----------------------------- practice ----------------------------- */

.round-bar { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.round-progress {
  flex: 1; height: 16px; background: var(--line); border-radius: 999px; overflow: hidden;
}
.round-progress i {
  display: block; height: 100%; width: 0; border-radius: 999px;
  background: var(--accent); transition: width 0.3s ease;
  position: relative;
}
/* the pale stripe along the top of the fill, which is what stops a flat
   bar from reading as a loading spinner */
.round-progress i::after {
  content: ""; position: absolute; left: 6px; right: 6px; top: 3px; height: 4px;
  border-radius: 999px; background: rgba(255,255,255,0.45);
}
#round-count { font-weight: 700; color: var(--muted); }

.card {
  background: var(--panel); border: 2px solid var(--line);
  border-radius: 24px; padding: 20px; overflow: hidden;
  animation: rise .18s ease-out;
}
@keyframes rise { from { opacity: 0; transform: translateY(6px); } }

.card-head { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; }
.band {
  font: 800 10.5px var(--round); letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--accent-deep); border: 2px solid var(--accent-soft);
  background: var(--accent-soft); border-radius: 999px; padding: 4px 11px;
}
.card-head .mono { margin-left: auto; font-weight: 700; }
/* A new word is not a band you have climbed to, so it is not badged like one. */
.card.teaching .band {
  color: var(--text); background: var(--line); border-color: var(--line2);
}

.prompt { font: 800 28px/1.3 var(--round); margin: 0 0 6px; word-break: break-word; letter-spacing: -0.4px; }
.prompt .blank { color: var(--accent); letter-spacing: 2px; }

#answer-form { display: flex; gap: 10px; margin-top: 18px; }
#answer { font-size: 17px; font-weight: 600; }
#answer-form .btn { flex: none; }

/* The Spanish letters, in a row over the box. Sized for a thumb, not a
   cursor: nine keys share the width, so they fit a phone without wrapping. */
.accents { display: flex; gap: 5px; flex: 0 0 100%; }
#answer-form { flex-wrap: wrap; }
#answer-form input { flex: 1; min-width: 0; }
.key {
  flex: 1 1 0; min-width: 0; height: 40px; padding: 0;
  background: var(--panel2); border: 2px solid var(--line); border-radius: 11px;
  color: var(--text); font: 700 18px var(--round); cursor: pointer;
  box-shadow: 0 3px 0 var(--line2);
  transition: transform .06s, box-shadow .06s;
}
.key:active { transform: translateY(3px); box-shadow: 0 0 0 var(--line2); }

/* Anything that reads Spanish aloud. Small and round, sat in the line it
   reads rather than on a line of its own, so it costs no height on a card
   that has to fit one screen. */
.say-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; padding: 0; margin-left: 8px; flex: none;
  vertical-align: middle; border-radius: 999px; cursor: pointer;
  background: var(--accent-soft); border: 2px solid var(--accent);
  color: var(--accent-deep); box-shadow: 0 2px 0 var(--accent);
  transition: transform .06s, box-shadow .06s;
}
.say-btn:active { transform: translateY(2px); box-shadow: none; }
.say-btn svg, .listen-play svg { width: 18px; height: 18px; display: block; }
.answer-line .say-btn { align-self: center; margin-left: 2px; }
/* Inside a line of text, the negative margins let the button hang over the
   line's own height instead of pushing the line taller. */
.prompt .say-btn, .teach-es .say-btn { width: 30px; height: 30px; margin: -8px 0 -6px 8px; }

/* A listening card has nothing written on it, so the play button is the
   prompt: big enough to find without looking. */
.listen { display: flex; gap: 10px; align-items: stretch; margin: 4px 0 2px; }
.listen .btn { display: inline-flex; align-items: center; gap: 8px; }
.listen-play { flex: 1; justify-content: center; font-size: 15px; padding: 14px; }
.listen-play svg { width: 22px; height: 22px; }
.verdict-en { margin: 0 0 6px; }

/* Lesson tables and examples you can tap to hear. Marked only by the pointer
   and a press, because a speaker in every cell of a table is a table of
   speakers. The hint above the table says so instead. */
[data-say] { cursor: pointer; }
td[data-say]:active, .example b[data-say]:active { background: var(--accent-soft); }
body.no-speech .say-hint { display: none; }

/* A verb drill's target: which person and which tense, as two labelled
   chips, so the ending being asked for is never a guess. */
.target { display: flex; flex-wrap: wrap; gap: 8px; margin: 2px 0 8px; }
.tchip { display: inline-flex; align-items: baseline; gap: 7px;
  background: var(--accent-soft); border: 2px solid var(--accent);
  border-radius: 999px; padding: 4px 13px; }
.tchip i { font: 800 10.5px var(--round); font-style: normal; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--accent-deep); }
.tchip b { font: 800 16px var(--round); color: var(--text); }
.tchip em { font-style: normal; font-size: 13px; color: var(--muted); }

/* A grammar card's choices: two to four big targets, two to a row. */
.choices { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 16px; }
.choices .btn { text-transform: none; letter-spacing: 0; font-size: 17px; padding: 13px 10px; }
.choices .btn.long { grid-column: 1 / -1; }

/* A lesson's classic mistake: the wrong version struck out, the right one
   beside it. */
.mistake { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 10px;
  background: var(--panel2); border: 2px solid var(--line); border-radius: 12px; padding: 9px 12px; }
.mistake s { color: var(--bad-deep); }
.mistake b { color: var(--good-deep); }
.mistake .muted { flex-basis: 100%; }
.lesson-body p { margin: 0 0 8px; }

/* How a grammar topic stands, on its row in the Lessons screen. */
/* Grammar rows: title and badge on the first line, the description under
   them at full width, rather than squeezed into a column between the two. */
#grammar-lessons details.lesson > summary .standing { order: 1; margin-left: auto; }
#grammar-lessons details.lesson > summary .small { order: 2; flex: 1 1 100%; padding-left: 20px; }
.standing { flex: none; font: 800 11px var(--round); letter-spacing: 0.04em;
  border-radius: 999px; padding: 3px 9px; background: var(--line); color: var(--muted); }
.standing.good { background: var(--good-soft); color: var(--good-deep); }
.standing.bad { background: var(--bad-soft); color: var(--bad-deep); }

/* Tappable words. A dotted underline says "there is more here" without
   turning a sentence into a row of buttons. */
.tap { cursor: pointer; border-radius: 4px;
  text-decoration: underline dotted; text-decoration-color: var(--line2);
  text-decoration-thickness: 1.5px; text-underline-offset: 4px; }
.tap.on { background: var(--accent-soft); text-decoration-color: var(--accent); }

/* What a tapped word means: a small card under the word. */
.gloss {
  position: absolute; z-index: 40; width: min(300px, calc(100vw - 16px));
  background: var(--panel); border: 2px solid var(--accent); border-radius: 14px;
  padding: 10px 12px; box-shadow: 0 8px 20px rgba(60, 40, 20, 0.22);
  font: 500 14px/1.4 var(--round); color: var(--text);
}
.gloss-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.gloss-head b { font: 800 18px var(--round); color: var(--accent-deep); }
.gloss p { margin: 4px 0 0; }
/* Which form was tapped, as labelled rows: label on the left, small capitals,
   answer on the right. */
.gloss-rows { display: grid; grid-template-columns: auto 1fr; gap: 4px 12px;
  margin: 10px 0 0; padding-top: 8px; border-top: 2px solid var(--line); }
.gloss-rows dt { font: 800 10.5px/1.9 var(--round); letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted); }
.gloss-rows dd { margin: 0; font-weight: 700; }
/* The same rows under a drill's answer, without the rule above them. */
.verdict-rows { border-top: none; padding-top: 0; margin: 6px 0 10px; }

/* "I know this": a small switch in the card's corner. Off, an outline; on,
   filled, and it says what it will do. */
.sure { margin-left: 8px; flex: none; cursor: pointer; border-radius: 999px;
  font: 800 11px var(--round); letter-spacing: 0.05em; text-transform: uppercase;
  padding: 5px 11px; background: var(--panel); color: var(--accent-deep);
  border: 2px dashed var(--accent); }
.sure[aria-pressed="true"] { background: var(--accent); color: var(--on-accent); border-style: solid; }
.card-head .mono + .sure { margin-left: 8px; }
.teach-acts { display: grid; grid-template-columns: 2fr 1fr; gap: 10px; }
.teach-acts .btn.big { width: 100%; }
/* One line, whatever the width: a second line here is height a phone cannot spare. */
.teach-acts #btn-know { white-space: nowrap; font-size: 13px; padding-left: 6px; padding-right: 6px; }
.end-acts { display: grid; gap: 10px; margin: 0 0 10px; }
.end-acts:has(> :not([hidden])) { margin-top: 4px; }
#btn-sticking-start { margin-top: 10px; }

/* The teaching card. Quieter than a verdict: nothing has happened yet, so
   nothing is coloured right or wrong. The meaning is the loud part, because
   it is the thing being taught. */
.teach { margin-top: 14px; }
/* Why a word you have already met is being shown again. Amber rather than
   red: a word that is not going in is not a failure, it is the next job. */
.teach-why {
  background: var(--warn-soft); border: 2px solid var(--warn);
  color: var(--warn-deep); border-radius: 12px;
  padding: 8px 12px; margin: 0 0 12px; font-weight: 700;
}
.teach-sense { margin: 0 0 8px; }
#teach-then { margin: 10px 0 0; }
.teach-meaning {
  font: 800 21px/1.4 var(--round); margin: 0 0 6px; color: var(--accent-deep);
  word-break: break-word;
}
.teach .say { margin: 0 0 10px; }
.teach .note { margin: 0 0 12px; }
.teach-example {
  background: var(--panel2); border: 2px solid var(--line);
  border-radius: 14px; padding: 12px 14px; margin-bottom: 14px;
}
.teach-es { font: 600 17px/1.5 var(--round); margin: 0 0 4px; }
/* The word itself, picked out of the sentence so the eye lands on it. */
.teach-es b { color: var(--accent-deep); background: var(--accent-soft);
  border-radius: 6px; padding: 1px 5px; }
.teach-example p:last-child { margin: 0; }

/* The verdict bleeds to the card edges and takes the colour of the result,
   so the answer to "was I right" is the shape of the screen, not text. */
.verdict {
  margin: 20px -20px -20px; padding: 16px 20px 18px;
  background: var(--panel2); border-top: 2px solid var(--line);
}
.card.correct .verdict { background: var(--good-soft); border-top-color: #cfe9b4; }
.card.almost .verdict { background: var(--warn-soft); border-top-color: #f0dfa4; }
.card.wrong .verdict { background: var(--bad-soft); border-top-color: #f6cabe; }
/* An amber card stays open for a second go, so it keeps a border while the
   box is back and the verdict is hidden. */
.card.almost { border-color: var(--warn); }
.verdict-head { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; flex-wrap: wrap; }
.chip {
  font: 800 17px var(--round); letter-spacing: -0.2px;
  border-radius: 999px; padding: 0;
}
.chip.good { color: var(--good-deep); }
.chip.warn { color: var(--warn-deep); }
.chip.bad { color: var(--bad-deep); }

.answer-line { margin: 6px 0; display: flex; align-items: baseline; gap: 10px; }
.answer-line .small { font-weight: 800; letter-spacing: 0.07em; text-transform: uppercase; }
.answer-line b { font-size: 21px; font-weight: 800; color: var(--text); }
.card.correct .answer-line b { color: var(--good-deep); }
.card.almost .answer-line b { color: var(--warn-deep); }
.card.wrong .answer-line b { color: var(--bad-deep); }

/* The correction line: the answer's own words, with what was typed over
   the top of them. Marked three ways rather than by colour alone, because
   colour alone is not a way of telling anyone anything. */
.diff {
  margin: 4px 0 10px; font: 600 19px/1.5 var(--round);
  word-break: break-word;
}
.diff .d-extra {
  color: var(--bad-deep); text-decoration-thickness: 2px;
}
.diff .d-missing {
  color: var(--warn-deep); text-decoration: underline;
  text-decoration-style: wavy; text-decoration-thickness: 1.5px;
  text-underline-offset: 3px;
}
.diff .d-changed mark {
  background: var(--warn); color: #2f2202;
  border-radius: 5px; padding: 0 3px;
}
.context { color: var(--muted); margin: 8px 0 0; }
.note {
  margin: 12px 0 0; padding: 11px 13px; border-radius: 14px;
  background: var(--panel); border: 2px solid var(--line);
  font-size: 13px; line-height: 1.55;
}
/* Up to three buttons now, so they wrap rather than squeeze: at a phone
   width "Type it again" does not fit a third of the card. */
.verdict-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 16px; }
.verdict-actions .btn { flex: 1 1 130px; }
.card.correct .verdict .btn.primary {
  background: var(--good); border-color: var(--good); box-shadow: 0 4px 0 var(--good-edge);
}
.card.correct .verdict .btn.primary:active { box-shadow: 0 0 0 var(--good-edge); }
.card.wrong .verdict .btn.primary {
  background: var(--bad); border-color: var(--bad); box-shadow: 0 4px 0 var(--bad-edge);
}
.card.wrong .verdict .btn.primary:active { box-shadow: 0 0 0 var(--bad-edge); }
.card.almost .verdict .btn.primary {
  background: var(--warn); border-color: var(--warn); color: #2f2202;
  box-shadow: 0 4px 0 var(--warn-edge);
}
.card.almost .verdict .btn.primary:active { box-shadow: 0 0 0 var(--warn-edge); }
.verdict .btn:not(.primary) { background: transparent; }

.hero .hero-top { display: flex; align-items: center; gap: 14px; margin-bottom: 16px; }
.hero .bubble {
  position: relative; flex: 1;
  background: var(--panel2); border: 2px solid var(--line);
  border-radius: 18px; padding: 12px 14px;
}
/* the little tail pointing back at the fox */
.hero .bubble::before,
.hero .bubble::after {
  content: ""; position: absolute; top: 24px; width: 0; height: 0;
  border: 9px solid transparent;
}
.hero .bubble::before { left: -20px; border-right-color: var(--line); }
.hero .bubble::after { left: -16px; border-right-color: var(--panel2); }
.hero .bubble h2 { margin: 0 0 4px; }
.hero .bubble p { margin: 0; }

.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(112px, 1fr)); gap: 10px; }
.stat {
  background: var(--panel2); border: 2px solid var(--line);
  border-radius: 16px; padding: 12px 13px;
}
.stat b { display: block; font: 800 22px var(--round); color: var(--accent-deep); }
.stat span { font: 800 11px var(--round); color: var(--muted); letter-spacing: 0.06em; text-transform: uppercase; }

.movers { margin: 16px 0; display: flex; flex-direction: column; gap: 8px; }
.mover {
  display: flex; align-items: center; gap: 10px; font-size: 14px; font-weight: 700;
  background: var(--panel2); border: 2px solid var(--line);
  border-radius: 14px; padding: 8px 12px;
}
.mover .arrow { font-family: var(--mono); font-weight: 800; }
.mover.up { border-color: #d8ecc2; background: var(--good-soft); }
.mover.up .arrow { color: var(--good-deep); }
.mover.down { border-color: #f6cabe; background: var(--bad-soft); }
.mover.down .arrow { color: var(--bad-deep); }
.mover .lv { margin-left: auto; color: var(--muted); font: 700 12.5px var(--mono); }

/* --------------------------- topics, lessons --------------------------- */

.picked {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-bottom: 12px;
}
.pick-chip {
  flex: 1; min-width: 140px;
  font: 800 13px var(--round); color: var(--accent-deep);
  background: var(--accent-soft); border: 2px solid var(--accent);
  border-radius: 999px; padding: 8px 14px;
}
.count-chip {
  font: 800 11px var(--round); letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--muted); background: var(--panel2); border: 2px solid var(--line);
  border-radius: 999px; padding: 4px 11px; white-space: nowrap;
}

/* One bar per topic, the three bands stacked left to right, so how far
   through a topic you are is a shape rather than three numbers. */
.topic-bar {
  display: flex; height: 14px; margin: 10px 0 6px;
  background: var(--line); border-radius: 999px; overflow: hidden;
}
.topic-bar i { display: block; height: 100%; }
.topic-bar i.b1 { background: var(--accent); }
.topic-bar i.b2 { background: #ffa94d; }
.topic-bar i.b3 { background: var(--good); }

/* Eleven of these on one screen, so each is kept to a header, a line and a
   bar; the word list is behind the fold it deserves. */
.topic { padding: 14px 16px; margin-bottom: 10px; }
.topic .blurb { margin: 0; }
.topic .pane-head { margin-bottom: 6px; }
.topic details { margin-top: 10px; }

.lesson-list { display: flex; flex-direction: column; gap: 10px; }

details.lesson {
  border: 2px solid var(--line); border-radius: 16px;
  background: var(--panel2); overflow: hidden;
}
details.lesson > summary {
  cursor: pointer; list-style: none; padding: 12px 14px;
  font: 800 15px var(--round); color: var(--text);
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
}
details.lesson > summary::-webkit-details-marker { display: none; }
/* A twisty drawn rather than borrowed, so it turns the same way everywhere. */
details.lesson > summary::before {
  content: ""; flex: none; width: 0; height: 0;
  border: 5px solid transparent; border-left-color: var(--accent);
  transition: transform .15s; transform-origin: 3px 50%;
}
details.lesson[open] > summary::before { transform: rotate(90deg); }
details.lesson > summary .small { font-weight: 500; flex: 1; }
details.lesson > summary:hover { background: var(--accent-soft); }
details.lesson > *:not(summary) { margin: 0 14px 14px; }
details.lesson .table-wrap { margin: 0 0 12px; padding: 0 14px; }
.lesson-body { font-size: 14px; line-height: 1.6; }

table.conj { width: 100%; border-collapse: collapse; font-size: 14px; min-width: 420px; }
table.conj th, table.conj td {
  padding: 8px 10px; text-align: left; border-bottom: 2px solid var(--line);
  white-space: nowrap;
}
table.conj thead th {
  font: 800 11px var(--round); letter-spacing: 0.07em; text-transform: uppercase;
  color: var(--muted);
}
table.conj tbody th { font: 700 13px var(--round); color: var(--muted); }
table.conj tbody th .small { font-weight: 500; }
table.conj td { font-weight: 700; }
/* The stem is context; the ending is the lesson, so only the ending is loud. */
table.conj .stem { color: var(--muted); font-weight: 500; }
table.conj td b { color: var(--accent-deep); }

.examples { display: flex; flex-direction: column; gap: 8px; }
.example {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  padding: 8px 11px; background: var(--panel); border: 2px solid var(--line);
  border-radius: 12px;
}
.example b { font-size: 15px; min-width: 110px; }

/* The respelling, wherever it appears: monospaced so the capitals that mark
   the stress line up and read as emphasis rather than as shouting. */
.say-cell, .say {
  font-family: var(--mono); font-size: 12.5px; color: var(--accent-deep);
  letter-spacing: 0.01em;
}
.say { margin: 8px 0 0; font-size: 13px; }
.card.correct .say { color: var(--good-deep); }
.card.wrong .say { color: var(--bad-deep); }
.card.almost .say { color: var(--warn-deep); }

/* ------------------------------ manage ------------------------------ */

.filters { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.pill {
  background: var(--panel); border: 2px solid var(--line); color: var(--muted);
  border-radius: 999px; font: 800 12px var(--round); padding: 7px 14px; cursor: pointer;
  box-shadow: 0 2px 0 var(--line); transition: transform .06s, box-shadow .06s;
}
.pill:active { transform: translateY(2px); box-shadow: none; }
.pill.on {
  background: var(--accent-soft); border-color: var(--accent);
  color: var(--accent-deep); box-shadow: 0 2px 0 var(--accent);
}

/* The four things a round can be. Wide targets with the explanation on the
   button, because the difference between them is not obvious from a word.
   Two by two on a phone, which costs less height than one column of four. */
.modes {
  display: grid; gap: 8px; margin: 0 0 14px;
  grid-template-columns: 1fr 1fr;
}
@media (min-width: 620px) { .modes { grid-template-columns: repeat(5, 1fr); } }
/* Five on a phone is two rows of two and one on its own, which reads better
   across the full width than as half a row with a hole beside it. */
@media (max-width: 619px) { .modes .mode:last-child:nth-child(odd) { grid-column: 1 / -1; } }
.mode {
  display: flex; flex-direction: column; gap: 2px; text-align: left;
  background: var(--panel); border: 2px solid var(--line); color: var(--muted);
  border-radius: 14px; padding: 10px 14px; cursor: pointer;
  box-shadow: 0 3px 0 var(--line); transition: transform .06s, box-shadow .06s;
}
.mode b { font: 800 14px var(--round); color: var(--text); }
.mode span { font-size: 12px; line-height: 1.35; }
.mode:active { transform: translateY(3px); box-shadow: none; }
.mode.on {
  background: var(--accent-soft); border-color: var(--accent);
  box-shadow: 0 3px 0 var(--accent);
}
.mode.on b, .mode.on span { color: var(--accent-deep); }

/* Tapping words into order. The line is the answer being built and the tray
   is what is left; a tile moves between the two and nothing else happens. */
.build { margin-top: 14px; }
.build-line {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  min-height: 52px; padding: 10px;
  background: var(--panel2); border: 2px dashed var(--line); border-radius: 14px;
}
#build-hint { margin: 8px 0 10px; }
.build-tray { display: flex; flex-wrap: wrap; gap: 8px; }
.build-acts { display: flex; gap: 8px; margin-top: 14px; }
.build-acts .btn { flex: 1; }
.tile {
  background: var(--panel); border: 2px solid var(--line); color: var(--text);
  border-radius: 12px; font: 700 16px/1 var(--round); padding: 10px 13px;
  cursor: pointer; box-shadow: 0 3px 0 var(--line);
  transition: transform .06s, box-shadow .06s;
}
.tile:active { transform: translateY(3px); box-shadow: none; }
.tile.placed {
  background: var(--accent-soft); border-color: var(--accent);
  color: var(--accent-deep); box-shadow: 0 3px 0 var(--accent);
}
/* An empty tray with tiles still to place would otherwise collapse to nothing
   and look broken. */
.build-tray:empty::after {
  content: "Every word is placed."; color: var(--muted); font-size: 12px;
}

/* The collapsed pickers: one line saying what you chose, and a way back to
   choosing. Deliberately quiet, because it is not the thing on the screen
   that matters while a round is running. */
.picker-summary {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; margin: 0 0 12px; padding: 8px 14px; cursor: pointer;
  background: var(--panel); border: 2px solid var(--line); border-radius: 12px;
  box-shadow: 0 2px 0 var(--line); text-align: left;
  font: 800 13px var(--round); color: var(--text);
}
.picker-summary:active { transform: translateY(2px); box-shadow: none; }
.picker-summary i {
  font-style: normal; font-weight: 700; font-size: 12px; color: var(--accent-deep);
  text-decoration: underline; flex: none;
}

.pills { display: flex; flex-wrap: wrap; gap: 6px; }
/* The count on a pill, where there is one: how many words or sentences that
   choice would actually draw on. Quieter than the name, and it is the number
   that decides whether the pill is worth pressing. */
.pill i {
  font-style: normal; opacity: 0.65; margin-left: 5px; font-size: 11px;
}
.pill.more { border-style: dashed; }
.tenses {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 0 0 14px;
}
#pace-blurb { margin: -4px 0 12px; }

.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table.bank { width: 100%; border-collapse: collapse; font-size: 13.5px; min-width: 560px; }
table.bank th {
  text-align: left; font: 800 10.5px var(--round); letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted);
  padding: 8px 10px; border-bottom: 2px solid var(--line); white-space: nowrap;
}
table.bank td { padding: 10px; border-bottom: 2px solid var(--bg); vertical-align: top; }
table.bank tbody tr:hover td { background: var(--panel2); }
table.bank tr.off { opacity: 0.45; }
table.bank .es { font-weight: 800; }
table.bank .flag {
  font: 800 9.5px var(--round); letter-spacing: 0.07em; text-transform: uppercase;
  color: var(--accent-deep); background: var(--accent-soft);
  border-radius: 999px; padding: 2px 8px; margin-left: 6px; white-space: nowrap;
  display: inline-block;
}
table.bank .row-actions { display: flex; gap: 6px; }
table.bank .row-actions .btn { padding: 6px 11px; font-size: 11px; border-radius: 12px; box-shadow: 0 2px 0 var(--line2); }
table.bank .row-actions .btn:active { transform: translateY(2px); box-shadow: none; }
.lvl { font: 800 14px var(--round); color: var(--accent-deep); }

.edit-row td { background: var(--panel2); }
.edit-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }

/* ----------------------------- progress ----------------------------- */

.bands { display: flex; flex-direction: column; gap: 14px; }
.band-row { display: flex; align-items: center; gap: 12px; }
.band-name { width: 116px; font-size: 13.5px; font-weight: 700; flex: none; }
.band-name .small { font-weight: 500; }
.band-track { flex: 1; height: 24px; background: var(--line); border-radius: 999px; overflow: hidden; }
.band-track i { display: block; height: 100%; background: var(--accent); border-radius: 999px; }
.band-track i.b2 { background: #ffa94d; }
.band-track i.b3 { background: var(--good); }
.band-count { width: 74px; text-align: right; font: 800 14px var(--round); flex: none; }

/* ------------------------------ mobile ------------------------------ */

@media (max-width: 620px) {
  .grid { grid-template-columns: 1fr; }
  .prompt { font-size: 23px; }
  /* Under 16px, Safari zooms the page when an input takes focus. */
  .field input, .field select, .filter, #answer { font-size: 16px; }
  main { padding: 14px 10px calc(50px + env(safe-area-inset-bottom)); }
  .pane { padding: 14px; }
  .card { padding: 16px; }
  .verdict { margin: 18px -16px -16px; padding: 14px 16px 16px; }
  .band-name { width: 92px; font-size: 12.5px; }
  .fox-lg { width: 66px; height: 66px; }
  #answer-form { flex-direction: column; }
  #answer-form .btn { width: 100%; }
  .update-bar { font-size: 12.5px; }
  /* The form is a column here, where a basis would be a height. */
  .accents, #answer-form input { flex: none; }
  /* On a phone the wordmark gives way to the fox, and the tabs lose the
     wide tracking, so all three still fit without a sideways scroll. */
  .brand span { display: none; }
  .top { gap: 8px; padding: 0 10px; }
  .tab { padding: 6px 9px; font-size: 11px; letter-spacing: 0.01em; }
  /* Five tabs do not fit a phone at any width, so the strip scrolls sideways
     and says so with a fade at the edge rather than cutting a word in half.
     Hiding the brand does not change that, so the fox stays. */
  .tabs { -webkit-mask-image: linear-gradient(90deg, #000 85%, transparent);
          mask-image: linear-gradient(90deg, #000 85%, transparent); }
  table.conj { min-width: 380px; font-size: 13px; }
  .example b { min-width: 0; }
}

/* ----------------------------- installed ----------------------------- */
/* Behaviour that only makes sense once it is an app on a home screen, or on
   a touch screen in general. */

/* No grey flash over whatever was tapped, and no double-tap zoom delay. */
button, .btn, .pill, .tab, .tile, .key, label { -webkit-tap-highlight-color: transparent; touch-action: manipulation; }

@media (display-mode: standalone) {
  /* Pulling past the top would otherwise drag the whole app down like a page. */
  html, body { overscroll-behavior-y: none; }
  /* A long press on a button is a slow tap, not a request to copy its label. */
  .btn, .tab, .pill, .key, .tile, .brand { -webkit-user-select: none; user-select: none;
    -webkit-touch-callout: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important; animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* ------------------------------- dark ------------------------------- */
/* Same theme after dark: warm browns rather than blue-greys, so the orange
   still looks like it belongs. Tokens only; no layout changes below. */

/* Dark is opted into, never inherited. There is deliberately no
   prefers-color-scheme rule: paper is the default whatever the operating
   system prefers, and the attribute below is set by the inline script in the
   head before the first paint, so choosing dark does not cost a white flash
   on every load.

   The tokens hang off an attribute rather than a media query, which is the
   whole of the change; everything under them is the same swap it was. */
:root[data-theme="dark"] {
    /* The poster's own dark half: olive drab behind, sand in front. */
    --bg: #24241a;
    --panel: #2f3021;
    --panel2: #3a3a27;
    --line: #4a4832;
    --line2: #5f5b3e;
    --text: #efe3c8;
    --muted: #a79a77;
    --accent: #e08a3c;
    --accent-deep: #f2ba78;
    --accent-edge: #8c4f18;
    --accent-soft: #45381f;
    --on-accent: #241e10;
    --good: #8a9a44;
    --good-deep: #c3d17a;
    --good-edge: #4f5a22;
    --good-soft: #33381c;
    --bad: #c9583a;
    --bad-deep: #f0a086;
    --bad-edge: #7c3220;
    --bad-soft: #3d2018;
    --warn: #d9a93c;
    --warn-deep: #f0d183;
    --warn-edge: #8a6209;
    --warn-soft: #3b3318;
    --snout: #f0e2c0;
    /* The ear tips are the one dark part that sits outside the orange, so
       against an olive background they need lifting or the ears lose their
       points. Still plainly dark where it matters, on the fur. */
    --tip: #46514c;
    --coat: #8a7444;
    --coat-line: #6b5a34;
    --shirt: #cdbf96;
    color-scheme: dark;
  }

:root[data-theme="dark"] .card.correct .verdict { border-top-color: #3f5a28; }
:root[data-theme="dark"] .card.wrong .verdict { border-top-color: #61342a; }
:root[data-theme="dark"] .mover.up { border-color: #3f5a28; }
:root[data-theme="dark"] .mover.down { border-color: #61342a; }
:root[data-theme="dark"] .field input::placeholder, :root[data-theme="dark"] .filter::placeholder, :root[data-theme="dark"] #answer::placeholder { color: #7d6858; }
:root[data-theme="dark"] .toast { background: var(--panel2); border: 2px solid var(--line2); color: var(--text); }
:root[data-theme="dark"] .toast.bad { background: var(--bad-soft); border-color: var(--bad); color: var(--text); }
:root[data-theme="dark"] .btn.primary { color: var(--on-accent); }


/* Chunks: the word as it is said. On the teaching card it sits straight under
   the meaning, in the accent, because it is the part to take away. */
.chunk {
  border: 2px solid var(--accent); background: var(--accent-soft);
  border-radius: 14px; padding: 10px 14px; margin: 4px 0 12px;
}
.chunk-label {
  display: block; font: 800 11px var(--round); letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--accent-deep); margin-bottom: 2px;
}
.chunk-es { font: 700 19px/1.45 var(--round); margin: 0 0 2px; color: var(--text); }
.chunk-es b, .chunk-line b { color: var(--accent-deep); }
.chunk-es .say-btn { width: 30px; height: 30px; margin: -8px 0 -6px 8px; }
.chunk p:last-child { margin: 0; }
.chunk-line { margin: 8px 0 0; font: 600 15px/1.5 var(--round); }
.chunk-line .chunk-label { display: inline; margin: 0 6px 0 0; }
.chunk-line .say-btn { width: 28px; height: 28px; margin: -6px 0 -6px 6px; }
.chunk-line .muted { display: block; font-weight: 400; }

/* Memory hooks: the learner's own words, so set apart from the app's notes. */
.hook { margin: 12px 0 0; }
.hook-line {
  margin: 0 0 8px; padding: 9px 12px; border-radius: 12px;
  border: 2px dashed var(--line2); background: var(--panel);
  font-size: 14px; line-height: 1.5; font-style: italic;
}
.teach .hook-line { margin: 0 0 12px; }
.btn.small { font-size: 13px; padding: 6px 12px; }
.hook-edit { display: grid; gap: 8px; }
.hook-edit label { line-height: 1.45; }
.hook-edit label .muted { display: block; }
.hook-edit textarea {
  width: 100%; box-sizing: border-box; font-family: inherit; font-size: 16px; line-height: 1.4; color: var(--text);
  background: var(--panel); border: 2px solid var(--line2); border-radius: 12px; padding: 8px 10px;
  resize: vertical;
}
.hook-acts { display: flex; gap: 10px; justify-content: flex-end; }

/* Today's session: the main button on the start screen, with a free round
   underneath for anything else. */
.today { display: grid; gap: 6px; margin-bottom: 10px; }
.today p { margin: 0; }
.today-end { margin: 0 0 12px; display: grid; gap: 10px; }
.today-steps { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; }
.tstep {
  font: 700 13px var(--round); padding: 4px 10px; border-radius: 999px;
  border: 2px solid var(--line2); color: var(--muted);
}
.tstep.done { border-color: var(--good); background: var(--good-soft); color: var(--good-deep); }
.tdone { flex-basis: 100%; font: 800 15px var(--round); color: var(--good-deep); margin-top: 4px; }

/* The course. A unit card is a whole button, laid out like a pane. */
#units { display: grid; gap: 12px; }
.unit-card {
  display: grid; gap: 6px; text-align: left; width: 100%; cursor: pointer;
  font: inherit; color: var(--text); margin: 0;
}
.unit-card.next { border-color: var(--accent); }
.unit-num {
  font: 800 11px var(--round); letter-spacing: 0.06em; text-transform: uppercase; color: var(--accent-deep);
}
.unit-title b { font: 800 18px var(--round); }
.unit-steps { display: flex; flex-wrap: wrap; gap: 6px; }
.unit-head h2 { margin: 2px 0 6px; font: 800 21px var(--round); }
.unit-head .back { display: block; padding: 4px 0; margin: -4px 0 6px; font-size: 13px; letter-spacing: 0.02em; }
.unit-head p { margin: 0 0 10px; }

.ustep { margin-bottom: 12px; }
.ustep > summary {
  display: flex; align-items: baseline; gap: 10px; cursor: pointer; list-style: none;
  font: 800 17px var(--round);
}
.ustep > summary::-webkit-details-marker { display: none; }
.ustep[open] > summary { margin-bottom: 10px; }
.snum {
  display: inline-grid; place-items: center; flex: none; width: 26px; height: 26px; border-radius: 50%;
  background: var(--accent); color: var(--on-accent); font-size: 13px;
}
.sdetail { margin-left: auto; font-weight: 600; }
.ustep h3 { font: 800 15px var(--round); margin: 16px 0 4px; }
.ustep-acts { display: flex; flex-wrap: wrap; gap: 10px; margin: 10px 0; }

.frame {
  background: var(--panel2); border: 2px solid var(--line); border-radius: 14px;
  padding: 10px 14px; margin: 0 0 10px;
}
.frame p { margin: 0; }
.fes { font: 800 17px/1.45 var(--round); color: var(--accent-deep); }
.gap {
  display: inline-block; min-width: 2.6em; border-bottom: 3px solid var(--accent);
  margin: 0 2px; vertical-align: baseline;
}
.frame ul, .models { margin: 6px 0 0; padding: 0; list-style: none; display: grid; gap: 4px; }
.frame li, .models li { font: 600 15px/1.5 var(--round); }
.frame li .muted { display: block; font-weight: 400; }
.frame .say-btn, .models .say-btn, .des .say-btn { width: 28px; height: 28px; margin: -6px 0 -6px 6px; }
.say-btn.slow { font: 800 12px var(--round); }

.uwords-label { font-weight: 800; margin: 12px 0 4px; }
.uwords { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; }
.uword {
  font-size: 13px; padding: 3px 9px; border-radius: 999px;
  border: 2px solid var(--line2); color: var(--muted);
}
.uword b { color: var(--text); }
.uword.met { border-color: var(--good); background: var(--good-soft); }

.dialogue { display: grid; gap: 8px; margin: 10px 0 12px; }
.dline { border-left: 3px solid var(--line2); padding: 2px 0 2px 10px; }
.dline.playing { border-left-color: var(--accent); background: var(--accent-soft); border-radius: 0 10px 10px 0; }
.dline .who {
  font: 800 11px var(--round); letter-spacing: 0.05em; text-transform: uppercase; color: var(--accent-deep);
  cursor: pointer;
}
.des { font: 600 16px/1.5 var(--round); margin: 0; }
.den { margin: 2px 0 0; }
.shadow .des { font-size: 15px; }

.task { border-top: 2px solid var(--line); padding: 12px 0 4px; }
.task:first-of-type { border-top: 0; }
.task p { margin: 0 0 4px; }
.task-prompt { font-weight: 700; }
.task textarea {
  width: 100%; box-sizing: border-box; font-family: inherit; font-size: 16px; line-height: 1.4;
  color: var(--text); background: var(--panel); border: 2px solid var(--line2); border-radius: 12px;
  padding: 8px 10px; margin: 6px 0 8px; resize: vertical;
}
.task-result { margin-top: 10px; }
.task-ok { color: var(--good-deep); font-weight: 700; }
.task-try { color: var(--warn-deep); font-weight: 700; }

.points { display: flex; flex-wrap: wrap; gap: 6px; }
.point {
  font: 700 14px var(--round); padding: 4px 10px; border-radius: 10px;
  background: var(--panel2); border: 2px solid var(--line);
}
.retell { display: flex; align-items: center; gap: 16px; margin: 10px 0; }
.clock { font: 800 34px var(--round); min-width: 2.2em; color: var(--accent-deep); font-variant-numeric: tabular-nums; }
.retell-msg { font-weight: 700; color: var(--good-deep); }
.model summary { cursor: pointer; font-weight: 700; margin: 8px 0; }
.model p { font: 600 15px/1.55 var(--round); }
.btn.recording { border-color: var(--bad, #b33); color: var(--bad, #b33); }
#unit-audio { width: 100%; margin-top: 4px; }
