/* ── TEXT SIZE, SITE-WIDE (Robin, 15 Aug 2026: "all text should probably
   come down in size... maybe like 2px equivalent"; then 23 Aug 2026:
   "a 2px size increase body wide, everything excluding large titling")
   ─────────────────── ONE rule does it: every font-size is rem, so this
   root number tunes the whole site. Back to 100% (16px). The LARGE
   TITLES are excluded by counter-scaling their own rem values by 0.875
   — the hero title and section titles in pageContent's tokens, the
   nanum pair below, and the two big score numbers — so they render the
   same pixels as before while the body grows. */
html { font-size: 100%; }

* { margin: 0; padding: 0; box-sizing: border-box; }
/* THE GROUND IS A TOKEN. It was hardcoded var(--c-ground) here, which meant a
   theme could recolour every word on the page and not the paper it sits
   on — the same bug notebookCS fixed on 3 Sep with ground-to-token.py,
   never swept through AP. Found on 7 Sep because the '90s theme asks for
   true black and got var(--c-ground). matrix and noir were quietly affected too.
   The fallback keeps every theme that does not set --c-ground unchanged. */
body, html { width: 100%; height: 100vh; overflow: hidden; font-family: 'Outfit', sans-serif; color: #fff; background: var(--c-ground, #0a0a0f); }

/* ── BACKGROUND: FLAT (owner, 30 Aug 2026: "Take away the bg altogether.
   Nothing we do stops the blocky artifacting on the tv — not worth my
   time.") ──────────────── The wheel-and-aurora field and the grain that
   dithered it are both gone. They were the artifacting: a gradient has
   to step somewhere, and the film grain is exactly the high-frequency
   noise a classroom TV's compression turns into blocks. One flat color
   is the only thing that cannot band. #07070c is what the old stack
   actually resolved to under its veil, so nothing else on the page
   shifts. The wrapper stays because every page sits on top of it. */
.orb-container { position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background: #07070c; }
.orb { display: none; }

/* THE MATRIX THEME'S BINARY RAIN. Inside .orb-container, so it inherits
   the fixed full-viewport box and the pointer-events:none that stops it
   ever swallowing a tap. Painted by matrix-rain.js, which only mounts
   the canvas when the theme is actually matrix — every other theme
   carries no canvas at all, not a hidden one. */
.matrix-rain { position: absolute; inset: 0; width: 100%; height: 100%;
  opacity: .40; pointer-events: none; }

.app-wrapper { display: flex; height: 100vh; position: relative; z-index: 10; width: 100%; }
/* THE NAV PUBLISHES ITS WIDTH so the logo can be a FRACTION of it.
   Robin, 4 Sep 2026: "logo should be about 2/3 of the width of the
   navigation." That is a ratio, not a number, and it has to hold on
   a 252px desktop rail and a min(92vw,380px) phone drawer alike --
   which a hardcoded 180px cannot do. One token, one multiplier, and
   the mobile override below only has to restate the width. */
.sidebar { --nav-w: 252px; width: var(--nav-w); background: rgba(var(--c-ground-rgb), 0.45); backdrop-filter: blur(20px); border-right: 1px solid rgba(255,255,255,0.1); display: flex; flex-direction: column; padding: 2rem 0; overflow-y: auto; flex-shrink: 0; }
.brand { display: flex; flex-direction: column; align-items: flex-start; gap: 0.2rem; margin-bottom: 2rem; padding: 0 1rem; }
.logo-placeholder { font-size: 2rem; font-weight: 900; color: var(--c-pink); letter-spacing: 4px; }
.brand span { font-size: 0.9rem; letter-spacing: 2px; padding: 0 1.5rem; color: rgba(255,255,255,0.5); }
.nav-chapter-title { color: var(--c-pink); font-size: 0.75rem; font-weight: 200; margin: 1rem 0 0.2rem 0; text-transform: uppercase; letter-spacing: 0.5px; display: flex; align-items: center; gap: 0.75rem; justify-content: space-between; cursor: pointer; padding: 0 1rem; border-radius: 6px; transition: background 0.2s; user-select: none; }
.nav-chapter-title .nav-chapter-title-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-chapter-title .nav-collapse-icon { flex-shrink: 0; }
.nav-chapter-title:hover { background: rgba(var(--c-pink-rgb), 0.08); }
.nav-chapter-locked .nav-chapter-title { cursor: default; opacity: 0.45; }
.nav-chapter-locked .nav-chapter-title:hover { background: none; }
.nav-item { color: #fff; padding: 0.3rem 1rem 0.3rem 1.3rem; cursor: pointer; font-size: 0.82rem; display: flex; align-items: center; gap: 0.4rem; overflow: hidden; }
.nav-item-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-exam-badge { flex-shrink: 0; text-transform: uppercase; font-size: 0.80rem; font-weight: 700; color: var(--c-green); padding: 0.1rem 0.20rem; }
.nav-num { font-size: 0.35rem; font-weight: 400; flex-shrink: 0; background: rgba(var(--c-purple-rgb), 0.12) !important; border: 1px solid var(--c-purple) !important; border-radius: 4px; padding: 0.1rem 0.20rem; letter-spacing: 0.2px; }
.nav-num, .nav-num * { color: var(--c-purple) !important; }
.nav-exam-label { background: rgba(var(--c-gold-rgb),0.1) !important; color: var(--c-gold) !important; border-color: rgba(var(--c-gold-rgb),0.3) !important; }
.nav-unit-exam .nav-item-text { color: rgba(var(--c-gold-rgb),0.8); }
.nav-unit-exam:hover .nav-item-text { color: var(--c-gold); }
.nav-item:hover, .nav-item.active { color: #fff; background: rgba(var(--c-cyan-rgb),0.15);}
/* NOT a size container. A container-type element becomes the containing
   block for position:fixed descendants, and .vex (the exam overlay) is
   fixed and lives inside here — it would have been trapped in this box
   instead of covering the viewport. The sidebar is accounted for in the
   .tb-columns breakpoint arithmetic instead; see there. */
.main-content { flex: 1; overflow-y: auto; padding: 3rem 4rem; }
:root { --content-w: 1000px; } /* one knob: .content-container AND .thub share this, so every element on a page lines up to the same width */
.content-container { max-width: var(--content-w); margin: 0 auto; }
h1 { font-size: 1.4rem; font-weight: 200; color: #fff; line-height: 1.2; letter-spacing: -0.3px; margin-bottom: 1rem;}
.intro-box { background: rgba(var(--c-pink-rgb),0.1); padding: 1.25rem 1.5rem; border-radius: 12px; border: 1px solid rgba(var(--c-pink-rgb),0.2); color: #fff; margin-bottom: 2.5rem; font-size: 1rem; line-height: 1.6; }
.section-label { display: inline-block; font-size: 0.8rem; font-weight: 800; letter-spacing: 2px; text-transform: uppercase; padding: 0.25rem 0.75rem; border-radius: 4px; margin-bottom: 0.75rem; margin-top: 0.25rem; }
.section-label.pink   { background: rgba(var(--c-pink-rgb),0.2);   color: var(--c-pink); }
.section-label.cyan   { background: rgba(var(--c-cyan-rgb),0.12);  color: var(--c-cyan); }
.section-label.gold   { background: rgba(var(--c-gold-rgb),0.15);  color: var(--c-gold); }
.section-label.green  { background: rgba(var(--c-green-rgb),0.12);  color: var(--c-green); }
.section-label.purple { background: rgba(var(--c-purple-rgb),0.15);color: var(--c-purple); }
.section-label.general { background: rgba(var(--c-orange-rgb),0.15); color: var(--c-orange); }
.section-label.orange { background: rgba(var(--c-orange-rgb),0.15); color: var(--c-orange); }
.vocab-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem; margin: 0.75rem 0 1.5rem; }
.vocab-grid.single { grid-template-columns: 1fr; }
.vocab-grid.triple { grid-template-columns: 1fr 1fr 1fr; }
.vocab-card { background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.07); border-left: 3px solid var(--c-pink); border-radius: 10px; padding: 0.9rem 1.1rem; }
.vocab-card .term { color: var(--c-pink); font-weight: 700; font-size: 1rem; margin-bottom: 0.35rem; display: flex; align-items: center; gap: 8px; }
.vocab-card.cyan-card   { border-left-color: var(--c-cyan); }
.vocab-card.cyan-card   .term { color: var(--c-cyan); }
.vocab-card.gold-card   { border-left-color: var(--c-gold); }
.vocab-card.gold-card   .term { color: var(--c-gold); }
.vocab-card.green-card  { border-left-color: var(--c-green); }
.vocab-card.green-card  .term { color: var(--c-green); }
.vocab-card.purple-card { border-left-color: var(--c-purple); }
.vocab-card.purple-card .term { color: var(--c-purple); }
.callout { border-radius: 12px; padding: 1rem 1.3rem; margin: 1.25rem 0; font-size: 1rem; line-height: 1.65; color: rgba(255,255,255,.85); }
.callout.exam-tip  { background: rgba(var(--c-gold-rgb),0.07);    border: 1px solid rgba(var(--c-gold-rgb),0.25);    border-left: 4px solid var(--c-gold); }
.callout.analogy   { background: rgba(var(--c-purple-rgb),0.07);  border: 1px solid rgba(var(--c-purple-rgb),0.2);   border-left: 4px solid var(--c-purple); }
.callout.warning   { background: rgba(var(--c-orange-rgb),0.07);    border: 1px solid rgba(var(--c-orange-rgb),0.2);     border-left: 4px solid var(--c-orange); }
.callout.fun-fact  { background: rgba(var(--c-green-rgb),0.06);    border: 1px solid rgba(var(--c-green-rgb),0.2);     border-left: 4px solid var(--c-green); }
.callout.general  { background: rgba(var(--c-orange-rgb),0.07);   border: 1px solid rgba(var(--c-orange-rgb),0.25); }
.callout.gold { background: rgba(var(--c-gold-rgb),0.07);   border: 1px solid rgba(var(--c-gold-rgb),0.25);   border-left: 4px solid var(--c-gold); }
.callout.purple { background: rgba(var(--c-purple-rgb),0.1);   border: 1px solid rgba(var(--c-purple-rgb),0.35);  border-left: 4px solid var(--c-purple); }
.callout.pink   { background: rgba(var(--c-pink-rgb),0.07);   border: 1px solid rgba(var(--c-pink-rgb),0.25);   border-left: 4px solid var(--c-pink); }
.callout.green  { background: rgba(var(--c-green-rgb),0.06);   border: 1px solid rgba(var(--c-green-rgb),0.2);    border-left: 4px solid var(--c-green); }
.callout.cyan   { background: rgba(var(--c-cyan-rgb),0.06);   border: 1px solid rgba(var(--c-cyan-rgb),0.2);    border-left: 4px solid var(--c-cyan); }
.callout.orange { background: rgba(var(--c-orange-rgb),0.07);  border: 1px solid rgba(var(--c-orange-rgb),0.25);  border-left: 4px solid var(--c-orange); }
.callout-head { font-weight: 800; display: block; margin-bottom: 0.3rem; font-size: 0.88rem; letter-spacing: 1.5px; text-transform: uppercase; }
.callout.gold .callout-head { color: var(--c-gold); }
.callout.purple .callout-head { color: var(--c-purple); }
.callout.pink .callout-head { color: var(--c-pink); }
.callout.green .callout-head { color: var(--c-green); }
.callout.cyan .callout-head { color: var(--c-cyan); }
.callout.orange .callout-head { color: var(--c-orange); }
.callout.exam-tip  .callout-head { color: var(--c-gold); }
.callout.analogy   .callout-head { color: var(--c-purple); }
.callout.warning   .callout-head { color: var(--c-orange); }
.callout.fun-fact  .callout-head { color: var(--c-green); }
.callout.general  .callout-head { color: var(--c-orange); }
.callout.magenta  { background: rgba(var(--c-pink-rgb),0.07);  border: 1px solid rgba(var(--c-pink-rgb),0.25); border-left: 4px solid var(--c-pink); }
.callout.magenta  .callout-head { color: var(--c-pink); }
.compare-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem; margin: 0.75rem 0 1.5rem; }
.compare-box { background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.08); border-radius: 12px; padding: 1.1rem 1.3rem; }
.compare-box h4 { font-size: 0.95rem; font-weight: 700; margin-bottom: 0.7rem; text-transform: uppercase; letter-spacing: 1px; }
.compare-box ul { padding-left: 1.1rem; }
.compare-box.vs-a { border-top: 2px solid var(--c-cyan); }
.compare-box.vs-a h4 { color: var(--c-cyan); }
.compare-box.vs-b { border-top: 2px solid var(--c-pink); }
.compare-box.vs-b h4 { color: var(--c-pink); }
.diagram { background: rgba(8,8,18,0.9); border: 1px solid rgba(255,255,255,0.09); border-radius: 14px; padding: 1.5rem; margin: 1rem 0 1.5rem; text-align: center; }
.diagram-label { font-size: 0.8rem; letter-spacing: 2px; text-transform: uppercase; color: rgba(255,255,255,0.3); margin-bottom: 1.1rem; }
.packet-visual { display: flex; border-radius: 8px; overflow: hidden; margin: 0.5rem auto; max-width: 520px; }
.packet-part { padding: 0.65rem 0.5rem; font-size: 0.8rem; font-weight: 700; text-align: center; }
.packet-part.hdr  { background: rgba(var(--c-pink-rgb),0.25); border: 1px solid rgba(var(--c-pink-rgb),0.5); color: var(--c-pink); flex: 0 0 140px; font-size: 0.85rem; line-height: 1.4; }
.packet-part.body { background: rgba(var(--c-cyan-rgb),0.08); border: 1px solid rgba(var(--c-cyan-rgb),0.2); color: var(--c-cyan); flex: 1; }
.binary-row  { display: flex; justify-content: center; gap: 6px; margin: 0.4rem 0; flex-wrap: wrap; }
.bit         { width: 46px; height: 46px; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 1.25rem; font-weight: 900; }
.bit.one     { background: rgba(var(--c-pink-rgb),0.2); border: 2px solid var(--c-pink); color: var(--c-pink); }
.bit.zero    { background: rgba(255,255,255,0.04); border: 2px solid rgba(255,255,255,0.15); color: rgba(255,255,255,0.25); }
.bit-labels  { display: flex; justify-content: center; gap: 6px; flex-wrap: wrap; margin-top: 4px; }
.bit-lbl     { width: 46px; font-size: 0.65rem; color: rgba(255,255,255,0.3); text-align: center; }
.search-visual { display: flex; gap: 6px; justify-content: center; flex-wrap: wrap; margin: 0.75rem 0; }
.s-cell { width: 44px; height: 44px; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 1rem; font-weight: 700; border: 1px solid rgba(255,255,255,0.15); background: rgba(255,255,255,0.05); color: rgba(255,255,255,0.6); }
.s-cell.found { background: rgba(var(--c-green-rgb),0.2); border-color: var(--c-green); color: var(--c-green); }
.s-cell.eliminated { background: rgba(255,255,255,0.02); border-color: rgba(255,255,255,0.05); color: rgba(255,255,255,0.15); }
.s-cell.mid { background: rgba(var(--c-gold-rgb),0.2); border-color: var(--c-gold); color: var(--c-gold); }
.truth-table { width: 100%; border-collapse: collapse; font-size: 0.875rem; margin: 0.5rem auto; max-width: 400px; }
.truth-table th { background: rgba(var(--c-pink-rgb),0.15); color: var(--c-pink); padding: 0.5rem 1.2rem; font-weight: 700; font-size: 0.88rem; text-transform: uppercase; letter-spacing: 1px; text-align: center; }
.truth-table td { padding: 0.5rem 1.2rem; border-bottom: 1px solid rgba(255,255,255,0.05); text-align: center; }
.truth-table .t { color: var(--c-green); font-weight: 700; }
.truth-table .f { color: var(--c-orange); font-weight: 700; }
.encrypt-flow { display: flex; align-items: center; justify-content: center; gap: 0.6rem; flex-wrap: wrap; margin: 0.75rem 0; }
.encrypt-box  { background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.12); border-radius: 10px; padding: 0.6rem 1rem; font-size: 0.85rem; text-align: center; color: rgba(255,255,255,.8); min-width: 90px; }
.encrypt-box.key-box { background: rgba(var(--c-gold-rgb),0.1); border-color: rgba(var(--c-gold-rgb),0.3); color: var(--c-gold); }
.encrypt-box.plain   { background: rgba(var(--c-cyan-rgb),0.08); border-color: rgba(var(--c-cyan-rgb),0.25); color: var(--c-cyan); }
.encrypt-box.cipher  { background: rgba(var(--c-pink-rgb),0.1);  border-color: rgba(var(--c-pink-rgb),0.3); color: var(--c-pink); }
.encrypt-arrow { color: rgba(255,255,255,0.3); font-size: 1.1rem; }
.time-bar-wrap { margin: 0.6rem 0; }
.time-bar-label { font-size: 0.9rem; color: rgba(255,255,255,0.5); margin-bottom: 0.25rem; display: flex; justify-content: space-between; }
.time-bar { height: 28px; border-radius: 6px; display: flex; align-items: center; padding: 0 0.75rem; font-size: 0.8rem; font-weight: 700; }
.time-bar.seq { background: rgba(var(--c-pink-rgb),0.3); border: 1px solid var(--c-pink); color: var(--c-pink); width: 100%; }
.time-bar.par { background: rgba(var(--c-green-rgb),0.2); border: 1px solid var(--c-green); color: var(--c-green); }
.content-block { margin-bottom: 2.25rem; }
.quiz-section { background: rgba(255,255,255,0.025); padding: 2rem; border-radius: 16px; margin-top: 3rem; border: 1px solid rgba(255,255,255,0.06); }
.quiz-section h3 { color: #fff; font-size: 1.2rem; margin-bottom: 0.6rem; font-weight: 300;}
.option-btn { width: 100%; text-align: left; padding: 0.85rem 1.1rem; margin-bottom: 0.5rem; background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.1); color: rgba(255,255,255,.85); cursor: pointer; border-radius: 10px; font-family: 'Outfit', sans-serif; font-size: 0.9rem; transition: 0.15s; }
.option-btn:hover:not(:disabled) { background: rgba(255,255,255,0.08); border-color: rgba(255,255,255,0.2); }
.option-btn.correct { background: rgba(var(--c-green-rgb),0.15); border-color: var(--c-green); color: var(--c-green); }
.option-btn.wrong    { background: rgba(var(--c-orange-rgb),0.15);  border-color: var(--c-orange); color: var(--c-orange); }
.option-btn:disabled { cursor: default; }
.action-btn { background: transparent; border: 1px solid rgba(var(--c-pink-rgb),0.5); color: var(--c-pink); padding: 0.65rem 1.5rem; border-radius: 8px; cursor: pointer; font-family: 'Outfit', sans-serif; font-size: 0.9rem; font-weight: 400; letter-spacing: 0.5px; transition: 0.2s; }
.action-btn:hover { background: rgba(var(--c-pink-rgb),0.08); border-color: var(--c-pink); }
.practice-test-section { margin-top: auto; padding-top: 1.5rem; padding-left: 1.5rem;padding-right: 1.5rem;border-top: 1px solid rgba(255,255,255,0.06); }
.practice-test-nav { width: 100%; background: linear-gradient(135deg, rgba(var(--c-pink-rgb),0.2), rgba(var(--c-pink-rgb),0.2)); border: 1px solid rgba(var(--c-pink-rgb),0.3); color: var(--c-pink); padding: 0.75rem 1rem; border-radius: 10px; cursor: pointer; font-weight: 700; font-family: 'Outfit', sans-serif; font-size: 0.9rem; transition: 0.2s; letter-spacing: 0.5px; }
.practice-test-nav:hover { background: linear-gradient(135deg, rgba(var(--c-pink-rgb),0.35), rgba(var(--c-pink-rgb),0.35)); transform: translateY(-1px); }
.nav-q-badge { background: rgba(var(--c-pink-rgb),0.15); color: var(--c-pink); font-size: 0.75rem; font-weight: 400; padding: 0.15rem 0.4rem; border-radius: 4px; margin-left: 0.4rem; vertical-align: middle; }
.quiz-launch-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-top: 0.75rem; }
.quiz-launch-option { background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.08); border-radius: 12px; padding: 1.25rem; }
.quiz-launch-option.quiz-launch-ap { border-color: rgba(var(--c-gold-rgb),0.2); background: rgba(var(--c-gold-rgb),0.04); }
.ql-label { font-size: 0.92rem; font-weight: 800; letter-spacing: 2px; text-transform: uppercase; color: var(--c-pink); }
.ql-label.ap-label { color: var(--c-gold); }
.ql-desc { color: rgba(255,255,255,0.5); font-size: 0.92rem; margin: 0.4rem 0 1rem; }
.ap-btn { background: linear-gradient(135deg, var(--c-gold), var(--c-gold)) !important; color: #000 !important; }
.q-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.75rem; }
.q-mode-badge { font-size: 0.92rem; font-weight: 700; letter-spacing: 1.5px; text-transform: uppercase; color: var(--c-pink); background: rgba(var(--c-pink-rgb),0.12); padding: 0.2rem 0.6rem; border-radius: 4px; }
.q-progress-text { font-size: 1rem; color: rgba(255,255,255,0.4); }
.q-progress-bar { height: 3px; background: rgba(255,255,255,0.07); border-radius: 2px; margin-bottom: 1.5rem; overflow: hidden; }
.q-progress-fill { height: 100%; background: linear-gradient(90deg, var(--c-pink), var(--c-cyan)); border-radius: 2px; transition: width 0.4s ease; }
.q-context { background: rgba(var(--c-cyan-rgb),0.05); border: 1px solid rgba(var(--c-cyan-rgb),0.15); border-radius: 10px; padding: 0.9rem 1.1rem; margin-bottom: 1rem; font-size: 1.12rem; color: rgba(255,255,255,.87); line-height: 1.6; }
.q-stem { font-size: 1.2rem; font-weight: 600; line-height: 1.6; margin-bottom: 1.1rem; color: #fff; }
.multi-note { background: rgba(var(--c-gold-rgb),0.1); border: 1px solid rgba(var(--c-gold-rgb),0.3); color: var(--c-gold); font-size: 0.78rem; font-weight: 700; padding: 0.4rem 0.8rem; border-radius: 6px; margin-bottom: 0.75rem; display: inline-block; }
.q-options { display: flex; flex-direction: column; gap: 0.5rem; }
.option-btn { width: 100%; text-align: left; padding: 0.85rem 1.1rem; background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.1); color: rgba(255,255,255,.85); cursor: pointer; border-radius: 10px; font-family: 'Outfit', sans-serif; font-size: 1.06rem; transition: 0.15s; display: flex; align-items: flex-start; gap: 0.75rem; }
.option-btn:hover:not(:disabled) { background: rgba(255,255,255,0.08); border-color: rgba(255,255,255,0.2); }
.option-btn.correct { background: rgba(var(--c-green-rgb),0.12); border-color: var(--c-green); color: var(--c-green); }
.option-btn.wrong    { background: rgba(var(--c-orange-rgb),0.12);  border-color: var(--c-orange); color: var(--c-orange); }
.option-btn.selected-multi { background: rgba(var(--c-cyan-rgb),0.1); border-color: var(--c-cyan); color: var(--c-cyan); }
.option-btn:disabled { cursor: default; }
.opt-letter { font-size: 0.95rem; font-weight: 900; background: rgba(255,255,255,0.1); padding: 0.15rem 0.45rem; border-radius: 4px; flex-shrink: 0; margin-top: 0.1rem; letter-spacing: 1px; }
.opt-text { flex: 1; line-height: 1.5; }
.submit-multi-btn { margin-top: 0.75rem; opacity: 0.4; transition: opacity 0.2s; }
.feedback-box { border-radius: 12px; padding: 1rem 1.25rem; margin-top: 1.25rem; }
.feedback-box.fb-correct { background: rgba(var(--c-green-rgb),0.08); border: 1px solid rgba(var(--c-green-rgb),0.25); }
.feedback-box.fb-wrong    { background: rgba(var(--c-orange-rgb),0.08);  border: 1px solid rgba(var(--c-orange-rgb),0.25); }
.fb-status { font-weight: 900; font-size: 1rem; margin-bottom: 0.4rem; }
.feedback-box.fb-correct .fb-status { color: var(--c-green); }
.feedback-box.fb-wrong    .fb-status { color: var(--c-orange); }
.fb-explain { font-size: 1rem; color: rgba(255,255,255,.78); line-height: 1.6; }
.feedback-actions { display: flex; align-items: center; margin-top: 1rem; gap: 0.75rem; flex-wrap: wrap; }
.outline-btn { background: transparent; border: 1px solid rgba(255,255,255,0.2); color: rgba(255,255,255,0.65); padding: 0.65rem 1.25rem; border-radius: 10px; cursor: pointer; font-family: 'Outfit', sans-serif; font-size: 0.875rem; transition: 0.2s; }
.outline-btn:hover { border-color: rgba(255,255,255,0.4); color: #fff; }
.q-code-area { margin-bottom: 1.25rem; border: 1px solid rgba(255,255,255,0.1); border-radius: 12px; overflow: hidden; }
.q-code-header { display: flex; justify-content: space-between; align-items: center; padding: 0.6rem 1rem; background: rgba(255,255,255,0.04); border-bottom: 1px solid rgba(255,255,255,0.08); }
.q-code-label { font-size: 0.9rem; font-weight: 800; letter-spacing: 2px; text-transform: uppercase; color: rgba(255,255,255,0.4); }
.toggle-view-btn { background: rgba(var(--c-pink-rgb),0.15); border: 1px solid rgba(var(--c-pink-rgb),0.3); color: var(--c-pink); font-size: 0.95rem; font-weight: 700; padding: 0.25rem 0.6rem; border-radius: 6px; cursor: pointer; font-family: 'Outfit', sans-serif; transition: 0.15s; }
.toggle-view-btn:hover { background: rgba(var(--c-pink-rgb),0.25); }
.pseudo-raw { font-family: 'Source Code Pro', 'Menlo', 'Monaco', 'Consolas', monospace; font-size: 1.05rem; color: rgba(255,255,255,.85); padding: 1.1rem 1.25rem; line-height: 1.85; white-space: pre-wrap; background: rgba(0,0,0,0.3); }
.apcsp-blocks { padding: 1.1rem 1.25rem; background: rgba(0,0,0,0.4); }
.bl-row { margin: 4px 0; }
.bl-stmt { display: inline-block; background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.18); border-radius: 8px; padding: 0.35rem 0.85rem; font-family: 'JetBrains Mono', monospace; font-size: 0.82rem; color: rgba(255,255,255,.93); }
.bl-arrow { color: var(--c-pink); font-size: 1rem; }
.bl-val { display: inline-block; background: rgba(var(--c-cyan-rgb),0.12); border: 1px solid rgba(var(--c-cyan-rgb),0.3); border-radius: 4px; padding: 0.1rem 0.4rem; font-family: 'JetBrains Mono', monospace; font-size: 0.78rem; color: var(--c-cyan); }
.bl-cond { display: inline-block; background: rgba(var(--c-purple-rgb),0.12); border: 1px solid rgba(var(--c-purple-rgb),0.35); border-radius: 999px; padding: 0.15rem 0.65rem; font-family: 'JetBrains Mono', monospace; font-size: 0.78rem; color: var(--c-purple); }
.bl-ctrl-block { background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.1); border-radius: 10px; overflow: hidden; margin: 4px 0; }
.bl-ctrl-title { background: rgba(255,255,255,0.08); padding: 0.4rem 0.85rem; }
.bl-ctrl-header { display: inline-block; font-family: 'JetBrains Mono', monospace; font-size: 1rem; font-weight: 700; color: rgba(255,255,255,.93); }
.bl-ctrl-body { padding: 0.5rem 0.85rem 0.5rem 1.5rem; display: flex; flex-direction: column; gap: 4px; }
.bl-else { color: var(--c-gold); }
.pt-lobby { display: flex; flex-direction: column; gap: 1.5rem; margin-top: 0.5rem; }
.pt-config-section { background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.08); border-radius: 14px; padding: 1.25rem 1.5rem; }
.pt-config-section h3 { color: var(--c-pink); font-size: 1rem; font-weight: 800; text-transform: uppercase; letter-spacing: 1.5px; margin-bottom: 1rem; }
.pt-count-row { display: flex; flex-wrap: wrap; gap: 0.6rem; }
.pt-count-btn { background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.12); color: rgba(255,255,255,.76); padding: 0.55rem 1.1rem; border-radius: 8px; cursor: pointer; font-family: 'Outfit', sans-serif; font-size: 0.9rem; font-weight: 600; transition: 0.15s; }
.pt-count-btn:hover { border-color: rgba(var(--c-pink-rgb),0.4); color: var(--c-pink); }
.pt-count-btn.selected { background: rgba(var(--c-pink-rgb),0.2); border-color: var(--c-pink); color: var(--c-pink); font-weight: 800; }
.pt-unit-row { display: flex; flex-wrap: wrap; gap: 0.6rem; }
.pt-start-btn { font-size: 1rem; padding: 0.9rem 2.5rem; margin-top: 0.5rem; }
.results-screen { text-align: center; }
.results-score { font-size: 4.5rem; font-weight: 900; line-height: 1; margin: 1.25rem 0 0.5rem; }
.results-fraction { color: rgba(255,255,255,0.45); font-size: 1rem; margin-bottom: 0.5rem; }
.results-msg { font-size: 1rem; font-weight: 700; margin-bottom: 1.5rem; }
.results-btns { display: flex; justify-content: center; gap: 0.75rem; flex-wrap: wrap; margin-top: 1.5rem; }
.results-grade-block { display: flex; flex-direction: column; align-items: center; margin: 1.5rem 0 0.75rem; gap: 0.5rem; }
.results-grade-score { font-size: 2.2rem; font-weight: 900; color: rgba(255,255,255,.9); font-family: 'JetBrains Mono', monospace; letter-spacing: 1px; }
.results-grade-letter { font-size: 2.2rem; font-weight: 900; line-height: 1; font-family: 'Outfit', sans-serif; }
.brand { display: flex; flex-direction: column; align-items: flex-start; gap: 0.2rem; margin-bottom: 0.75rem; }
/* ═══════════════════════════════════════════════════════════════════
   THE WORDMARK
   Robin, 3 Sep 2026: "Hate the smaller ones with the cs or ap after...
   I uploaded a plain white one... Just use it at 220px width - the color
   controls the look as always... replace both notebooks pls." Then, same
   day, once he saw it on the page: "too big" -- 180px in both.

   So the two-part lockup is gone -- no suffix, no second mask, no
   per-course artwork. ONE shape, painted from the palette, in both
   notebooks. Which course you are in is said by the nav and the page,
   not by two letters at 12px.

   The source is ariaPlain.png, cropped to its ink by
   tools/cut-plain-logo.py. Robin re-uploads that file rather than
   editing the derived one, and the 4 Sep upload changed its SHAPE --
   1047x514 became 1047x352, a third shorter at the same width -- so the
   aspect-ratio below is not decoration. Get it wrong and the mark
   stretches. Re-run the tool after any upload; it prints the numbers.

   AP KEEPS THE DISCO RAINBOW on the word -- the original six-stop run,
   drifting -- which is what it had before the lockup experiment. Noir
   overrides it to solid brass further down this file, which is the whole
   point of noir. */
