/* ==========================================================================
   Surfaces that are not a lesson: the contents page, drills, quiz, reference
   sheets, glossary, playground, project. Same restraint as base.css — lists
   with hairlines rather than grids of cards.
   ========================================================================== */

/* ---------- 1. Home ----------------------------------------------------- */

.hero {
  max-width: var(--shell);
  margin-inline: auto;
  padding: var(--s9) var(--s5) var(--s7);
}

.hero__title {
  margin: 0;
  max-width: 26ch;
  font-size: var(--t-hero);
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -0.03em;
  text-wrap: balance;
}

.hero__lede {
  max-width: 60ch;
  margin: var(--s5) 0 0;
  font-size: var(--t-lede);
  line-height: 1.6;
  color: var(--fg-muted);
}

.hero__actions {
  display: flex;
  align-items: center;
  gap: var(--s4);
  flex-wrap: wrap;
  margin-top: var(--s6);
}

.hero__facts {
  display: flex;
  gap: var(--s5);
  flex-wrap: wrap;
  margin: var(--s6) 0 0;
  padding: 0;
  list-style: none;
  font-size: var(--t-label);
  color: var(--fg-faint);
}

/* Contents: a numbered list, grouped, with hairlines. No cards. */
.contents {
  max-width: var(--shell);
  margin-inline: auto;
  padding: 0 var(--s5) var(--s8);
}

.group + .group {
  margin-top: var(--s8);
}

.group__head {
  display: flex;
  align-items: baseline;
  gap: var(--s4);
  flex-wrap: wrap;
  padding-bottom: var(--s3);
  border-bottom: 1px solid var(--line);
}

.group__name {
  margin: 0;
  font-size: var(--t-h3);
  font-weight: 600;
  letter-spacing: -0.011em;
}

.group__note {
  margin: 0;
  font-size: var(--t-small);
  color: var(--fg-faint);
}

.lessons {
  margin: 0;
  padding: 0;
  list-style: none;
}

.lesson-row {
  border-bottom: 1px solid var(--line);
}

.lesson-row__link {
  display: grid;
  grid-template-columns: 2.75rem 1fr auto;
  align-items: baseline;
  gap: var(--s4);
  padding: var(--s4) var(--s2);
  text-decoration: none;
  color: var(--fg);
  border-radius: var(--radius-sm);
  transition: background-color 0.15s var(--ease);
}

.lesson-row__link:hover {
  background: var(--bg-subtle);
}

.lesson-row__n {
  font-size: var(--t-label);
  font-variant-numeric: tabular-nums;
  color: var(--fg-faint);
}

.lesson-row__body {
  min-width: 0;
}

.lesson-row__title {
  display: block;
  font-size: var(--t-body);
  font-weight: 500;
  letter-spacing: -0.011em;
}

.lesson-row__link:hover .lesson-row__title {
  color: var(--accent);
}

.lesson-row__grip {
  display: block;
  margin: 3px 0 0;
  font-size: var(--t-small);
  line-height: 1.5;
  color: var(--fg-muted);
}

.lesson-row__aside {
  display: flex;
  align-items: center;
  gap: var(--s3);
  font-size: var(--t-label);
  color: var(--fg-faint);
  white-space: nowrap;
}

.lesson-row[data-done='true'] .lesson-row__n {
  color: var(--ok);
}

.tick {
  display: none;
  width: 15px;
  height: 15px;
  color: var(--ok);
}

.lesson-row[data-done='true'] .tick {
  display: block;
}

.progress-line {
  margin: var(--s6) 0 0;
  font-size: var(--t-label);
  color: var(--fg-faint);
}

/* Other rooms: a plain definition list. */
.rooms {
  max-width: var(--shell);
  margin-inline: auto;
  padding: 0 var(--s5) var(--s9);
}

.rooms .prose h2 {
  margin-top: 0;
  padding-top: 0;
  border-top: none;
}

.rooms__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1px;
  margin-top: var(--s5);
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}

.room {
  display: block;
  padding: var(--s5);
  background: var(--bg);
  text-decoration: none;
  color: var(--fg);
  transition: background-color 0.15s var(--ease);
}

.room:hover {
  background: var(--bg-subtle);
}

.room__name {
  display: block;
  font-size: var(--t-small);
  font-weight: 600;
  letter-spacing: -0.011em;
  margin-bottom: var(--s1);
}

.room:hover .room__name {
  color: var(--accent);
}

.room__blurb {
  margin: 0;
  font-size: var(--t-label);
  line-height: 1.6;
  color: var(--fg-muted);
}

/* ---------- 2. Pillars (four ideas) ------------------------------------- */

.pillars {
  margin: var(--s5) 0 0;
  border-top: 1px solid var(--line);
}

.pillar {
  display: grid;
  grid-template-columns: 10rem 1fr;
  gap: var(--s5);
  padding: var(--s5) 0;
  border-bottom: 1px solid var(--line);
}

.pillar__name {
  margin: 0;
  font-size: var(--t-body);
  font-weight: 600;
  letter-spacing: -0.011em;
}

