/* learn.gaitherstephens.com */

/* Theme: three modes. `data-theme` on <html> is "light", "dark", or absent /
   "system". Dark tokens are declared twice on purpose, once for the system
   preference (unless the user explicitly chose light) and once for the explicit
   dark choice. A preprocessor would DRY this up; a 20-line repeat is cheaper
   than a build step for a site with no build step. */

:root {
  --cyan: #0099cc;
  --fg: #1a1a1a;
  --muted: #4a4a4a;
  --bg: #fafaf7;
  --card-bg: #ffffff;
  --line: #e5e2db;
  --line-strong: #cfcabf;
  --good: #1a7f52;
  --good-bg: #e8f5ee;
  --bad: #b3253f;
  --bad-bg: #fbeaee;
  --warn: #8a5a00;
  --warn-bg: #fdf3e0;
  --flame: #d2601a;
  --on-cyan: #06222c;

  /* One colour per competency, used consistently everywhere so "the purple
     one" becomes a real handle for matter. Colour NEVER carries meaning on
     its own: every use is paired with the competency number, an icon, or
     both, so nothing is lost to colour blindness or a greyscale screen. */
  --comp-1: #7048c4;
  --comp-2: #2f6fbb;
  --comp-3: #a86508;
  --comp-4: #97522a;
  --comp-5: #4a42b0;
  --comp-6: #16794c;
  --comp-7: #0b6f6b;
  --comp-8: #a83459;
  --comp-9: #0d6480;
  --sans: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --serif: "Source Serif 4", Georgia, "Times New Roman", serif;
  --radius: 12px;
  --shadow: 0 1px 2px rgba(0,0,0,.05), 0 4px 16px rgba(0,0,0,.05);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --cyan: #01ccff;
    --fg: #e8e6df;
    --muted: #a8a59c;
    --bg: #0f1419;
    --card-bg: #1a2129;
    --line: #2a3138;
    --line-strong: #3d454e;
    --good: #5fd39b;
    --good-bg: #14352a;
    --bad: #ff8fa3;
    --bad-bg: #3a1a22;
    --warn: #f0c674;
    --warn-bg: #3a2f18;
    --flame: #ffa24d;
    --on-cyan: #06222c;
    --comp-1: #a78bfa;
    --comp-2: #6da4d8;
    --comp-3: #f0b44a;
    --comp-4: #d99a6c;
    --comp-5: #9a93f5;
    --comp-6: #5fd39b;
    --comp-7: #4ecdc4;
    --comp-8: #f08fb0;
    --comp-9: #61bcd8;
    --shadow: 0 1px 2px rgba(0,0,0,.3), 0 4px 16px rgba(0,0,0,.25);
  }
}

:root[data-theme="dark"] {
  --cyan: #01ccff;
  --fg: #e8e6df;
  --muted: #a8a59c;
  --bg: #0f1419;
  --card-bg: #1a2129;
  --line: #2a3138;
  --line-strong: #3d454e;
  --good: #5fd39b;
  --good-bg: #14352a;
  --bad: #ff8fa3;
  --bad-bg: #3a1a22;
  --warn: #f0c674;
  --warn-bg: #3a2f18;
  --flame: #ffa24d;
  --on-cyan: #06222c;
  --comp-1: #a78bfa;
  --comp-2: #6da4d8;
  --comp-3: #f0b44a;
  --comp-4: #d99a6c;
  --comp-5: #9a93f5;
  --comp-6: #5fd39b;
  --comp-7: #4ecdc4;
  --comp-8: #f08fb0;
  --comp-9: #61bcd8;
  --shadow: 0 1px 2px rgba(0,0,0,.3), 0 4px 16px rgba(0,0,0,.25);
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--sans);
  background: var(--bg);
  color: var(--fg);
  line-height: 1.55;
  font-size: 16px;
}

h1, h2, h3 { line-height: 1.25; margin: 0 0 .5em; }
h1 { font-size: 1.6rem; }
h2 { font-size: 1.25rem; }
h3 { font-size: 1.05rem; }
p { margin: 0 0 1em; }
a { color: var(--cyan); }
.muted { color: var(--muted); }
.small { font-size: .85rem; }

button, .btn {
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  border-radius: 10px;
  border: 1px solid var(--line-strong);
  background: var(--card-bg);
  color: var(--fg);
  padding: .6rem 1rem;
  transition: border-color .15s, background .15s;
}
button:hover, .btn:hover { border-color: var(--cyan); }
button:focus-visible, a:focus-visible, input:focus-visible, textarea:focus-visible {
  outline: 3px solid var(--cyan);
  outline-offset: 2px;
}
button:disabled { opacity: .5; cursor: not-allowed; }
.btn-primary {
  background: var(--cyan);
  border-color: var(--cyan);
  color: var(--on-cyan);
}
.btn-primary:hover { filter: brightness(1.08); }

/* Icons. Sizing is font-relative so buttons and headings scale together. */
.ico { width: 1.1em; height: 1.1em; flex: none; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.ico--lg { width: 1.5em; height: 1.5em; }
.ico--sm { width: .9em; height: .9em; }

/* Competency colour. Put .c1 .. .c9 on any element and --comp resolves; the
   icon, chip, dot and bar helpers below all read from it, so a competency
   looks the same everywhere in the app. */
.c1 { --comp: var(--comp-1); }
.c2 { --comp: var(--comp-2); }
.c3 { --comp: var(--comp-3); }
.c4 { --comp: var(--comp-4); }
.c5 { --comp: var(--comp-5); }
.c6 { --comp: var(--comp-6); }
.c7 { --comp: var(--comp-7); }
.c8 { --comp: var(--comp-8); }
.c9 { --comp: var(--comp-9); }

.ico--comp { color: var(--comp, var(--cyan)); }

/* Competency chip: colour PLUS the number PLUS the icon. Three redundant
   cues, so none of them has to carry the meaning alone. */
.cchip {
  display: inline-flex; align-items: center; gap: .35rem;
  font-size: .72rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  padding: .2rem .55rem; border-radius: 999px;
  color: var(--comp, var(--muted));
  background: color-mix(in srgb, var(--comp, var(--line)) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--comp, var(--line)) 35%, transparent);
  white-space: nowrap;
}
.cchip .ico { width: .95em; height: .95em; }