.brand-logo {
  width: calc(var(--nav-w) * 0.66);
  max-width: 100%;
  aspect-ratio: 1047 / 352;
  height: auto;
  display: block;
  background: linear-gradient(95deg,
    rgba(var(--c-pink-rgb), 0.95) 0%,
    rgba(var(--c-purple-rgb), 0.95) 22%,
    rgba(var(--c-orange-rgb), 0.95) 40%,
    rgba(var(--c-gold-rgb), 0.90) 58%,
    rgba(var(--c-cyan-rgb), 0.95) 75%,
    rgba(var(--c-green-rgb), 0.90) 100%
  );
  background-size: 160% 100%;
  -webkit-mask: url('../logos/aria-plain.png') left center / contain no-repeat;
          mask: url('../logos/aria-plain.png') left center / contain no-repeat;
  animation: logodrift 20s ease-in-out infinite alternate;
}
/* No masking support: the flat artwork rather than a blank box. */
@supports not ((-webkit-mask-image: url('#')) or (mask-image: url('#'))) {
  .brand-logo { background: url('../logos/aria-plain.png') left center / contain no-repeat; }
}

.brand-subtitle { font-size: 0.85rem; font-weight: 400; letter-spacing: 2px; color: rgba(255,255,255,.76); text-transform: uppercase; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
.hamburger { display: none; position: fixed; top: 1rem; left: 1rem; z-index: 50; width: 40px; height: 40px; background: rgba(var(--c-pink-rgb),0.1); border: 1px solid rgba(var(--c-pink-rgb),0.3); border-radius: 8px; cursor: pointer; flex-direction: column; justify-content: center; align-items: center; gap: 6px; padding: 0; transition: all 0.3s; }
.hamburger span { width: 24px; height: 2px; background: var(--c-pink); border-radius: 1px; transition: all 0.3s; }
.hamburger.open { background: rgba(var(--c-pink-rgb),0.2); border-color: var(--c-pink); }
.hamburger.open span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.hamburger.open span:nth-child(2) { opacity: 0; transform: scaleX(0); }
.hamburger.open span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
#sidebar-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.5); z-index: 9; opacity: 0; pointer-events: none; transition: opacity 0.3s; }
#sidebar-overlay.visible { opacity: 1; pointer-events: auto; }
@media (max-width: 768px) {
  body, html { overflow: auto; height: auto; }
  .app-wrapper { flex-direction: column; height: auto; min-height: 100vh; }
  .hamburger { display: flex; }
  .sidebar { position: fixed; left: -232px; top: 0; height: 100vh; z-index: 10; transition: left 0.3s ease; border-right: 1px solid rgba(255,255,255,0.1); }
  .sidebar.open { left: 0; }
  .brand { flex-direction: column; justify-content: center; align-items: center; margin-bottom: 2rem; gap: 0.3rem; padding-top: 1rem; }
  /* NO WIDTH CAP. There are two mobile blocks in this file -- this
     older one and the newer drawer block further down -- and a
     max-width here beats the width in either, so the logo sat at
     100px on a 359px drawer: 0.28 of the nav, not the 0.66 Robin
     asked for. Removing the cap in the newer block alone changed
     nothing, which is how the ratio came out wrong on a check that
     had just been "fixed". Size is --nav-w * 0.66 now, one place. */
  .brand-subtitle { font-size: 0.7rem; letter-spacing: 2px; }
  .nav-chapter-title { margin-top: 0.65rem; }
  .main-content { padding: 1.5rem 1rem; overflow: visible; height: auto; margin-top: 3rem; }
  .content-container { max-width: 100%; }
  .practice-test-section { margin-top: 1rem; padding-top: 0.75rem; }
  .vocab-grid, .vocab-grid.triple, .compare-grid { grid-template-columns: 1fr; }
  h1 { font-size: 1.4rem; }
  .mobile-topic-dropdown { display: none !important; }
}
.pt-overlay { position: fixed; inset: 0; z-index: 1000; background: var(--c-ground); overflow-y: auto; animation: pt-fade-in 0.2s ease; }
@keyframes pt-fade-in { from { opacity: 0; } to { opacity: 1; } }
.pt-overlay-inner { max-width: 720px; margin: 0 auto; padding: 2rem 2rem 4rem; }
.pt-close-btn { background: none; border: 1px solid rgba(255,255,255,0.15); color: rgba(255,255,255,0.5); padding: 0.4rem 0.9rem; border-radius: 8px; cursor: pointer; font-family: 'Outfit', sans-serif; font-size: 0.82rem; margin-bottom: 1.5rem; display: block; transition: 0.15s; }
.pt-close-btn:hover { border-color: rgba(var(--c-orange-rgb),0.4); color: var(--c-orange); }
@media (max-width: 768px) { .pt-overlay-inner { padding: 1.25rem 1rem 4rem; } }
body.exam-mode #aria-bubble, body.exam-mode #aria-chat-window, body.exam-mode #hamburger, body.exam-mode #sidebar { display: none !important; }
.vocab-card .def, .compare-box li, .compare-box ul { font-size: 1rem; line-height: 1.65; color: rgba(255,255,255,.85); }
.content-container div[style*="font-size:0.82rem"]:not([style*="background"]), .content-container div[style*="font-size: 0.82rem"]:not([style*="background"]), .content-container div[style*="font-size:0.85rem"]:not([style*="background"]), .content-container div[style*="font-size: 0.85rem"]:not([style*="background"]), .content-container div[style*="font-size:0.88rem"]:not([style*="background"]), .content-container div[style*="font-size: 0.88rem"]:not([style*="background"]) { font-size: 1rem !important; line-height: 1.65 !important; color: rgba(255,255,255,.85) !important; }
.content-container span[style*="font-size:0.82rem"], .content-container span[style*="font-size: 0.82rem"], .content-container span[style*="font-size:0.85rem"], .content-container span[style*="font-size: 0.85rem"], .content-container span[style*="font-size:0.88rem"], .content-container span[style*="font-size: 0.88rem"] { font-size: 1rem !important; line-height: 1.65 !important; }
.ccard { background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.1); border-radius: 14px; padding: 1.4rem 1.6rem; }
.ccard.cyan   { border-color: rgba(var(--c-cyan-rgb),0.3); background: rgba(var(--c-cyan-rgb),0.05); }
.ccard.gold   { border-color: rgba(var(--c-gold-rgb),0.3); background: rgba(var(--c-gold-rgb),0.05); }
.ccard.pink   { border-color: rgba(var(--c-pink-rgb),0.3); background: rgba(var(--c-pink-rgb),0.05); }
.ccard.green  { border-color: rgba(var(--c-green-rgb),0.3); background: rgba(var(--c-green-rgb),0.05); }
.ccard.purple { border-color: rgba(var(--c-purple-rgb),0.3); background: rgba(var(--c-purple-rgb),0.05); }
.ccard.orange { border-color: rgba(var(--c-orange-rgb),0.3); background: rgba(var(--c-orange-rgb),0.05); }
.ccard.white  { border-color: rgba(255,255,255,0.15); }
/* :is(.ccard, .codecard) — Code Concept Cards (the block-styled reskin,
   further down) share this whole label/title/body colour system rather
   than duplicating it. */