.pillar__body p {
  max-width: 64ch;
  margin: 0 0 var(--s2);
}

.pillar__body p:last-child {
  margin-bottom: 0;
}

.pillar__where {
  font-size: var(--t-label);
  color: var(--fg-faint);
}

/* ---------- 3. Drills --------------------------------------------------- */

.drill {
  margin-block: var(--s7);
  padding-top: var(--s5);
  border-top: 1px solid var(--line);
}

.drill__head {
  display: flex;
  align-items: baseline;
  gap: var(--s3);
  flex-wrap: wrap;
  margin-bottom: var(--s3);
}

.drill__n {
  font-size: var(--t-label);
  color: var(--fg-faint);
  font-variant-numeric: tabular-nums;
}

.drill__title {
  margin: 0;
  font-size: var(--t-h3);
  font-weight: 600;
  letter-spacing: -0.011em;
}

.drill__level {
  margin-left: auto;
  padding: 2px var(--s2);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  font-size: 0.75rem;
  color: var(--fg-faint);
}

.solution {
  margin-top: var(--s4);
}

.solution > summary {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  padding: 6px var(--s3);
  border: 1px solid var(--border-control);
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-size: var(--t-label);
  font-weight: 500;
  color: var(--fg-muted);
  list-style: none;
  transition: background-color 0.15s var(--ease), color 0.15s var(--ease);
}

.solution > summary::-webkit-details-marker {
  display: none;
}

.solution > summary:hover {
  background: var(--bg-subtle);
  color: var(--fg);
}

.solution > summary::before {
  content: '';
  width: 7px;
  height: 7px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  rotate: -45deg;
  transition: rotate 0.18s var(--ease);
}

.solution[open] > summary::before {
  rotate: 45deg;
}

.solution__body {
  padding-top: var(--s3);
}

.solution__body > p {
  margin: 0;
  font-size: var(--t-small);
  color: var(--fg-muted);
}

/* Patterns page: the recognition line under each heading, and the list of
   problems a pattern unlocks. */
.brief-signal {
  max-width: var(--measure);
  margin: 0 0 var(--s4);
  padding: var(--s3) var(--s4);
  border-left: 2px solid var(--accent);
  background: var(--bg-subtle);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  font-size: var(--t-small);
  line-height: 1.65;
  color: var(--fg-muted);
}

.brief-signal strong {
  color: var(--fg);
  font-weight: 600;
}

.unlocks {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 2px var(--s5);
  margin: 0;
  padding: 0;
  list-style: none;
}

.unlocks li {
  font-size: var(--t-label);
  line-height: 1.7;
  color: var(--fg-muted);
}

.unlocks li::before {
  content: '·';
  margin-right: var(--s2);
  color: var(--fg-faint);
}

/* Problem set: pattern groups, difficulty tags, and the hint ladder. */
.group-block + .group-block {
  margin-top: var(--s9);
}

.group-block > .group__head {
  margin-bottom: var(--s5);
}

.drill__level[data-level='Easy'] {
  border-color: color-mix(in srgb, var(--ok) 45%, var(--line-strong));
  color: var(--ok);
}

.drill__level[data-level='Medium'] {
  border-color: color-mix(in srgb, var(--accent) 45%, var(--line-strong));
  color: var(--accent);
}

.drill__level[data-level='Hard'] {
  border-color: color-mix(in srgb, var(--warn) 45%, var(--line-strong));
  color: var(--warn);
}

.hints {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  margin-bottom: var(--s4);
}

.solution.hint {
  margin-top: 0;
}

.solution.hint[open] {
  flex-basis: 100%;
}

.solution.hint .solution__body {
  max-width: var(--measure);
}

.solution.hint .solution__body p {
  margin: 0;
  font-size: var(--t-small);
  line-height: 1.65;
  color: var(--fg-muted);
}

/* ---------- 4. Quiz ----------------------------------------------------- */

.score {
  position: sticky;
  top: 57px;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: var(--s4);
  flex-wrap: wrap;
  margin-bottom: var(--s7);
  padding: var(--s3) var(--s4);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--bg) 90%, transparent);
  backdrop-filter: blur(10px);
  font-size: var(--t-label);
  color: var(--fg-muted);
}

.score__n {
  font-size: var(--t-small);
  font-weight: 600;
  color: var(--fg);
  font-variant-numeric: tabular-nums;
}

.score__track {
  flex: 1;
  min-width: 100px;
  height: 4px;
  border-radius: 999px;
  background: var(--bg-sunken);
  overflow: hidden;
}

.score__fill {
  display: block;
  height: 100%;
  width: 100%;
  background: var(--accent);
  transform-origin: left center;
  scale: 0 1;
  transition: scale 0.35s var(--ease);
}

.q {
  margin-block: var(--s7);
  padding-top: var(--s5);
  border-top: 1px solid var(--line);
}

.q__n {
  font-size: var(--t-label);
  color: var(--fg-faint);
  font-variant-numeric: tabular-nums;
}

.q__stem {
  max-width: var(--measure);
  margin: var(--s1) 0 var(--s4);
  font-size: var(--t-body);
  font-weight: 500;
  line-height: 1.55;
  letter-spacing: -0.011em;
}