/* Left colour rail on a competency row, so the eye can group by subject.
   The specific selectors are needed because `details.sec` and `.mode` both
   set their own border and would otherwise win on specificity. */
.rail,
details.sec.rail,
button.mode.rail,
.mrow.rail {
  border-left: 3px solid var(--comp, var(--line-strong));
  padding-left: .7rem;
}

/* Status: mastered / shaky / untouched. Always icon + word + colour. */
.status {
  display: inline-flex; align-items: center; gap: .3rem;
  font-size: .74rem; font-weight: 700;
  padding: .15rem .5rem; border-radius: 999px;
}
.status.ok { background: var(--good-bg); color: var(--good); }
.status.mid { background: var(--warn-bg); color: var(--warn); }
.status.no { background: var(--line); color: var(--muted); }

/* Difficulty: three pips, filled to the item's level. */
.diff { display: inline-flex; gap: .18rem; align-items: center; vertical-align: middle; }
.diff i { width: .38rem; height: .38rem; border-radius: 50%; background: var(--line-strong); }
.diff i.on { background: var(--muted); }

/* ---------- login ---------- */

.login-body {
  display: grid;
  place-items: center;
  min-height: 100vh;
  padding: 1.5rem;
}
.login-card {
  background: var(--card-bg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 2rem;
  width: 100%;
  max-width: 380px;
  text-align: center;
}
.login-mark {
  font-family: var(--serif);
  font-weight: 700;
  font-size: 1.5rem;
  letter-spacing: .08em;
  color: var(--cyan);
  margin-bottom: .5rem;
}
.login-card h1 { font-family: var(--serif); font-size: 1.5rem; }
.login-card form { margin-top: 1.5rem; text-align: left; }
.login-card label { display: block; font-weight: 600; font-size: .9rem; margin-bottom: .35rem; }
.login-card input {
  width: 100%;
  font: inherit;
  padding: .65rem .8rem;
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  background: var(--bg);
  color: var(--fg);
}
.login-card button { width: 100%; margin-top: 1rem; background: var(--cyan); border-color: var(--cyan); color: #06222c; }
.passkey-wrap { margin-top: .75rem; }
.passkey-wrap button {
  width: 100%;
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
}
.passkey-wrap button::before {
  content: "";
  width: 1.05rem; height: 1.05rem; flex: none;
  background: currentColor;
  -webkit-mask: no-repeat center / contain; mask: no-repeat center / contain;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M12 2a5 5 0 0 0-5 5v3M7 10a5 5 0 0 1 10 0v2M4 14c0-1 .4-2 1-2.7M12 22c-1.5-2-2-4.5-2-7M16 21c.7-1.6 1-3.3 1-5M20 17c.3-1.3.4-2.6.4-4'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M12 2a5 5 0 0 0-5 5v3M7 10a5 5 0 0 1 10 0v2M4 14c0-1 .4-2 1-2.7M12 22c-1.5-2-2-4.5-2-7M16 21c.7-1.6 1-3.3 1-5M20 17c.3-1.3.4-2.6.4-4'/%3E%3C/svg%3E");
}

.demo-wrap { margin-top: 1.25rem; padding-top: 1.1rem; border-top: 1px solid var(--line); }
.demo-or {
  display: block; text-align: center; font-size: .78rem;
  text-transform: uppercase; letter-spacing: .08em; color: var(--muted);
  margin-bottom: .7rem;
}
.demo-btn {
  display: block; text-align: center; text-decoration: none;
  font-weight: 600; font-size: .95rem;
  padding: .7rem 1rem; min-height: 44px;
  border: 1px solid var(--line-strong); border-radius: 10px;
  color: var(--fg); background: var(--card-bg);
}
.demo-btn:hover { border-color: var(--cyan); color: var(--cyan); }
.demo-note { font-size: .78rem; color: var(--muted); margin: .6rem 0 0; text-align: center; line-height: 1.45; }

.login-legal {
  max-width: 380px; margin: 1.2rem auto 0;
  font-size: .72rem; line-height: 1.5; color: var(--muted);
  text-align: center;
}

/* Demo banner inside the app */
/* Deliberately NOT sticky: the header already sticks to top 0, and two
   sticky bars fight for the same offset and overlap on scroll. */
.demo-bar {
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  padding: .5rem .8rem;
  background: var(--warn-bg); color: var(--warn);
  font-size: .84rem; font-weight: 600;
}
.demo-bar .ico { flex: none; }
.demo-bar span { flex: 1 1 12rem; font-weight: 400; }
.demo-bar a {
  color: inherit; font-weight: 700; text-decoration: underline;
  padding: .3rem 0; white-space: nowrap;
}

.login-error {
  background: var(--bad-bg);
  color: var(--bad);
  border-radius: 8px;
  padding: .6rem .8rem;
  font-size: .9rem;
  margin: 1rem 0 0;
}

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

.shell { max-width: 860px; margin: 0 auto; padding: 0 1rem 5rem; }

header.top {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
  margin-bottom: 1.25rem;
}
.top-inner {
  max-width: 860px;
  margin: 0 auto;
  padding: .7rem 1rem;
  display: flex;
  align-items: center;
  gap: .75rem;
}
.wordmark {
  font-family: var(--serif);
  font-weight: 700;
  color: var(--fg);
  text-decoration: none;
  font-size: 1.05rem;
  margin-right: auto;
}
.wordmark span { color: var(--cyan); }
.sync-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--line-strong);
  flex: none;
  transition: background .3s;
}
.sync-dot.ok { background: var(--good); }
.sync-dot.busy { background: var(--warn); }
.sync-dot.err { background: var(--bad); }