:is(.ccard, .codecard) .cc-label { font-size: 0.72rem; font-weight: 900; letter-spacing: 2.5px; text-transform: uppercase; margin-bottom: 0.4rem; }
:is(.ccard, .codecard).cyan   .cc-label { color: var(--c-cyan); }
:is(.ccard, .codecard).gold   .cc-label { color: var(--c-gold); }
:is(.ccard, .codecard).pink   .cc-label { color: var(--c-pink); }
:is(.ccard, .codecard).green  .cc-label { color: var(--c-green); }
:is(.ccard, .codecard).purple .cc-label { color: var(--c-purple); }
:is(.ccard, .codecard).orange .cc-label { color: var(--c-orange); }
:is(.ccard, .codecard).white  .cc-label { color: rgba(255,255,255,0.5); }
.cc-label:empty, .cc-label:has(> br:only-child) { display: none; }
.cc-label:empty + .cc-title, .cc-label:has(> br:only-child) + .cc-title { margin-top: -0.35rem; }
:is(.ccard, .codecard) .cc-title { font-size: 1.75rem; font-weight: 900; line-height: 1.2; color: #fff; margin-bottom: 0.6rem; }
:is(.ccard, .codecard).cyan   .cc-title { color: var(--c-cyan); }
:is(.ccard, .codecard).gold   .cc-title { color: var(--c-gold); }
:is(.ccard, .codecard).pink   .cc-title { color: var(--c-pink); }
:is(.ccard, .codecard).green  .cc-title { color: var(--c-green); }
:is(.ccard, .codecard).purple .cc-title { color: var(--c-purple); }
:is(.ccard, .codecard).orange .cc-title { color: var(--c-orange); }
:is(.ccard, .codecard) .cc-body { font-size: 1rem; line-height: 1.65; color: rgba(255,255,255,.9); }
:is(.ccard, .codecard) .cc-body ul { padding-left: 1.1rem; display: flex; flex-direction: column; gap: 0.35rem; }
:is(.ccard, .codecard) .cc-body li { font-size: 1rem; line-height: 1.65; color: rgba(255,255,255,.9); }
/* Code Concept Cards — same body system above (no label — these never
   render one, see codeCardMarkup), wearing an APBlocks-style shell
   (monospace, chip-dark, rounded) instead of the flat colour-tinted card.
   .apblocks (added alongside .codecard on the element) supplies
   --apb-tray/--apb-line for free — see apblocks.js. The title is now REAL
   block markup (.apblocks output), not free text, so it renders in the
   exam's own monochrome — the colour swatch instead tints the card's own
   border, so left/right (or per-row) cards stay visually distinct. The
   body paragraph is an instance-wide on/off (default off); when off,
   codeCardMarkup omits the .cc-body element entirely and
   :not(:has(.cc-body)) below zeroes the title's reserved gap so the card
   collapses to a thin block-sized shell. */
.codecard { border-radius: 14px; padding: 1.3rem 1.7rem; background: var(--apb-tray, rgba(0,0,0,.30)); border: 1px solid var(--apb-line, rgba(255,255,255,.16)); }
.codecard.cyan   { border-color: var(--c-cyan); }
.codecard.gold   { border-color: var(--c-gold); }
.codecard.pink   { border-color: var(--c-pink); }
.codecard.green  { border-color: var(--c-green); }
.codecard.purple { border-color: var(--c-purple); }
.codecard.orange { border-color: var(--c-orange); }
.codecard .cc-title { margin-bottom: 0.6rem; }
.codecard .cc-title .pr-code { display: block; }
.codecard .cc-title .apblocks { font-size: 1.5rem; }
.codecard .cc-body { font-family: var(--mono,'Source Code Pro',ui-monospace,Consolas,monospace); font-size: 0.92rem; }
.codecard:not(:has(.cc-body)) .cc-title { margin-bottom: 0; }

.pr-code { font-family: 'Source Code Pro', ui-monospace, Consolas, monospace; }
.pr-code code { font-size: 1.05rem; }
/* .pr-src is a real <textarea> (Studio editing only — never exported, see
   codeCardMarkup) so it needs the usual form-control reset on top of the
   same dashed "raw source" look. */
.pr-code .pr-src { display: block; width: 100%; box-sizing: border-box; font: inherit; font-size: 0.82rem; color: rgba(255,255,255,0.5); background: rgba(255,255,255,0.03); border: 1px dashed rgba(255,255,255,0.18); border-radius: 6px; padding: 0.3rem 0.6rem; margin-bottom: 0.5rem; white-space: pre-wrap; resize: vertical; min-height: 2.4em; }

/* Code — a from-scratch dark pseudocode renderer (see cbParse/cbRenderNode
   in elements/index.html), independent of apblocks.js: that renderer
   strips "#"/"//" comments before parsing (real AP exam blocks never show
   them) — wrong here, where showing comments inline, in grey, with no box
   around them (unlike real code, which keeps its chip/pill shapes) is the
   whole point. No bold anywhere, per spec. */
.cb-wrap { font-family: 'Source Code Pro', ui-monospace, Consolas, monospace; color: #e8ecf3; line-height: 1.65; }

/* ── the code panel ───────────────────────────────────────────────
   A framed window rather than text floating in the column: header strip,
   rule under it, line numbers down the left, generous row rhythm.

   The header label is a custom property, so it can say something true
   instead of the same word seven times a page. Default is PSEUDOCODE;
   override per block:

       <div class="cb-pane" style="--cb-label:'What is wrong with this?';
                                   --cb-label-col:var(--c-pink)">

   Line numbers come from a CSS counter, so every block already on the
   site gets them with no markup change and nothing to regenerate.
   (style.css already carried a .cb-ln rule for exactly this, styled and
   never emitted by anything — the counter supersedes it.) */
.cb-pane { --cb-label: "PSEUDOCODE"; --cb-label-col: rgba(255,255,255,0.38);
  background: #0b0e12; border: 1px solid rgba(255,255,255,0.09);
  border-radius: 14px; overflow: hidden; box-shadow: 0 8px 30px rgba(0,0,0,0.35); }
.cb-pane::before { content: var(--cb-label); display: block;
  padding: 0.5rem 0.95rem; font-family: 'Outfit', sans-serif; font-size: 0.62rem;
  font-weight: 700; letter-spacing: 1.6px; text-transform: uppercase;
  color: var(--cb-label-col);
  background: rgba(255,255,255,0.02); border-bottom: 1px solid rgba(255,255,255,0.07);
  user-select: none; -webkit-user-select: none; }
.cb-numbered { counter-reset: cbln; padding: 0.7rem 0.9rem 0.75rem 0; }
.cb-num-row { padding: 0.14rem 0; }
/* the row is flex/flex-start, so the number's own line box starts at the top
   of the row while the chip sits lower by its margin, border and padding.
   Measured: the number lands 6.2px (0.46em at this size) above the chip's
   centre, so it gets that back as padding — expressed in em so it holds if
   the block is set at a different size. */
.cb-num-row::before { counter-increment: cbln; content: counter(cbln);
  flex: none; width: 2.1em; text-align: right; color: rgba(255,255,255,0.26);
  font-size: 0.85em; line-height: 2.1; padding-top: 0.46em;
  user-select: none; -webkit-user-select: none; font-variant-numeric: tabular-nums; }
/* a comment that fits sits beside its code; one that does not drops whole to
   its own line; one longer than the pane wraps inside its own box so the
   runover stays under the comment instead of under the line number */
.cb-line .cb-comment { display: inline-block; vertical-align: top; font-style: italic; }
/* ...but "beside if it fits" is per-LINE, so a narrow panel ends up with
   some comments beside and some below, which reads as broken rather than
   as responsive. Below the width where comments reliably fit, every
   comment in the panel drops — consistent by panel, not by line. The
   panel is its own container, so this keys off the panel's real width and
   works the same whether it is standalone or in a squeezed column. */
.cb-pane { container-type: inline-size; container-name: cbpane; }
@container cbpane (max-width: 560px) {
  .cb-comment { display: block !important; margin-left: 0; }
}
/* A real label element instead of the ::before one, for panels built in
   Element Studio — a pseudo-element can't be typed into on the page, and
   the whole point of naming a box is that you name it yourself. Identical
   look; the pane drops its pseudo-label when it carries one of these.
   text-transform keeps the strip's shape whatever case you type in. */
.cb-pane.cb-labelled::before { content: none; }
.cb-pane-label { display: block; padding: 0.5rem 0.95rem;
  font-family: 'Outfit', sans-serif; font-size: 0.62rem; font-weight: 700;
  letter-spacing: 1.6px; text-transform: uppercase; color: var(--cb-label-col);
  background: rgba(255,255,255,0.02); border-bottom: 1px solid rgba(255,255,255,0.07); }
/* a panel beside a free column, or two panels side by side */
.cb-panelgrid { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr);
  gap: 1.6rem; align-items: start; margin-bottom: 1rem; }
@media (max-width: 700px) { .cb-panelgrid { grid-template-columns: 1fr; } }

.cb-editgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.1rem; align-items: start; }
/* Two panels stacked in a column. .cb-pane + .cb-pane covers two panes in
   ONE wrap (the "Both" mode); two separate code elements one above the
   other are .cb-wrap siblings, which nothing was spacing at all — they sat
   flush, reading as one window with a stray header partway down. */