.q .code {
  margin-block: 0 var(--s4);
}

.opts {
  display: grid;
  gap: var(--s2);
  max-width: var(--measure);
  margin: 0;
  padding: 0;
  list-style: none;
}

.opt {
  display: flex;
  align-items: flex-start;
  gap: var(--s3);
  width: 100%;
  padding: var(--s3) var(--s4);
  text-align: left;
  font-size: var(--t-small);
  line-height: 1.6;
  color: var(--fg);
  background: var(--bg);
  border: 1px solid var(--border-control);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background-color 0.15s var(--ease), border-color 0.15s var(--ease);
}

.opt:hover:not([disabled]) {
  background: var(--bg-subtle);
  border-color: var(--fg-faint);
}

.opt[disabled] {
  cursor: default;
}

.opt__key {
  flex: none;
  width: 1.35em;
  font-weight: 500;
  color: var(--fg-faint);
  font-variant-numeric: tabular-nums;
}

.opt__verdict {
  margin-left: auto;
  padding-left: var(--s3);
  flex: none;
  font-size: var(--t-label);
  font-weight: 500;
}

.opt[data-verdict='right'] {
  background: var(--ok-subtle);
  border-color: var(--ok);
}

.opt[data-verdict='right'] .opt__key,
.opt[data-verdict='right'] .opt__verdict {
  color: var(--ok);
}

.opt[data-verdict='wrong'] {
  background: var(--warn-subtle);
  border-color: var(--warn);
}

.opt[data-verdict='wrong'] .opt__key,
.opt[data-verdict='wrong'] .opt__verdict {
  color: var(--warn);
}

.why {
  margin: var(--s3) 0 0;
  max-width: var(--measure);
  padding: var(--s4);
  border-left: 2px solid var(--line-strong);
  font-size: var(--t-small);
  color: var(--fg-muted);
}

.why[hidden] {
  display: none;
}

.why strong {
  display: block;
  margin-bottom: var(--s1);
  color: var(--fg);
  font-weight: 600;
}

/* ---------- 5. Reference sheet ------------------------------------------ */

.ref {
  margin: var(--s5) 0 var(--s7);
  border-top: 1px solid var(--line);
}

.ref__row {
  display: grid;
  grid-template-columns: 12rem 1fr;
  gap: var(--s5);
  padding: var(--s5) 0;
  border-bottom: 1px solid var(--line);
  align-items: start;
}

.ref__what {
  margin: 0;
  font-size: var(--t-small);
  font-weight: 600;
  letter-spacing: -0.011em;
}

.ref__gotcha {
  margin: var(--s2) 0 0;
  font-size: var(--t-label);
  line-height: 1.6;
  color: var(--fg-muted);
}

.ref__row .code {
  margin: 0;
}

/* ---------- 6. Glossary ------------------------------------------------- */

.filter {
  display: flex;
  gap: var(--s3);
  align-items: center;
  flex-wrap: wrap;
  margin: var(--s5) 0 var(--s6);
}

.filter input {
  flex: 1;
  min-width: 200px;
  max-width: 360px;
  padding: 9px var(--s3);
  font: inherit;
  font-size: var(--t-small);
  color: var(--fg);
  background: var(--bg);
  border: 1px solid var(--border-control);
  border-radius: var(--radius-sm);
}

.filter input::placeholder {
  color: var(--fg-faint);
}

.filter__count {
  font-size: var(--t-label);
  color: var(--fg-faint);
}

.lex {
  border-top: 1px solid var(--line);
}

.lex__row {
  display: grid;
  grid-template-columns: 10rem 1fr;
  gap: var(--s5);
  padding: var(--s5) 0;
  border-bottom: 1px solid var(--line);
}

.lex__row[hidden] {
  display: none;
}

.lex__term {
  margin: 0;
  font-size: var(--t-body);
  font-weight: 600;
  letter-spacing: -0.011em;
}

.lex__short {
  max-width: 64ch;
  margin: 0 0 var(--s2);
}

.lex__long {
  margin: 0;
  font-size: var(--t-small);
  color: var(--fg-muted);
}

.lex__see {
  margin: var(--s2) 0 0;
  font-size: var(--t-label);
  color: var(--fg-faint);
}

.lex__empty {
  padding: var(--s7) 0;
  color: var(--fg-muted);
}

.lex__empty[hidden] {
  display: none;
}

/* ---------- 7. Playground ----------------------------------------------- */

.pg .code__edit {
  min-height: min(54vh, 520px);
}

.starters {
  margin-top: var(--s6);
  padding-top: var(--s5);
  border-top: 1px solid var(--line);
}

.starters h2 {
  margin: 0 0 var(--s3);
  font-size: var(--t-label);
  font-weight: 600;
  color: var(--fg-faint);
}

.starters ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.starters button {
  padding: 6px var(--s3);
  border: 1px solid var(--border-control);
  border-radius: 999px;
  background: transparent;
  font-size: var(--t-label);
  color: var(--fg-muted);
  cursor: pointer;
  transition: background-color 0.15s var(--ease), color 0.15s var(--ease),
    border-color 0.15s var(--ease);
}

