/* ROS2Lab MOOC: shared styles */
:root {
  --paper: #EEF4FB;
  --grid: #DCE6F3;
  --ink: #1D2B53;
  --ink-soft: #4A5779;
  --line-soft: #C9D5E8;
  --white: #FFFFFF;
  --sun: #FFC83D;
  --sun-tint: #FFF3D1;
  --teal: #0E9F95;   --teal-tint: #D8F3EF;   /* Module A: Ubuntu terminal */
  --grape: #6C4FE0;  --grape-tint: #ECE7FF;  /* Module B: Python */
  --coral: #D93E5F;  --coral-tint: #FFE4EA;
  --green: #1F8A47;  --green-tint: #DDF3E4;
  --term-bg: #14203F; --term-fg: #E3ECFF; --term-green: #7EE2B8; --term-yellow: #FFD66B; --term-red: #FF8FA3;

  --border: 2.5px solid var(--ink);
  --shadow: 4px 4px 0 var(--ink);
  --shadow-sm: 2px 2px 0 var(--ink);
  --r-lg: 18px; --r-md: 12px; --r-sm: 8px;

  --font-head: "Lexend", "Segoe UI", system-ui, sans-serif;
  --font-body: "Atkinson Hyperlegible", "Segoe UI", system-ui, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, Menlo, Consolas, monospace;
}

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; color: var(--ink); font-family: var(--font-body); font-size: 1.125rem; line-height: 1.65;
  background-color: var(--paper);
  background-image: linear-gradient(var(--grid) 1px, transparent 1px), linear-gradient(90deg, var(--grid) 1px, transparent 1px);
  background-size: 32px 32px;
}
h1, h2, h3, h4 { font-family: var(--font-head); line-height: 1.2; margin: 0 0 .5em; letter-spacing: -0.01em; }
h1 { font-size: clamp(2rem, 5vw, 3rem); font-weight: 700; }
h2 { font-size: clamp(1.45rem, 3vw, 1.9rem); font-weight: 600; }
h3 { font-size: 1.25rem; font-weight: 600; }
p { margin: 0 0 1em; }
a { color: var(--grape); text-underline-offset: 3px; }
a:hover { color: var(--ink); }
code, kbd, pre { font-family: var(--font-mono); }
:not(pre) > code {
  font-size: .9em; background: var(--white); border: 1.5px solid var(--line-soft); border-radius: 6px; padding: .05em .35em;
  white-space: normal; overflow-wrap: anywhere;
}
kbd { font-size: .85em; background: var(--white); border: 1.5px solid var(--ink); border-bottom-width: 3px; border-radius: 6px; padding: 0 .4em; }
:focus-visible { outline: 3px solid var(--grape); outline-offset: 2px; }

.wrap { max-width: 1100px; margin: 0 auto; padding: 0 20px; }
.narrow { max-width: 780px; margin: 0 auto; padding: 0 20px; }
.muted { color: var(--ink-soft); }
.small { font-size: .95rem; }