.cb-pane + .cb-pane { margin-top: 1rem; }
.cb-wrap + .cb-wrap { margin-top: 1.75rem; }
.cb-numbered { display: flex; flex-direction: column; }
.cb-num-row { display: flex; gap: 0.8rem; align-items: flex-start; }
.cb-ln { flex: none; width: 1.6em; text-align: right; color: rgba(255,255,255,0.32); font-size: 0.85em; user-select: none; }
.cb-num-content { flex: 1; min-width: 0; }
.cb-line { display: block; margin: 2px 0; font-weight: 400; }
.cb-comment-line { color: rgba(255,255,255,0.42); font-weight: 400; }
.cb-comment { color: rgba(255,255,255,0.42); font-weight: 400; }
.cb-code-text { color: #e8ecf3; font-weight: 400; }
.cb-kw { font-weight: 400; color: #fff; }
.cb-arrow { font-weight: 400; }
/* The chip border matches the hairline that separates a panel's title strip
   from its body (0.07), one shade lighter so the chip still reads as an
   object — Robin, 12 Aug 2026: the 0.22 white ring was shouting. */
.cb-expr { border: 1px solid rgba(255,255,255,0.11); border-radius: 5px; padding: 2px 7px; background: rgba(255,255,255,0.04); display: inline-block; font-weight: 400; }
.cb-val { border: 1px solid rgba(255,255,255,0.22); margin: 1px; padding: 2px 5px; display: inline-block; background: rgba(255,255,255,0.06); font-weight: 400; }
.cb-cond { border: 1px solid rgba(255,255,255,0.22); border-radius: 30px; padding: 2px 12px; display: inline-block; background: rgba(255,255,255,0.06); font-weight: 400; }
.cb-list { border: 1px solid rgba(255,255,255,0.22); padding: 2px 5px; display: inline-block; background: rgba(255,255,255,0.06); font-weight: 400; }
.cb-control, .cb-proc { background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.18); border-radius: 6px; padding: 7px; margin: 2px 22px 2px 0; display: table; max-width: 100%; }
.cb-control-header, .cb-proc-header { display: inline; font-weight: 400; }
.cb-body { display: block; margin-left: 20px; margin-top: 2px; }
.cb-else { display: block; margin-top: 3px; font-weight: 400; }
/* Code, note below (repeated per line) — stacked, not side-by-side. A
   note is a sentence of unpredictable length; the code above it is
   often just a few characters. No side-by-side alignment of two things
   that differently sized ever reads as "lined up," so this sidesteps
   the problem instead of fighting it: code on top, note underneath,
   both flush left, in normal document flow — nothing to center or
   balance against anything else. */
.cb-side-row { display: flex; flex-direction: column; align-items: flex-start; gap: 0.5rem; margin-bottom: 1.2rem; }
.cb-note { font-size: 0.95em; line-height: 1.6; color: rgba(255,255,255,.8); font-weight: 400; max-width: 60ch; }
/* "Center on page" toggle (Element Studio) — centers the whole code
   block (or, in the stacked layout, each code+note pair) as a unit
   instead of stretching it to fill the full width, which would just
   strand it looking left-anchored with dead space to the right.
   cb-numbered deliberately keeps its default align-items:stretch (NOT
   center) here — center would align each LINE independently by its
   own width, breaking the shared left edge real code is supposed to
   have. Stretch makes every line match the widest line's width, so
   they all still start flush-left with each other; it's the resulting
   block AS A WHOLE (sized to that widest line) that cb-wrap centers. */
.cb-wrap.cb-center { display: flex; flex-direction: column; align-items: center; }
.cb-wrap.cb-center .cb-control, .cb-wrap.cb-center .cb-proc { margin-left: auto; margin-right: 2px; }
/* "Right" alignment (Element Studio, plain Code block) — same shrink-
   to-fit-then-position trick as cb-center, just flex-end instead of
   center. Useful when Code sits in one column of a hand-built 2-col
   layout (paragraph in the other) and should hug the shared gutter
   rather than float in the middle of its own column. */
.cb-wrap.cb-right { display: flex; flex-direction: column; align-items: flex-end; }
.cb-wrap.cb-right .cb-control, .cb-wrap.cb-right .cb-proc { margin-left: auto; margin-right: 2px; }
/* Code + explanation's 2-column grid. minmax(0,1fr) — not plain 1fr — on
   purpose: a bare `1fr` track's automatic minimum is its content's
   min-content size, so a long-enough unbroken line in one column can
   still force that column past its "half" and eat into the other one.
   minmax(0,1fr) zeroes that floor out, making this an actually-hard
   50/50 split regardless of what either side contains. */
.bx-explain-grid { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 2rem; align-items: start; margin-bottom: 1rem; }
@media (max-width: 700px) { .bx-explain-grid { grid-template-columns: 1fr; } }
/* the mobile breakpoint below matches on the iframe's actual viewport
   width, which stays true regardless of how wide this element's own box
   is forced to be — so the desktop grid needs !important to win over it
   while authoring. */
.es-preview .cb-editgrid { width: 820px; max-width: none; margin-left: auto; margin-right: auto; grid-template-columns: 1fr 1fr !important; }
@media (max-width: 700px) { .cb-editgrid { grid-template-columns: 1fr; } }
@media (max-width: 768px) {
  div[style*="grid-template-columns:1fr 1fr 1fr"], div[style*="grid-template-columns: 1fr 1fr 1fr"], div[style*="grid-template-columns:1fr 1fr"], div[style*="grid-template-columns: 1fr 1fr"] { grid-template-columns: 1fr !important; }
  img[style*="width:90%"], img[style*="width: 90%"], img[style*="width:80%"], img[style*="width: 80%"] { width: 100% !important; }
  .ccard { width: 100%; }
}
.vocab-pill { display: inline-block; font-size: 0.78rem; font-weight: 800; letter-spacing: 0.5px; padding: 0.15rem 0.55rem; border-radius: 4px; background: rgba(var(--c-pink-rgb),0.15); border: 1px solid rgba(var(--c-pink-rgb),0.35); color: var(--c-pink); font-family: 'Outfit', sans-serif; vertical-align: middle; margin: 0 0.1rem; }
/* No border-top here on purpose: the section already draws one rule — the
   .tb-section-line running out from the label — and a second full-width
   line sitting right above it read as a double underline stacked on
   nothing. The margin/padding alone give the section its breathing room. */
.tb-section { margin-top: 2.5rem; padding-top: 2rem; }
.tb-section-header { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 1.5rem; }
.tb-section-label { font-size: 1.5rem; font-weight: 500; letter-spacing: 3px; color: rgba(255,255,255,.93); }
.tb-section-line { flex: 1; height: 1px; background: rgba(255,255,255,0.08); }
/* minmax(0,1fr), not 1fr. A plain 1fr floors at the track's min-content
   width, and a code panel's min-content is its widest line — so the panel
   held ~286px while the prose column next to it was crushed to 74px. The
   two columns are meant to be equal; this makes them equal. */
.tb-columns { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 2.5rem; margin-bottom: 1.5rem; }
.tb-columns.one-col { grid-template-columns: minmax(0,1fr); }
.tb-col h3 { font-size: 1.2rem; font-weight: 900; color: var(--c-gold); margin-bottom: 0.6rem; letter-spacing: 0.3px; }
.tb-col h4 { font-size: 1.2rem; font-weight: 900; color: var(--c-gold); margin-bottom: 0.6rem; letter-spacing: 0.3px; }
.tb-col p { font-size: 1rem; color: rgba(255,255,255,.85); line-height: 1.75; margin-bottom: 0.75rem; }
.tb-col p:last-child { margin-bottom: 0; }
.tb-col strong { color: rgba(255,255,255,.93); font-weight: 700; }
.tb-col em { color: rgba(255,255,255,0.55); font-style: italic; }
.abstraction-callout { background: rgba(var(--c-purple-rgb),0.07); border: 1px solid rgba(var(--c-purple-rgb),0.25); border-left: 4px solid var(--c-purple); border-radius: 12px; padding: 1rem 1.3rem; margin-top: 1.5rem; }
.abstraction-callout-head { font-weight: 800; font-size: 0.78rem; letter-spacing: 1.5px; text-transform: uppercase; color: var(--c-purple); margin-bottom: 0.4rem; display: flex; align-items: center; gap: 6px; }
.abstraction-callout p { font-size: 0.92rem; color: rgba(255,255,255,.8); line-height: 1.65; margin: 0; }
@media (max-width: 768px) { .tb-columns { grid-template-columns: 1fr; gap: 0; } }
/* Above 768px the sidebar is on-canvas and the window is NOT what these
   columns get. The maths: 232px sidebar + 2 x 4rem of .main-content
   padding = 360px the page never sees. Two columns stop being able to
   hold a code panel and a paragraph at about 760px of real content, so
   the window number that matters is 760 + 360 = 1120. Anything narrower
   stacks. If the sidebar width or that padding ever changes, this number
   moves with them. */
@media (min-width: 769px) and (max-width: 1120px) { .tb-columns { grid-template-columns: 1fr; gap: 0; } }
.hide-h1 h1 { display: none; }
.nanum-hero { font-size: 3.325rem !important; line-height: 1.1 !important; }
.nanum-sub  { font-size: 2.19rem !important; max-width: none !important; }
.context-block-cyan, .context-block-gold, .context-block-pink, .context-block-purple { border-radius: 12px; padding: 1.25rem 1.5rem; margin-bottom: 1.5rem; }
.context-block-title { font-size: 0.78rem; font-weight: 800; letter-spacing: 1.8px; text-transform: uppercase; margin-bottom: 0.6rem; }
.context-block-cyan .context-block-title, .context-block-gold .context-block-title, .context-block-pink .context-block-title, .context-block-purple .context-block-title { font-size: 1rem; color: rgba(255,255,255,.93); }
.context-block-cyan p, .context-block-gold p, .context-block-pink p, .context-block-purple p { color: rgba(255,255,255,.8); font-size: 1rem; line-height: 1.65; margin: 0; }
.context-block-cyan { background: rgba(var(--c-cyan-rgb),0.05); border: 1px solid rgba(var(--c-cyan-rgb),0.2); border-left: 4px solid var(--c-cyan); }
.context-block-cyan .context-block-title { color: var(--c-cyan); }
.context-block-gold { background: rgba(var(--c-gold-rgb),0.06); border: 1px solid rgba(var(--c-gold-rgb),0.2); border-left: 4px solid var(--c-gold); }
.context-block-gold .context-block-title { color: var(--c-gold); }
.context-block-pink { background: rgba(var(--c-pink-rgb),0.06); border: 1px solid rgba(var(--c-pink-rgb),0.2); border-left: 4px solid var(--c-pink); }
.context-block-pink .context-block-title { color: var(--c-pink); }
.context-block-purple { background: rgba(var(--c-purple-rgb),0.07); border: 1px solid rgba(var(--c-purple-rgb),0.2); border-left: 4px solid var(--c-purple); }
.context-block-purple .context-block-title { color: var(--c-purple); }
.ccard-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin: 0.75rem 0 1.5rem; }
.pairbox { background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.1); border-radius: 14px; padding: 1.25rem 1.4rem; display: flex; flex-direction: column; gap: 0.55rem; }
.ccard-label { font-size: 0.68rem; font-weight: 900; letter-spacing: 2px; text-transform: uppercase; padding: 0.2rem 0.6rem; border-radius: 4px; display: inline-block; align-self: flex-start; }
.ccard-label.pink   { background: rgba(var(--c-pink-rgb),0.15);   color: var(--c-pink);  border: 1px solid rgba(var(--c-pink-rgb),0.3); }
.ccard-label.cyan   { background: rgba(var(--c-cyan-rgb),0.1);    color: var(--c-cyan);  border: 1px solid rgba(var(--c-cyan-rgb),0.25); }
.ccard-label.gold   { background: rgba(var(--c-gold-rgb),0.12);   color: var(--c-gold);  border: 1px solid rgba(var(--c-gold-rgb),0.3); }
.ccard-label.green  { background: rgba(var(--c-green-rgb),0.1);    color: var(--c-green);  border: 1px solid rgba(var(--c-green-rgb),0.25); }
.ccard-label.purple { background: rgba(var(--c-purple-rgb),0.1);  color: var(--c-purple);  border: 1px solid rgba(var(--c-purple-rgb),0.25); }
.ccard-body { font-size: 1rem; line-height: 1.65; color: rgba(255,255,255,.87); }
.ccard-example { font-size: 0.84rem; color: rgba(255,255,255,0.4); font-style: italic; border-top: 1px solid rgba(255,255,255,0.06); padding-top: 0.5rem; margin-top: 0.2rem; }
.color-tile { display: flex; align-items: center; gap: 0.65rem; padding: 0.75rem 1.1rem; border-radius: 10px; font-size: 0.78rem; font-weight: 900; letter-spacing: 2px; text-transform: uppercase; margin-bottom: 1rem; color: #000; }
.color-tile svg { flex-shrink: 0; }
.color-tile.cyan   { background: var(--c-cyan); }
.color-tile.gold   { background: var(--c-gold); }
.color-tile.green  { background: var(--c-green); }
.color-tile.purple { background: var(--c-purple); color: #fff; }
.color-tile.pink { background: var(--c-pink); color: #fff; }
.color-tile.orange { background: var(--c-orange); color: #fff; }
.abstraction-callout { background: rgba(var(--c-purple-rgb),0.07); border: 1px solid rgba(var(--c-purple-rgb),0.25); border-left: 4px solid var(--c-purple); border-radius: 12px; padding: 1rem 1.3rem; margin-top: 1.5rem; font-size: 1rem; line-height: 1.65; color: rgba(255,255,255,.85); }
.abstraction-label { display: block; font-size: 0.72rem; font-weight: 900; letter-spacing: 1.8px; text-transform: uppercase; color: var(--c-purple); margin-bottom: 0.4rem; }
.vocab-pill.cyan   { background: rgba(var(--c-cyan-rgb),0.1);   border-color: rgba(var(--c-cyan-rgb),0.3);   color: var(--c-cyan); }
.vocab-pill.gold   { background: rgba(var(--c-gold-rgb),0.1);   border-color: rgba(var(--c-gold-rgb),0.3);   color: var(--c-gold); }
.vocab-pill.green  { background: rgba(var(--c-green-rgb),0.1);   border-color: rgba(var(--c-green-rgb),0.3);   color: var(--c-green); }
.vocab-pill.purple { background: rgba(var(--c-purple-rgb),0.1); border-color: rgba(var(--c-purple-rgb),0.3); color: var(--c-purple); }
@media (max-width: 768px) { .ccard-pair { grid-template-columns: 1fr; } }
.content-block img { width: 85%; display: block; margin: 0 auto 2rem; border-radius: 12px; aspect-ratio: 16 / 9; object-fit: cover; }
.card-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin: 0.75rem 0 1.5rem; }
.card-grid.three { grid-template-columns: 1fr 1fr 1fr; }
.card-grid.four { grid-template-columns: 1fr 1fr 1fr 1fr; }
.card-grid.solo { grid-template-columns: 1fr; max-width: 680px; }
@media (max-width: 768px) { .card-grid, .card-grid.three, .card-grid.four { grid-template-columns: 1fr; } }
@media (min-width: 769px) and (max-width: 1100px) { .card-grid.three, .card-grid.four { grid-template-columns: 1fr 1fr; } }
@media (max-width: 768px) { .content-block img { width: 100% !important; max-width: 100% !important; } }
@media (max-height: 500px) and (orientation: landscape) {
  body, html { overflow: auto; height: auto; }
  .app-wrapper { flex-direction: column; height: auto; min-height: 100vh; }
  .hamburger { display: flex; }
  .sidebar { position: fixed; left: -232px; top: 0; height: 100vh; z-index: 10; transition: left 0.3s ease; }
  .sidebar.open { left: 0; }
  .main-content { padding: 1.5rem 1rem; overflow: visible; height: auto; margin-top: 3rem; }
  .content-container { max-width: 100%; }
  .vocab-grid, .vocab-grid.triple, .compare-grid { grid-template-columns: 1fr; }
  .content-block img { width: 100% !important; max-width: 100% !important; }
  div[style*="grid-template-columns:1fr 1fr"], div[style*="grid-template-columns: 1fr 1fr"] { grid-template-columns: 1fr !important; }
}
.nav-sub-list { display: none; }
.nav-chapter.open .nav-sub-list { display: block; }
.sampling-diagram-container { width: 100%; max-width: 1000px; margin: 2rem auto; background: rgba(20, 18, 30, 0.6); border-radius: 14px; padding: 2rem; box-sizing: border-box; box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3); }
.sampling-diagram-container .diagram-label { font-family: 'Outfit', sans-serif; font-size: 1rem; font-weight: 500; color: #fff; margin-bottom: 1.5rem; letter-spacing: 0.5px; }
.sampling-diagram-container svg { width: 100%; display: block; }

.number-systems-diagram { width: 100%; max-width: 1100px; margin: 0 auto; background: transparent; box-sizing: border-box; display: flex; flex-direction: column; }
.diagram-blurb { text-align: center; line-height: 1.4; margin: 1.5rem auto 0.75rem; max-width: 950px; font-family: cursive !important; }
.main-question { color: rgba(255, 255, 255, 0.95); font-size: clamp(1.05rem, 2.5vw, 1.8rem); }
.footer-blurb { color: var(--c-green); font-size: clamp(1rem, 2.3vw, 1.7rem); margin-top: 1.25rem; }
.highlight-cyan { color: var(--c-cyan); font-weight: bold; }
.highlight-pink { color: var(--c-pink); font-weight: bold; }
.highlight-gold { color: var(--c-gold); font-weight: bold; }
.number-systems-diagram svg { width: 100%; height: auto; display: block; }
.algorithm-component { width: 100%; max-width: 1100px; margin: 0 auto; padding: 1.5rem; display: flex; flex-direction: column; background: transparent; box-sizing: border-box; }
.algorithm-component, .algorithm-component .algorithm-header, .algorithm-component .algorithm-definition { font-family: cursive; text-align: center; }
.algorithm-component .algorithm-header { color: var(--c-gold); font-size: clamp(2rem, 4vw, 2.75rem); letter-spacing: 2px; margin: 0 0 1.25rem 0; }
.algorithm-component .algorithm-definition { color: rgba(255, 255, 255, 0.95); font-size: clamp(1.3rem, 2.5vw, 1.8rem); line-height: 1.4; margin: 0 auto 1rem auto; max-width: 950px; }
.algorithm-component svg { width: 100%; height: auto; display: block; }
.sketch-line { fill: none; stroke: var(--c-gold); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.sketch-step { fill: none; stroke: var(--c-cyan); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.sketch-decision { fill: none; stroke: var(--c-pink); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.sketch-terminus { fill: none; stroke: var(--c-purple); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.algorithm-component svg text, .algorithm-component svg tspan, .algorithm-component text { font-family: cursive !important; }
.nb-container-compression { display: flex; flex-direction: column; align-items: center; justify-content: flex-start; width: 100%; max-width: 800px; margin: 0 auto; padding: 2rem 2rem; box-sizing: border-box; background: transparent; }
.nb-branches-row-compression { display: flex; justify-content: space-between; width: 100%; max-width: 1000px; gap: 2.5rem; margin-top: -10px; }
.nb-branch-desc-compression { flex: 1; text-align: center; padding: 0 0.5rem; box-sizing: border-box; }
.nb-branch-text-compression { font-family: cursive; font-size: clamp(0.95rem, 2.2vw, 1.2rem); line-height: 1.45; color: #ffffff; margin: 0; padding: 0; }
.nb-svg-compression { width: 100%; height: auto; display: block; }
@media (max-width: 767px) { .nb-container-think { display: none !important; } }


/* ═══════════════════════════════════════════════════════════════════
   UNIT 1.1 NUMBER SYSTEMS — shared house style
   Used across bin_what_is_binary, bin_conversion, bin_values,
   bin_overflow, bin_review. Do not duplicate these inline again —
   add new shared rules here, keep only widget-specific CSS inline.
   ═══════════════════════════════════════════════════════════════════ */
/* NOTE: this block was pasted from a standalone widget page. Its global
   @import (Source Code Pro), `* { box-sizing }` reset, and
   `body { background:#000; padding }` rule were removed during the summer
   2026 cleanup — they leaked into the app shell (the app already sets
   box-sizing and background in the header rules above). Only the
   widget-scoped classes remain. */
.wrap { max-width: 760px; margin: 0 auto; }
.vocab-row { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 2rem; justify-content: center; }
.n1vocab-pill {
  background: rgba(var(--c-cyan-rgb),0.08);
  border: 1px solid rgba(var(--c-cyan-rgb),0.3);
  color: var(--c-cyan);
  padding: 0.35rem 0.85rem;
  border-radius: 999px;
  font-size: 0.85rem;
  font-weight: 700;
}
p.body-text { font-size: 1rem; line-height: 1.7; color: rgba(255,255,255,.87); margin-bottom: 1.25rem; }
p.body-text:last-child { margin-bottom: 0; }
p.body-text strong { color: #fff; }
.n1block { margin-bottom: 2rem; }
.n1tile {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.85rem 1.1rem;
  border-radius: 12px 12px 0 0;
  font-weight: 900;
  font-size: 1.05rem;
}
.n1tile.cyan { background: var(--c-cyan); color: #003d3b; }
.n1tile.green { background: var(--c-green); color: #003317; }
.n1tile.gold { background: var(--c-gold); color: #181818; }
.n1tile.pink { background: var(--c-pink); color: #fff; }
.n1tile.magenta { background: var(--c-pink); color: #fff; }
.n1tile.orange { background: var(--c-orange); color: #fff; }
.n1tile.purple { background: var(--c-purple); color: #fff; }
.n1tile svg { flex-shrink: 0; }
.block-body {
  background: rgba(255,255,255,0.03);
  border: 1px solid rgba(255,255,255,0.08);
  border-top: none;
  border-radius: 0 0 12px 12px;
  padding: 1.4rem 1.4rem 1.5rem;
}
.callout-exam {
  background: rgba(var(--c-gold-rgb),0.06);
  border: 1px solid rgba(var(--c-gold-rgb),0.25);
  border-left: 4px solid var(--c-gold);
  border-radius: 10px;
  padding: 1rem 1.1rem;
  margin-top: 1.25rem;
}
.callout-exam-label { font-size: 0.72rem; font-weight: 900; letter-spacing: 0.8px; text-transform: uppercase; color: var(--c-gold); margin-bottom: 0.35rem; }
.callout-exam-text { font-size: 0.95rem; line-height: 1.6; color: rgba(255,255,255,.9); }
.bwtab{flex:1;padding:.5rem 1rem;border-radius:8px;border:1px solid rgba(255,255,255,.12);background:rgba(255,255,255,.04);color:rgba(255,255,255,.4);font-size:.85rem;font-weight:700;cursor:pointer;letter-spacing:.5px;transition:all .18s;font-family:inherit}
.bwtab.bwact{background:rgba(var(--c-cyan-rgb),.1);border-color:var(--c-cyan);color:var(--c-cyan)}
.bwtile-col{display:flex;flex-direction:column;align-items:center;gap:5px;flex:1;min-width:0}
.bw0{background:rgba(255,255,255,.03);border:2px solid rgba(255,255,255,.1);color:rgba(255,255,255,.2)}
.bw1{background:rgba(255,255,255,.06);border:2px solid rgba(255,255,255,.35);color:#fff}
.bwlit{background:rgba(255,255,255,.03);border:2px solid var(--c-green);color:var(--c-green);cursor:pointer}
.bwlit:hover{transform:scale(1.06)}
.bw0:hover{transform:scale(1.06)}
.bwgreen{background:rgba(var(--c-green-rgb),.18);border:2px solid var(--c-green);color:var(--c-green);box-shadow:0 0 12px rgba(var(--c-green-rgb),.35)}
.bwhint{text-align:center;font-size:.75rem;color:rgba(255,255,255,.25);margin:.1rem 0 .4rem}
.bwans-row{display:flex;align-items:center;justify-content:center;gap:.6rem;margin:.3rem 0 .2rem}
.bweq-sym{font-size:1.8rem;font-weight:900;color:rgba(255,255,255,.2)}
.bwans-inp{background:rgba(255,255,255,.06);border:2px solid rgba(var(--c-cyan-rgb),.4);border-radius:8px;color:#fff;font-size:1.8rem;font-weight:800;padding:.25rem .6rem;width:110px;text-align:center;outline:none;font-family:inherit;-moz-appearance:textfield}
.bwans-inp:focus{border-color:var(--c-cyan)}
.bwans-inp::-webkit-inner-spin-button,.bwans-inp::-webkit-outer-spin-button{-webkit-appearance:none}
.bwchkbtn{padding:.42rem 1.1rem;border-radius:8px;font-size:.88rem;font-weight:700;cursor:pointer;font-family:inherit;border:1px solid rgba(var(--c-cyan-rgb),.4);background:rgba(var(--c-cyan-rgb),.08);color:var(--c-cyan)}
.bwnxtbtn{padding:.42rem 1.4rem;border-radius:8px;font-size:.88rem;font-weight:700;cursor:pointer;font-family:inherit;border:1px solid rgba(var(--c-green-rgb),.4);background:rgba(var(--c-green-rgb),.08);color:var(--c-green)}
.bwfb{text-align:center;font-size:.95rem;font-weight:700;min-height:1.4rem;margin:.3rem 0}
.bwfbok{color:var(--c-green)}
.bwfbno{color:rgba(var(--c-orange-rgb),.8)}
.bwcurscore{text-align:center;font-size:.82rem;color:rgba(255,255,255,.3);margin:.1rem 0 .3rem}
.bwnewbtn{display:block;margin:.5rem auto 0;padding:.4rem 1.6rem;border-radius:8px;border:1px solid rgba(var(--c-cyan-rgb),.25);background:rgba(var(--c-cyan-rgb),.05);color:rgba(var(--c-cyan-rgb),.6);font-size:.82rem;font-weight:700;cursor:pointer;font-family:inherit;transition:all .15s}
.bwnewbtn:hover{background:rgba(var(--c-cyan-rgb),.12);border-color:var(--c-cyan);color:var(--c-cyan)}
.bw-widget-wrap{background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.08);border-radius:14px;padding:1.25rem;margin-top:0.25rem;}
.n1notes { margin-bottom: 1rem; }
.n1notes-header { margin-bottom: 1rem; }
.n1notes-label {
  font-size: 0.78rem;
  font-weight: 900;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: rgba(255,255,255,0.4);
  border-bottom: 1px solid rgba(255,255,255,0.1);
  display: block;
  padding-bottom: 0.6rem;
}
.n1notes-columns { display: grid; grid-template-columns: 1fr 1fr; gap: 1.75rem; }
.n1notes-col h3 { font-size: 1.02rem; color: var(--c-cyan); margin: 0 0 0.6rem; }
.n1notes-col h4 { font-size: 0.92rem; color: var(--c-gold); margin: 1.1rem 0 0.5rem; }
.n1notes-col p { font-size: 0.92rem; line-height: 1.65; color: rgba(255,255,255,.83); margin-bottom: 0.9rem; }
.n1notes-col ol { padding-left: 1.2rem; margin: 0 0 0.9rem; }
.n1notes-col ol li { font-size: 0.92rem; line-height: 1.6; color: rgba(255,255,255,.83); margin-bottom: 0.45rem; }
.n1notes-col .n1vocab-pill { font-size: 0.78rem; padding: 0.15rem 0.55rem; }
.quiz-head { font-size: 1.05rem; font-weight: 800; color: var(--c-pink); margin-bottom: 0.25rem; }
.quiz-sub { color: rgba(255,255,255,0.4); font-size: 0.85rem; margin-bottom: 1.5rem; }
.n1q-box { background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.08); border-radius: 14px; padding: 1.5rem; }
.n1q-parts { font-size: 0.95rem; line-height: 1.8; color: rgba(255,255,255,.9); margin-bottom: 1.1rem; }
.n1q-parts .roman { color: var(--c-cyan); font-weight: 800; margin-right: 0.4rem; }
.n1q-stem { font-size: 1rem; font-weight: 700; color: #fff; margin-bottom: 1rem; }
.n1q-opt:hover:not(:disabled) { border-color: rgba(var(--c-cyan-rgb),0.4); }
.n1q-opt.correct { background: rgba(var(--c-green-rgb),0.14); border-color: var(--c-green); color: var(--c-green); }
.n1q-opt.wrong { background: rgba(var(--c-orange-rgb),0.12); border-color: var(--c-orange); color: var(--c-orange); }
.n1q-opt:disabled { cursor: default; }
.n1q-fb { font-size: 0.9rem; line-height: 1.55; margin-top: 0.75rem; padding: 0.85rem 1rem; border-radius: 8px; display: none; }
.n1q-fb.show { display: block; }
.n1q-fb.ok { background: rgba(var(--c-green-rgb),0.08); border: 1px solid rgba(var(--c-green-rgb),0.25); color: rgba(255,255,255,.9); }
.n1q-fb.no { background: rgba(var(--c-orange-rgb),0.08); border: 1px solid rgba(var(--c-orange-rgb),0.25); color: rgba(255,255,255,.9); }
.n1q-next {
  margin-top: 1rem;
  background: rgba(var(--c-cyan-rgb),0.1);
  border: 1px solid var(--c-cyan);
  color: var(--c-cyan);
  padding: 0.55rem 1.4rem;
  border-radius: 8px;
  font-family: inherit;
  font-weight: 700;
  cursor: pointer;
  display: none;
}
.n1q-next.show { display: inline-block; }
.n1q-done { text-align: center; padding: 2rem 1rem; }
.n1n1q-done-score { font-size: 2.5rem; font-weight: 900; color: var(--c-gold); }
.n1q-tag { display: inline-block; font-size: 0.68rem; font-weight: 900; letter-spacing: 0.5px; text-transform: uppercase; padding: 0.2rem 0.55rem; border-radius: 999px; }
.n1q-opt.picked { border-color: var(--c-cyan); background: rgba(var(--c-cyan-rgb),0.08); color: var(--c-cyan); }
.n1q-submit { margin-top: 0.5rem; background: rgba(var(--c-gold-rgb),0.1); border: 1px solid var(--c-gold); color: var(--c-gold); padding: 0.55rem 1.4rem; border-radius: 8px; font-family: inherit; font-weight: 700; cursor: pointer; }
.step-list { display: flex; flex-direction: column; gap: 0.6rem; margin: 1rem 0 1.5rem; }
.step-row { display: flex; gap: 0.75rem; align-items: flex-start; }
.step-num {
  width: 26px; height: 26px; flex-shrink: 0;
  border-radius: 50%;
  background: rgba(var(--c-gold-rgb),0.12);
  border: 1px solid rgba(var(--c-gold-rgb),0.4);
  color: var(--c-gold);
  font-weight: 900;
  font-size: 0.85rem;
  display: flex; align-items: center; justify-content: center;
}
.step-text { font-size: 0.95rem; line-height: 1.6; color: rgba(255,255,255,.87); padding-top: 0.15rem; }
.step-text strong { color: #fff; }
.worked-box {
  background: rgba(var(--c-cyan-rgb),0.04);
  border: 1px solid rgba(var(--c-cyan-rgb),0.18);
  border-radius: 10px;
  padding: 1rem 1.1rem;
  margin-bottom: 1.25rem;
}
.worked-label { font-size: 0.72rem; font-weight: 900; letter-spacing: 0.8px; text-transform: uppercase; color: var(--c-cyan); margin-bottom: 0.5rem; }
.worked-equation {
  display: flex; align-items: center; justify-content: center; flex-wrap: wrap;
  gap: 0.5rem; font-family: 'Source Code Pro', monospace; font-size: 1.2rem; font-weight: 800;
  color: #fff; margin: 0.6rem 0 0.2rem; padding: 0.9rem; background: rgba(var(--c-cyan-rgb),0.05);
  border: 1px solid rgba(var(--c-cyan-rgb),0.2); border-radius: 10px;
}
.worked-equation .term { color: var(--c-cyan); }
.worked-equation .plus { color: rgba(255,255,255,0.3); font-weight: 400; }
.worked-equation .answer { color: var(--c-gold); font-size: 1.5rem; }
.trace-list { display: flex; flex-direction: column; gap: 5px; margin: 0.9rem 0 0.2rem; }
.trace-row.yes { background: rgba(var(--c-green-rgb),0.06); }
.trace-colval {
  font-family: 'Source Code Pro', monospace; font-weight: 800; font-size: 0.9rem;
  color: var(--c-gold); text-align: center;
}
.trace-colval.crossed { color: rgba(255,255,255,0.22); text-decoration: line-through; font-weight: 700; }
.trace-text { font-size: 0.85rem; color: rgba(255,255,255,.8); }
.n1q-progress { font-size: 0.78rem; color: rgba(255,255,255,0.35); font-weight: 700; margin-bottom: 0.4rem; }
.n1q-opt {
  display: block; width: 100%; text-align: left;
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.12);
  color: rgba(255,255,255,.85);
  padding: 0.7rem 1rem;
  border-radius: 8px;
  margin-bottom: 0.5rem;
  font-family: inherit;
  font-size: 0.9rem;
  cursor: pointer;
  transition: all 0.12s;
}
@media (max-width: 560px) {
  .n1notes-columns { grid-template-columns: 1fr; }
}
.ladder-table { width: 100%; border-collapse: collapse; margin: 1rem 0 0.5rem; }
.ladder-table th, .ladder-table td { text-align: center; padding: 0.45rem 0.3rem; font-family: 'Source Code Pro', monospace; font-size: 0.9rem; }
.ladder-table td.bits-cell { color: var(--c-cyan); font-weight: 800; }
.ladder-table td.pat-cell { color: var(--c-gold); font-weight: 800; border-top: 1px solid rgba(255,255,255,0.08); }
.img-slot {
  border: 2px dashed rgba(255,255,255,0.2);
  border-radius: 12px;
  padding: 2rem 1rem;
  text-align: center;
  color: rgba(255,255,255,0.3);
  font-size: 0.85rem;
  font-weight: 700;
  margin-top: 1.25rem;
}

/* ═══════════════════════════════════════════════════════════════════
   PRACTICE / REVIEW SYSTEM — Big Idea 3 rebuild
   Two question types, never blended (build spec Part 1):
   PRACTICE (cyan) = unscored click-through traces; REVIEW (gold) =
   exam-format generator embed. Banner colors are fixed identities;
   trace reveals cycle the full site palette (disco directive).
   ═══════════════════════════════════════════════════════════════════ */
.qtype-section { margin-top: 2.5rem; }
.qtype-banner {
  display: flex; align-items: center; gap: 0.7rem;
  padding: 0.85rem 1.25rem;
  border-radius: 12px 12px 0 0;
  font-weight: 900; font-size: 0.95rem; letter-spacing: 1px; text-transform: uppercase;
}
.qtype-banner .qtype-icon { font-size: 1.1rem; }
.qtype-banner .qtype-sub {
  font-weight: 400; text-transform: none; letter-spacing: 0; font-size: 0.82rem;
  opacity: 0.7; margin-left: auto;
}
.qtype-banner.practice { background: rgba(var(--c-cyan-rgb),0.12); border: 1px solid rgba(var(--c-cyan-rgb),0.35); border-bottom: none; color: var(--c-cyan); }
.qtype-banner.review   { background: rgba(var(--c-gold-rgb),0.12);  border: 1px solid rgba(var(--c-gold-rgb),0.35);  border-bottom: none; color: var(--c-gold); }
.qtype-body {
  border-radius: 0 0 12px 12px;
  border: 1px solid rgba(255,255,255,0.08);
  border-top: none;
  padding: 1.5rem;
}
.qtype-body.practice-body { background: rgba(var(--c-cyan-rgb),0.03); }
.qtype-body.review-body   { background: rgba(var(--c-gold-rgb),0.03); }

/* PRACTICE — trace card */
.trace-card {
  background: rgba(0,0,0,0.35);
  border: 1px solid rgba(var(--c-cyan-rgb),0.15);
  border-radius: 12px;
  padding: 1.25rem 1.4rem;
  margin-bottom: 1rem;
}
.trace-card-label { font-size: 0.78rem; font-weight: 900; letter-spacing: 1px; text-transform: uppercase; color: rgba(var(--c-cyan-rgb),0.6); margin-bottom: 0.6rem; }
.trace-card-code {
  font-family: 'Source Code Pro', monospace;
  font-size: 0.95rem; line-height: 1.9;
  color: rgba(255,255,255,.9);
  background: rgba(0,0,0,0.4);
  border-radius: 8px; padding: 1rem 1.2rem;
  margin-bottom: 1rem; white-space: pre-wrap;
}
.trace-reveal-row {
  display: flex; align-items: center; gap: 0.75rem;
  padding: 0.6rem 0.9rem; margin-bottom: 0.4rem;
  background: rgba(255,255,255,0.03); border-radius: 8px;
  border: 1px solid rgba(255,255,255,0.06);
  font-size: 0.9rem; color: rgba(255,255,255,0.5);
  cursor: pointer; transition: all 0.2s;
}
.trace-reveal-row:hover:not(.revealed) { border-color: rgba(255,255,255,0.2); }
.trace-reveal-row .trace-step-num {
  width: 22px; height: 22px; border-radius: 50%; flex-shrink: 0;
  background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.3);
  color: rgba(255,255,255,0.6); font-weight: 900; font-size: 0.75rem;
  display: flex; align-items: center; justify-content: center;
}
/* Disco reveal — rows light up cycling the full site palette */
@keyframes disco-pop { 0% { transform: scale(0.985); } 60% { transform: scale(1.01); } 100% { transform: scale(1); } }
.trace-reveal-row.revealed { animation: disco-pop 0.25s ease; cursor: default; }
.trace-reveal-row.revealed:nth-child(5n+1) { color: var(--c-pink); border-color: rgba(var(--c-pink-rgb),0.35);  background: rgba(var(--c-pink-rgb),0.06); }
.trace-reveal-row.revealed:nth-child(5n+2) { color: var(--c-cyan); border-color: rgba(var(--c-cyan-rgb),0.35);  background: rgba(var(--c-cyan-rgb),0.06); }
.trace-reveal-row.revealed:nth-child(5n+3) { color: var(--c-gold); border-color: rgba(var(--c-gold-rgb),0.35);  background: rgba(var(--c-gold-rgb),0.06); }
.trace-reveal-row.revealed:nth-child(5n+4) { color: var(--c-green); border-color: rgba(var(--c-green-rgb),0.35);  background: rgba(var(--c-green-rgb),0.06); }
.trace-reveal-row.revealed:nth-child(5n+5) { color: var(--c-purple); border-color: rgba(var(--c-purple-rgb),0.35);background: rgba(var(--c-purple-rgb),0.06); }
.trace-reveal-row.revealed:nth-child(5n+1) .trace-step-num { background: rgba(var(--c-pink-rgb),0.15);   border-color: var(--c-pink); color: var(--c-pink); }
.trace-reveal-row.revealed:nth-child(5n+2) .trace-step-num { background: rgba(var(--c-cyan-rgb),0.15);   border-color: var(--c-cyan); color: var(--c-cyan); }
.trace-reveal-row.revealed:nth-child(5n+3) .trace-step-num { background: rgba(var(--c-gold-rgb),0.15);   border-color: var(--c-gold); color: var(--c-gold); }
.trace-reveal-row.revealed:nth-child(5n+4) .trace-step-num { background: rgba(var(--c-green-rgb),0.15);   border-color: var(--c-green); color: var(--c-green); }
.trace-reveal-row.revealed:nth-child(5n+5) .trace-step-num { background: rgba(var(--c-purple-rgb),0.15); border-color: var(--c-purple); color: var(--c-purple); }
.trace-reveal-btn {
  background: rgba(var(--c-cyan-rgb),0.1); border: 1px solid var(--c-cyan); color: var(--c-cyan);
  padding: 0.5rem 1.2rem; border-radius: 8px; font-family: inherit;
  font-weight: 700; cursor: pointer; font-size: 0.85rem; margin-top: 0.5rem;
}
.trace-final-answer {
  margin-top: 0.75rem; padding: 0.75rem 1rem; border-radius: 8px;
  background: rgba(var(--c-green-rgb),0.08); border: 1px solid rgba(var(--c-green-rgb),0.25);
  color: var(--c-green); font-weight: 800; font-family: 'Source Code Pro', monospace;
  display: none;
}
.trace-final-answer.show { display: block; animation: disco-pop 0.25s ease; }

/* REVIEW — generator embed wrapper */
.review-embed-note { font-size: 0.85rem; color: rgba(255,255,255,0.5); margin-bottom: 1rem; }

/* ── Exam-question display + trap ledger (Big Idea 3 pages; ex-card
      pattern promoted from the 1.5 Data-from-Info page) ── */
.ex-card { background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.08); border-radius: 14px; padding: 1.5rem; margin: 1rem 0 1.5rem; }
.ex-label { font-size: 0.72rem; font-weight: 900; letter-spacing: 1.5px; text-transform: uppercase; color: rgba(255,255,255,0.4); margin-bottom: 0.9rem; }
.ex-stem { font-size: 1rem; font-weight: 700; color: #fff; line-height: 1.6; margin-bottom: 1.1rem; }
.ex-code { font-family: 'Source Code Pro', monospace; font-size: 0.95rem; line-height: 1.9; color: rgba(255,255,255,.9); background: rgba(0,0,0,0.4); border-radius: 8px; padding: 1rem 1.2rem; margin-bottom: 1.1rem; white-space: pre-wrap; }

/* Syntax colors for static teach-block code (code-highlight.js). Same
   palette as the live editor/trace widgets so the same code reads the
   same everywhere. */
.ex-code .hl-keyword, .ysbat-code .hl-keyword { color: var(--c-blue); }
.ex-code .hl-proc,    .ysbat-code .hl-proc    { color: var(--c-purple); }
.ex-code .hl-io,      .ysbat-code .hl-io      { color: var(--c-green); }
.ex-code .hl-builtin, .ysbat-code .hl-builtin { color: var(--c-pink); }
.ex-code .hl-string,  .ysbat-code .hl-string  { color: var(--c-gold); }
.ex-code .hl-number,  .ysbat-code .hl-number  { color: var(--c-orange); }
.ex-code .hl-arrow,   .ysbat-code .hl-arrow   { color: var(--c-pink); }
.ex-code .hl-comment, .ysbat-code .hl-comment { color: #788096; }
.ex-code .hl-boolop,  .ysbat-code .hl-boolop  { color: #969593; }
.ex-code .hl-literal, .ysbat-code .hl-literal { color: var(--c-purple); }
.ex-opt { display: block; width: 100%; text-align: left; background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.12); color: rgba(255,255,255,.8); padding: 0.7rem 1rem; border-radius: 8px; margin-bottom: 0.5rem; font-size: 0.92rem; }
.ex-opt.is-correct { background: rgba(var(--c-green-rgb),0.12); border-color: var(--c-green); color: var(--c-green); font-weight: 700; }
.ex-opt .opt-letter { font-weight: 900; margin-right: 0.5rem; opacity: 0.6; }

.trap-ledger { display: flex; flex-direction: column; gap: 0.6rem; margin: 1rem 0 0.25rem; }
.trap-item { display: flex; gap: 0.75rem; align-items: flex-start; background: rgba(var(--c-orange-rgb),0.06); border: 1px solid rgba(var(--c-orange-rgb),0.25); border-radius: 10px; padding: 0.75rem 1rem; }
.trap-num { width: 22px; height: 22px; flex-shrink: 0; border-radius: 50%; background: rgba(var(--c-orange-rgb),0.15); border: 1px solid var(--c-orange); color: var(--c-orange); font-weight: 900; font-size: 0.75rem; display: flex; align-items: center; justify-content: center; margin-top: 0.1rem; }
.trap-text { font-size: 0.92rem; line-height: 1.55; color: rgba(255,255,255,.9); }
.trap-text strong { color: var(--c-orange); }

/* shape headers — disco rotation across the four+ shapes on a page */
.shape-head { display: flex; align-items: center; gap: 0.6rem; font-weight: 900; font-size: 1rem; margin: 1.75rem 0 0.5rem; }
.shape-head .shape-tag { font-size: 0.68rem; font-weight: 900; letter-spacing: 1px; text-transform: uppercase; padding: 0.2rem 0.6rem; border-radius: 999px; }
.shape-head.pink   { color: var(--c-pink); } .shape-head.pink .shape-tag   { background: rgba(var(--c-pink-rgb),0.14);   border: 1px solid rgba(var(--c-pink-rgb),0.35);   color: var(--c-pink); }
.shape-head.cyan   { color: var(--c-cyan); } .shape-head.cyan .shape-tag   { background: rgba(var(--c-cyan-rgb),0.1);    border: 1px solid rgba(var(--c-cyan-rgb),0.3);    color: var(--c-cyan); }
.shape-head.gold   { color: var(--c-gold); } .shape-head.gold .shape-tag   { background: rgba(var(--c-gold-rgb),0.12);   border: 1px solid rgba(var(--c-gold-rgb),0.3);    color: var(--c-gold); }
.shape-head.green  { color: var(--c-green); } .shape-head.green .shape-tag  { background: rgba(var(--c-green-rgb),0.1);    border: 1px solid rgba(var(--c-green-rgb),0.3);    color: var(--c-green); }
.shape-head.orange { color: var(--c-orange); } .shape-head.orange .shape-tag { background: rgba(var(--c-orange-rgb),0.1); border: 1px solid rgba(var(--c-orange-rgb),0.3); color: var(--c-orange); }
.shape-head.purple { color: var(--c-purple); } .shape-head.purple .shape-tag { background: rgba(var(--c-purple-rgb),0.1);  border: 1px solid rgba(var(--c-purple-rgb),0.3);  color: var(--c-purple); }

/* ── Predict-the-trace + streak (Practice upgrade, owner directive:
      streaks allowed — competitive juice, not a grade) ── */
.trace-q { flex: 1; }
.trace-choices { margin-left: auto; display: flex; gap: 0.4rem; flex-wrap: wrap; }
.trace-choice {
  background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.18);
  color: rgba(255,255,255,.8); padding: 0.25rem 0.7rem; border-radius: 999px;
  font-family: 'Source Code Pro', monospace; font-size: 0.8rem; font-weight: 700;
  cursor: pointer; transition: all 0.15s;
}
.trace-choice:hover { border-color: var(--c-cyan); color: var(--c-cyan); }
.trace-reveal-row.missed { border-color: rgba(var(--c-orange-rgb),0.4); background: rgba(var(--c-orange-rgb),0.06); color: var(--c-orange); animation: trace-shake 0.3s ease; }
.trace-reveal-row.missed .trace-step-num { background: rgba(var(--c-orange-rgb),0.15); border-color: var(--c-orange); color: var(--c-orange); }
@keyframes trace-shake { 0%,100% { transform: translateX(0); } 25% { transform: translateX(-4px); } 75% { transform: translateX(4px); } }

.streak-badge {
  margin-left: auto; display: inline-flex; align-items: center; gap: 0.4rem;
  background: rgba(var(--c-gold-rgb),0.1); border: 1px solid rgba(var(--c-gold-rgb),0.35);
  color: var(--c-gold); font-size: 0.78rem; font-weight: 900; letter-spacing: 0.5px;
  padding: 0.25rem 0.75rem; border-radius: 999px; text-transform: uppercase;
}
.streak-badge .streak-best { font-weight: 400; opacity: 0.6; text-transform: none; }
@keyframes streak-pulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.08); } }
.streak-badge.hot { animation: streak-pulse 0.9s ease infinite; background: rgba(var(--c-pink-rgb),0.12); border-color: var(--c-pink); color: var(--c-pink); }

/* ── "You should be able to…" (per-topic can-do block: whole-class
      framing, builds toward the Create Task) ── */
.ysbat { background: rgba(var(--c-green-rgb),0.04); border: 1px solid rgba(var(--c-green-rgb),0.22); border-left: 4px solid var(--c-green); border-radius: 12px; padding: 1.25rem 1.4rem; margin: 2rem 0 0.5rem; }
.ysbat-head { font-weight: 900; font-size: 0.82rem; letter-spacing: 1.5px; text-transform: uppercase; color: var(--c-green); margin-bottom: 0.75rem; display: flex; align-items: center; gap: 0.5rem; }
.ysbat-head .ysbat-sub { font-weight: 400; text-transform: none; letter-spacing: 0; color: rgba(255,255,255,0.4); margin-left: auto; font-size: 0.78rem; }
.cando-list { display: flex; flex-direction: column; gap: 0.5rem; margin-bottom: 1rem; }
.cando-item { display: flex; gap: 0.7rem; align-items: flex-start; }
.cando-check { width: 20px; height: 20px; flex-shrink: 0; border-radius: 50%; background: rgba(var(--c-green-rgb),0.12); border: 1px solid var(--c-green); color: var(--c-green); font-weight: 900; font-size: 0.7rem; display: flex; align-items: center; justify-content: center; margin-top: 0.15rem; }
.cando-text { font-size: 0.95rem; line-height: 1.55; color: rgba(255,255,255,.9); }
.cando-text strong { color: #fff; }
.ysbat-code { font-family: 'Source Code Pro', monospace; font-size: 0.92rem; color: rgba(255,255,255,.9); background: rgba(0,0,0,0.35); border-radius: 8px; padding: 0.9rem 1.1rem; white-space: pre-wrap; margin-bottom: 0.9rem; }
.ysbat-note { font-size: 0.88rem; line-height: 1.6; color: rgba(255,255,255,0.6); border-top: 1px solid rgba(255,255,255,0.07); padding-top: 0.7rem; }
.ysbat-note strong { color: var(--c-green); }

/* ── WAYPOINTS (unit 3 wayfinding) ──────────────────────────────
   Big, bold, numbered section headers — the SAME seven, in the SAME
   order, on every 3.x page, so students learn the pattern once and
   can be sent to "the tracing" or "the shapes" without scrolling
   blind. The ▼ stem above each one draws the progression. */
.wp { margin: 3rem 0 1.2rem; }
.wp.wp-first { margin-top: 1.8rem; }
.wp-arrow { text-align: center; font-size: 1.5rem; line-height: 1; margin-bottom: 0.55rem; opacity: 0.25; }
.wp-first .wp-arrow { display: none; }
.wp-bar { display: flex; align-items: center; gap: 1rem; padding: 0.4rem 0.2rem; }
.wp-num { flex: 0 0 auto; width: 2.7rem; height: 2.7rem; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 1.35rem; font-weight: 900; color: #0a0a12; }
.wp-label { font-size: clamp(1.1rem, 2.6vw, 1.5rem); font-weight: 900; letter-spacing: 2.5px; text-transform: uppercase; display: flex; align-items: center; gap: 0.7rem; }
.wp-label svg { flex-shrink: 0; }

.wp.gold   .wp-num { background: var(--c-gold); }
.wp.gold   .wp-label { color: var(--c-gold); }
.wp.gold   .wp-arrow { color: var(--c-gold); }
.wp.cyan   .wp-num { background: var(--c-cyan); }
.wp.cyan   .wp-label { color: var(--c-cyan); }
.wp.cyan   .wp-arrow { color: var(--c-cyan); }
.wp.pink   .wp-num { background: var(--c-pink); color: #fff; }
.wp.pink   .wp-label { color: var(--c-pink); }
.wp.pink   .wp-arrow { color: var(--c-pink); }
.wp.green  .wp-num { background: var(--c-green); }
.wp.green  .wp-label { color: var(--c-green); }
.wp.green  .wp-arrow { color: var(--c-green); }
.wp.purple .wp-num { background: var(--c-purple); }
.wp.purple .wp-label { color: var(--c-purple); }
.wp.purple .wp-arrow { color: var(--c-purple); }
.wp.orange .wp-num { background: var(--c-orange); color: #fff; }
.wp.orange .wp-label { color: var(--c-orange); }
.wp.orange .wp-arrow { color: var(--c-orange); }

/* ── SIGNAL WORD INVENTORY (the decoder, not the lesson) ────────
   Sits at the very top of every rebuilt topic page: shape tags
   naming the archetypes, then a two-column translation table from
   CB's wording to the operation it demands. The gold top border +
   faint field mark it as apparatus, distinct from the teaching
   below. Populated only from content already on the page. */
.swi { background: rgba(255,255,255,0.035); border-top: 3px solid var(--c-gold); border-radius: 0 0 14px 14px; padding: 1.1rem 1.4rem 1.15rem; margin-bottom: 2.4rem; }
.swi-head { display: flex; align-items: baseline; gap: 0.6rem; flex-wrap: wrap; margin-bottom: 0.8rem; }
.swi-title { font-size: 0.8rem; font-weight: 900; letter-spacing: 2px; text-transform: uppercase; color: var(--c-gold); }
.swi-sub { font-size: 0.78rem; color: rgba(255,255,255,0.4); }
.swi-tags { display: flex; flex-wrap: wrap; gap: 0.45rem; margin-bottom: 1rem; }
.swi-tags .n1q-tag { background: rgba(var(--c-gold-rgb),0.12); border: 1px solid rgba(var(--c-gold-rgb),0.35); color: var(--c-gold); }
.swi-table { width: 100%; border-collapse: collapse; }
.swi-table th { text-align: left; font-size: 0.7rem; font-weight: 900; letter-spacing: 1.5px; text-transform: uppercase; color: rgba(255,255,255,0.4); padding: 0 1rem 0.45rem 0; border-bottom: 1px solid rgba(255,255,255,0.12); }
.swi-table td { padding: 0.55rem 1rem 0.55rem 0; font-size: 0.92rem; line-height: 1.55; vertical-align: top; border-bottom: 1px solid rgba(255,255,255,0.05); }
.swi-table tr:last-child td { border-bottom: none; padding-bottom: 0.1rem; }
.swi-see { color: var(--c-gold); font-weight: 700; white-space: normal; width: 38%; }
.swi-do { color: rgba(255,255,255,.9); }
@media (max-width: 640px) { .swi-see { width: 45%; } .swi-table td, .swi-table th { padding-right: 0.6rem; } }
.center-on-page { display: block; margin: 0 auto; }

/* ── CODE IT — the lite editor panel under "You Should Be Able To
      Code". Three challenge tabs swap the embedded editor's ?id=.
      Green, to belong to the Code section. ── */
.codeit { margin: 0.5rem 0 0.5rem; border: 1px solid rgba(var(--c-green-rgb),0.28); border-radius: 16px; overflow: hidden; background: rgba(0,20,8,0.25); }
.codeit-head { padding: 0.9rem 1.2rem 0.75rem; }
.codeit-title { font-size: 0.8rem; font-weight: 900; letter-spacing: 2px; text-transform: uppercase; color: var(--c-green); }
.codeit-sub { display: block; font-size: 0.85rem; color: rgba(255,255,255,0.5); margin-top: 0.2rem; }
.codeit-tabs { display: flex; gap: 0.4rem; padding: 0 1.2rem 0.85rem; flex-wrap: wrap; }
.codeit-tab { font-family: 'Outfit', sans-serif; font-size: 0.8rem; font-weight: 800; padding: 0.4rem 0.85rem; border-radius: 999px; cursor: pointer; border: 1px solid rgba(255,255,255,0.14); background: rgba(255,255,255,0.04); color: rgba(255,255,255,0.55); transition: all .14s; }
.codeit-tab:hover { color: #fff; background: rgba(var(--c-green-rgb),0.1); }
.codeit-tab.active { color: var(--c-green); border-color: var(--c-green); background: rgba(var(--c-green-rgb),0.14); }
.codeit iframe { width: 100%; border: none; display: block; background: transparent; }

/* ── Generated data tables in questions (10 Aug 2026) ──────────────
   A data question IS its table. These used to arrive as pipe-separated
   text inside a <pre>, which asked the student to do typography before
   they could do data analysis. */
.qtable-wrap { overflow-x: auto; margin: 0 0 1.1rem; }
.q-tbl { border-collapse: collapse; width: auto; min-width: 60%; font-size: 1.06rem; }
.q-tbl th, .q-tbl td { padding: 0.5rem 1rem; text-align: left; border-bottom: 1px solid rgba(255,255,255,0.12); }
.q-tbl th { font-weight: 800; color: var(--c-cyan); border-bottom-color: rgba(var(--c-cyan-rgb),0.45); white-space: nowrap; }
.q-tbl td { color: rgba(255,255,255,.92); }
.q-tbl tbody tr:last-child td { border-bottom: none; }
.qsvg-wrap { margin: 0 0 1.2rem; }
.qsvg-wrap svg, .qsvg-wrap img { width: 100%; height: auto; max-width: 460px; display: block; margin: 0 auto; }

/* Inline pseudocode inside an option or a stem. One line of code is
   still code; it used to arrive looking like an English sentence. */
code.qcode {
  font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.94em;
  background: rgba(0,0,0,0.35);
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 6px;
  padding: 0.12em 0.45em;
  color: #dce3ee;
  white-space: pre-wrap;
}

/* CODE IN AN ANSWER looks like code in the question above it.
   optionCodeHTML() in app-engine renders every option through the panels'
   own tokenizer, so these are the panels' colours — one set of rules, and
   an option is no longer the only code on an exam with no syntax colour
   at all (Robin, 16 Aug 2026).

   The multi-line form reuses pre.cb-plain, which is the panel's TEXT view,
   but drops its panel padding and ground: inside an option button the
   button already supplies both. */
.option-btn pre.cb-plain,
.vex-opt pre.cb-plain,
pre.cb-plain.qcode-seg {
  margin: 0;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
}
.qopt-blocks { display: block; }
code.qcode .hl-keyword, pre.qcode-seg .hl-keyword { color: var(--c-blue-new, #6ea8ff); }
code.qcode .hl-proc,    pre.qcode-seg .hl-proc    { color: var(--c-purple, #b18cff); }
code.qcode .hl-io,      pre.qcode-seg .hl-io      { color: var(--c-green, #3ddc84); }
code.qcode .hl-builtin, pre.qcode-seg .hl-builtin { color: var(--c-pink, #ff3d9a); }
code.qcode .hl-string,  pre.qcode-seg .hl-string  { color: var(--c-gold, #ffd83d); }
code.qcode .hl-number,  pre.qcode-seg .hl-number  { color: var(--c-orange, #ff9f43); }
code.qcode .hl-arrow,   pre.qcode-seg .hl-arrow   { color: var(--c-pink, #ff3d9a); }


/* MOBILE NAVIGATION — one clear control and a readable course drawer. */
.hamburger{width:auto;height:2.85rem;padding:0 .78rem;gap:.48rem;flex-direction:row;background:rgba(8,12,18,.94);border-color:rgba(var(--c-cyan-rgb),.5);border-radius:999px;color:#fff;box-shadow:0 8px 28px rgba(0,0,0,.32)}
.hamburger:hover,.hamburger.open{background:rgba(var(--c-cyan-rgb),.13);border-color:var(--c-cyan)}
.hamburger-label{font:600 .82rem/1 Outfit,sans-serif;letter-spacing:.02em}
.hamburger-glyph{width:1rem;text-align:center;color:var(--c-cyan);font:500 1.28rem/1 Arial,sans-serif}
.hamburger span{background:none!important;height:auto!important;transform:none!important;opacity:1!important}
@media (max-width:768px){
  .hamburger{left:1rem;top:.8rem;z-index:70}
  /* THE CLOSE PILL SAT ON TOP OF THE WORDMARK. It is position:fixed
     at left:1rem, which is fine as a "Menu" button over the page and
     wrong the moment the drawer slides under it -- the drawer's
     top-left corner is exactly where the logo is, so "Close x" was
     printed across the letters (Robin, 4 Sep 2026, iPhone). Open, it
     belongs at the drawer's far edge, which is the usual place for a
     close control anyway. */
  .hamburger.open{left:auto;right:calc(100vw - min(92vw,380px) + 1rem)}
  .sidebar{--nav-w:min(92vw,380px);width:var(--nav-w);left:-400px;z-index:60;padding:.85rem 0 2rem;background:rgba(8,10,15,.97);border-right-color:rgba(255,255,255,.16);box-shadow:18px 0 45px rgba(0,0,0,.48)}

  /* ═════════════════════════════════════════════════════════════════
     THE PHONE MENU IS AN OVERLAY, NOT A NARROW SIDEBAR
     Robin, 4 Sep 2026, after two goes at making the drawer smaller:
     "I still hate the menu. It looks moronic like that... They click a
     topic and it expands, dark overlay, same color menus but nothing
     else."

     He is right, and shrinking it was the wrong instinct. A drawer is a
     sidebar that has been squeezed — it still reads as a piece of
     furniture pushed in from the edge, with the page peering round it.
     What a phone wants is a SCREEN: the menu takes the whole thing,
     says only what it needs to, and gets out of the way.

     So on a phone the nav stops being 92% of the width and becomes all
     of it. No borders, no dividers, no panel edge, no rounded corner
     hinting at a box. Unit names large and in their own colours — "same
     color menus" — with the topics expanding underneath the one that is
     tapped. Nothing else on screen.
     ═════════════════════════════════════════════════════════════════ */
  .sidebar{
    left:-100%; width:100%; max-width:none;
    height:100dvh; max-height:none;
    padding:0; border-right:0; border-radius:0; box-shadow:none;
    background:rgba(7,8,12,.985);
    -webkit-backdrop-filter:blur(16px); backdrop-filter:blur(16px);
    display:flex; flex-direction:column;
  }
  .sidebar.open{left:0}
  /* the menu IS the dim, so a second scrim underneath it only muddies
     the colours it is meant to show off */
  #sidebar-overlay{display:none !important}
  /* the close button belongs at the screen's edge now, not at the edge
     of a 380px drawer that no longer exists */
  .hamburger.open{left:auto;right:.9rem}

  .brand{margin:0;padding:1.15rem 1.25rem .35rem}

  /* SCOPED WITH .sidebar SO ORDER DOES NOT DECIDE. The first pass put
     these before the older mobile rules in the same media block, so the
     dividers and the small uppercase chapter type simply won on source
     order and the menu still had lines through it. Specificity is the
     fix, not moving the block and hoping. */
  .sidebar .nav-chapter{border:0}
  .sidebar .nav-chapter-title{
    margin:0; padding:.68rem 1.35rem;
    border:0 !important; border-radius:0; background:none;
    /* lighter and smaller: 800/1.55rem was shouting. 600/1.28rem still
       sits clearly above the 1.08rem topic rows, so the hierarchy holds
       without the colour having to fight the weight. */
    font:600 1.28rem/1.3 Outfit,sans-serif !important;
    letter-spacing:-.01em !important; text-transform:none;
    color:var(--unit-c,#fff);
    display:flex; align-items:baseline; justify-content:space-between;
  }
  .sidebar .nav-chapter-title .nav-collapse-icon{font-size:1.05rem;opacity:.45;font-weight:400}
  .sidebar .nav-chapter.open > .nav-chapter-title .nav-collapse-icon{opacity:.9}
  /* a locked unit says so by being quiet — same size, just faded */
  .sidebar .nav-chapter-locked .nav-chapter-title{opacity:.3}

  .sidebar .nav-sub-list{padding:.1rem 0 1.05rem}
  .sidebar .nav-item{
    padding:.52rem 1.35rem .52rem 1.5rem;
    font:500 1.08rem/1.3 Outfit,sans-serif;
    color:rgba(255,255,255,.72);
    gap:.7rem; border:0; background:none;
  }
  .sidebar .nav-item.active{color:#fff;font-weight:700;background:none}
  .sidebar .nav-num{opacity:.5}

  /* the two footer controls: present, not shouting */
  .sidebar .nav-foot-wrap{margin-top:1.5rem;padding:1.2rem 1.35rem .2rem;
                          border-top:1px solid rgba(255,255,255,.08)}
  .sidebar .admin-section-wrap{padding:.2rem 1.35rem 1rem}
  .sidebar .nav-foot-wrap .nav-foot-btn,
  .sidebar .nav-foot-wrap .nav-item,
  .sidebar .admin-section-wrap .admin-lock-btn{
    border:0; background:none; padding:.45rem 0;
    font:600 .95rem/1 Outfit,sans-serif; color:rgba(255,255,255,.5);
  }

  /* the account button sits exactly where the close pill now lives */
  /* WHILE THE MENU IS OPEN, THE MENU IS THE SCREEN. The account button
     sits exactly where the close pill now lives, and the aria orb floats
     over the list wearing the same mark as the header — two copies of
     the same logo on one screen, one of them on top of the words. Both
     step aside; both come back on close. */
  body:has(#sidebar.open) #acct-btn{display:none}
  .sidebar.open{left:0}

  /* (The half-height drawer that used to be here is gone. Sizing it to
     its content was the second of three attempts and still wrong — it
     read as a sidebar with the bottom cut off. Robin: "I still hate the
     menu. It looks moronic like that." The overlay below replaced it.) */

  .brand{align-items:flex-start;justify-content:flex-start;margin:0 0 .7rem;padding:1.15rem 1.15rem .55rem}

  /* THE LITTLE "a" ON PHONES, NOT THE WORDMARK.
     Robin, 4 Sep 2026: "just use the small aria a instead of the full
     menu." The 2/3-of-the-nav rule is right for the desktop rail and
     wrong here — at 359px wide the wordmark plus its padding was ~270px
     of a 602px drawer, nearly half the menu, on the device most of these
     students use as their only way online.

     Still a MASK, not the artwork: aria-a.png carries a baked pink-to-
     purple gradient, and painting it as an image would leave a pink mark
     sitting in noir. Masked, it takes the theme like everything else.
     Only the image and the shape change — position, size and repeat stay
     from the shorthand above. */
  .brand{padding:.9rem 1.15rem .5rem}
  .brand-logo{
    width:46px;
    aspect-ratio:1;
    -webkit-mask-image:url('aria-a.png');
            mask-image:url('aria-a.png');
  }

  /* no max-width: the logo is two thirds of --nav-w, which the rule
     above has just restated for the drawer. A cap here would break
     the ratio on a wide phone. */
  .nav-chapter-title{margin-top:.65rem;padding:.76rem 1.12rem .5rem;font-size:.78rem;font-weight:400!important;letter-spacing:.08em;border-top:1px solid rgba(255,255,255,.08);border-radius:0}
  .nav-sub-list{padding:.12rem 0 .35rem}
  .nav-item{padding:.6rem 1.15rem .6rem 1.35rem;font-size:.96rem;gap:.55rem}
  .nav-num{font-size:.68rem!important}
  #sidebar-overlay{z-index:9;background:rgba(0,0,0,.72)}
}


/* ═══ NOIR chrome (owner, 26 Aug 2026) — tokens flip in css/palette.css;
   this is what a palette swap alone cannot say. Solids only: the
   background goes to plain black, and the logo mask fills with solid
   cream and holds still. (The grain that used to live under noir went
   with the neon field on 30 Aug — see the background note up top.) */
html[data-theme="noir"] .orb-container{background:#000}
/* NOIR PAINTS THE WORD, NOT THE BOX -- and it also kills the disco
   gradient, which is the whole point of noir. This rule sat on
   .brand-logo itself, which was right while that element WAS the mask:
   the brass got cut into letter shapes. Splitting the lockup made it the
   flex container instead, so the brass filled the entire box with the
   letters knocked out of it. Robin, 3 Sep 2026: "noir broken in both
   notebooks."
   "ap" stays white here as it does everywhere. */
/* NOIR: solid brass, no drift. Targets the ELEMENT -- it briefly
   targeted ::before, which was correct only while the wordmark was a
   two-part lockup. That lockup is gone, so a ::before rule now styles
   nothing at all and noir quietly kept the disco gradient. Third time a
   rule has outlived the structure it was written for. */
html[data-theme="noir"] .brand-logo{background:var(--c-gold);animation:none}
/* Matrix does what noir does: the disco gradient is the DEFAULT theme's
   identity, so any theme that means something else has to say so. The
   mask stays; only what fills it changes. */
html[data-theme="matrix"] .brand-logo{background:var(--t-title,#00FF41);animation:none}

/* ── THE LADDER NAV (23 Sep 2026) ──────────────────────────────────
   One numbered spine instead of seven chapters. The rows themselves
   are ordinary .nav-item rows and take every rule above; this block is
   only the progress line at the top and the badge tint that marks the
   woven no-code rungs. LADDER_MODE = false in app-engine.js turns all
   of it off — nothing here fires when there is no ladder. */
.nav-ladder-head{padding:.55rem 1rem .5rem;}
.nav-ladder-count{
  font-size:.62rem;letter-spacing:.09em;text-transform:uppercase;
  color:rgba(255,255,255,.55);margin-bottom:.35rem;
  font-variant-numeric:tabular-nums;
}
.nav-ladder-bar{
  height:3px;border-radius:3px;overflow:hidden;
  background:rgba(255,255,255,.10);
}
.nav-ladder-bar > i{
  display:block;height:100%;width:0;border-radius:3px;
  background:var(--c-green);transition:width .25s ease;
}
/* THE TRAFFIC LIGHT lives in app-engine.js: each rung sets its own
   --unit-c from LADDER_HUE, and app-extra.css's existing badge rules
   colour it. Green go forward, amber a different kind of day, orange
   stop and look back. Nothing extra is needed here for that.
   "Later in the year" rows are off the ladder, so they sit back a
   little. Their empty .nav-num keeps them aligned. */
.nav-item.nav-rung-later .nav-item-text{color:rgba(255,255,255,.72);}
@media (prefers-reduced-motion: reduce){
  .nav-ladder-bar > i{transition:none;}
}