.starters button:hover {
  background: var(--bg-subtle);
  color: var(--fg);
}

.starters button[aria-pressed='true'] {
  background: var(--fg);
  border-color: var(--fg);
  color: var(--bg);
}

.pg__notes {
  margin-top: var(--s6);
  font-size: var(--t-small);
  color: var(--fg-muted);
}

.pg__notes p {
  margin: 0 0 var(--s3);
}

.pg__notes strong {
  color: var(--fg);
  font-weight: 600;
}

/* ---------- 8. Project -------------------------------------------------- */

.step {
  margin-block: var(--s8);
  padding-top: var(--s5);
  border-top: 1px solid var(--line);
}

.step__n {
  font-size: var(--t-label);
  color: var(--fg-faint);
  font-variant-numeric: tabular-nums;
}

.step__title {
  margin: var(--s1) 0 var(--s3);
  font-size: var(--t-h2);
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.02em;
}

.brief {
  margin: var(--s6) 0;
  padding: var(--s6);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg-subtle);
}

.brief h2 {
  margin: 0 0 var(--s4);
  padding: 0;
  border: none;
  font-size: var(--t-label);
  font-weight: 600;
  color: var(--fg-faint);
}

.brief ul {
  margin: 0;
  padding-left: var(--s5);
}

.brief li {
  margin-bottom: var(--s2);
}

.brief li:last-child {
  margin-bottom: 0;
}

/* ---------- 9. Tables (complexity sheets) -------------------------------- */

.tbl {
  margin: var(--s5) 0 var(--s7);
  overflow-x: auto;
}

.tbl table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--t-small);
}

.tbl caption {
  margin-bottom: var(--s3);
  text-align: left;
  font-size: var(--t-label);
  font-weight: 600;
  color: var(--fg-faint);
}

.tbl th,
.tbl td {
  padding: var(--s3) var(--s4) var(--s3) 0;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--line);
  line-height: 1.55;
}

.tbl th {
  font-weight: 600;
  color: var(--fg);
  white-space: nowrap;
  border-bottom-color: var(--line-strong);
}

.tbl tbody th {
  font-weight: 500;
}

.tbl td:last-child,
.tbl th:last-child {
  padding-right: 0;
}

.tbl code {
  white-space: nowrap;
}

.tbl .num {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.tbl .good { color: var(--ok); }
.tbl .bad { color: var(--warn); }

.tbl tbody tr:hover {
  background: var(--bg-subtle);
}

/* ---------- 10. Print --------------------------------------------------- */

@media print {
  .site-header,
  .site-footer,
  .skip,
  .code__bar,
  .out,
  .hints,
  .btn {
    display: none !important;
  }

  .page,
  .prose {
    max-width: none;
  }

  .tbl {
    break-inside: avoid;
    overflow: visible;
  }

  .tbl table {
    font-size: 9pt;
  }

  .solution > summary {
    display: none;
  }

  .solution__body {
    display: block !important;
  }

  a {
    text-decoration: none;
    color: inherit;
  }
}

/* ---------- 11. Narrow -------------------------------------------------- */

@media (max-width: 860px) {
  .hero,
  .contents,
  .rooms {
    padding-inline: var(--s4);
  }

  .hero {
    padding-top: var(--s7);
  }

  .pillar,
  .ref__row,
  .lex__row {
    grid-template-columns: 1fr;
    gap: var(--s3);
  }

  .lesson-row__link {
    grid-template-columns: 2.25rem 1fr;
    gap: var(--s3);
  }

  .lesson-row__aside {
    grid-column: 2;
    margin-top: var(--s1);
  }

  .drill__level {
    margin-left: 0;
  }

  .score {
    position: static;
  }

  .brief {
    padding: var(--s5) var(--s4);
  }
}

/* ---------- exercises course: added for the three tracks ----------------- */

/* The contents page: one card per track, with an honest progress bar. */
.tcards {
  display: grid;
  gap: var(--s5);
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
}

.tcard {
  padding: var(--s5);
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--bg-subtle);
}

.tcard h3 {
  margin: 0 0 var(--s2);
  font-size: var(--t-h3);
  font-weight: 600;
}

.tcard h3 a { text-decoration: none; }
.tcard h3 a:hover { text-decoration: underline; }

.tcard p {
  margin: 0 0 var(--s4);
  color: var(--fg-muted);
  font-size: var(--t-small);
  line-height: 1.55;
}

.tcard__bar { margin-bottom: var(--s4) !important; }

.tcard__rows {
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--line);
}

.tcard__rows li {
  display: flex;
  justify-content: space-between;
  gap: var(--s3);
  padding: var(--s2) 0;
  border-bottom: 1px solid var(--line);
  font-size: var(--t-label);
}

.tcard__rows a { text-decoration: none; }
.tcard__rows a:hover { text-decoration: underline; }

.tcard__rows span {
  font-family: var(--mono);
  color: var(--fg-faint);
  white-space: nowrap;
}