/* ---------- Header ---------- */
.top { position: sticky; top: 0; z-index: 40; background: var(--white); border-bottom: var(--border); }
.top .wrap { display: flex; align-items: center; gap: 14px; min-height: 64px; }
.brand { display: flex; align-items: center; gap: 10px; text-decoration: none; color: var(--ink); font-family: var(--font-head); font-weight: 700; font-size: 1.3rem; }
.brand-mark { width: 34px; height: 34px; border-radius: 9px; background: var(--ink); color: var(--sun); display: grid; place-items: center; font-family: var(--font-mono); font-size: .95rem; font-weight: 700; }
.brand small { font-family: var(--font-body); font-weight: 400; font-size: .85rem; color: var(--ink-soft); }
.top-right { margin-left: auto; display: flex; align-items: center; gap: 12px; }
.who { font-size: .95rem; color: var(--ink-soft); text-align: right; line-height: 1.25; }
.who b { color: var(--ink); display: block; }
@media (max-width: 640px) { .who, .brand small { display: none; } }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5em; cursor: pointer; text-decoration: none;
  font-family: var(--font-head); font-weight: 600; font-size: 1.05rem; line-height: 1.1; color: var(--ink);
  padding: .75em 1.25em; background: var(--sun); border: var(--border); border-radius: var(--r-md); box-shadow: var(--shadow-sm);
  transition: transform .08s ease, box-shadow .08s ease;
}
.btn:hover { color: var(--ink); transform: translate(-1px, -1px); box-shadow: 3px 3px 0 var(--ink); }
.btn:active { transform: translate(2px, 2px); box-shadow: 0 0 0 var(--ink); }
.btn-white { background: var(--white); }
.btn-small { font-size: .95rem; padding: .5em .9em; }
.btn-danger { background: var(--coral-tint); }
.btn[disabled] { background: #E3E8F1; color: #7D88A6; border-color: #9AA6C2; box-shadow: none; cursor: not-allowed; transform: none; }
.btn-google { background: var(--white); font-size: 1.1rem; }
.btn-google svg { width: 22px; height: 22px; }

/* ---------- Panels ---------- */
.panel { background: var(--white); border: var(--border); border-radius: var(--r-lg); box-shadow: var(--shadow); padding: clamp(18px, 3.5vw, 32px); }
.stack > * + * { margin-top: 22px; }
.notice { border: 2px solid var(--ink); border-radius: var(--r-md); padding: 12px 16px; background: var(--sun-tint); }
.notice.err { background: var(--coral-tint); }
.notice.ok { background: var(--green-tint); }
.chip { display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-head); font-weight: 600; font-size: .85rem; padding: 4px 10px; border: 2px solid var(--ink); border-radius: 999px; background: var(--white); white-space: nowrap; }
.chip.done { background: var(--green-tint); }
.chip.going { background: var(--sun-tint); }
.chip.locked { background: #E9EDF4; color: var(--ink-soft); border-color: #9AA6C2; }

/* Module colour coding */
[data-mod="A"] { --mc: var(--teal); --mt: var(--teal-tint); }
[data-mod="B"] { --mc: var(--grape); --mt: var(--grape-tint); }

/* ---------- Landing ---------- */
.landing { padding: 48px 0 40px; }
.landing-grid { display: grid; grid-template-columns: 1.05fr .95fr; gap: 40px; align-items: center; }
.landing h1 { font-size: clamp(2.2rem, 5.5vw, 3.6rem); max-width: 14ch; }
.landing .lead { font-size: 1.25rem; color: var(--ink-soft); max-width: 44ch; }
.hero-term { background: var(--term-bg); color: var(--term-fg); border: var(--border); border-radius: var(--r-lg); box-shadow: var(--shadow); font-family: var(--font-mono); font-size: .95rem; overflow: hidden; }
.hero-term .bar { display: flex; gap: 6px; padding: 10px 12px; background: #0E1830; border-bottom: 2px solid var(--ink); }
.hero-term .bar i { width: 11px; height: 11px; border-radius: 50%; background: #3B4A75; }
.hero-term pre { margin: 0; padding: 16px 18px; white-space: pre-wrap; line-height: 1.7; min-height: 260px; }
.hero-term .p { color: var(--term-green); }
.hero-term .c { color: var(--term-yellow); }
.facts { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.fact { border: 2px solid var(--ink); border-radius: var(--r-md); padding: 16px; background: var(--white); }
.fact b { display: block; font-family: var(--font-head); font-size: 1.1rem; margin-bottom: 4px; }
.fact p { margin: 0; font-size: 1rem; color: var(--ink-soft); }
@media (max-width: 860px) { .landing-grid, .facts { grid-template-columns: 1fr; } }

/* ---------- Course dashboard ---------- */
.dash-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 16px; margin: 32px 0 22px; }
.meter { height: 14px; background: var(--white); border: 2px solid var(--ink); border-radius: 999px; overflow: hidden; min-width: 220px; }
.meter > span { display: block; height: 100%; background: var(--green); width: 0; transition: width .4s ease; }
.module { border: var(--border); border-left: 12px solid var(--mc); border-radius: var(--r-lg); background: var(--white); box-shadow: var(--shadow); overflow: hidden; }
.module-head { padding: 18px 22px; background: var(--mt); border-bottom: 2px solid var(--ink); display: flex; flex-wrap: wrap; justify-content: space-between; gap: 10px; align-items: center; }
.module-head h2 { margin: 0; font-size: 1.4rem; }
.module-head p { margin: 2px 0 0; color: var(--ink-soft); font-size: 1rem; }
.lessons { list-style: none; margin: 0; padding: 0; }
.lessons li + li { border-top: 1.5px solid var(--line-soft); }
.lesson-row { display: grid; grid-template-columns: 44px 1fr auto; gap: 14px; align-items: center; padding: 14px 22px; color: var(--ink); text-decoration: none; }
.lesson-row:hover { background: var(--paper); color: var(--ink); }
.lesson-row .num { width: 36px; height: 36px; border-radius: 50%; border: 2px solid var(--ink); display: grid; place-items: center; font-family: var(--font-head); font-weight: 600; background: var(--white); }
.lesson-row.is-done .num { background: var(--green); color: var(--white); border-color: var(--green); }
.lesson-row.is-next { background: var(--sun-tint); }
.lesson-row .t { font-family: var(--font-head); font-weight: 600; line-height: 1.3; }
.lesson-row .s { font-size: .95rem; color: var(--ink-soft); }
.test-row { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; justify-content: space-between; padding: 16px 22px; background: var(--paper); border-top: 2px solid var(--ink); }
.test-row h3 { margin: 0; font-size: 1.1rem; }
@media (max-width: 560px) { .lesson-row { grid-template-columns: 36px 1fr; padding: 12px 14px; } .lesson-row .chip { grid-column: 2; justify-self: start; } }

/* ---------- Lesson page ---------- */
.lesson-top { position: sticky; top: 64px; z-index: 30; background: var(--white); border-bottom: 2px solid var(--ink); }
.lesson-top .narrow { display: flex; align-items: center; gap: 12px; min-height: 52px; font-size: .95rem; }
.lesson-top .meter { flex: 1; min-width: 80px; height: 10px; }
.lesson-hero { padding: 30px 0 8px; }
.lesson-hero .kicker { font-family: var(--font-head); font-weight: 600; color: var(--mc); }
.lesson-body { padding-bottom: 60px; }
.lesson-body > * + * { margin-top: 20px; }
.lesson-body h2 { margin-top: 36px; font-size: 1.5rem; }
.lesson-body p, .lesson-body li { max-width: 68ch; }
.callout { border: 2px solid var(--ink); border-radius: var(--r-md); padding: 14px 18px; background: var(--white); position: relative; }
.callout .label { font-family: var(--font-head); font-weight: 600; font-size: .95rem; display: block; margin-bottom: 4px; }
.callout.analogy { background: var(--sun-tint); }
.callout.tip { background: var(--green-tint); }
.callout.warn { background: var(--coral-tint); }
.callout p:last-child { margin-bottom: 0; }
pre.code { margin: 0; background: var(--term-bg); color: var(--term-fg); border: var(--border); border-radius: var(--r-md); padding: 14px 18px; overflow-x: auto; font-size: .95rem; line-height: 1.6; }
pre.code .cm { color: #8FA3D1; }
.figure-out { margin: -8px 0 0; background: #0E1830; color: var(--term-green); border: var(--border); border-top: none; border-radius: 0 0 var(--r-md) var(--r-md); padding: 10px 18px; font-family: var(--font-mono); font-size: .9rem; white-space: pre-wrap; }
.steps-list { padding-left: 1.4em; }
.steps-list li { margin-bottom: 8px; }
.recap { background: var(--mt); border: var(--border); border-radius: var(--r-lg); padding: 18px 22px; }
.recap ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 8px; }
.recap li { display: flex; gap: 10px; align-items: baseline; }
.recap li::before { content: "✓"; flex: none; width: 24px; height: 24px; display: grid; place-items: center; background: var(--white); border: 2px solid var(--ink); border-radius: 6px; font-size: .85rem; font-weight: 700; }
.glossary-word { border-bottom: 2px dotted var(--mc); cursor: help; }
.complete-bar { border: var(--border); border-radius: var(--r-lg); background: var(--white); box-shadow: var(--shadow); padding: 20px 22px; display: flex; flex-wrap: wrap; gap: 14px; align-items: center; justify-content: space-between; }

/* Practice checks */
.check { border: var(--border); border-radius: var(--r-lg); background: var(--white); overflow: hidden; }
.check-head { display: flex; justify-content: space-between; gap: 10px; align-items: center; padding: 10px 16px; background: var(--paper); border-bottom: 2px solid var(--ink); font-family: var(--font-head); font-weight: 600; font-size: .95rem; }
.check-body { padding: 16px; }
.check-q { font-weight: 700; margin-bottom: 12px; }
.opts { display: grid; gap: 8px; }
.opt { text-align: left; font: inherit; font-size: 1.02rem; color: var(--ink); cursor: pointer; background: var(--white); border: 2px solid var(--ink); border-radius: var(--r-sm); padding: 10px 14px; display: flex; gap: 10px; align-items: baseline; }
.opt:hover { background: var(--paper); }
.opt .k { flex: none; font-family: var(--font-head); font-weight: 600; width: 26px; height: 26px; border-radius: 50%; border: 2px solid var(--ink); display: grid; place-items: center; font-size: .85rem; }
.opt.right { background: var(--green-tint); border-color: var(--green); }
.opt.wrong { background: var(--coral-tint); border-color: var(--coral); }
.opt[disabled] { cursor: default; }
.fb { margin-top: 12px; padding: 10px 14px; border-radius: var(--r-sm); border: 2px solid var(--ink); }
.fb.ok { background: var(--green-tint); }
.fb.no { background: var(--sun-tint); }
.text-answer { display: flex; gap: 10px; flex-wrap: wrap; }
.text-answer input { flex: 1; min-width: 200px; font-family: var(--font-mono); font-size: 1rem; padding: 10px 12px; border: 2px solid var(--ink); border-radius: var(--r-sm); background: var(--white); color: var(--ink); }
.order-list { list-style: none; margin: 0 0 12px; padding: 0; display: grid; gap: 8px; }
.order-list li { display: flex; align-items: center; gap: 8px; border: 2px solid var(--ink); border-radius: var(--r-sm); padding: 6px 8px 6px 12px; background: var(--white); }
.order-list li code { white-space: normal; border: none; background: none; padding: 0; font-size: .95rem; }
.order-list .t { flex: 1; font-family: var(--font-mono); font-size: .95rem; overflow-wrap: anywhere; white-space: pre-wrap; }
.order-list button { font: inherit; width: 36px; height: 36px; border: 2px solid var(--ink); border-radius: 8px; background: var(--sun-tint); cursor: pointer; }
.order-list button[disabled] { opacity: .35; cursor: default; }

/* ---------- Practice terminal ---------- */
.term { border: var(--border); border-radius: var(--r-lg); overflow: hidden; box-shadow: var(--shadow); background: var(--term-bg); }
.term-title { display: flex; align-items: center; gap: 10px; padding: 9px 14px; background: #0E1830; color: var(--term-fg); font-family: var(--font-head); font-size: .95rem; border-bottom: 2px solid var(--ink); }
.term-title i { width: 10px; height: 10px; border-radius: 50%; background: #3B4A75; }
.term-title span { margin-left: 6px; }
.term-tasks { background: var(--white); padding: 12px 16px; border-bottom: 2px solid var(--ink); }
.term-tasks ol { margin: 0; padding: 0; list-style: none; display: grid; gap: 6px; }
.term-tasks li { display: flex; gap: 10px; align-items: baseline; font-size: 1rem; color: var(--ink-soft); }
.term-tasks li .box { flex: none; width: 22px; height: 22px; border: 2px solid var(--ink); border-radius: 6px; display: grid; place-items: center; font-size: .8rem; font-weight: 700; background: var(--white); }
.term-tasks li.now { color: var(--ink); font-weight: 700; }
.term-tasks li.now .box { background: var(--sun); }
.term-tasks li.done .box { background: var(--green); color: var(--white); border-color: var(--green); }
.term-tasks li.done { color: var(--ink-soft); }
.term-screen { padding: 12px 14px; font-family: var(--font-mono); font-size: .93rem; line-height: 1.55; color: var(--term-fg); height: 300px; overflow-y: auto; cursor: text; }
.term-screen .line { white-space: pre-wrap; overflow-wrap: anywhere; }
.term-screen .pr { color: var(--term-green); }
.term-screen .pr b { color: #8FB8FF; font-weight: 400; }
.term-screen .err { color: var(--term-red); }
.term-screen .hint { color: var(--term-yellow); }
.term-input-row { display: flex; align-items: baseline; gap: 0; }
.term-input-row input { flex: 1; min-width: 40px; background: transparent; border: none; outline: none; color: var(--term-fg); font: inherit; caret-color: var(--term-yellow); padding: 0; }
.term-done { padding: 10px 16px; background: var(--green-tint); border-top: 2px solid var(--ink); font-weight: 700; }
.term-tools { display: flex; gap: 8px; padding: 8px 14px; background: #0E1830; border-top: 2px solid var(--ink); flex-wrap: wrap; }
.term-tools button { font-family: var(--font-head); font-size: .85rem; color: var(--term-fg); background: transparent; border: 1.5px solid #3B4A75; border-radius: 8px; padding: 4px 10px; cursor: pointer; }
.term-tools button:hover { border-color: var(--term-fg); }
.nano { position: absolute; inset: 0; background: var(--term-bg); display: flex; flex-direction: column; z-index: 2; }
.nano-bar { background: var(--term-fg); color: var(--term-bg); font-family: var(--font-mono); font-size: .85rem; padding: 4px 10px; text-align: center; }
.nano textarea { flex: 1; resize: none; background: transparent; color: var(--term-fg); border: none; outline: none; font-family: var(--font-mono); font-size: .93rem; padding: 10px 14px; line-height: 1.5; }
.nano-keys { display: flex; gap: 8px; padding: 6px 10px; background: #0E1830; font-family: var(--font-mono); font-size: .85rem; color: var(--term-fg); flex-wrap: wrap; }
.nano-keys button { font: inherit; color: var(--term-bg); background: var(--term-fg); border: none; border-radius: 4px; padding: 2px 8px; cursor: pointer; }

/* ---------- Python playground ---------- */
.py { border: var(--border); border-radius: var(--r-lg); overflow: hidden; box-shadow: var(--shadow); background: var(--white); }
.py-head { display: flex; flex-wrap: wrap; gap: 10px; justify-content: space-between; align-items: center; padding: 10px 14px; background: var(--grape-tint); border-bottom: 2px solid var(--ink); }
.py-head b { font-family: var(--font-head); }
.py textarea { display: block; width: 100%; min-height: 180px; resize: vertical; border: none; outline: none; padding: 14px 16px; font-family: var(--font-mono); font-size: .95rem; line-height: 1.6; color: var(--ink); background: #FBFCFF; tab-size: 4; }
.py-out { border-top: 2px solid var(--ink); background: var(--term-bg); color: var(--term-fg); font-family: var(--font-mono); font-size: .9rem; padding: 12px 16px; white-space: pre-wrap; min-height: 56px; max-height: 320px; overflow-y: auto; }
.py-out .err { color: var(--term-red); }
.py-out .info { color: #8FA3D1; }
.py-help { border-top: 2px solid var(--ink); padding: 10px 16px; background: var(--sun-tint); font-size: 1rem; }
.py-goal { padding: 10px 16px; border-bottom: 2px solid var(--ink); background: var(--white); font-size: 1rem; }
.py-pass { padding: 10px 16px; border-top: 2px solid var(--ink); background: var(--green-tint); font-weight: 700; }

/* ---------- Test page ---------- */
.test-card { margin: 28px auto; }
.q-top { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 10px; align-items: center; margin-bottom: 12px; font-family: var(--font-head); font-weight: 600; }
.timer { display: inline-flex; gap: 6px; align-items: center; padding: 4px 12px; border: 2px solid var(--ink); border-radius: 999px; background: var(--white); font-variant-numeric: tabular-nums; }
.timer.low { background: var(--coral-tint); }
.q-bar { height: 8px; border: 2px solid var(--ink); border-radius: 999px; overflow: hidden; background: var(--white); margin-bottom: 18px; }
.q-bar span { display: block; height: 100%; background: var(--sun); transition: width 1s linear; }
.q-prompt { font-size: 1.2rem; font-weight: 700; margin-bottom: 14px; }
.q-actions { margin-top: 20px; display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.rules { padding-left: 1.3em; }
.rules li { margin-bottom: 6px; }
.review-item { border: 2px solid var(--ink); border-radius: var(--r-md); padding: 14px 16px; background: var(--white); }
.review-item.ok { border-left: 10px solid var(--green); }
.review-item.no { border-left: 10px solid var(--coral); }

/* ---------- Watermark and protection ---------- */
.watermark { position: fixed; inset: 0; pointer-events: none; z-index: 100; opacity: .085; background-repeat: repeat; }
.no-select { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
.no-select input, .no-select textarea { -webkit-user-select: text; user-select: text; }
@media print { body * { visibility: hidden !important; } body::after { content: "Printing is disabled for ROS2Lab course pages."; visibility: visible; } }

/* ---------- Dialog / forms ---------- */
.overlay { position: fixed; inset: 0; background: rgba(29, 43, 83, .55); z-index: 80; display: grid; place-items: center; padding: 16px; }
.dialog { width: min(560px, 100%); max-height: 92vh; overflow-y: auto; }
.form-row { display: grid; gap: 6px; margin-bottom: 14px; }
.form-row label { font-family: var(--font-head); font-weight: 600; font-size: 1rem; }
.form-row input, .form-row select { font: inherit; font-size: 1.05rem; padding: 10px 12px; border: 2px solid var(--ink); border-radius: var(--r-sm); background: var(--white); color: var(--ink); }
.consent { display: flex; gap: 10px; align-items: flex-start; font-size: 1rem; }
.consent input { margin-top: 6px; width: 20px; height: 20px; flex: none; }
.toast { position: fixed; left: 50%; bottom: 20px; transform: translateX(-50%); z-index: 120; background: var(--ink); color: var(--white); padding: 12px 18px; border-radius: var(--r-md); font-size: 1rem; max-width: 90vw; }

/* ---------- Admin ---------- */
.tabs { display: flex; gap: 8px; flex-wrap: wrap; margin: 22px 0 16px; }
.tabs button { font-family: var(--font-head); font-weight: 600; font-size: 1rem; padding: 8px 14px; border: 2px solid var(--ink); border-radius: 10px; background: var(--white); cursor: pointer; color: var(--ink); }
.tabs button[aria-selected="true"] { background: var(--sun); }
.table-wrap { overflow-x: auto; border: var(--border); border-radius: var(--r-md); background: var(--white); }
table.data { width: 100%; border-collapse: collapse; font-size: .95rem; }
table.data th, table.data td { padding: 8px 10px; border-bottom: 1.5px solid var(--line-soft); text-align: left; vertical-align: top; white-space: nowrap; }
table.data th { font-family: var(--font-head); font-weight: 600; background: var(--paper); position: sticky; top: 0; cursor: pointer; }
table.data tr:hover td { background: #F7FAFF; }
table.data td.num { text-align: right; font-variant-numeric: tabular-nums; }
.flag { color: var(--coral); font-weight: 700; }
.toolbar { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin-bottom: 12px; }
.toolbar input, .toolbar select { font: inherit; font-size: 1rem; padding: 8px 10px; border: 2px solid var(--ink); border-radius: 8px; background: var(--white); color: var(--ink); }
.grid-form { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px; }

.site-foot { margin-top: 48px; border-top: var(--border); background: var(--white); }
.site-foot .wrap { padding: 20px; display: flex; flex-wrap: wrap; gap: 8px 20px; font-size: .95rem; color: var(--ink-soft); }

@media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; } }

/* terminal colours for ls output */
.term-screen .dir { color: #8FB8FF; font-weight: 700; }
.term-screen .exe { color: var(--term-green); font-weight: 700; }
.lead { font-size: 1.15rem; }

/* ---------- Weeks (module colours) ---------- */
[data-mod="W1"] { --mc: var(--teal); --mt: var(--teal-tint); }
[data-mod="W2"] { --mc: var(--grape); --mt: var(--grape-tint); }
.two-weeks { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.week { border-top: 12px solid var(--mc); }
.week h2 { font-size: 1.35rem; }
.days { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.days li { display: grid; grid-template-columns: 70px 1fr; gap: 8px; align-items: baseline; font-size: 1.02rem; }
.days b { font-family: var(--font-head); color: var(--mc); filter: brightness(.85); }
@media (max-width: 860px) { .two-weeks { grid-template-columns: 1fr; } }

/* ---------- Registration wizard ---------- */
.wizard-steps { list-style: none; margin: 0 0 18px; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.wizard-steps li { display: flex; align-items: center; gap: 6px; font-family: var(--font-head); font-size: .9rem; color: var(--ink-soft); background: var(--white); border: 2px solid #9AA6C2; border-radius: 999px; padding: 3px 12px 3px 4px; }
.wizard-steps .n { width: 24px; height: 24px; border-radius: 50%; display: grid; place-items: center; background: #E9EDF4; font-weight: 700; font-size: .8rem; }
.wizard-steps li.now { color: var(--ink); border-color: var(--ink); background: var(--sun-tint); }
.wizard-steps li.now .n { background: var(--sun); }
.wizard-steps li.done { color: var(--ink); border-color: var(--green); }
.wizard-steps li.done .n { background: var(--green); color: var(--white); }
.form-row small { font-size: .9rem; }
.id-preview { display: block; max-width: 100%; max-height: 360px; border: var(--border); border-radius: var(--r-md); margin: 6px 0 14px; }
.linklike { font: inherit; background: none; border: none; color: var(--grape); text-decoration: underline; text-underline-offset: 3px; cursor: pointer; padding: 0; }

/* ---------- Course list: day dividers ---------- */
.lessons li.day-head { padding: 8px 22px; background: var(--paper); font-family: var(--font-head); font-weight: 600; font-size: .95rem; color: var(--ink-soft); }

/* ---------- Lesson extras ---------- */
.callout.story { background: var(--mt); }
.callout.goal { background: var(--white); border-left: 8px solid var(--mc); }
.twin { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.twin > div { min-width: 0; }
.twin .twin-label { font-family: var(--font-head); font-weight: 600; font-size: .95rem; margin-bottom: 4px; }
@media (max-width: 760px) { .twin { grid-template-columns: 1fr; } }
.code-wrap { position: relative; }
.copy-btn { position: absolute; top: 8px; right: 8px; font-family: var(--font-head); font-size: .8rem; color: var(--term-bg); background: var(--term-fg); border: none; border-radius: 6px; padding: 4px 10px; cursor: pointer; }
.copy-btn:hover { background: var(--sun); }
.checklist { border: var(--border); border-radius: var(--r-lg); background: var(--white); overflow: hidden; }
.checklist h3 { margin: 0; padding: 12px 16px; background: var(--mt); border-bottom: 2px solid var(--ink); font-size: 1.1rem; }
.checklist ul { list-style: none; margin: 0; padding: 8px 16px 14px; }
.checklist li { display: flex; gap: 12px; align-items: flex-start; padding: 8px 0; border-bottom: 1.5px solid var(--line-soft); }
.checklist li:last-child { border-bottom: none; }
.checklist input { width: 22px; height: 22px; margin-top: 3px; flex: none; }
.checklist .cl-text { display: grid; gap: 4px; }
.checklist code { white-space: normal; }

/* ---------- Admin: registrations ---------- */
.reg-card { display: grid; grid-template-columns: minmax(220px, 1fr) minmax(260px, 1.2fr); gap: 18px; align-items: start; }
.reg-card .id-box { min-height: 180px; border: 2px dashed #9AA6C2; border-radius: var(--r-md); display: grid; place-items: center; background: var(--paper); overflow: hidden; }
.reg-card .id-box img { width: 100%; height: auto; display: block; }
.reg-card dl { display: grid; grid-template-columns: auto 1fr; gap: 4px 12px; margin: 0 0 12px; }
.reg-card dt { font-weight: 700; }
.reg-card dd { margin: 0; overflow-wrap: anywhere; }
.reg-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.reg-actions select, .reg-actions input { font: inherit; font-size: .95rem; padding: 7px 9px; border: 2px solid var(--ink); border-radius: 8px; }
.status-chip.pending { background: var(--sun-tint); }
.status-chip.approved { background: var(--green-tint); }
.status-chip.rejected { background: var(--coral-tint); }
@media (max-width: 760px) { .reg-card { grid-template-columns: 1fr; } }

/* phones: keep wide controls inside their cards */
.reg-card > * { min-width: 0; }
.reg-actions select, .reg-actions input { max-width: 100%; min-width: 0; }
.term-tasks li > span:last-child { min-width: 0; }

.reg-card.no-id { grid-template-columns: 1fr; }

/* =====================================================================
   v2 redesign: RViz-style night stage, TF axis colours, games
   ===================================================================== */
:root {
  --night: #14204A; --night-2: #1C2C60; --night-line: rgba(160, 185, 255, .10);
  --tf-x: #FF5C6C; --tf-y: #3DDC97; --tf-z: #5B9CFF;
  --packet: #FFC83D;
}

/* header nav */
.top-nav { display: flex; gap: 4px; margin-left: 18px; }
.top-nav a { font-family: var(--font-head); font-weight: 600; font-size: .98rem; color: var(--ink); text-decoration: none; padding: 6px 12px; border-radius: 10px; border: 2px solid transparent; }
.top-nav a:hover { border-color: var(--ink); color: var(--ink); }
.top-nav a[aria-current="page"] { background: var(--sun-tint); border-color: var(--ink); }
@media (max-width: 720px) {
  .top .wrap { flex-wrap: wrap; padding-top: 6px; padding-bottom: 6px; }
  .top-nav { order: 3; width: 100%; margin: 0 0 4px -12px; }
}
.btn-ghost { background: transparent; color: var(--white); border-color: var(--white); box-shadow: 2px 2px 0 rgba(255,255,255,.35); }
.btn-ghost:hover { color: var(--white); box-shadow: 3px 3px 0 rgba(255,255,255,.55); }

/* ---------- Hero ---------- */
.hero {
  color: #E8EEFF; background-color: var(--night); border-bottom: var(--border);
  background-image: linear-gradient(var(--night-line) 1px, transparent 1px), linear-gradient(90deg, var(--night-line) 1px, transparent 1px);
  background-size: 40px 40px; padding: 52px 0 56px;
}
.hero-grid { display: grid; grid-template-columns: .9fr 1.1fr; gap: 44px; align-items: center; }
.hero h1 { font-size: clamp(2.3rem, 5.6vw, 3.9rem); max-width: 12ch; color: var(--white); margin-bottom: .35em; letter-spacing: -0.02em; }
.hero .lead { color: #C3CEEE; font-size: 1.2rem; max-width: 46ch; }
.hero-facts { list-style: none; margin: 26px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px 22px; color: #C3CEEE; font-size: 1rem; }
.hero-facts b { font-family: var(--font-head); font-size: 1.5rem; color: var(--packet); margin-right: 4px; }
.hero-note { color: #9FB0DE; margin-top: 14px; }
.hero-graph { margin: 0; }
.hero-graph figcaption { font-size: .98rem; color: #C3CEEE; margin-bottom: 10px; max-width: 54ch; }
.hero-graph figcaption b { color: var(--white); }
@media (max-width: 900px) { .hero-grid { grid-template-columns: 1fr; gap: 28px; } .hero { padding: 34px 0 38px; } }

/* live ROS graph */
.hg { border: 2.5px solid #000A2A; border-radius: var(--r-lg); overflow: hidden; background: #0D1738; box-shadow: 5px 5px 0 #000A2A; }
.hg-svg { display: block; width: 100%; height: auto; touch-action: manipulation; }
.hg-grid line { stroke: rgba(160, 185, 255, .09); stroke-width: 1; }
.hg-tf line { stroke-width: 3; stroke-linecap: round; }
.hg-tf .tf-x { stroke: var(--tf-x); } .hg-tf .tf-y { stroke: var(--tf-y); } .hg-tf .tf-z { fill: var(--tf-z); }
.hg-tf text { fill: #7F90BF; font: 11px var(--font-mono); }
.hg-edge { fill: none; stroke: #5D6FA6; stroke-width: 2.5; transition: stroke .2s; }
.hg-edge.hot { stroke: var(--packet); }
.hg-arrowhead { fill: #5D6FA6; }
.hg-packet { fill: var(--packet); stroke: #0D1738; stroke-width: 2; }
.hg-node { cursor: pointer; outline: none; }
.hg-node rect { fill: #1E2F66; stroke: #8FA6E6; stroke-width: 2; transition: fill .2s, stroke .2s; }
.hg-node.brain rect { fill: #2C2470; stroke: #B4A3FF; }
.hg-node text { fill: #F0F4FF; font: 600 14px var(--font-mono); pointer-events: none; }
.hg-beat { fill: var(--tf-y); transform-box: fill-box; transform-origin: center; }
.hg-node.rx .hg-beat { animation: hg-beat .5s ease-out; }
@keyframes hg-beat { 0% { transform: scale(1); } 40% { transform: scale(2); fill: #B6FFD9; } 100% { transform: scale(1); } }
.hg-node:hover rect, .hg-node:focus-visible rect, .hg-node.sel rect { stroke: var(--packet); stroke-width: 3; }
.hg-topic { cursor: pointer; outline: none; }
.hg-topic rect { fill: #0D1738; stroke: #5D6FA6; stroke-width: 1.5; }
.hg-topic text { fill: #FFE7A3; font: 12.5px var(--font-mono); pointer-events: none; }
.hg-topic:hover rect, .hg-topic:focus-visible rect, .hg-topic.sel rect { stroke: var(--packet); stroke-width: 2.5; fill: #1A2550; }
.hg-term { border-top: 2px solid #000A2A; background: #091130; font-family: var(--font-mono); font-size: .88rem; }
.hg-out-head { padding: 8px 14px 0; color: var(--term-green); }
.hg-out { margin: 0; padding: 4px 14px 12px; color: #D7E1FF; white-space: pre-wrap; min-height: 9.5em; line-height: 1.5; }

/* ---------- Generic sections ---------- */
.section { padding-top: 56px; padding-bottom: 8px; }
.section-head { max-width: 62ch; margin-bottom: 22px; }
.section-head h2 { font-size: clamp(1.6rem, 3.4vw, 2.2rem); margin-bottom: .25em; }
.section-head p { margin: 0; font-size: 1.1rem; }
.band { margin-top: 56px; background: var(--white); border-top: var(--border); border-bottom: var(--border); padding-bottom: 52px; }

/* ---------- Metro route ---------- */
.metro { display: grid; gap: 18px; }
.metro-line { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 170px repeat(6, 1fr); position: relative; align-items: start; }
.metro-line::before { content: ""; position: absolute; left: 170px; right: 6%; top: 17px; height: 8px; background: var(--mc); border: 2px solid var(--ink); border-radius: 99px; }
.metro-name { padding-right: 14px; }
.metro-name b { font-family: var(--font-head); font-size: 1.25rem; display: block; color: var(--ink); }
.metro-name span { font-size: .95rem; color: var(--ink-soft); line-height: 1.3; display: block; }
.stn { position: relative; padding: 46px 8px 0; text-align: center; }
.stn::before { content: ""; position: absolute; top: 7px; left: 50%; transform: translateX(-50%); width: 28px; height: 28px; border-radius: 50%; background: var(--white); border: 3px solid var(--ink); }
.stn.test::before { width: 34px; height: 34px; top: 4px; border-radius: 9px; background: var(--sun); }
.stn b { display: block; font-family: var(--font-head); font-size: 1rem; }
.stn span { display: block; font-size: .92rem; color: var(--ink-soft); line-height: 1.35; }
@media (max-width: 900px) {
  .metro { grid-template-columns: 1fr 1fr; gap: 12px 24px; }
  .metro-line { grid-template-columns: 1fr; padding-left: 0; }
  .metro-line::before { left: 13px; right: auto; top: 64px; bottom: 18px; width: 8px; height: auto; }
  .metro-name { padding: 0 0 12px; }
  .stn { text-align: left; padding: 6px 0 14px 46px; }
  .stn::before { left: 17px; top: 6px; }
}
@media (max-width: 560px) { .metro { grid-template-columns: 1fr; } }

/* ---------- Three ways nodes talk ---------- */
.talk { display: grid; gap: 14px; }
.talk-row { display: grid; grid-template-columns: minmax(260px, 380px) 1fr; gap: 28px; align-items: center; padding: 18px; border: 2px solid var(--ink); border-radius: var(--r-lg); background: var(--paper); }
.talk-row h3 { font-size: 1.3rem; margin-bottom: .3em; }
.talk-row p { margin-bottom: .5em; max-width: 60ch; }
.talk-svg { width: 100%; height: auto; background: var(--night); border: 2px solid var(--ink); border-radius: var(--r-md); }
.tk-lines line, .tk-wire { stroke: #5D6FA6; stroke-width: 2.5; stroke-dasharray: 5 6; }
.tk-box rect { fill: #1E2F66; stroke: #8FA6E6; stroke-width: 2; }
.tk-box.pub rect { fill: #2C2470; stroke: #B4A3FF; }
.tk-box text { fill: #fff; font: 600 13px var(--font-head); text-anchor: middle; }
.tk-box .tk-small { font: 11px var(--font-body); fill: #B8C4EA; }
.tk-label { fill: #FFE7A3; font: 11.5px var(--font-mono); text-anchor: middle; }
.tk-dot, .sv-req, .ac-goal { fill: var(--packet); }
.sv-res, .ac-fb { fill: var(--tf-y); }
.ac-res { fill: var(--tf-x); }
.tk-dot { animation: tk-travel 1.8s linear infinite; }
.sv-req { animation: sv-req 3.6s linear infinite; }
.sv-res { opacity: 0; animation: sv-res 3.6s linear infinite; }
.sv-client .tk-small { animation: sv-wait 3.6s steps(1) infinite; }
.ac-goal { animation: ac-goal 5s linear infinite; }
.ac-fb, .ac-res { opacity: 0; }
.ac-fb { animation: ac-fb 5s linear infinite; }
.ac-fb.f2 { animation-delay: .8s; } .ac-fb.f3 { animation-delay: 1.6s; }
.ac-res { animation: ac-res 5s linear infinite; }
@keyframes tk-travel { 0% { transform: translateX(0); opacity: 0; } 8% { opacity: 1; } 88% { opacity: 1; } 100% { transform: translateX(var(--len)); opacity: 0; } }
@keyframes sv-req { 0% { transform: translateX(0); opacity: 0; } 4% { opacity: 1; } 34% { transform: translateX(var(--len)); opacity: 1; } 36%, 100% { transform: translateX(var(--len)); opacity: 0; } }
@keyframes sv-res { 0%, 54% { transform: translateX(0); opacity: 0; } 56% { opacity: 1; } 86% { transform: translateX(var(--len)); opacity: 1; } 88%, 100% { transform: translateX(var(--len)); opacity: 0; } }
@keyframes sv-wait { 0% { opacity: 0; } 4% { opacity: 1; } 88% { opacity: 0; } }
@keyframes ac-goal { 0% { transform: translateX(0); opacity: 0; } 3% { opacity: 1; } 18% { transform: translateX(var(--len)); opacity: 1; } 20%, 100% { transform: translateX(var(--len)); opacity: 0; } }
@keyframes ac-fb { 0%, 24% { transform: translateX(0); opacity: 0; } 26% { opacity: 1; } 42% { transform: translateX(var(--len)); opacity: 1; } 44%, 100% { transform: translateX(var(--len)); opacity: 0; } }
@keyframes ac-res { 0%, 76% { transform: translateX(0); opacity: 0; } 78% { opacity: 1; } 94% { transform: translateX(var(--len)); opacity: 1; } 96%, 100% { transform: translateX(var(--len)); opacity: 0; } }
@media (max-width: 760px) { .talk-row { grid-template-columns: 1fr; gap: 14px; } }
@media (prefers-reduced-motion: reduce) {
  .tk-dot, .sv-req, .ac-goal { animation: none; transform: translateX(calc(var(--len) * .5)); opacity: 1; }
  .sv-res, .ac-fb.f1, .ac-res { animation: none; opacity: 1; transform: translateX(calc(var(--len) * .5)); }
  .sv-client .tk-small { animation: none; }
}

/* ---------- Play section ---------- */
.play-grid { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 22px; align-items: start; }
.game-list { border: var(--border); border-radius: var(--r-lg); background: var(--white); padding: 18px; box-shadow: var(--shadow); }
.game-list h3 { font-size: 1.15rem; }
.game-list ul { list-style: none; margin: 0 0 16px; padding: 0; display: grid; gap: 4px; }
.game-list a { display: flex; gap: 12px; align-items: center; text-decoration: none; color: var(--ink); padding: 8px; border-radius: 10px; }
.game-list a:hover { background: var(--paper); color: var(--ink); }
.game-list a > span:last-child { display: grid; line-height: 1.3; }
.gl-icon, .pg-icon { flex: none; width: 40px; height: 40px; display: grid; place-items: center; border: 2px solid var(--ink); border-radius: 10px; background: var(--sun-tint); font-size: 1.2rem; font-family: var(--font-mono); font-weight: 700; }
@media (max-width: 900px) { .play-grid { grid-template-columns: 1fr; } }

/* ---------- Lesson flow ---------- */
.flow { list-style: none; counter-reset: f; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(5, 1fr); gap: 0; }
.flow li { counter-increment: f; position: relative; padding: 0 16px 0 0; }
.flow li::before { content: counter(f); display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%; border: 2.5px solid var(--ink); background: var(--sun); font-family: var(--font-head); font-weight: 700; margin-bottom: 10px; position: relative; z-index: 1; }
.flow li::after { content: ""; position: absolute; top: 19px; left: 40px; right: 0; border-top: 2.5px dashed var(--ink); }
.flow li:last-child::after { display: none; }
.flow b { display: block; font-family: var(--font-head); font-size: 1.1rem; }
.flow span { display: block; color: var(--ink-soft); font-size: 1rem; line-height: 1.45; }
@media (max-width: 860px) {
  .flow { grid-template-columns: 1fr; gap: 14px; }
  .flow li { padding: 0 0 0 56px; min-height: 40px; }
  .flow li::before { position: absolute; left: 0; top: 0; }
  .flow li::after { top: 40px; left: 19px; right: auto; bottom: -14px; border-top: none; border-left: 2.5px dashed var(--ink); }
}

/* ---------- Join ---------- */
.join { display: grid; grid-template-columns: 1.3fr 1fr; gap: 24px; align-items: start; }
.join > div:first-child { background: var(--white); border: var(--border); border-radius: var(--r-lg); box-shadow: var(--shadow); padding: clamp(18px, 3.5vw, 30px); }
.join-side { padding: 8px 4px; }
.join-side ul { padding-left: 1.2em; }
@media (max-width: 860px) { .join { grid-template-columns: 1fr; } }

/* ---------- Playground page ---------- */
.pg-hero { color: #E8EEFF; background-color: var(--night); border-bottom: var(--border); padding: 36px 0 30px;
  background-image: linear-gradient(var(--night-line) 1px, transparent 1px), linear-gradient(90deg, var(--night-line) 1px, transparent 1px); background-size: 40px 40px; }
.pg-hero h1 { color: var(--white); margin-bottom: .2em; }
.pg-hero .lead { color: #C3CEEE; max-width: 56ch; }
.shelf { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-top: 18px; }
.shelf-badge { display: flex; align-items: center; gap: 8px; padding: 6px 12px 6px 6px; border: 2px dashed #5D6FA6; border-radius: 999px; color: #8C9CCB; font-family: var(--font-head); font-size: .9rem; }
.shelf-badge .sb-icon { width: 30px; height: 30px; display: grid; place-items: center; border-radius: 50%; background: #1E2F66; filter: grayscale(1); opacity: .6; font-family: var(--font-mono); font-weight: 700; }
.shelf-badge.got { border: 2px solid var(--packet); color: var(--white); background: #1E2F66; }
.shelf-badge.got .sb-icon { background: var(--packet); filter: none; opacity: 1; color: var(--ink); }
.shelf-count { width: 100%; margin: 4px 0 0; color: #C3CEEE; font-size: .95rem; }
.pg-main { display: grid; grid-template-columns: 290px minmax(0, 1fr); gap: 24px; padding-top: 26px; align-items: start; }
.pg-pick { display: grid; gap: 8px; position: sticky; top: 80px; }
.pg-tile { display: grid; grid-template-columns: 40px 1fr auto; gap: 10px; align-items: center; padding: 10px; border: 2px solid var(--ink); border-radius: var(--r-md); background: var(--white); color: var(--ink); text-decoration: none; }
.pg-tile:hover { background: var(--paper); color: var(--ink); }
.pg-tile.on { background: var(--sun-tint); box-shadow: var(--shadow-sm); }
.pg-text { display: grid; line-height: 1.25; } .pg-text .small { color: var(--ink-soft); }
.pg-when { color: var(--ink-soft); white-space: nowrap; }
.pg-stage { min-width: 0; scroll-margin-top: 80px; }
@media (max-width: 900px) {
  .pg-main { grid-template-columns: 1fr; }
  .pg-pick { position: static; grid-auto-flow: column; grid-auto-columns: minmax(220px, 1fr); overflow-x: auto; padding-bottom: 6px; scroll-snap-type: x mandatory; }
  .pg-tile { scroll-snap-align: start; }
}

/* ---------- Resources page ---------- */
.res { padding-top: 32px; }
.res-head { max-width: 64ch; margin-bottom: 18px; }
.res-group { margin-top: 26px; border: var(--border); border-radius: var(--r-lg); background: var(--white); overflow: hidden; }
.res-group h2 { margin: 0; padding: 14px 20px; background: var(--mt); border-bottom: 2px solid var(--ink); font-size: 1.35rem; }
.res-list { margin: 0; padding: 6px 20px 10px 52px; }
.res-list li { padding: 12px 0; border-bottom: 1.5px solid var(--line-soft); }
.res-list li:last-child { border-bottom: none; }
.res-list li::marker { font-family: var(--font-head); font-weight: 700; color: var(--mc); }
.res-list a { font-family: var(--font-head); font-weight: 600; font-size: 1.12rem; }
.res-list p { margin: 4px 0; max-width: 68ch; }
.res-meta { font-size: .9rem; color: var(--ink-soft); }
.res-note { margin-top: 28px; max-width: 70ch; }

/* ---------- Mini-game frame ---------- */
.game { border: var(--border); border-radius: var(--r-lg); background: var(--white); box-shadow: var(--shadow); overflow: hidden; }
.game-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 12px 16px; background: var(--night); color: var(--white); border-bottom: 2px solid var(--ink); }
.game-head h3 { margin: 0; font-size: 1.2rem; color: var(--white); }
.game-concept { font-size: .9rem; color: #FFE7A3; font-family: var(--font-mono); }
.game-head .btn { flex: none; }
.game-goal { margin: 0; padding: 12px 16px; border-bottom: 2px solid var(--ink); background: var(--sun-tint); font-size: 1.02rem; }
.game-stage { padding: 16px; display: grid; gap: 12px; }
.game-fb { margin: 0 16px; }
.game-fb:not(:empty) { margin-bottom: 14px; padding: 10px 14px; border: 2px solid var(--ink); border-radius: var(--r-sm); }
.game-fb.ok { background: var(--green-tint); }
.game-fb.no { background: var(--coral-tint); }
.game-fb.info { background: var(--paper); }
.game-win { display: grid; grid-template-columns: 64px 1fr; gap: 14px; align-items: start; margin: 0 16px 16px; padding: 14px; border: var(--border); border-radius: var(--r-md); background: var(--green-tint); }
.game-win p { margin: 4px 0 8px; }
.game-badge { width: 64px; height: 64px; border-radius: 50%; display: grid; place-items: center; background: var(--packet); border: 3px solid var(--ink); font-size: 1.8rem; font-family: var(--font-mono); font-weight: 700; box-shadow: var(--shadow-sm); animation: badge-pop .5s cubic-bezier(.3, 1.6, .5, 1); }
@keyframes badge-pop { from { transform: scale(.3) rotate(-30deg); } to { transform: none; } }
.game-cmd { margin-top: 4px; font-size: .88rem; }
.rd-label { font-family: var(--font-head); font-weight: 600; font-size: .9rem; color: var(--ink-soft); }
.small.muted, .game .muted { color: var(--ink-soft); }

/* mission checklist used by several games */
.pz-missions { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.pz-missions li { display: flex; gap: 10px; align-items: baseline; font-size: 1rem; }
.pz-missions .box { flex: none; width: 22px; height: 22px; border: 2px solid var(--ink); border-radius: 6px; display: grid; place-items: center; font-size: .8rem; font-weight: 700; background: var(--white); }
.pz-missions li.done { color: var(--ink-soft); }
.pz-missions li.done .box { background: var(--green); color: var(--white); border-color: var(--green); }

/* Path Finder */
.pf-round { font-family: var(--font-head); font-weight: 600; }
.pf-tree { border: 2px solid var(--ink); border-radius: var(--r-md); background: var(--paper); padding: 8px 4px; font-family: var(--font-mono); font-size: .92rem; max-height: 340px; overflow-y: auto; }
.pf-row { display: flex; align-items: center; gap: 8px; padding: 3px 6px; border-radius: 6px; }
.pf-icon { color: var(--ink-soft); width: 12px; }
.pf-row.here { background: #DCE8FF; }
.pf-row.target { background: var(--sun-tint); }
.pf-tag { font-family: var(--font-head); font-size: .78rem; font-weight: 600; padding: 1px 8px; border-radius: 99px; border: 1.5px solid var(--ink); background: var(--white); }
.pf-tag.goal { background: var(--sun); }
.pf-term { display: flex; gap: 8px; align-items: center; background: var(--term-bg); border: var(--border); border-radius: var(--r-md); padding: 8px 8px 8px 12px; }
.pf-line { flex: 1; display: flex; align-items: baseline; min-width: 0; font-family: var(--font-mono); font-size: .93rem; color: var(--term-fg); }
.pf-prompt { color: var(--term-green); white-space: nowrap; }
.pf-input { flex: 1; min-width: 60px; background: transparent; border: none; outline: none; color: var(--term-fg); font: inherit; caret-color: var(--term-yellow); padding: 4px 0; }
@media (max-width: 520px) { .pf-line { flex-wrap: wrap; } .pf-input { width: 100%; } }

/* Tune the Radio */
.rd-pubs { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 10px; }
.rd-subs { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 10px; }
.rd-pub { position: relative; display: flex; gap: 10px; align-items: center; padding: 10px 12px; border: 2px solid var(--ink); border-radius: var(--r-md); background: #2C2470; color: var(--white); overflow: hidden; }
.rd-pub code { display: block; background: none; border: none; color: #FFE7A3; padding: 0; font-size: .88rem; }
.rd-icon { font-size: 1.4rem; flex: none; }
.rd-wave { position: absolute; right: 12px; top: 50%; width: 14px; height: 14px; margin-top: -7px; border-radius: 50%; background: var(--packet); opacity: .25; }
.rd-pub.tx .rd-wave { animation: rd-wave .8s ease-out; }
@keyframes rd-wave { 0% { opacity: 1; box-shadow: 0 0 0 0 rgba(255,200,61,.8); } 100% { opacity: .25; box-shadow: 0 0 0 26px rgba(255,200,61,0); } }
.rd-air { height: 10px; background: repeating-linear-gradient(90deg, var(--line-soft) 0 10px, transparent 10px 20px); border-radius: 4px; }
.rd-sub { border: 2px solid var(--ink); border-radius: var(--r-md); background: var(--white); padding: 10px 12px; display: grid; gap: 8px; transition: background .3s; }
.rd-sub.ok { background: var(--green-tint); }
.rd-sub.rx { animation: rd-rx .6s ease-out; }
@keyframes rd-rx { 0% { box-shadow: 0 0 0 4px var(--packet); } 100% { box-shadow: 0 0 0 0 transparent; } }
.rd-sub-top { display: flex; gap: 8px; align-items: flex-start; }
.rd-sub-top > div { display: grid; line-height: 1.25; flex: 1; }
.rd-count { font-size: .8rem; color: var(--ink-soft); white-space: nowrap; }
.rd-dial { display: grid; grid-template-columns: 38px 1fr 38px; gap: 6px; align-items: center; }
.rd-btn { font: inherit; height: 38px; border: 2px solid var(--ink); border-radius: 8px; background: var(--sun-tint); cursor: pointer; color: var(--ink); }
.rd-btn:hover { background: var(--sun); }
.rd-name { text-align: center; font-size: .9rem; padding: 6px 4px !important; background: var(--term-bg) !important; color: var(--term-fg); border-color: var(--ink) !important; }
.rd-last { font-family: var(--font-mono); font-size: .8rem; color: var(--ink-soft); min-height: 1.4em; overflow-wrap: anywhere; }
.rd-details summary { cursor: pointer; font-family: var(--font-head); font-weight: 600; font-size: .95rem; }
.rd-list { margin: 8px 0 0; background: var(--term-bg); color: var(--term-fg); border-radius: var(--r-sm); padding: 10px 14px; font-size: .88rem; }

/* Pizza Tracker */
.pz-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.pz-card { border: 2px solid var(--ink); border-radius: var(--r-md); padding: 12px; background: var(--paper); display: grid; gap: 8px; align-content: start; }
.pz-card h4 { margin: 0; font-family: var(--font-head); font-size: 1.02rem; }
.pz-card p { margin: 0; }
.pz-friend { background: var(--white); }
.pz-btns { display: flex; gap: 8px; flex-wrap: wrap; }
.pz-out { min-height: 1.5em; font-weight: 700; }
.pz-meter { min-width: 0; height: 12px; }
.pz-meter > span { background: var(--packet); }
.pz-feed { margin: 0; padding-left: 1.2em; font-size: .92rem; font-family: var(--font-mono); }
.pz-cancel { color: var(--coral); }
@media (max-width: 820px) { .pz-grid { grid-template-columns: 1fr; } }

/* Topic, Service or Action? */
.ts-top { font-family: var(--font-head); font-weight: 600; color: var(--ink-soft); }
.ts-card { font-size: 1.25rem; font-weight: 700; padding: 18px; border: var(--border); border-radius: var(--r-md); background: var(--paper); min-height: 4.5em; display: flex; align-items: center; }
.ts-btns { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.ts-opt { justify-content: center; font-family: var(--font-head); font-weight: 600; }
.ts-legend { display: grid; gap: 4px; color: var(--ink-soft); }
@media (max-width: 480px) { .ts-btns { grid-template-columns: 1fr; } }

/* Source It! */
.so-wrap { display: grid; grid-template-columns: minmax(0, 1fr) 220px; gap: 12px; align-items: start; }
.so-term { border: var(--border); border-radius: var(--r-md); overflow: hidden; background: var(--term-bg); }
.so-bar { display: flex; gap: 6px; align-items: center; padding: 6px; background: #0E1830; border-bottom: 2px solid var(--ink); flex-wrap: wrap; }
.so-tab, .so-new { font-family: var(--font-head); font-size: .85rem; border-radius: 7px; padding: 4px 10px; cursor: pointer; border: 1.5px solid #3B4A75; background: transparent; color: var(--term-fg); }
.so-tab[aria-selected="true"] { background: var(--term-fg); color: var(--term-bg); border-color: var(--term-fg); }
.so-new { margin-left: auto; border-style: dashed; }
.so-screen { height: 230px; overflow-y: auto; padding: 10px 12px; font-family: var(--font-mono); font-size: .86rem; color: var(--term-fg); line-height: 1.5; }
.so-line { white-space: pre-wrap; overflow-wrap: anywhere; }
.so-line.err { color: var(--term-red); } .so-line.out { color: #B9C7EE; }
.so-pr { color: var(--term-green); }
.so-belt { display: grid; gap: 6px; margin-top: 6px; }
.so-layer { border: 2px dashed #9AA6C2; border-radius: var(--r-sm); padding: 8px 10px; display: grid; line-height: 1.25; color: #8C97B3; background: var(--white); transition: all .25s; }
.so-layer span { font-size: .82rem; }
.so-layer.on { border-style: solid; border-color: var(--ink); color: var(--ink); }
.so-layer.base.on { background: #E9EDF4; }
.so-layer.jazzy.on { background: var(--teal-tint); box-shadow: 3px 3px 0 var(--teal); }
.so-layer.ws.on { background: var(--grape-tint); box-shadow: 3px 3px 0 var(--grape); }
.so-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.so-chip { font-family: var(--font-mono); font-size: .84rem; text-align: left; padding: 7px 10px; border: 2px solid var(--ink); border-radius: 8px; background: var(--white); color: var(--ink); cursor: pointer; overflow-wrap: anywhere; }
.so-chip:hover { background: var(--sun-tint); }
.so-chip:active { transform: translate(1px, 1px); }
@media (max-width: 680px) { .so-wrap { grid-template-columns: 1fr; } }

/* Turtle Commander */
.tt-grid { display: grid; grid-template-columns: minmax(0, 420px) minmax(0, 1fr); gap: 14px; align-items: start; }
.tt-win { border: var(--border); border-radius: var(--r-md); overflow: hidden; background: #E9EDF4; }
.tt-title { font-family: var(--font-head); font-size: .85rem; padding: 4px 10px; border-bottom: 2px solid var(--ink); background: #D5DCEA; }
.tt-canvas { display: block; width: 100%; height: auto; aspect-ratio: 1; }
.tt-term { display: grid; grid-template-columns: 1fr auto; gap: 8px; align-items: end; background: var(--term-bg); border: var(--border); border-radius: var(--r-md); padding: 8px; }
.tt-out { grid-column: 1 / -1; max-height: 200px; min-height: 90px; overflow-y: auto; font-family: var(--font-mono); font-size: .8rem; color: #B9C7EE; padding: 2px 4px; line-height: 1.45; }
.tt-l { white-space: pre-wrap; overflow-wrap: anywhere; }
.tt-l.cmd { color: var(--term-green); } .tt-l.err { color: var(--term-red); } .tt-l.warn, .tt-l.hint { color: var(--term-yellow); }
.tt-line { padding: 0 4px; }
.tt-chip { font-family: var(--font-head); }
@media (max-width: 760px) { .tt-grid { grid-template-columns: 1fr; } }

/* ---------- Lesson extras for games and links ---------- */
.lesson-game .bonus-note { font-family: var(--font-head); font-weight: 600; font-size: .95rem; color: var(--ink-soft); margin-bottom: 6px; }
.links-box { border: 2px solid var(--ink); border-radius: var(--r-md); background: var(--white); padding: 14px 18px; }
.links-box .label { font-family: var(--font-head); font-weight: 600; display: block; margin-bottom: 6px; }
.links-box ul { margin: 0; padding-left: 1.2em; }
.links-box li { margin-bottom: 6px; }
.links-box .small { color: var(--ink-soft); }

/* ---------- Course page polish ---------- */
.arcade { display: flex; gap: 16px; align-items: center; justify-content: space-between; flex-wrap: wrap; padding: 16px 20px; border: var(--border); border-radius: var(--r-lg); background: var(--night); color: #E8EEFF; box-shadow: var(--shadow); margin-bottom: 22px;
  background-image: linear-gradient(var(--night-line) 1px, transparent 1px), linear-gradient(90deg, var(--night-line) 1px, transparent 1px); background-size: 32px 32px; }
.arcade h2 { color: var(--white); font-size: 1.25rem; margin: 0 0 2px; }
.arcade p { margin: 0; color: #C3CEEE; font-size: 1rem; }
.arcade .shelf { margin: 0; }
.dash-head h1 { font-size: clamp(1.8rem, 4vw, 2.5rem); }
.game-win > div, .game-stage > *, .pz-card, .tt-side { min-width: 0; }
.game-cmd { overflow-x: auto; white-space: pre; }
.hero-facts li { display: flex; align-items: baseline; }
@media (max-width: 560px) {
  .rd-subs { grid-template-columns: 1fr; }
  .game-stage { padding: 12px; }
  .game-head { padding: 10px 12px; }
}
.rd-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: .85rem !important; }
.lesson-body .game p, .lesson-body .game li { max-width: none; }

/* =====================================================================
   v3: Week 3 colour, concept animations and puzzle blocks
   ===================================================================== */
:root { --sky: #2F7DD1; --sky-tint: #DCEBFF; }
[data-mod="W3"] { --mc: var(--sky); --mt: var(--sky-tint); }
[data-mod="IN"] { --mc: #B86E00; --mt: var(--sun-tint); }
[data-mod="PF"] { --mc: var(--coral); --mt: var(--coral-tint); }
[data-mod="NP"] { --mc: #1E8A4C; --mt: var(--green-tint); }
.lesson-body > .lesson-anim, .lesson-body > .pzl { margin: 26px 0; }

/* ---------- concept animations ---------- */
.anim { border: var(--border); border-radius: var(--r-lg); background: var(--white); box-shadow: var(--shadow); overflow: hidden; }
.anim-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; padding: 12px 16px; background: var(--night); color: var(--white); border-bottom: 2px solid var(--ink); }
.anim-head h3 { margin: 0; font-size: 1.12rem; color: var(--white); }
.anim-tag { font-family: var(--font-head); font-weight: 700; font-size: .75rem; letter-spacing: .06em; text-transform: uppercase; color: var(--ink); background: var(--packet); border-radius: 999px; padding: 2px 10px; }
.anim-concept { margin-left: auto; font-size: .9rem; color: #C3CEEE; }
.anim-stage { background: #F7FAFF; border-bottom: 2px solid var(--line-soft); background-image: linear-gradient(var(--grid) 1px, transparent 1px), linear-gradient(90deg, var(--grid) 1px, transparent 1px); background-size: 24px 24px; }
.anim-svg { display: block; width: 100%; height: auto; max-height: 420px; font-family: var(--font-head); }
.anim-cap { margin: 0; padding: 12px 16px; min-height: 3.4em; font-size: 1.02rem; border-bottom: 2px solid var(--line-soft); background: var(--sun-tint); }
.anim-cap.ok { background: var(--green-tint); }
.anim-cap.no { background: var(--coral-tint); }
.anim-extra:not(:empty) { display: flex; flex-wrap: wrap; gap: 10px 18px; padding: 12px 16px 0; align-items: center; }
.anim-ctrl { display: flex; flex-wrap: wrap; gap: 8px; padding: 12px 16px 14px; }
.anim-field { display: inline-flex; align-items: center; gap: 8px; font-family: var(--font-mono); font-size: .95rem; }
.anim-field input[type=number], .anim-field input[type=text] { width: 7em; font: inherit; padding: 4px 8px; border: 2px solid var(--ink); border-radius: 8px; }
.anim-field.wide { flex: 1 1 260px; font-family: var(--font-body); }
.anim-field.wide input[type=range] { flex: 1; accent-color: var(--grape); }
.anim-field.wide b { min-width: 3.5em; font-family: var(--font-mono); }
.anim-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; width: 100%; }
.anim-row input[type=text] { flex: 1 1 220px; font: inherit; font-family: var(--font-mono); padding: 6px 10px; border: 2px solid var(--ink); border-radius: 8px; }
.anim-pwd { font-size: 1rem; }
.anim-log { margin: 0 16px 16px; max-height: 190px; overflow: auto; background: var(--term-bg); color: var(--term-fg); border: 2px solid var(--ink); border-radius: var(--r-md); padding: 10px 12px; font-size: .85rem; line-height: 1.5; white-space: pre-wrap; }
.anim-log .ok { color: var(--term-green); } .anim-log .warn { color: var(--term-yellow); } .anim-log .err { color: var(--term-red); }
.anim-tf { display: grid; gap: 4px; width: 100%; font-size: .98rem; }
.tf-dot { display: inline-block; width: 12px; height: 12px; border-radius: 50%; border: 2px solid var(--ink); margin-right: 8px; vertical-align: -1px; }
.tf-dot.map { background: var(--ink); } .tf-dot.base { background: var(--grape); } .tf-dot.laser { background: var(--sun); }

/* svg pieces */
.an-box rect { fill: var(--white); stroke: var(--ink); stroke-width: 2.5; }
.an-box.pub rect { fill: var(--sun-tint); }
.an-box.sub rect { fill: var(--sky-tint); }
.an-box.off rect { fill: #EEF1F6; stroke-dasharray: 6 5; }
.an-box.wait rect { stroke: var(--grape); stroke-width: 3.5; }
.an-t { font-size: 15px; font-weight: 600; fill: var(--ink); text-anchor: middle; }
.an-t.left { text-anchor: start; } .an-s.right { text-anchor: end; }
.an-s { font-size: 12.5px; fill: var(--ink-soft); text-anchor: middle; font-family: var(--font-body); }
.an-lbl { font-size: 13px; fill: var(--ink-soft); text-anchor: middle; font-family: var(--font-body); }
.an-lbl.c { font-family: var(--font-mono); font-weight: 700; fill: var(--grape); font-size: 14px; }
.an-wire { stroke: var(--ink); stroke-width: 2.5; stroke-dasharray: 7 6; }
.an-wire.solid { stroke-dasharray: none; stroke: #9AA6C2; }
.an-wire.dead { stroke: #C9D2E3; }
.an-bus rect { fill: var(--grape-tint); stroke: var(--grape); stroke-width: 3; }
.an-bus text { font-family: var(--font-mono); font-weight: 700; font-size: 16px; text-anchor: middle; fill: var(--grape); }
.an-pk rect { fill: var(--packet); stroke: var(--ink); stroke-width: 2; }
.an-pk text { font-size: 12px; font-weight: 600; text-anchor: middle; fill: var(--ink); font-family: var(--font-mono); }
.an-pk.req rect { fill: #FFD9A8; } .an-pk.res rect { fill: #BFF0D4; } .an-pk.fb rect { fill: #CFE2FF; }
.an-pulse { animation: anPulse .6s ease; transform-box: fill-box; transform-origin: center; }
@keyframes anPulse { 40% { filter: drop-shadow(0 0 6px var(--packet)); } }
.an-map rect { fill: #FFFFFF; stroke: var(--ink); stroke-width: 2; }
.an-goal { fill: #BFF0D4; stroke: var(--green); stroke-width: 2; stroke-dasharray: 4 3; }
.an-robot rect { fill: var(--sun); stroke: var(--ink); stroke-width: 2.5; }
.an-robot circle { fill: var(--ink); }
.an-bar { fill: var(--green); } .an-bar-bg { fill: #E3E8F1; }
.an-tsim { fill: rgb(69, 86, 255); stroke: var(--ink); stroke-width: 2.5; }
.an-turtle { font-size: 26px; }
.an-param { font-family: var(--font-mono); font-size: 14px; fill: var(--ink); }
.an-path { fill: none; stroke: var(--packet); stroke-width: 3; stroke-dasharray: 2 6; stroke-linecap: round; }
.mono { font-family: var(--font-mono); font-size: 12.5px; fill: var(--ink); white-space: pre; }
.mono.b { font-weight: 700; fill: var(--grape); } .mono.dim { fill: var(--ink-soft); }
.an-term rect { fill: var(--term-bg); stroke: var(--ink); stroke-width: 2; } .an-term rect.bar { fill: #0E1830; }
.an-term .mono { fill: var(--term-green); } .an-term .mono.dim { fill: var(--term-fg); }
.an-file rect { fill: var(--white); stroke: var(--ink); stroke-width: 2.5; }
.an-tree { font-family: var(--font-mono); font-size: 14px; fill: var(--ink); }
.an-tree.new { fill: var(--green); font-weight: 700; }
.an-tree.here { font-weight: 700; fill: var(--grape); }
.an-treeline { fill: none; stroke: #9AA6C2; stroke-width: 2; }
.an-pin circle { fill: var(--packet); stroke: var(--ink); stroke-width: 2; } .an-pin text { font-size: 11px; text-anchor: middle; }
.an-layer rect { stroke: var(--ink); stroke-width: 2.5; }
.an-layer text { font-size: 14px; text-anchor: middle; font-weight: 600; fill: var(--ink); }
.an-layer .an-t { text-anchor: start; font-size: 14.5px; } .an-layer .an-s { text-anchor: end; font-weight: 400; }
.an-layer.l0 rect { fill: #E3E8F1; } .an-layer.l1 rect { fill: var(--teal-tint); } .an-layer.l2 rect { fill: var(--grape-tint); } .an-layer.l3 rect { fill: var(--sky-tint); }
.an-layer.top rect { fill: var(--sun); }
.an-layer.off rect { fill: #F4F6FA; stroke-dasharray: 6 5; } .an-layer.off text { fill: #8A95B1; }
.an-queue { fill: #FFFFFF; stroke: var(--ink); stroke-width: 2; stroke-dasharray: 6 5; }
.an-clock { fill: var(--white); stroke: var(--ink); stroke-width: 2.5; } .an-hand { stroke: var(--coral); stroke-width: 3; stroke-linecap: round; }
.an-blueprint rect { fill: #DCEBFF; stroke: var(--sky); stroke-width: 2.5; stroke-dasharray: 8 5; }
.an-obj rect:first-child { fill: var(--white); stroke: var(--ink); stroke-width: 2.5; }
.an-grid line { stroke: #DCE6F3; stroke-width: 1; }
.an-axes line { stroke-width: 3.5; stroke-linecap: round; } .an-axes .ax { stroke: var(--tf-x); } .an-axes .ay { stroke: var(--tf-y); }
.an-axes text { font-size: 11px; text-anchor: start; font-family: var(--font-mono); }
.an-laser { fill: var(--packet); stroke: var(--ink); stroke-width: 2; }
.an-ray { stroke: var(--packet); stroke-width: 2.5; stroke-dasharray: 5 4; }
.an-obst { fill: var(--coral); stroke: var(--ink); stroke-width: 2; }
.perm-grid { display: grid; grid-template-columns: auto repeat(3, 64px); gap: 6px 8px; align-items: center; }
.perm-grid > b { font-family: var(--font-head); font-size: .9rem; text-align: center; }
.perm-grid .perm-who { text-align: left; }
.perm-bit { font-family: var(--font-mono); font-weight: 700; font-size: 1.2rem; height: 44px; border: 2px solid var(--ink); border-radius: 10px; background: #EEF1F6; color: #8A95B1; cursor: pointer; }
.perm-bit.on { background: var(--green-tint); color: var(--ink); box-shadow: var(--shadow-sm); }
.perm-task { width: 100%; padding: 8px 12px; border: 2px dashed var(--ink); border-radius: 10px; background: var(--white); }
.perm-ls, .perm-num { font-size: 1.05rem; }

/* ---------- puzzle blocks ---------- */
.pzl { border: var(--border); border-radius: var(--r-lg); background: var(--white); overflow: hidden; }
.pzl-head { display: flex; justify-content: space-between; gap: 10px; flex-wrap: wrap; padding: 10px 16px; border-bottom: 2px solid var(--ink); background: var(--mt, var(--paper)); font-size: .95rem; }
.pzl-kind { font-family: var(--font-head); font-weight: 700; }
.pzl-kind::before { margin-right: 8px; }
.pzl-trace .pzl-kind::before { content: "▶"; } .pzl-match .pzl-kind::before { content: "⇄"; } .pzl-sort .pzl-kind::before { content: "▦"; }
.pzl-bug .pzl-kind::before { content: "🐞"; } .pzl-think .pzl-kind::before { content: "💡"; } .pzl-cards .pzl-kind::before { content: "🃏"; }
.pzl-body { padding: 16px; }
/* trace */
.tr-grid { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); gap: 14px; }
.tr-code { margin: 0; padding: 8px 0; list-style: none; counter-reset: ln; background: var(--term-bg); border: 2px solid var(--ink); border-radius: var(--r-md); overflow-x: auto; }
.tr-code li { counter-increment: ln; display: flex; padding: 1px 12px 1px 0; color: var(--term-fg); border-left: 5px solid transparent; transition: background .2s; }
.tr-code li::before { content: counter(ln); width: 2.4em; flex: none; text-align: right; padding-right: 12px; color: #6F80AE; font-family: var(--font-mono); font-size: .85rem; }
.tr-code li code { font-size: .9rem; white-space: pre; background: none; border: 0; padding: 0; color: inherit; }
.tr-code li.ran { color: #FFFFFF; }
.tr-code li.now { background: rgba(255, 200, 61, .25); border-left-color: var(--packet); }
.tr-side { display: grid; gap: 6px; align-content: start; }
.tr-label { font-family: var(--font-head); font-weight: 600; font-size: .9rem; }
.tr-vars { width: 100%; border-collapse: collapse; font-size: .92rem; }
.tr-vars th, .tr-vars td { border: 2px solid var(--ink); padding: 4px 8px; text-align: left; }
.tr-vars th { background: var(--paper); font-family: var(--font-head); font-weight: 600; }
.tr-vars tr.changed td { background: var(--sun-tint); animation: anPulse .6s; }
.tr-out { margin: 0; min-height: 2.4em; background: var(--term-bg); color: var(--term-green); border: 2px solid var(--ink); border-radius: var(--r-sm); padding: 6px 10px; font-size: .88rem; white-space: pre-wrap; }
.tr-note { margin-top: 12px; padding: 10px 14px; border-radius: var(--r-sm); border: 2px solid var(--ink); background: var(--sun-tint); min-height: 2.8em; }
.tr-ctrl { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 12px; }
.tr-grid > div { min-width: 0; }
@media (max-width: 700px) { .tr-grid { grid-template-columns: minmax(0, 1fr); } }
/* match */
.mt-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 16px; }
.mt-col { display: grid; gap: 8px; align-content: start; }
.mt-item { font: inherit; font-size: 1rem; text-align: left; color: var(--ink); background: var(--white); border: 2px solid var(--ink); border-radius: var(--r-sm); padding: 9px 12px; cursor: pointer; position: relative; }
.mt-item:hover { background: var(--paper); }
.mt-item.sel { background: var(--sun-tint); box-shadow: var(--shadow-sm); }
.mt-item.ok { background: var(--green-tint); border-color: var(--green); cursor: default; padding-right: 34px; }
.mt-item.ok::after { content: attr(data-n); position: absolute; right: 8px; top: 50%; transform: translateY(-50%); width: 20px; height: 20px; border-radius: 50%; background: var(--green); color: #fff; font-size: .75rem; display: grid; place-items: center; font-family: var(--font-head); }
.mt-item.bad, .st-bin.bad { animation: shake .4s; background: var(--coral-tint); }
@keyframes shake { 25% { transform: translateX(-5px); } 75% { transform: translateX(5px); } }
/* sort */
.st-pool { display: flex; flex-wrap: wrap; gap: 8px; min-height: 44px; padding: 10px; border: 2px dashed #9AA6C2; border-radius: var(--r-md); margin-bottom: 12px; }
.st-chip { display: inline-block; font-size: .98rem; background: var(--white); border: 2px solid var(--ink); border-radius: 10px; padding: 6px 10px; cursor: grab; box-shadow: var(--shadow-sm); }
.st-chip.sel { background: var(--sun); }
.st-chip.ok { background: var(--green-tint); border-color: var(--green); box-shadow: none; cursor: default; font-size: .9rem; }
.st-bins { display: grid; gap: 10px; }
.st-bin { font: inherit; color: var(--ink); text-align: left; min-height: 120px; background: var(--mt, var(--paper)); border: 2.5px solid var(--ink); border-radius: var(--r-md); padding: 10px; cursor: pointer; display: flex; flex-direction: column; gap: 8px; }
.st-bin.over { background: var(--sun-tint); }
.st-name { font-family: var(--font-head); font-weight: 700; }
.st-list { display: flex; flex-wrap: wrap; gap: 6px; }
@media (max-width: 640px) { .st-bins { grid-template-columns: 1fr !important; } .mt-grid { grid-template-columns: 1fr; } }
/* bug */
.bg-code { margin: 0; padding: 8px 0; list-style: none; counter-reset: ln; background: var(--term-bg); border: 2px solid var(--ink); border-radius: var(--r-md); overflow-x: auto; }
.bg-code li { counter-increment: ln; display: flex; }
.bg-code li::before { content: counter(ln); width: 2.4em; flex: none; text-align: right; padding: 3px 12px 0 0; color: #6F80AE; font-family: var(--font-mono); font-size: .85rem; }
.bg-code button { flex: 1; text-align: left; font: inherit; background: none; border: 0; border-left: 5px solid transparent; color: var(--term-fg); padding: 2px 10px; cursor: pointer; }
.bg-code button:hover:not([disabled]) { background: rgba(255,255,255,.08); }
.bg-code code { white-space: pre; background: none; border: 0; color: inherit; padding: 0; font-size: .9rem; }
.bg-code li.ok button { background: rgba(126, 226, 184, .22); border-left-color: var(--term-green); }
.bg-code li.bad button { background: rgba(255, 143, 163, .18); border-left-color: var(--term-red); }
.bg-fix { margin-top: 8px; }
/* think */
.th-ans { margin-top: 10px; padding: 12px 14px; border: 2px solid var(--ink); border-radius: var(--r-sm); background: var(--green-tint); animation: fadeUp .35s ease; }
@keyframes fadeUp { from { opacity: 0; transform: translateY(6px); } }
/* flashcards */
.fc-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 12px; }
.fc { position: relative; min-height: 120px; font: inherit; color: var(--ink); cursor: pointer; border: 2.5px solid var(--ink); border-radius: var(--r-md); background: var(--white); box-shadow: var(--shadow-sm); padding: 0; perspective: 600px; }
.fc span { position: absolute; inset: 0; display: grid; place-items: center; text-align: center; padding: 12px; border-radius: 10px; backface-visibility: hidden; transition: transform .45s ease; }
.fc-front { font-family: var(--font-head); font-weight: 600; font-size: 1.05rem; background: var(--mt, var(--sun-tint)); }
.fc-back { transform: rotateY(180deg); font-size: .98rem; background: var(--white); }
.fc.flip .fc-front { transform: rotateY(180deg); } .fc.flip .fc-back { transform: rotateY(0); }

/* ---------- v3 landing: concept lab, three metro lines, six flow steps ---------- */
.lab { display: grid; grid-template-columns: 250px minmax(0, 1fr); gap: 20px; align-items: start; }
.lab-tabs { display: grid; gap: 8px; position: sticky; top: 80px; }
.lab-tab { display: grid; gap: 2px; text-align: left; font: inherit; color: var(--ink); cursor: pointer; padding: 10px 12px; background: var(--white); border: 2px solid var(--ink); border-radius: var(--r-md); line-height: 1.25; }
.lab-tab b { font-family: var(--font-head); font-weight: 600; }
.lab-tab .small { color: var(--ink-soft); font-size: .88rem; }
.lab-tab:hover { background: var(--paper); }
.lab-tab[aria-pressed="true"] { background: var(--sun-tint); box-shadow: var(--shadow-sm); }
.lab-stage { min-width: 0; min-height: 420px; }
@media (max-width: 900px) {
  .lab { grid-template-columns: 1fr; }
  .lab-tabs { position: static; grid-auto-flow: column; grid-auto-columns: minmax(180px, 1fr); overflow-x: auto; padding-bottom: 6px; }
  .metro { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
}
.flow { grid-template-columns: repeat(6, 1fr); }
@media (max-width: 860px) { .flow { grid-template-columns: 1fr; } }
.anim-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 10px; margin-bottom: 18px; }
.pg-sec { margin: 34px 0 10px; }
.pg-sec h2 { margin-bottom: .2em; }

/* ---------- Week 3 and 5 animations ---------- */
.an-box.ok rect { fill: var(--green-tint); }
.an-box.bad rect { fill: var(--coral-tint); stroke: var(--coral); }
.an-wire.bad { stroke: var(--coral); stroke-width: 4; stroke-dasharray: none; animation: an-flash .5s 3; }
@keyframes an-flash { 50% { opacity: .25; } }
.an-pk.bad rect { fill: var(--coral-tint); stroke: var(--coral); }
.an-lbl.small { font-size: 11.5px; }
.an-lbl.l { text-anchor: start; font-weight: 700; } .an-lbl.r { text-anchor: end; font-weight: 600; fill: var(--ink); } .an-lbl.in { text-anchor: start; font-size: 11.5px; fill: var(--ink); }
.an-rail { stroke-width: 6; stroke-linecap: round; } .an-rail.r1 { stroke: #5B8DEF; } .an-rail.r2 { stroke: #F59E0B; }
.an-stopblock { fill: var(--ink); }
.an-stn { fill: var(--white); stroke: var(--ink); stroke-width: 2.5; } .an-stn.now { fill: var(--sun); }
.an-gridline { stroke: #DCE3EF; stroke-width: 1; }
.an-span { fill: #E3E8F1; stroke: var(--ink); stroke-width: 1.5; } .an-span.lts { fill: var(--teal-tint); } .an-span.sel { stroke: var(--grape); stroke-width: 4; }
.an-today { stroke: var(--coral); stroke-width: 3; stroke-dasharray: 5 4; }
.an-ripple { fill: none; stroke: var(--grape); stroke-width: 3; animation: an-ripple 1.2s ease-out 1 forwards; }
@keyframes an-ripple { from { r: 10; opacity: 1; } to { r: 150; opacity: 0; } }
.an-net { fill: #E3E8F1; stroke: var(--ink); stroke-width: 2; }
.an-state rect { fill: var(--white); stroke: #9AA6C2; stroke-width: 2; } .an-state text { font-size: 11.5px; text-anchor: middle; font-weight: 700; fill: var(--ink-soft); }
.an-state.now rect { fill: var(--sun); stroke: var(--ink); } .an-state.now text { fill: var(--ink); }
.anim-file { font-family: var(--font-mono); font-size: .85rem; background: var(--term-bg); color: var(--term-fg); border-radius: 8px; padding: 10px 12px; margin: 8px 0; overflow-x: auto; white-space: pre; }
.anim-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 4px 0; }
.anim-extra select { font: inherit; font-size: .9rem; padding: 4px 6px; border: 2px solid var(--ink); border-radius: 6px; }
@media (prefers-reduced-motion: reduce) { .an-ripple, .an-wire.bad { animation: none; } }

/* ---------- v5: screenshot deterrent ---------- */
body.shielded main, body.shielded .watermark { filter: blur(18px) grayscale(1); }
.shield { position: fixed; inset: 0; z-index: 9999; display: grid; place-items: center; background: rgba(20, 32, 74, .92); padding: 20px; cursor: pointer; }
.shield-box { max-width: 420px; background: var(--white); border: var(--border); border-radius: var(--r-lg); box-shadow: var(--shadow); padding: 22px; text-align: center; }
.shield-box strong { font-family: var(--font-head); font-size: 1.2rem; display: block; margin-bottom: 6px; }
.shield-box p { margin: 0; }
@media print { main { display: none !important; } }

/* ---------- v6: terminal tabs, running nodes, TurtleSim window, teleop keys ---------- */
.term-tabrow { display: flex; align-items: flex-end; gap: 6px; padding: 8px 10px 0; background: #0E1830; border-bottom: 2px solid #2B3A66; flex-wrap: wrap; }
.term-tabs { display: flex; gap: 4px; flex-wrap: wrap; }
.term-tab { display: inline-flex; align-items: center; gap: 8px; font: inherit; font-family: var(--font-mono); font-size: .85rem; color: #AFC0EA; background: #1A2750; border: 1.5px solid #2B3A66; border-bottom: none; border-radius: 8px 8px 0 0; padding: 6px 10px; cursor: pointer; }
.term-tab.on { background: var(--term-bg); color: var(--white); border-color: #4A5C93; }
.term-tab .tt-x { opacity: .6; padding: 0 2px; border-radius: 4px; }
.term-tab .tt-x:hover { opacity: 1; background: rgba(255,255,255,.15); }
.term-tab-add { font: inherit; font-family: var(--font-head); font-size: .82rem; font-weight: 600; color: var(--ink); background: var(--packet); border: 1.5px solid var(--ink); border-radius: 8px; padding: 4px 10px; margin: 0 0 6px auto; cursor: pointer; }
.term-tab-add[disabled] { opacity: .45; cursor: not-allowed; }
.term-proc { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin-top: 6px; padding: 8px 10px; border: 1.5px dashed #4A5C93; border-radius: 8px; color: var(--term-fg); font-family: var(--font-body); font-size: .92rem; }
.term-proc .muted { color: #9FB0DE; }
.term-proc .tp-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--term-green); box-shadow: 0 0 0 0 rgba(126,226,184,.7); animation: tpPulse 1.6s infinite; }
@keyframes tpPulse { 70% { box-shadow: 0 0 0 8px rgba(126,226,184,0); } 100% { box-shadow: 0 0 0 0 rgba(126,226,184,0); } }
.term-proc .tp-text { flex: 1 1 260px; }
.tele-keys { width: 100%; display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.tk-grid { display: grid; grid-template-columns: repeat(3, 44px); grid-template-rows: repeat(2, 40px); gap: 4px; }
.tk-key { font-size: 1.2rem; font-weight: 700; color: var(--ink); background: var(--white); border: 2px solid var(--ink); border-radius: 8px; cursor: pointer; box-shadow: 0 2px 0 var(--ink); }
.tk-key:active { transform: translateY(2px); box-shadow: none; }
.tsim-panel { display: flex; flex-wrap: wrap; gap: 12px; padding: 12px; background: #0E1830; border-bottom: 2px solid #2B3A66; }
.tsim-win { margin: 0; background: #DDE3EE; border: 2px solid #111; border-radius: 8px; overflow: hidden; box-shadow: 0 6px 18px rgba(0,0,0,.35); max-width: 100%; }
.tsim-win figcaption { display: flex; align-items: center; gap: 6px; padding: 4px 8px; background: #2F2F35; color: #EEE; font-size: .8rem; font-family: var(--font-body); }
.tsim-win figcaption i { width: 10px; height: 10px; border-radius: 50%; background: #E9524A; }
.tsim-win figcaption i:nth-child(2) { background: #F5B33B; } .tsim-win figcaption i:nth-child(3) { background: #58C243; }
.tsim-win figcaption span { margin-left: 6px; }
.tsim-win canvas { display: block; max-width: 100%; height: auto !important; }
@media (max-width: 560px) { .tsim-win canvas { width: 100% !important; } }
.term-screen .warn-line { color: var(--term-yellow); }

/* ---------- v7: playground drawings, tabbed code ---------- */
.py-viz:not(:empty) { display: flex; flex-wrap: wrap; gap: 12px; padding: 10px 12px; border-top: 2px solid var(--line-soft); background: var(--paper); }
.py-viz-fig { margin: 0; border: 2px solid var(--ink); border-radius: var(--r-sm); background: var(--white); overflow: hidden; max-width: 100%; }
.py-viz-fig figcaption { font-family: var(--font-head); font-size: .85rem; padding: 4px 8px; border-bottom: 2px solid var(--ink); background: var(--sun-tint); }
.py-viz-fig canvas { display: block; max-width: 100%; height: auto !important; }
.langs { border: var(--border); border-radius: var(--r-lg); overflow: hidden; background: var(--white); }
.langs-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 8px 10px; background: var(--paper); border-bottom: 2px solid var(--ink); }
.langs-head b { font-family: var(--font-head); margin-right: auto; }
.langs-tab { font: inherit; font-family: var(--font-head); font-size: .88rem; font-weight: 600; color: var(--ink); background: var(--white); border: 2px solid var(--ink); border-radius: 999px; padding: 3px 12px; cursor: pointer; }
.langs-tab[aria-selected="true"] { background: var(--sun); box-shadow: var(--shadow-sm); }
.langs-body { padding: 12px; }
.langs-body .code-wrap, .langs-body pre.code { margin: 0; }
.langs-note { margin: 10px 0 0; font-size: .98rem; }

/* phone widths: long words and code never push the page sideways */
.lesson-hero h1, h1, h2, .lesson-body p, .lesson-body li, .lesson-body .opt, .lesson-body td { overflow-wrap: anywhere; }
.lesson-body pre { max-width: 100%; overflow-x: auto; }
.lesson-body { overflow-x: clip; }

/* wide lessons: the whole lesson, code included, is visible without scrolling sideways */
.lesson-top .narrow, main > .narrow[data-mod], #root.narrow { max-width: 1280px; }
.lesson-body p, .lesson-body li { max-width: 90ch; }
.lesson-body pre.code, .tr-code li code, .figure-out, .langs-body pre { white-space: pre-wrap; overflow-wrap: anywhere; overflow-x: hidden; }
.tr-code { overflow-x: hidden; }
.tr-code li code { min-width: 0; }
.py textarea, .nano textarea { white-space: pre-wrap; overflow-wrap: anywhere; overflow-x: hidden; }
@media (min-width: 1100px) { .tr-grid { grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr); } }
.anim-file { white-space: pre-wrap; overflow-wrap: anywhere; overflow-x: hidden; }