/* ---------- home ---------- */

.hero {
  background: var(--card-bg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.25rem;
  margin-bottom: 1.25rem;
  box-shadow: var(--shadow);
}
.hero h1 { font-family: var(--serif); margin-bottom: .25rem; }

.stat-row { display: flex; flex-wrap: wrap; gap: 1.5rem; margin-top: 1rem; }
.stat { min-width: 90px; }
.stat b { display: block; font-size: 1.5rem; font-family: var(--serif); line-height: 1.1; }
.stat span { font-size: .78rem; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; display: inline-flex; align-items: center; gap: .25rem; }
.stat span .ico { opacity: .8; }

.greet { font-family: var(--serif); font-size: 1.5rem; margin: .2rem 0 .9rem; }

/* Grouped mode sections. Thirteen equal cards in one grid is a wall; four
   labelled groups of two to five is a menu. */
.sec-h {
  display: flex; align-items: center; gap: .45rem;
  margin: 1.9rem 0 .1rem; font-size: 1.1rem;
}
.sec-h .ico { color: var(--cyan); }
.sec-sub { font-size: .86rem; color: var(--muted); margin: 0 0 .7rem; }

.modes { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: .85rem; }
.mode {
  display: block;
  text-align: left;
  width: 100%;
  background: var(--card-bg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1rem;
  box-shadow: var(--shadow);
}
.mode:hover { border-color: var(--cyan); }
.mode h3 { margin-bottom: .2rem; }
.mode p { margin: 0; font-size: .87rem; color: var(--muted); font-weight: 400; line-height: 1.45; }
.mode .tagline { display: block; font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; color: var(--cyan); margin-bottom: .35rem; font-weight: 700; }
.mode .badge {
  display: inline-block; margin-top: .5rem; font-size: .75rem; font-weight: 700;
  background: var(--warn-bg); color: var(--warn); padding: .15rem .5rem; border-radius: 999px;
}

/* ---------- mastery bars ---------- */

.mastery { margin-top: 1.5rem; }
.mrow { display: grid; grid-template-columns: 1fr auto; gap: .5rem 1rem; align-items: baseline; margin-bottom: .1rem; }
.mrow .lbl { font-size: .87rem; display: flex; align-items: center; gap: .45rem; }
.mrow .lbl .ico { color: var(--cyan); opacity: .85; }
h2 .ico, h3 .ico { color: var(--cyan); vertical-align: -.15em; }
.tagline .ico { vertical-align: -.2em; margin-right: .2em; }
.chip .ico { vertical-align: -.2em; margin-right: .25em; }
.mrow .val { font-size: .8rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.bar { height: 7px; border-radius: 4px; background: var(--line); overflow: hidden; margin-bottom: .7rem; }
.bar i { display: block; height: 100%; background: var(--cyan); border-radius: 4px; transition: width .4s; }
.bar i.weak { background: var(--bad); }
.bar i.mid { background: var(--warn); }
.bar i.strong { background: var(--good); }

/* ---------- cards / quiz ---------- */

.panel {
  background: var(--card-bg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.25rem;
  box-shadow: var(--shadow);
  margin-bottom: 1rem;
}

.crumb { display: flex; align-items: center; gap: .75rem; margin-bottom: 1rem; flex-wrap: wrap; }
.crumb .chip {
  font-size: .75rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  background: var(--line); color: var(--muted); padding: .2rem .55rem; border-radius: 999px;
}
.crumb .prog { margin-left: auto; font-size: .85rem; color: var(--muted); font-variant-numeric: tabular-nums; }

.stem { font-size: 1.08rem; margin-bottom: 1.1rem; }
.stem code, .body-md code { background: var(--line); padding: .1em .35em; border-radius: 4px; font-size: .92em; }

.choices { display: grid; gap: .5rem; margin-bottom: 1rem; }
.choice {
  display: flex; gap: .7rem; align-items: flex-start;
  text-align: left; width: 100%; font-weight: 400;
  padding: .7rem .85rem; border-radius: 10px;
  border: 1px solid var(--line-strong); background: var(--card-bg);
}
.choice:hover:not(:disabled) { border-color: var(--cyan); }
.choice .key {
  flex: none; font-weight: 700; font-size: .8rem; width: 1.4rem; height: 1.4rem;
  display: grid; place-items: center; border-radius: 5px;
  background: var(--line); color: var(--muted);
}
.choice.correct { border-color: var(--good); background: var(--good-bg); }
.choice.correct .key { background: var(--good); color: var(--card-bg); }
.choice.wrong { border-color: var(--bad); background: var(--bad-bg); }
.choice.wrong .key { background: var(--bad); color: var(--card-bg); }
.choice:disabled { opacity: 1; cursor: default; }

.verdict { font-weight: 700; margin-bottom: .35rem; }
.verdict.ok { color: var(--good); }
.verdict.no { color: var(--bad); }
.explain {
  border-left: 3px solid var(--cyan);
  padding: .1rem 0 .1rem .9rem;
  margin-bottom: 1rem;
  font-size: .95rem;
}

.flash {
  min-height: 190px;
  display: grid;
  place-items: center;
  text-align: center;
  padding: 1.75rem 1rem;
  font-size: 1.15rem;
}
.flash .back { border-top: 1px solid var(--line); margin-top: 1.1rem; padding-top: 1.1rem; font-size: 1.02rem; text-align: left; }
.rate { display: grid; grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); gap: .5rem; }
.rate button small { display: block; font-weight: 400; font-size: .72rem; color: var(--muted); }

.actions { display: flex; gap: .6rem; flex-wrap: wrap; }

textarea.recall {
  width: 100%; min-height: 190px; font: inherit; line-height: 1.6;
  padding: .8rem; border-radius: 10px; border: 1px solid var(--line-strong);
  background: var(--bg); color: var(--fg); resize: vertical;
}

.keypoints { list-style: none; padding: 0; margin: 0 0 1rem; }
.keypoints li {
  display: flex; gap: .6rem; align-items: flex-start;
  padding: .55rem .7rem; border: 1px solid var(--line); border-radius: 9px; margin-bottom: .45rem;
}
.keypoints li.hit { border-color: var(--good); background: var(--good-bg); }
.keypoints input { margin-top: .3rem; flex: none; width: 1.05rem; height: 1.05rem; accent-color: var(--cyan); }

/* ---------- guide ---------- */

.body-md { font-size: .97rem; }
.body-md h2, .body-md h3 { font-family: var(--serif); margin-top: 1.4em; }
.body-md table { border-collapse: collapse; width: 100%; margin: 1em 0; font-size: .88rem; display: block; overflow-x: auto; }
.body-md th, .body-md td { border: 1px solid var(--line); padding: .4rem .6rem; text-align: left; vertical-align: top; }
.body-md th { background: var(--line); font-weight: 700; }
.body-md pre {
  background: var(--line); padding: .7rem .9rem; border-radius: 8px;
  overflow-x: auto; font-size: .9rem; margin: .8em 0;
}
.body-md .trap {
  background: var(--warn-bg); border-left: 3px solid var(--warn);
  padding: .6rem .9rem; border-radius: 0 8px 8px 0; margin: .9em 0;
}
.body-md ul, .body-md ol { padding-left: 1.3em; }
.body-md li { margin-bottom: .3em; }

details.sec { border: 1px solid var(--line); border-radius: 10px; margin-bottom: .6rem; background: var(--card-bg); }
details.sec > summary {
  cursor: pointer; font-weight: 600; padding: .75rem 1rem; list-style: none;
  display: flex; align-items: center; gap: .6rem;
}
details.sec > summary::-webkit-details-marker { display: none; }
details.sec > summary::before { content: "\25B8"; color: var(--cyan); transition: transform .2s; }
details.sec[open] > summary::before { transform: rotate(90deg); }
details.sec .inner { padding: 0 1rem 1rem; border-top: 1px solid var(--line); }

/* ---------- exam ---------- */

.timer {
  font-variant-numeric: tabular-nums; font-weight: 700;
  padding: .2rem .6rem; border-radius: 999px; background: var(--line); font-size: .9rem;
}
.timer.low { background: var(--bad-bg); color: var(--bad); }

.grid-nav { display: grid; grid-template-columns: repeat(auto-fill, minmax(38px, 1fr)); gap: .3rem; }
.grid-nav button {
  padding: .35rem 0; font-size: .78rem; border-radius: 7px;
  font-variant-numeric: tabular-nums;
}
.grid-nav button.answered { background: var(--cyan); border-color: var(--cyan); color: #06222c; }
.grid-nav button.flagged { border-color: var(--warn); border-width: 2px; }
.grid-nav button.here { outline: 2px solid var(--fg); outline-offset: 1px; }

.score-big { font-family: var(--serif); font-size: 3rem; line-height: 1; margin-bottom: .2rem; }
.verdict-band { display: inline-block; padding: .3rem .8rem; border-radius: 999px; font-weight: 700; font-size: .9rem; }
.verdict-band.pass { background: var(--good-bg); color: var(--good); }
.verdict-band.close { background: var(--warn-bg); color: var(--warn); }
.verdict-band.no { background: var(--bad-bg); color: var(--bad); }

.opts { display: grid; gap: .5rem; margin: 1rem 0; }
.opt {
  display: flex; gap: .7rem; align-items: center; padding: .6rem .8rem;
  border: 1px solid var(--line-strong); border-radius: 10px; cursor: pointer;
}
.opt:hover { border-color: var(--cyan); }
.opt input { accent-color: var(--cyan); width: 1.05rem; height: 1.05rem; flex: none; }
.opt .meta { margin-left: auto; font-size: .8rem; color: var(--muted); font-variant-numeric: tabular-nums; }

footer.foot {
  max-width: 860px; margin: 2.5rem auto 0; padding: 1.25rem 1rem;
  border-top: 1px solid var(--line); font-size: .82rem; color: var(--muted);
}
footer.foot a { color: var(--muted); }

.hidden { display: none !important; }

/* ---------- daily goal, streak, resume ---------- */

.today {
  display: flex;
  align-items: center;
  gap: 1.1rem;
  flex-wrap: wrap;
}
.ring { position: relative; width: 78px; height: 78px; flex: none; }
.ring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.ring circle { fill: none; stroke-width: 8; stroke-linecap: round; }
.ring .track { stroke: var(--line); }
.ring .fill { stroke: var(--cyan); transition: stroke-dasharray .6s ease; }
.ring .fill.done { stroke: var(--good); }
/* Flex row, not grid: a grid with two children puts the count and the "/20"
   on separate rows, which read as a broken fraction. */
/* Flex ROW so the count and the "/20" sit side by side (a grid put them on
   separate rows, which read as a broken fraction), and align CENTER so the
   text is centred in the ring. `baseline` here pushed a lone number to the
   top of the 78px box. The small denominator gets a nudge so it still looks
   like it is sitting on the number's baseline. */
.ring b {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center; gap: 1px;
  font-family: var(--serif); font-size: 1.15rem; line-height: 1;
}
.ring b .of { font-size: .62rem; color: var(--muted); align-self: center; margin-top: .3em; }
.today-copy { min-width: 0; flex: 1 1 12rem; }
.today-copy h3 { margin-bottom: .15rem; display: flex; align-items: center; gap: .4rem; }
.today-copy p { margin: 0; font-size: .87rem; color: var(--muted); }

.streak {
  display: inline-flex; align-items: center; gap: .4rem;
  font-weight: 700; font-size: .92rem;
  padding: .35rem .7rem; border-radius: 999px;
  background: var(--warn-bg); color: var(--flame);
  white-space: nowrap;
}
.streak.cold { background: var(--line); color: var(--muted); }

.resume {
  display: flex; align-items: center; gap: .8rem;
  width: 100%; text-align: left;
  padding: .85rem 1rem;
  border-radius: var(--radius);
  border: 1px solid var(--cyan);
  background: var(--card-bg);
  margin-bottom: 1.25rem;
}
.resume .ico { color: var(--cyan); }
.resume span { min-width: 0; }
.resume b { display: block; font-size: .95rem; }
.resume small { color: var(--muted); font-weight: 400; }
.resume .go { margin-left: auto; color: var(--cyan); flex: none; }

/* Week strip: seven dots, one per day. Read-only, no guilt. */
.week { display: flex; gap: .3rem; margin-top: .6rem; }
.week i {
  width: 1.55rem; height: 1.55rem; border-radius: 50%;
  display: grid; place-items: center;
  font-size: .62rem; font-style: normal; font-weight: 700;
  border: 1px solid var(--line);
  color: var(--muted);
}
.week i.hit { background: var(--cyan); border-color: var(--cyan); color: var(--on-cyan); }
.week i.today { outline: 2px solid var(--fg); outline-offset: 1px; }

/* ---------- readiness ---------- */

.ready-num { font-family: var(--serif); font-size: 2.6rem; line-height: 1; }
.ready-bar { height: 10px; border-radius: 5px; background: var(--line); overflow: hidden; margin: .6rem 0 .4rem; position: relative; }
.ready-bar i { display: block; height: 100%; border-radius: 5px; background: var(--cyan); transition: width .5s; }
.ready-bar .mark {
  position: absolute; top: -3px; bottom: -3px; width: 2px;
  background: var(--fg); opacity: .55;
}

/* ---------- welcome ---------- */

.welcome { max-width: 30rem; margin: 1.5rem auto; }
.welcome-mark { color: var(--cyan); margin-bottom: .4rem; }
.welcome h1 { font-family: var(--serif); margin-bottom: .25rem; }
.wfield { display: block; margin-top: 1.15rem; }
.wfield > span {
  display: flex; align-items: center; gap: .4rem;
  font-weight: 600; font-size: .92rem; margin-bottom: .35rem;
}
.wfield > span .ico { color: var(--cyan); }
.wfield > span em { font-style: normal; font-weight: 400; color: var(--muted); font-size: .82rem; }
.wfield input[type="text"], .wfield input[type="date"] {
  width: 100%; font: inherit;
  padding: .65rem .8rem;
  border: 1px solid var(--line-strong); border-radius: 10px;
  background: var(--bg); color: var(--fg);
  min-height: 44px;
}
.wfield small { display: block; margin-top: .3rem; font-size: .8rem; }
.welcome .seg { width: 100%; }
.welcome .seg button { flex: 1; justify-content: center; }

/* ---------- help ---------- */

/* Collapsed by default and placed on the screen it explains. An expanded
   explainer on every visit becomes noise she scrolls past. */
.helpbox {
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--bg);
  margin: 0 0 1rem;
}
.helpbox > summary {
  cursor: pointer; list-style: none;
  display: flex; align-items: center; gap: .45rem;
  padding: .6rem .8rem; min-height: 44px;
  font-size: .88rem; font-weight: 600; color: var(--muted);
}
.helpbox > summary::-webkit-details-marker { display: none; }
.helpbox > summary .ico { color: var(--cyan); }
.helpbox[open] > summary { color: var(--fg); border-bottom: 1px solid var(--line); }
.helpbox-in { padding: .8rem; font-size: .89rem; }
.helpbox-in p { margin: 0 0 .6rem; }
.helpbox-in ul { margin: 0 0 .6rem; padding-left: 1.1rem; }
.helpbox-in li { margin-bottom: .35rem; }

.tip {
  display: flex; gap: .5rem; align-items: flex-start;
  background: var(--warn-bg); color: var(--warn);
  border-radius: 8px; padding: .5rem .7rem; margin: 0;
  font-size: .86rem;
}
.tip .ico { flex: none; margin-top: .1rem; }

ol.howto, ul.howto { padding-left: 1.2rem; margin: 0 0 .5rem; }
ol.howto li, ul.howto li { margin-bottom: .5rem; }

.rhythm { display: grid; gap: .55rem; }
.rhythm div {
  display: grid; grid-template-columns: 11rem 1fr; gap: .3rem 1rem;
  padding: .6rem .75rem; border: 1px solid var(--line); border-radius: 9px;
}
.rhythm b { color: var(--cyan); font-size: .88rem; }
.rhythm span { font-size: .89rem; }
@media (max-width: 640px) {
  .rhythm div { grid-template-columns: 1fr; }
}

/* ---------- readiness evidence ---------- */

.ready-band { margin-bottom: .2rem; }
.evidence {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  gap: .8rem 1rem;
  padding-top: .8rem;
  border-top: 1px solid var(--line);
}
.evidence div b { display: block; font-family: var(--serif); font-size: 1.25rem; line-height: 1.1; }
.evidence div b .muted { font-size: .8rem; color: var(--muted); }
.evidence div span { font-size: .74rem; color: var(--muted); text-transform: uppercase; letter-spacing: .03em; display: inline-flex; align-items: center; gap: .25rem; }
.evidence div span .ico { opacity: .8; }

/* ---------- confidence / why-missed prompts ---------- */

.ask {
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  padding: .8rem;
  margin-bottom: 1rem;
  background: var(--bg);
}
.ask-q { font-weight: 700; font-size: .93rem; margin: 0 0 .55rem; }
.ask-opts { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: .45rem; }
.ask-opts.why { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.ask-opts button { font-size: .85rem; padding: .6rem .5rem; min-height: 44px; }

.choice.picked { border-color: var(--cyan); background: var(--card-bg); }
.choice.picked .key { background: var(--cyan); color: var(--on-cyan); }

.conf-tag {
  font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  background: var(--line); color: var(--muted);
  padding: .12rem .45rem; border-radius: 999px; vertical-align: middle;
}
.conf-tag.danger { background: var(--bad-bg); color: var(--bad); }

/* ---------- typed formula drill ---------- */

.typed-in {
  width: 100%;
  font: inherit;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  padding: .8rem;
  margin-bottom: 1rem;
  border-radius: 10px;
  border: 1px solid var(--line-strong);
  background: var(--bg);
  color: var(--fg);
}

/* Native controls need explicit sizing: a default select is ~30px tall with a
   13px font, which is both under the 44px touch floor and small enough that
   iOS zooms the page when it gains focus. */
.field-row {
  display: flex; align-items: center; gap: .5rem;
  margin-bottom: .6rem; font-size: .9rem;
}
.field-row .ico { color: var(--cyan); }
.field-row > span { font-weight: 600; }
.sel {
  flex: 1; min-width: 0;
  font: inherit; font-size: max(16px, 1rem);
  min-height: 44px; padding: .5rem .7rem;
  border-radius: 10px;
  background: var(--bg); color: var(--fg);
  border: 1px solid var(--line-strong);
}
.check-row {
  display: flex; align-items: center; gap: .55rem;
  min-height: 44px; margin-bottom: .6rem;
  font-size: .9rem; cursor: pointer;
}
.check-row input { width: 1.15rem; height: 1.15rem; accent-color: var(--cyan); flex: none; }

.date-in {
  font: inherit;
  padding: .55rem .7rem;
  border-radius: 10px;
  border: 1px solid var(--line-strong);
  background: var(--bg);
  color: var(--fg);
  min-height: 44px;
}

/* ---------- plan ---------- */

.plan { list-style: none; padding: 0; margin: .6rem 0 0; }
.plan li { margin-bottom: .45rem; }
.plan button {
  display: flex; align-items: center; gap: .65rem;
  width: 100%; text-align: left;
  padding: .7rem .8rem; font-weight: 500; font-size: .92rem;
}
.plan button .ico { color: var(--cyan); }
.plan button .go { margin-left: auto; color: var(--muted); }
/* The first plan item is the recommended next action, so it reads as the
   primary button rather than one of five equal choices. */
.plan button.first { border-color: var(--cyan); font-weight: 600; }

/* ---------- teaching today ---------- */

.teach h3 { display: flex; align-items: center; gap: .45rem; margin-bottom: .25rem; }

/* Collapsed by default. It is optional, and nine competency buttons expanded
   on every visit pushed the actual plan below the fold. */
.teach-details > summary {
  cursor: pointer; list-style: none;
  display: flex; align-items: flex-start; gap: .55rem;
  min-height: 44px;
}
.teach-details > summary::-webkit-details-marker { display: none; }
.teach-details > summary .ico { color: var(--cyan); flex: none; margin-top: .15rem; }
.teach-details > summary b { display: block; font-size: .95rem; }
.teach-details > summary small { color: var(--muted); font-size: .84rem; }
.teach-details[open] > summary { margin-bottom: .3rem; }

.teach-opts { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: .4rem; margin-top: .7rem; }
.teach-opt {
  display: flex; align-items: center; gap: .5rem;
  text-align: left; font-size: .85rem; font-weight: 500;
  padding: .6rem .7rem; min-height: 44px;
}
.teach-opt .ico { color: var(--cyan); flex: none; }

/* ---------- skill map ---------- */

.skill-sum { display: flex; gap: .5rem; flex-wrap: wrap; margin-top: .9rem; }
.pill {
  display: inline-flex; align-items: baseline; gap: .35rem;
  padding: .35rem .75rem; border-radius: 999px;
  font-size: .84rem; font-weight: 600;
  border: 1px solid var(--line-strong);
}
.pill b { font-family: var(--serif); font-size: 1.05rem; }
.pill.mastered { background: var(--good-bg); color: var(--good); border-color: transparent; }
.pill.shaky { background: var(--warn-bg); color: var(--warn); border-color: transparent; }
.pill.untouched { background: var(--line); color: var(--muted); border-color: transparent; }

/* Stacked coverage bar: mastered / shaky / untouched at a glance. */
.stackbar { display: flex; height: 10px; border-radius: 5px; overflow: hidden; margin-top: .8rem; background: var(--line); }
.stackbar i { display: block; height: 100%; }
.stackbar i.m { background: var(--good); }
.stackbar i.s { background: var(--warn); }
.stackbar i.u { background: var(--line-strong); }

/* Verdict, warning and rating colour cues. */
.verdict { display: flex; align-items: center; gap: .4rem; }
.warn-note {
  display: flex; gap: .5rem; align-items: flex-start;
  background: var(--bad-bg); color: var(--bad);
  border-radius: 9px; padding: .55rem .7rem;
  font-size: .87rem; margin-bottom: .7rem;
}
.warn-note .ico { flex: none; margin-top: .1rem; }

.rate button { display: flex; flex-direction: column; align-items: center; gap: .1rem; }
.rate button .ico { margin-bottom: .1rem; }
.rate .g0 { color: var(--bad); }
.rate .g1 { color: var(--warn); }
.rate .g2 { color: var(--good); }
.rate .g3 { color: var(--cyan); }
.rate button small { color: var(--muted); }

.ask-opts button { display: inline-flex; align-items: center; justify-content: center; gap: .35rem; }
.ask-q { display: flex; align-items: center; gap: .4rem; }
.conf-tag { display: inline-flex; align-items: center; gap: .25rem; }

.pill .ico { flex: none; }
.pill { align-items: center; }

.rail-bar { border-left: 3px solid transparent; padding-left: .7rem; }

ol.skills { list-style: none; padding: 0; margin: 0; counter-reset: sk; }
ol.skills .sk .sk-ico { margin-top: .15rem; flex: none; }
ol.skills .sk.mastered .sk-ico { color: var(--good); }
ol.skills .sk.shaky .sk-ico { color: var(--warn); }
ol.skills .sk.untouched .sk-ico { color: var(--muted); opacity: .7; }
ol.skills .sk button { display: inline-flex; align-items: center; gap: .25rem; }
ol.skills .sk {
  display: flex; align-items: flex-start; gap: .6rem;
  padding: .6rem 0; border-bottom: 1px solid var(--line);
  font-size: .89rem;
}
ol.skills .sk:last-child { border-bottom: 0; }
ol.skills .sk .dot {
  width: .7rem; height: .7rem; border-radius: 50%; flex: none; margin-top: .35rem;
  background: var(--line-strong);
}
ol.skills .sk.mastered .dot { background: var(--good); }
ol.skills .sk.shaky .dot { background: var(--warn); }
ol.skills .sk .sk-txt { display: block; }
ol.skills .sk > span:nth-child(2) { flex: 1; min-width: 0; }
ol.skills .sk button { flex: none; padding: .3rem .6rem; align-self: center; }
details.sec > summary .small { margin-left: auto; }

/* ---------- celebration ---------- */

.celebrate { text-align: center; padding: .5rem 0 0; }
.celebrate .big { font-size: 2.6rem; line-height: 1; margin-bottom: .4rem; }
.celebrate h2 { font-family: var(--serif); margin-bottom: .25rem; }
@keyframes pop { 0% { transform: scale(.7); opacity: 0 } 60% { transform: scale(1.08) } 100% { transform: scale(1); opacity: 1 } }
.celebrate .big, .celebrate .score-big { animation: pop .45s ease-out both; }

/* ---------- theme switcher ---------- */

.seg {
  display: inline-flex;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  overflow: hidden;
  background: var(--card-bg);
}
.seg button {
  border: 0; border-radius: 0;
  padding: .45rem .8rem;
  font-size: .82rem; font-weight: 600;
  background: none; color: var(--muted);
  display: inline-flex; align-items: center; gap: .35rem;
  /* 44px, not 40: this selector is more specific than the mobile
     `button { min-height: 44px }` rule and would otherwise silently win. */
  min-height: 44px;
}
.seg button + button { border-left: 1px solid var(--line); }
.seg button[aria-pressed="true"] { background: var(--cyan); color: var(--on-cyan); }
.seg button:hover:not([aria-pressed="true"]) { color: var(--fg); }

.theme-btn {
  width: 40px; height: 40px; padding: 0;
  display: grid; place-items: center;
  border-radius: 10px;
  color: var(--muted);
}
.theme-btn:hover { color: var(--cyan); }

/* ---------- floating buttons: flag bottom-left, top bottom-right ---------- */

#topSentinel {
  position: absolute;
  top: 0; left: 0;
  width: 1px; height: 400px;
  pointer-events: none;
  visibility: hidden;
}

.fab {
  position: fixed;
  bottom: 1rem;
  z-index: 40;
  width: 42px; height: 42px;
  padding: 0;
  display: grid; place-items: center;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
  background: var(--card-bg);
  color: var(--muted);
  box-shadow: var(--shadow);
}
.fab:hover { border-color: var(--cyan); color: var(--cyan); }
.fab svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.fab--flag { left: 1rem; }
.fab--top { right: 1rem; }
.fab--top[hidden] { display: none; }

.footer-version { cursor: pointer; font-variant-numeric: tabular-nums; }
.footer-version:hover { color: var(--cyan); }

/* ---------- flag dialog ---------- */

.flag-dialog {
  width: min(440px, calc(100vw - 32px));
  border-radius: var(--radius);
  border: 1px solid var(--line-strong);
  background: var(--card-bg);
  color: var(--fg);
  padding: 1.25rem;
  box-shadow: var(--shadow);
}
.flag-dialog::backdrop { background: rgba(0,0,0,.5); }
.flag-head { display: flex; align-items: center; justify-content: space-between; }
.flag-dialog h3 { font-family: var(--serif); margin: 0 0 .25rem; }
.flag-x { background: none; border: 0; color: var(--muted); font-size: 1.4rem; line-height: 1; padding: .1rem .4rem; }
.flag-x:hover { color: var(--fg); border-color: transparent; }
.flag-hint { color: var(--muted); font-size: .84rem; margin: 0 0 .5rem; }
.flag-meta { font-size: .72rem; color: var(--muted); margin: 0 0 .7rem; }
.flag-meta code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.flag-step { display: flex; flex-direction: column; gap: .25rem; }
/* The flex rule above beats the UA [hidden] rule, so force it. Without this
   every step stays visible and the sub-menu appears never to open. */
.flag-step[hidden] { display: none !important; }

.flag-opt {
  display: flex; align-items: center; gap: .5rem;
  width: 100%; text-align: left;
  padding: .5rem .6rem;
  border-radius: 9px;
  border: 1px solid transparent;
  background: none;
  color: var(--fg);
  font-size: .88rem; font-weight: 500;
}
.flag-opt:hover { background: var(--bg); border-color: var(--line-strong); }
.flag-opt .fo-arrow { margin-left: auto; color: var(--muted); }
.flag-back-row {
  align-self: flex-start;
  background: none; border: 0; color: var(--cyan);
  font-size: .8rem; padding: .1rem 0 .5rem;
}
.flag-back-row:hover { border-color: transparent; text-decoration: underline; }
.flag-note-step .field { display: flex; flex-direction: column; gap: .3rem; font-size: .85rem; font-weight: 600; }
.flag-note-step textarea {
  width: 100%; font: inherit; font-weight: 400;
  padding: .6rem; border-radius: 9px;
  border: 1px solid var(--line-strong);
  background: var(--bg); color: var(--fg); resize: vertical;
}
.flag-actions { display: flex; gap: .5rem; justify-content: flex-end; margin-top: .7rem; }
.flag-toast { margin-top: .7rem; font-size: .85rem; }
.flag-toast.ok { color: var(--good); }
.flag-toast.err { color: var(--bad); }

@media (max-width: 560px) {
  .fab { width: 38px; height: 38px; bottom: .7rem; }
  .fab--flag { left: .7rem; }
  .fab--top { right: .7rem; }
}

/* ---------- responsive ----------
   She studies on a phone more than anything else, so the phone rules are not
   an afterthought: 44px minimum touch targets, no hover-only affordances,
   16px form text so iOS does not zoom on focus, and safe-area insets so the
   floating buttons clear the home indicator. */

@supports (padding: max(0px)) {
  .fab { bottom: max(1rem, env(safe-area-inset-bottom)); }
  .fab--flag { left: max(1rem, env(safe-area-inset-left)); }
  .fab--top { right: max(1rem, env(safe-area-inset-right)); }
  footer.foot { padding-bottom: max(1.25rem, calc(env(safe-area-inset-bottom) + 3.5rem)); }
}

/* Tablet: two columns of modes, roomier reading measure. */
@media (max-width: 900px) {
  .shell, .top-inner, footer.foot { max-width: 100%; }
  .modes { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }
}

@media (max-width: 640px) {
  body { font-size: 16px; }
  .shell { padding: 0 .8rem 5.5rem; }
  .top-inner { padding: .6rem .8rem; }
  .panel, .hero { padding: .95rem; }
  .modes { grid-template-columns: 1fr; gap: .6rem; }
  .stat-row { gap: 0; display: grid; grid-template-columns: repeat(2, 1fr); row-gap: .9rem; }
  .stat b { font-size: 1.35rem; }
  .ring { width: 66px; height: 66px; }
  .stem { font-size: 1.05rem; }

  /* Comfortable thumb targets. 44px is the Apple/WCAG floor and choices are
     what she taps hundreds of times a session. */
  .choice { padding: .85rem .8rem; min-height: 52px; }
  .choice .key { width: 1.6rem; height: 1.6rem; }
  button, .btn { min-height: 44px; }
  .actions { gap: .5rem; }
  .actions button { flex: 1 1 auto; }
  .rate { grid-template-columns: repeat(2, 1fr); }
  .rate button { min-height: 56px; }

  /* Exam navigator: smaller cells so 80 questions stay reachable. */
  .grid-nav { grid-template-columns: repeat(auto-fill, minmax(34px, 1fr)); }
  .grid-nav button { min-height: 34px; padding: .3rem 0; }

  .body-md table { font-size: .82rem; }
  .flag-dialog { width: calc(100vw - 20px); padding: 1rem; }
  .seg button { padding: .45rem .6rem; }
  .today { gap: .8rem; }
}

/* Landscape phone: the sticky header eats too much of a 375px-tall viewport. */
@media (max-height: 460px) and (orientation: landscape) {
  header.top { position: static; }
}

/* Inputs at 16px or iOS zooms the whole page on focus. */
input, textarea, select { font-size: max(16px, 1rem); }

/* Coarse pointers get no hover styling, which otherwise sticks after a tap. */
@media (hover: none) {
  .mode:hover, .choice:hover:not(:disabled), button:hover, .btn:hover { border-color: var(--line-strong); }
  .btn-primary:hover { border-color: var(--cyan); filter: none; }
  .fab:hover { color: var(--muted); border-color: var(--line-strong); }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; scroll-behavior: auto !important; }
}