.tcard__rows .row--done span { color: var(--ok, var(--accent)); }
.tcard__rows .row--none a { color: var(--fg-faint); }

/* A progress bar. Deliberately plain: it is a fact, not a celebration. */
.bar {
  display: inline-block;
  width: 8rem;
  height: 6px;
  margin-right: var(--s3);
  vertical-align: middle;
  border-radius: 3px;
  background: var(--bg-sunken);
  overflow: hidden;
}

.bar__fill {
  display: block;
  height: 100%;
  background: var(--accent);
}

.bar__text {
  font-family: var(--mono);
  font-size: var(--t-label);
  color: var(--fg-muted);
}

/* Section headers on a track page. */
.sec {
  padding-bottom: var(--s4);
  margin-bottom: var(--s6);
  border-bottom: 1px solid var(--line);
}

.sec h2 {
  margin: 0 0 var(--s2);
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--s3);
}

.sec__todo {
  margin: var(--s3) 0 0;
  font-size: var(--t-small);
  color: var(--fg-faint);
}

/* Status tags: written, partly written, not started. */
.tag {
  padding: 0.15em 0.5em;
  border-radius: 999px;
  font-family: var(--mono);
  font-size: var(--t-label);
  font-weight: 500;
  white-space: nowrap;
}

.tag--done { background: var(--bg-sunken); color: var(--fg-muted); }
.tag--part { background: var(--bg-sunken); color: var(--warn); }
.tag--none { background: var(--bg-sunken); color: var(--fg-faint); }

/* One exercise. */
.drill__ask {
  margin-bottom: var(--s4);
}

.drill__ask p {
  margin: 0 0 var(--s3);
  max-width: var(--measure);
  line-height: 1.65;
  overflow-wrap: break-word;
}

.drill__ask p:last-child { margin-bottom: 0; }

/* The hint ladder, closed by default so you try first. */
.hints {
  margin-bottom: var(--s4);
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--bg-subtle);
}

.hints > summary {
  padding: var(--s3) var(--s4);
  cursor: pointer;
  font-size: var(--t-small);
  font-weight: 500;
  color: var(--fg-muted);
}

.hints > summary:hover { color: var(--fg); }
.hints[open] > summary { border-bottom: 1px solid var(--line); }

.hints__list {
  margin: 0;
  padding: var(--s4) var(--s4) var(--s4) var(--s6);
  list-style: none;
  counter-reset: none;
}

.hints__list li {
  margin-bottom: var(--s3);
  font-size: var(--t-small);
  line-height: 1.6;
  color: var(--fg-muted);
  overflow-wrap: break-word;
}

.hints__list li:last-child { margin-bottom: 0; }
.hints__list strong { color: var(--fg); }

/* The multi-file reference block, for exercises about import and export. */
.drill__files {
  margin-bottom: var(--s4);
  padding: var(--s4);
  border: 1px dashed var(--line);
  border-radius: 8px;
}

.drill__filesnote {
  margin: 0 0 var(--s3);
  font-size: var(--t-label);
  color: var(--fg-faint);
  line-height: 1.55;
  overflow-wrap: break-word;
}

/* What the exercise is really teaching. */
.drill__note {
  margin-top: var(--s4);
  padding-left: var(--s4);
  border-left: 2px solid var(--accent);
}

.drill__note p {
  margin: 0 0 var(--s3);
  max-width: var(--measure);
  font-size: var(--t-small);
  line-height: 1.65;
  color: var(--fg-muted);
  overflow-wrap: break-word;
}

.drill__note p:last-child { margin-bottom: 0; }
.drill__note strong { color: var(--fg); }

.drill__source {
  margin: var(--s3) 0 0;
  font-size: var(--t-label);
  color: var(--fg-faint);
}

.drill__source strong {
  font-family: var(--mono);
  font-weight: 500;
  color: var(--fg-muted);
}

/* Level pills, reusing the palette already checked by contrast.mjs. */
.drill__level--easy { color: var(--fg-muted); }
.drill__level--fair { color: var(--accent); }
.drill__level--hard { color: var(--warn); }

@media (max-width: 560px) {
  .bar { width: 5rem; }
  .tcard__rows li { font-size: 0.78rem; }
}

/* ---------- HTML/CSS exercises: source beside a live preview ------------- */

.hc {
  display: grid;
  gap: var(--s4);
  margin-bottom: var(--s4);
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: start;
}

.hc__source { min-width: 0; }

.hc__preview {
  margin: 0;
  min-width: 0;
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
  background: #fff;
}

.hc__preview figcaption {
  padding: var(--s2) var(--s3);
  border-bottom: 1px solid var(--line);
  background: var(--bg-subtle);
  color: var(--fg-faint);
  font-size: var(--t-label);
  line-height: 1.45;
}

/* The iframe is sandboxed with an empty allow-list, so nothing inside it can
   run scripts, submit forms or reach this page. It exists purely so you can see
   what the markup renders to. */
.hc__preview iframe {
  display: block;
  width: 100%;
  min-height: 12rem;
  border: 0;
  background: #fff;
}

/* Stack them on a narrow screen: side by side stops being readable well before
   the usual breakpoint, because both halves need real width. */
@media (max-width: 1000px) {
  .hc { grid-template-columns: minmax(0, 1fr); }
}

/* ---- live demo iframe, for the DOM and Events exercises -------------------
   Same frame treatment as the HTML/CSS preview, but this one is allowed to run
   scripts, because scripts are the subject. It is taller by default: these
   demos have buttons to press and grow when you press them. */
.hc__preview--live {
  margin: 0 0 var(--s4);
}
.hc__preview--live iframe {
  min-height: 13rem;
  background: #fff;
}
.hc__preview--live figcaption code {
  font-size: 0.92em;
}

/* ---- the DOM stand-in disclosure -----------------------------------------
   Collapsed by default. It matters that it is present and readable, not that it
   is in the way. */
.standin {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg-subtle);
  margin: 0 0 var(--s6);
}
.standin > summary {
  cursor: pointer;
  padding: var(--s3) var(--s4);
  font-size: var(--t-small);
  font-weight: 500;
  color: var(--fg-muted);
  list-style: none;
}
.standin > summary::-webkit-details-marker {
  display: none;
}
.standin > summary::before {
  content: '+';
  display: inline-block;
  width: 1rem;
  font-weight: 600;
  color: var(--fg-faint);
}
.standin[open] > summary::before {
  content: '\2212';
}
.standin > summary:hover {
  color: var(--fg);
}
.standin > summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius);
}
.standin__body {
  padding: 0 var(--s4) var(--s4);
  border-top: 1px solid var(--line);
}
.standin__body p {
  font-size: var(--t-small);
  line-height: 1.65;
  color: var(--fg-muted);
  margin: var(--s4) 0;
  max-width: var(--measure, 68ch);
}

/* ---- the folded extra checks ---------------------------------------------
   Same treatment as the stand-in disclosure: present and reachable, not in the
   way. Sits directly under its solution panel, so it reads as belonging to it. */
.more {
  margin: calc(var(--s3) * -1) 0 var(--s5);
  border-left: 2px solid var(--line);
  padding-left: var(--s3);
}
.more > summary {
  cursor: pointer;
  font-size: var(--t-label);
  color: var(--fg-faint);
  list-style: none;
  padding: var(--s2) 0;
}
.more > summary::-webkit-details-marker {
  display: none;
}
.more > summary::before {
  content: '+ ';
  font-weight: 600;
}
.more[open] > summary::before {
  content: '\2212 ';
}
.more > summary:hover {
  color: var(--fg-muted);
}
.more > summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
.more__body p {
  font-size: var(--t-label);
  line-height: 1.6;
  color: var(--fg-faint);
  margin: 0 0 var(--s3);
  max-width: 68ch;
}

/* ==========================================================================
   AI Engineer course components.
   The base sheet and the panel styles are shared with the other courses here.
   Everything below is specific to this one.
   ========================================================================== */

/* ---- lessons ------------------------------------------------------------- */
.lesson {
  padding: var(--s7) 0;
  border-top: 1px solid var(--line);
}
.lesson:first-of-type {
  border-top: 0;
}
.lesson__head {
  display: flex;
  align-items: baseline;
  gap: var(--s3);
  flex-wrap: wrap;
  margin-bottom: var(--s4);
}
.lesson__title {
  font-size: var(--t-h2);
  margin: 0;
  line-height: 1.25;
}
.lesson__n {
  display: inline-block;
  min-width: 2.1rem;
  color: var(--fg-faint);
  font-variant-numeric: tabular-nums;
  font-weight: 500;
}
.lesson__lede {
  font-size: var(--t-lede);
  line-height: 1.6;
  color: var(--fg-muted);
  max-width: var(--measure, 68ch);
  margin: 0 0 var(--s5);
}
.lesson h4 {
  font-size: var(--t-h3);
  margin: var(--s6) 0 var(--s3);
}
.lesson h5 {
  font-size: var(--t-body);
  margin: 0 0 var(--s2);
}
.lesson p,
.lesson li {
  max-width: var(--measure, 68ch);
}
.lesson--todo {
  opacity: 0.72;
}
.lesson__todo {
  font-size: var(--t-small);
  color: var(--fg-muted);
  border-left: 2px solid var(--line-strong);
  padding-left: var(--s4);
  margin: 0;
}
.tag--todo {
  background: var(--bg-sunken);
  color: var(--fg-faint);
}

/* ---- the role comparison grid ------------------------------------------- */
.rolegrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  gap: var(--s4);
  margin: var(--s5) 0 var(--s6);
}
.role {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--s4) var(--s5) var(--s5);
  background: var(--bg-subtle);
}
.role__alias {
  display: block;
  font-size: var(--t-label);
  font-weight: 400;
  color: var(--fg-faint);
  margin-top: 2px;
}
.role__one {
  font-size: var(--t-small);
  font-weight: 500;
  color: var(--fg);
  margin: 0 0 var(--s3);
}
.role ul {
  margin: 0 0 var(--s4);
  padding-left: var(--s5);
}
.role li {
  font-size: var(--t-small);
  line-height: 1.6;
  color: var(--fg-muted);
  margin-bottom: 3px;
}
.role__real {
  font-size: var(--t-small);
  line-height: 1.6;
  color: var(--fg-muted);
  margin: 0;
  padding-top: var(--s3);
  border-top: 1px solid var(--line);
}

/* ---- callouts ------------------------------------------------------------
   Two kinds only, and they mean different things: one is the thing worth
   remembering, the other is a way this goes wrong. More kinds than that and
   readers stop distinguishing them. */
.callout {
  border-left: 3px solid var(--line-strong);
  padding: var(--s3) 0 var(--s3) var(--s5);
  margin: var(--s5) 0;
  background: transparent;
}
.callout p {
  margin: 0;
  font-size: var(--t-small);
  line-height: 1.7;
  color: var(--fg-muted);
}
.callout p + p {
  margin-top: var(--s3);
}
.callout--point {
  border-left-color: var(--accent);
}
.callout--warn {
  border-left-color: var(--warn);
}

.scope {
  padding-left: var(--s5);
}
.scope li {
  font-size: var(--t-small);
  line-height: 1.7;
  color: var(--fg-muted);
  margin-bottom: var(--s3);
}

/* An ordered list where the order is the content -- a procedure to follow in
   sequence, as opposed to .scope, which is an unordered set of takeaways. */
.steps {
  padding-left: var(--s5);
}

.steps li {
  font-size: var(--t-small);
  line-height: 1.7;
  color: var(--fg-muted);
  margin-bottom: var(--s3);
}

/* A directory listing. Deliberately NOT a code panel: nothing here was executed,
   and giving it the panel chrome would imply it had been. The muted spans are
   the trailing comments, so the structure reads first and the annotations
   second. */
.tree {
  margin: var(--s5) 0 var(--s7);
  padding: var(--s4) var(--s5);
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--bg-subtle);
}

.tree code {
  display: block;
  font-family: var(--mono);
  font-size: var(--t-mono);
  line-height: 1.75;
  white-space: pre;
  color: var(--fg-muted);
  background: none;
  padding: 0;
}

.tree__c {
  color: var(--fg-faint);
}

/* ---- panel badges -------------------------------------------------------
   The badge is load-bearing, not decoration: it is how you tell a panel that
   really ran from one that is only printed. */
.code__tag--ran {
  background: var(--ok-subtle);
  color: var(--ok);
}
.code__tag--both {
  background: var(--accent-subtle);
  color: var(--accent-hover);
}
/* The badge text now carries the kind, the environment and the React build
   (for example "ran at build time · in happy-dom 20.11.6 · React dev"), so it may
   wrap on a narrow screen instead of pushing the buttons out of the bar. */
.code__bar .code__tag {
  white-space: normal;
  text-align: left;
}
/* React-specific badge colours. Each pair is tested by tools/contrast.mjs in both
   colour schemes (4.5:1 for the text). The text always says the same thing as the
   colour, so colour is never the only signal. */
.code__tag--dom {
  background: var(--accent-subtle);
  color: var(--accent-hover);
}
.code__tag--warns {
  background: var(--warn-subtle);
  color: var(--warn);
}
.code__tag--prod {
  background: var(--bg-sunken);
  color: var(--fg);
  border-color: var(--border-control);
}

/* ---- the stage ----------------------------------------------------------
   Where a panel that also runs in the page draws what React rendered. It sits
   between the code and the output, is empty until Run, and is hidden until it
   holds something. The border is the only thing marking it out, so it uses the
   control border colour (3:1 against the page). */
.stage {
  margin: 0;
  padding: var(--s3) var(--s4);
  border: 1px solid var(--border-control);
  border-radius: var(--radius-sm);
  background: var(--bg);
  color: var(--fg);
  font-family: var(--sans);
  font-size: var(--t-small);
  line-height: 1.5;
}
.stage[hidden] {
  display: none;
}
.code .stage {
  margin: var(--s3) var(--s4);
}

/* ---- node panels: files, the command, the output ------------------------
   A panel can hold several files. Each carries its name, because "which file
   is this" is the first question in any multi-module example, and the answer
   has to be on the page rather than in a caption. */
.code__file + .code__file {
  border-top: 1px dashed var(--line);
}
.code__path {
  margin: 0;
  padding: var(--s2) var(--s4) 0;
  font-family: var(--mono);
  font-size: 0.75rem;
  color: var(--fg-muted);
}
.code__path + .code__body {
  padding-top: var(--s2);
}
/* The exact command the build ran, so the output is reproducible by pasting it. */
.out__cmd {
  margin: 0;
  padding: 0 var(--s4) var(--s2);
  font-family: var(--mono);
  font-size: var(--t-mono);
  color: var(--fg-muted);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.out__prompt,
.term__prompt {
  color: var(--fg-faint);
  user-select: none;
}
/* Browser output arrives line by line as spans; keep them inline so the
   newlines between them are the only line breaks, exactly as in Node's text. */
.out__body .ln {
  display: inline;
}
/* A terminal transcript: commands stand out from what they printed. */
.term__cmd {
  color: var(--fg);
  font-weight: 600;
}
.out--term .out__body {
  color: var(--fg-muted);
}
.code__bar .btn + .btn {
  margin-left: 0;
}
.code__tag--listing {
  background: var(--warn-subtle);
  color: var(--warn);
}
.code--listing .code__body {
  opacity: 0.9;
}
.code__why {
  margin: 0;
  padding: var(--s3) var(--s4);
  border-top: 1px solid var(--line);
  font-size: var(--t-label);
  line-height: 1.6;
  color: var(--warn);
  background: var(--warn-subtle);
}
/* A terminal session that reuses files printed in full earlier on the page. */
.code__also {
  margin: 0;
  padding: var(--s2) var(--s4);
  border-top: 1px dashed var(--line);
  font-size: var(--t-label);
  line-height: 1.6;
  color: var(--fg-muted);
}

/* ---- the contents page --------------------------------------------------- */
.standing {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--s5);
  margin: 0 0 var(--s7);
  background: var(--bg-subtle);
}
.standing h2 {
  font-size: var(--t-h3);
  margin: 0 0 var(--s3);
}
.standing p {
  font-size: var(--t-small);
  line-height: 1.7;
  color: var(--fg-muted);
  max-width: var(--measure, 68ch);
  margin: 0 0 var(--s4);
}
.standing__facts {
  list-style: none;
  padding: 0;
  margin: var(--s4) 0 0;
}
.standing__facts li {
  font-size: var(--t-small);
  line-height: 1.65;
  color: var(--fg-muted);
  padding-left: var(--s5);
  position: relative;
  margin-bottom: var(--s2);
}
.standing__facts li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.6em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--ok);
}
.bar--big {
  height: 8px;
}

.pcards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
  gap: var(--s5);
}
.pcard {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--s5);
}
.pcard h3 {
  font-size: var(--t-h3);
  margin: 0 0 var(--s2);
}
.pcard h3 a {
  text-decoration: none;
}
.pcard h3 a:hover {
  text-decoration: underline;
}
.pcard > p {
  font-size: var(--t-small);
  line-height: 1.6;
  color: var(--fg-muted);
  margin: 0 0 var(--s3);
}
.pcard__count {
  font-size: var(--t-label);
  color: var(--fg-faint);
  font-variant-numeric: tabular-nums;
}
.pcard__list {
  margin: var(--s4) 0 0;
  padding-left: var(--s5);
}
.pcard__list li {
  font-size: var(--t-small);
  line-height: 1.6;
  margin-bottom: 3px;
}
.pcard__list li.is-todo {
  color: var(--fg-faint);
}
.pcard__list li.is-todo a {
  color: inherit;
  text-decoration: none;
}
.pcard__list li.is-todo a::after {
  content: ' — not written yet';
  font-size: 0.9em;
}

@media (max-width: 560px) {
  .rolegrid,
  .pcards {
    grid-template-columns: 1fr;
  }
  .lesson__head {
    gap: var(--s2);
  }
}

/* ---------------------------------------------------------------------------
   The traceback catalogue.

   One entry is a heading naming the exception, the panel that really raised it,
   and two short paragraphs. The panel itself is styled by the shared code rules,
   so there is nothing here about how the traceback looks -- only the frame around
   it and the index at the top.
   ------------------------------------------------------------------------- */

.tb-nav {
  margin: 0 0 var(--s7);
  padding: var(--s4) var(--s5);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg-subtle);
}

.tb-nav ol {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: var(--s2) var(--s5);
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: none;
}

.tb-nav li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s3);
  padding: 0;
}

.tb-nav li::before {
  content: none;
}

.tb-nav a {
  font-weight: 500;
}

.tb-nav span {
  font: 500 var(--t-small) / 1 var(--mono);
  color: var(--fg-faint);
  font-variant-numeric: tabular-nums;
}

.tb-group {
  margin: 0 0 var(--s8);
}

.tb-group > .sec {
  margin-bottom: var(--s5);
}

.tb {
  margin: 0 0 var(--s7);
  padding-top: var(--s2);
}

/* The exception name is the thing readers scan for, so it is the loud part and
   the human-readable summary beside it is deliberately quieter. */
.tb__name {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--s3);
  margin: 0 0 var(--s3);
  font-size: var(--t-h3);
  line-height: 1.3;
}

.tb__name code {
  font: 600 var(--t-h3) / 1.3 var(--mono);
  padding: 0.1em 0.35em;
  border: 1px solid color-mix(in srgb, var(--warn) 35%, var(--line));
  border-radius: var(--radius-sm);
  background: var(--warn-subtle);
  color: var(--warn);
}

.tb__title {
  font-weight: 400;
  color: var(--fg-muted);
}

.tb__prose {
  margin-top: var(--s4);
  padding-left: var(--s4);
  border-left: 2px solid var(--line);
}

.tb__prose p {
  margin: 0 0 var(--s3);
}

.tb__prose p:last-child {
  margin-bottom: 0;
}

.tb__prose strong {
  color: var(--fg);
}
