/* ==========================================================================
   GRAMMARMETRIC DESIGN SYSTEM — "ELECTRIC"
   Implements grammarmetric-style-guide.md in full.

   Dark is the default mode. <html> carries two attributes:
     data-theme="dark|light"     — colour mode, set pre-paint by an inline
                                   <head> script, persisted under gm_theme.
     data-accent="cyan|yellow|orange|magenta"
                                 — the page's ONE lead accent. The guide is
                                   explicit that running all four accents at
                                   once is "the loudest possible use of this
                                   palette", so each page declares a single
                                   accent and every accented element on it
                                   reads from --accent. Omitting the
                                   attribute gives cyan.

   THREE DOCUMENTED DEVIATIONS from the guide as supplied. Do not "fix" back:

   1. --gm-magenta-text is #500050, not the guide's #5c005c. #5c005c on a
      #FF00FF fill measures 4.16:1, under the 4.5:1 the darkened-text rule
      exists to reach. #500050 measures 4.60:1. Same hue, same rule, corrected
      value — the guide itself asks for contrast fixes to be "narrow, named".
      The other four pairs in that table all pass as supplied and are untouched
      (yellow 4.79, cyan 7.72, orange 4.56, error 4.86).

   2. Hairlines are 1px, not 0.5px. On a 1x display 0.5px rounds to a
      sub-pixel line that some browsers drop entirely, and the card border is
      the only thing separating a card from the page in this flat system.
      "Hairline" in the Components section is unnumbered; 1px honours it.

   3b. Light-mode muted text is rgba(5,5,5,0.62), not 0.55 — see the token
      block for the measurement.

   3. This is a multi-page site sharing one stylesheet, not the guide's
      "single self-contained HTML file". That constraint is written for
      standalone deliverables (quizzes, worksheets). Inlining this file into
      all 8 pages would duplicate ~20KB per page, defeat HTTP caching, and
      wreck the Core Web Vitals this same brief asks us to optimise. Every
      other build constraint (no bundler, no framework, works from file://
      and inside a sandboxed iframe) is honoured.

   Accent-colour-as-text follows two different rules, deliberately:
     - on a BRIGHT fill (chips, icon badges, primary button) the darkened
       same-hue text is used in BOTH modes, per the guide's non-negotiable
       contrast rule. Those combinations never change between modes.
     - on the PAGE or on a 10-20% TINT the fill is dark in dark mode and light
       in light mode, so the safe text colour flips with the mode. That is
       --accent-ink.
   ========================================================================== */

/* -----------------------------------------------------------------------
   1. FONTS — loaded in each page's <head>:
   <link rel="preconnect" href="https://fonts.googleapis.com">
   <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
   <link href="https://fonts.googleapis.com/css2?family=Lexend:wght@400;500&display=swap" rel="stylesheet">

   Lexend only, 400 and 500 only. The guide says avoid 600+, so no weight
   above 500 appears anywhere below. Space Mono and Press Start 2P are gone.
   ----------------------------------------------------------------------- */

/* -----------------------------------------------------------------------
   2. TOKENS
   ----------------------------------------------------------------------- */
:root {
  /* Palette — identical in both modes, never redefined */
  --gm-yellow:       #FFFC00;
  --gm-yellow-text:  #736f00;
  --gm-cyan:         #00FFFF;
  --gm-cyan-text:    #004d4d;
  --gm-cyan-outline: #006666;  /* light-mode-only outline-button fix */
  --gm-orange:       #FF3503;
  --gm-orange-text:  #3d0f00;
  --gm-magenta:      #FF00FF;
  --gm-magenta-text: #500050;  /* deviation 1 */
  --gm-error:        #ff5252;
  --gm-error-text:   #4a0d0d;

  /* Channel triplets, for tints via rgba() */
  --rgb-yellow:  255, 252, 0;
  --rgb-cyan:    0, 255, 255;
  --rgb-orange:  255, 53, 3;
  --rgb-magenta: 255, 0, 255;
  --rgb-error:   255, 82, 82;

  /* Corners — the 14/10/20 scale, plus 9px for icon badges */
  --radius-card:    14px;
  --radius-control: 10px;
  --radius-pill:    20px;
  --radius-badge:   9px;

  --font: 'Lexend', system-ui, -apple-system, 'Segoe UI', sans-serif;

  /* Spacing scale — generous by default, the guide's main calming lever */
  --gap:      18px;
  --pad-card: 24px;
  --sec-y:    88px;
}

/* --- DARK MODE — the default --- */
:root,
:root[data-theme="dark"] {
  --bg:           #050505;
  --text:         #ffffff;
  --muted:        rgba(255, 255, 255, 0.55);
  --card:         rgba(255, 255, 255, 0.04);
  --line:         rgba(255, 255, 255, 0.08);
  --line-strong:  rgba(255, 255, 255, 0.16);
  /* Opaque surface for the mobile menu only. A translucent primary navigation
     lets the hero read through it and becomes hard to scan; that was fixed
     once already and must not regress. Nearest opaque neighbour of --bg. */
  --solid:        #0d0d0d;
  --link:         var(--gm-cyan);
  /* accent used as TEXT on the page or on a tint — see header note */
  --accent-ink:   var(--accent);
  --accent-line:  var(--accent-ink);
}

/* --- LIGHT MODE --- */
:root[data-theme="light"] {
  --bg:           #ffffff;
  --text:         #050505;
  /* deviation 4: the guide says rgba(5,5,5,0.55). That measures 4.57:1 on
     plain white, but the design also puts muted text on 8% accent tints
     (.is-lead cards), and on the lightest of those it drops to 4.43:1 —
     under AA for body copy. 0.62 clears 4.5:1 on every surface muted text
     actually lands on. Dark mode is unaffected: white at 0.55 measures
     6.2:1 on the equivalent dark tint, so it keeps the guide's value. */
  --muted:        rgba(5, 5, 5, 0.62);
  --card:         rgba(5, 5, 5, 0.03);
  --line:         rgba(5, 5, 5, 0.08);
  --line-strong:  rgba(5, 5, 5, 0.16);
  --solid:        #ffffff;
  --link:         var(--gm-cyan-outline);
  --accent-ink:   var(--accent-text);
  --accent-line:  var(--accent-ink);
}

/* --- LEAD ACCENT — one per page --- */
:root,
:root[data-accent="cyan"] {
  --accent:      var(--gm-cyan);
  --accent-text: var(--gm-cyan-text);
  --accent-rgb:  var(--rgb-cyan);
}
:root[data-accent="yellow"] {
  --accent:      var(--gm-yellow);
  --accent-text: var(--gm-yellow-text);
  --accent-rgb:  var(--rgb-yellow);
}
:root[data-accent="orange"] {
  --accent:      var(--gm-orange);
  --accent-text: var(--gm-orange-text);
  --accent-rgb:  var(--rgb-orange);
}
:root[data-accent="magenta"] {
  --accent:      var(--gm-magenta);
  --accent-text: var(--gm-magenta-text);
  --accent-rgb:  var(--rgb-magenta);
}
/* The guide's one named light-mode fix: cyan as a border or as page-level
   text on white. #004d4d would also clear AA (9.7:1) but #006666 is the value
   the guide specifies, and using it for ink as well keeps links, eyebrows and
   outline-button borders the same colour on a cyan-lead page. Deliberately
   scoped to cyan-in-light-mode only, not applied broadly "to be safe". */
:root[data-theme="light"]:not([data-accent]),
:root[data-theme="light"][data-accent="cyan"] {
  --accent-ink:  var(--gm-cyan-outline);
  --accent-line: var(--gm-cyan-outline);
}

/* -----------------------------------------------------------------------
   3. BASE
   ----------------------------------------------------------------------- */
* { box-sizing: border-box; }

/* font-family goes on <html>, not just <body>: the root element itself would
   otherwise compute to the browser default serif, which is what any element
   that escapes normal inheritance (and some UA-styled controls) falls back
   to. Verified by auditing computed styles, not by eye. */
html {
  font-family: var(--font);
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

/* Form controls and buttons do not inherit font by default; without this the
   burger, the theme toggle and every input render in Arial. */
button, input, select, textarea, optgroup {
  font-family: inherit;
  font-size: inherit;
}

body {
  margin: 0;
  font-family: var(--font);
  font-weight: 400;
  font-size: 16px;
  line-height: 1.65;
  color: var(--text);
  background: var(--bg);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Headings at 500. The guide caps emphasis at 500 and calls 600+ heavy, so
   hierarchy here is carried by size and spacing, not weight. */
h1, h2, h3, h4 {
  font-weight: 500;
  margin: 0 0 0.5em;
  letter-spacing: -0.02em;
  line-height: 1.15;
  text-wrap: balance;
}
h1 { font-size: clamp(34px, 5vw, 60px); letter-spacing: -0.03em; line-height: 1.08; }
h2 { font-size: clamp(24px, 3.6vw, 38px); }
h3 { font-size: 20px; }
h4 { font-size: 17px; }

p { margin: 0 0 1em; color: var(--muted); }
p:last-child { margin-bottom: 0; }
b, strong { font-weight: 500; color: var(--text); }

a { color: var(--link); text-decoration: none; }
a:hover { text-decoration: underline; }

img { max-width: 100%; height: auto; display: block; }
ul { margin: 0; padding: 0; }

:focus-visible {
  outline: 2px solid var(--accent-line);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Skip link — keyboard users should not have to tab the whole nav. */
.skip-link {
  position: absolute; left: 8px; top: -60px; z-index: 300;
  background: var(--gm-yellow); color: var(--gm-yellow-text);
  padding: 10px 18px; border-radius: var(--radius-control); font-weight: 500;
}
.skip-link:focus { top: 8px; text-decoration: none; }

/* The guide: motion stays minimal and purposeful. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  html { scroll-behavior: auto; }
}

/* -----------------------------------------------------------------------
   4. LAYOUT
   ----------------------------------------------------------------------- */
.wrap    { max-width: 900px;  margin: 0 auto; padding: 0 20px; }
.wrap-lg { max-width: 1140px; margin: 0 auto; padding: 0 20px; }
@media (max-width: 640px) {
  .wrap, .wrap-lg { padding: 0 16px; }
  :root { --sec-y: 64px; }
}

section { padding: var(--sec-y) 0; scroll-margin-top: 84px; }

.eyebrow {
  display: block;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--accent-ink);
  margin-bottom: 12px;
}

.sub {
  color: var(--muted);
  font-size: clamp(16px, 2.2vw, 18px);
  max-width: 62ch;
  margin: 16px 0 0;
  line-height: 1.65;
}
.sub b, .sub strong { color: var(--text); font-weight: 500; }

.sec-head { max-width: 46em; }
.sec-head .sub { margin-top: 14px; }
.sec-head.mid { margin-left: auto; margin-right: auto; text-align: center; }
.sec-head.mid .sub { margin-left: auto; margin-right: auto; }

/* -----------------------------------------------------------------------
   5. BUTTONS — 10px radius, per the corner scale
   ----------------------------------------------------------------------- */
.btn-primary, .btn-ghost {
  font-family: var(--font);
  font-weight: 500;
  font-size: 15px;
  line-height: 1.2;
  padding: 13px 22px;
  border-radius: var(--radius-control);
  border: 1px solid transparent;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  text-align: center;
  transition: opacity 0.15s ease, background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.btn-primary:hover, .btn-ghost:hover { text-decoration: none; }

/* Primary: bright yellow fill, darkened-yellow text, no border. Identical in
   both modes — a bright fill never changes between modes. */
.btn-primary {
  background: var(--gm-yellow);
  color: var(--gm-yellow-text);
}
.btn-primary:hover { opacity: 0.86; }

/* Outline: transparent fill, 1px accent border + matching text. In light mode
   cyan becomes #006666, which is the guide's one named light-mode fix. */
.btn-ghost {
  background: transparent;
  border-color: var(--accent-line);
  color: var(--accent-ink);
}
.btn-ghost:hover { background: rgba(var(--accent-rgb), 0.10); }

.btn-sm { padding: 9px 16px; font-size: 14px; }
.btn-lg { padding: 15px 26px; font-size: 16px; }

/* -----------------------------------------------------------------------
   6. CHIPS / TAGS — bright fill, pill radius, darkened same-hue text.
   Both modes identical, per the contrast-fix rule.
   ----------------------------------------------------------------------- */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 13px;
  border-radius: var(--radius-pill);
  font-size: 13px;
  font-weight: 500;
  line-height: 1.5;
  border: 1px solid var(--line);
  background: var(--card);
  color: var(--text);
}
.chip-yellow  { background: var(--gm-yellow);  color: var(--gm-yellow-text);  border-color: transparent; }
.chip-cyan    { background: var(--gm-cyan);    color: var(--gm-cyan-text);    border-color: transparent; }
.chip-orange  { background: var(--gm-orange);  color: var(--gm-orange-text);  border-color: transparent; }
.chip-magenta { background: var(--gm-magenta); color: var(--gm-magenta-text); border-color: transparent; }
/* The page's lead accent, so a chip can follow data-accent without naming a hue */
.chip-accent  { background: var(--accent);     color: var(--accent-text);     border-color: transparent; }

/* Quiet variant: a tint rather than a full fill, for chip rows where several
   appear at once. "Tint, don't dilute" — same hue, 12% opacity. */
.chip-soft {
  background: rgba(var(--accent-rgb), 0.12);
  border-color: rgba(var(--accent-rgb), 0.28);
  color: var(--accent-ink);
}

/* -----------------------------------------------------------------------
   7. CARDS — ONE card model. Translucent fill, hairline border, 14px radius,
   generous padding. Nothing below introduces a competing card style.
   ----------------------------------------------------------------------- */
.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: var(--pad-card);
  transition: border-color 0.2s ease;
}
.card > :last-child { margin-bottom: 0; }
.card p { font-size: 15px; margin: 10px 0 0; }
.card h3 { margin-bottom: 0; }

/* Icon badge: small rounded square, bright accent fill, darkened-hue glyph.
   This is what carries the accent on a card now — the old coloured top
   borders were a second card model and forced all four hues onto one screen. */
.ico {
  width: 40px;
  height: 40px;
  border-radius: var(--radius-badge);
  background: var(--accent);
  color: var(--accent-text);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  line-height: 1;
  margin-bottom: 16px;
}
.ico-yellow  { background: var(--gm-yellow);  color: var(--gm-yellow-text); }
.ico-cyan    { background: var(--gm-cyan);    color: var(--gm-cyan-text); }
.ico-orange  { background: var(--gm-orange);  color: var(--gm-orange-text); }
.ico-magenta { background: var(--gm-magenta); color: var(--gm-magenta-text); }

/* Icons are inline outline SVG using stroke="currentColor", so they inherit
   the darkened-hue colour of whatever badge or row they sit in. Sizing is set
   per context rather than on the sprite. */
.ico svg { width: 21px; height: 21px; }

.card .band { margin-top: 16px; }
.card .go {
  display: inline-block;
  margin-top: 16px;
  font-weight: 500;
  font-size: 15px;
  color: var(--link);
}

/* Highlighted card — a tint of the lead accent, never a raw fill. */
.card.is-lead {
  background: rgba(var(--accent-rgb), 0.08);
  border-color: rgba(var(--accent-rgb), 0.28);
}

/* -----------------------------------------------------------------------
   8. GRIDS
   ----------------------------------------------------------------------- */
.grid { display: grid; gap: var(--gap); margin-top: 40px; grid-template-columns: 1fr; }
@media (min-width: 700px) {
  .grid.c2 { grid-template-columns: repeat(2, 1fr); }
  .grid.c3 { grid-template-columns: repeat(3, 1fr); }
  .grid.c4 { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1000px) { .grid.c4 { grid-template-columns: repeat(4, 1fr); } }

/* ── rail: a numbered, ordered sequence ── */
.rail {
  display: grid;
  gap: var(--gap);
  margin-top: 40px;
  counter-reset: rail;
  grid-template-columns: 1fr;
}
@media (min-width: 820px) {
  .rail { grid-template-columns: repeat(4, 1fr); }
  .rail.three { grid-template-columns: repeat(3, 1fr); }
}
.step { display: flex; flex-direction: column; gap: 10px; }
.step::before {
  counter-increment: rail;
  content: counter(rail);
  width: 28px; height: 28px;
  border-radius: var(--radius-badge);
  background: rgba(var(--accent-rgb), 0.14);
  color: var(--accent-ink);
  display: grid; place-items: center;
  font-size: 13px; font-weight: 500;
  margin-bottom: 4px;
}
.step h3 { font-size: 18px; margin: 0; }
.step p { margin-top: 0; }
.step .chip { align-self: flex-start; margin-top: auto; }

/* ── split: text beside a supporting panel ── */
.split { display: grid; gap: 24px; margin-top: 40px; align-items: center; grid-template-columns: 1fr; }
@media (min-width: 880px) {
  .split { grid-template-columns: 1fr 1fr; gap: 48px; }
  .split.flip .split-txt { order: 2; }
}
.split-txt h3 { font-size: clamp(21px, 3vw, 28px); letter-spacing: -0.025em; }
.split-txt p { margin: 14px 0 0; }
.split-txt .chip { margin-top: 18px; }
.split-panel { padding: clamp(22px, 3.5vw, 32px); }
.split-panel ul { list-style: none; display: flex; flex-direction: column; gap: 16px; }
.split-panel li {
  display: flex; gap: 12px; align-items: flex-start;
  font-size: 15px; color: var(--muted); line-height: 1.6;
}
.split-panel li b { color: var(--text); font-weight: 500; }
/* Tick sits on a TINT, so its ink follows the mode (see header note). */
.split-panel li .tick {
  flex: none; width: 22px; height: 22px; border-radius: 50%; margin-top: 2px;
  background: rgba(var(--accent-rgb), 0.16);
  color: var(--accent-ink);
  display: grid; place-items: center;
  font-size: 12px; font-weight: 500;
}

/* ── facts: plain verifiable figures, never invented social proof ── */
.facts { display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px; margin-top: 36px; }
@media (min-width: 760px) { .facts { grid-template-columns: repeat(4, 1fr); } }
.fact { padding: 22px 20px; text-align: center; }
.fact .n {
  display: block;
  font-size: clamp(28px, 4vw, 36px);
  font-weight: 500;
  letter-spacing: -0.035em;
  line-height: 1;
  color: var(--accent-ink);
}
.fact .l { display: block; color: var(--muted); font-size: 13px; margin-top: 10px; line-height: 1.45; }

/* -----------------------------------------------------------------------
   9. TOPBAR / NAV
   Opaque, flat, hairline underline. The old bar used backdrop-filter blur,
   which the guide bans and which also costs a compositing pass on every
   scroll frame — measurable on the mid-range Android this site is mostly
   read on.
   ----------------------------------------------------------------------- */
.topbar {
  position: fixed; top: 0; left: 0; right: 0; z-index: 100;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
  padding: 12px 20px;
}
.topbar-inner {
  max-width: 1180px; margin: 0 auto;
  display: flex; align-items: center; gap: 14px;
}

.logo { font-weight: 500; font-size: 19px; letter-spacing: -0.03em; color: var(--text); flex: none; }
.logo:hover { text-decoration: none; }
.logo .metric { color: var(--accent-ink); }
.logo .dot { color: var(--gm-yellow-text); }
:root[data-theme="dark"] .logo .dot { color: var(--gm-yellow); }

.nav-links { display: none; gap: 2px; margin-left: auto; list-style: none; align-items: center; }
.nav-links a {
  color: var(--muted); font-size: 14.5px; font-weight: 400;
  padding: 8px 11px; border-radius: var(--radius-control); white-space: nowrap;
  transition: color 0.15s, background-color 0.15s;
}
.nav-links a:hover { color: var(--text); background: var(--card); text-decoration: none; }
.nav-links a[aria-current="page"] {
  color: var(--accent-ink);
  background: rgba(var(--accent-rgb), 0.12);
}

/* Student login stays deliberately quiet: it serves people who already pay
   us, and must not compete with the CTA that earns new students. */
.nav-login {
  display: none; align-items: center; gap: 0.4em; color: var(--muted);
  font-size: 13.5px; white-space: nowrap;
  padding: 8px 12px; border-radius: var(--radius-control);
  transition: color 0.15s, background-color 0.15s;
}
.nav-login:hover { color: var(--text); background: var(--card); text-decoration: none; }
.nav-login::before { content: ""; width: 1px; height: 18px; background: var(--line-strong); margin-right: 6px; flex: none; }

.nav-cta { flex: none; }

.burger {
  margin-left: auto; background: none; border: none; cursor: pointer;
  padding: 10px; display: flex; flex-direction: column; gap: 5px;
  border-radius: var(--radius-control);
}
.burger span { width: 22px; height: 2px; background: var(--text); border-radius: 2px; transition: transform 0.25s, opacity 0.25s; }
.burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.mobile-menu {
  display: none; position: absolute; top: 100%; left: 12px; right: 12px;
  background: var(--solid);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-card);
  padding: 10px; flex-direction: column;
  max-height: calc(100svh - 90px); overflow-y: auto;
}
.mobile-menu.open { display: flex; }
.mobile-menu a { padding: 13px 16px; border-radius: var(--radius-control); color: var(--text); font-size: 15px; }
.mobile-menu a:hover { background: var(--card); text-decoration: none; }
.mobile-menu a[aria-current="page"] { background: rgba(var(--accent-rgb), 0.12); color: var(--accent-ink); }
.mobile-menu .m-cta { color: var(--accent-ink); font-weight: 500; }
.mobile-menu .m-sep {
  margin: 8px 6px 4px; padding-top: 10px; border-top: 1px solid var(--line);
  font-size: 12px; color: var(--muted);
}

/* Six links, the student login and both CTAs need ~1180px once the chrome
   lane is reserved for the language switch and theme toggle. Below that it
   is the burger. Was 1040px before the language switch existed. */
@media (min-width: 1180px) {
  .nav-links { display: flex; }
  .nav-login { display: inline-flex; }
  .burger { display: none; }
}
@media (max-width: 1179px) { .nav-cta { display: none; } }

/* Fixed site chrome: language switch + theme toggle. Both are site-wide
   controls rather than navigation, so they sit together in one corner. On
   mobile the topbar owns the top-right, so the pair drops below it; on
   desktop the topbar reserves a lane wide enough for both, which is why the
   desktop nav breakpoint is 1180px rather than the old 1040px. */
.chrome-controls {
  position: fixed; top: 74px; right: 14px; z-index: 200;
  display: flex; align-items: center; gap: 8px;
}

.lang-switch {
  display: flex; align-items: center;
  background: var(--solid); border: 1px solid var(--line-strong);
  border-radius: var(--radius-control); overflow: hidden;
}
.lang-switch a, .lang-switch .lang-cur, .lang-switch .lang-off {
  padding: 0 9px; height: 38px; display: grid; place-items: center;
  font-size: 12.5px; font-weight: 400; line-height: 1;
  color: var(--muted); text-decoration: none;
  transition: color 0.15s, background-color 0.15s;
}
.lang-switch a:hover { color: var(--text); background: var(--card); text-decoration: none; }
/* The active language is a <span>, not a link: it goes nowhere. */
.lang-switch .lang-cur {
  color: var(--accent-ink);
  background: rgba(var(--accent-rgb), 0.14);
  font-weight: 500;
  cursor: default;
}
/* A locale this page has no translation for. Shown but not clickable, so a
   half-translated site never offers a link to a 404. */
.lang-switch .lang-off { color: var(--text); opacity: 0.32; cursor: not-allowed; }
.lang-switch > * + * { border-left: 1px solid var(--line); }

.theme-toggle {
  width: 40px; height: 40px; border-radius: var(--radius-control);
  background: var(--solid); border: 1px solid var(--line-strong);
  color: var(--text);
  display: grid; place-items: center; cursor: pointer; font-size: 17px;
  transition: border-color 0.2s ease;
  flex: none;
}
.theme-toggle:hover { border-color: var(--accent-line); }

@media (min-width: 1180px) {
  .chrome-controls { top: 13px; right: 14px; }
  /* room for the language switch (~104px) + gap + the toggle (40px) */
  .topbar-inner { padding-right: 162px; }
}

/* -----------------------------------------------------------------------
   10. HERO
   ----------------------------------------------------------------------- */
.hero { padding: 148px 0 80px; display: flex; align-items: center; }
.hero.tall { min-height: 86svh; }
.hero .wrap, .hero .wrap-lg { width: 100%; }
.hero-chip { margin-bottom: 22px; }
.hero h1 { max-width: 15em; }
/* Flat accent underline. The old highlight was a linear-gradient band, which
   the guide bans, and in dark mode white text on a yellow band failed
   contrast anyway. A rule under the phrase carries the same emphasis. */
.hero h1 .hl {
  border-bottom: 4px solid var(--accent);
  padding-bottom: 2px;
}
.hero-ctas { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 32px; }
.hero-trust { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 28px; }

/* -----------------------------------------------------------------------
   11. CONTENT BLOCKS
   ----------------------------------------------------------------------- */
/* method / materials strip */
.method { padding: clamp(24px, 4vw, 40px); }
.method h3 { font-size: clamp(20px, 3vw, 25px); }
.method .lead { color: var(--muted); margin-top: 12px; max-width: 60ch; font-size: 16px; }
.method .lead b { color: var(--text); font-weight: 500; }
.materials { display: grid; gap: 14px; margin-top: 26px; }
@media (min-width: 760px) { .materials { grid-template-columns: repeat(3, 1fr); } }
.mat {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: 20px;
}
.mat small { display: block; color: var(--accent-ink); font-size: 12px; }
.mat b { display: block; font-size: 16px; font-weight: 500; letter-spacing: -0.015em; margin-top: 4px; color: var(--text); }
.mat span { display: block; color: var(--muted); font-size: 14px; margin-top: 10px; line-height: 1.55; }

/* delivery modes: in-person / online / hybrid */
.modes { display: grid; gap: 14px; margin-top: 32px; grid-template-columns: 1fr; }
@media (min-width: 760px) { .modes { grid-template-columns: repeat(3, 1fr); } }
.mode { display: flex; flex-direction: column; gap: 8px; }
.mode .chip { align-self: flex-start; }
.mode h3 { font-size: 17px; margin: 0; }
.mode p { margin-top: 0; font-size: 14.5px; }

/* student strip: the quiet in-page route to the classroom */
.student-strip {
  display: flex; flex-wrap: wrap; align-items: center; gap: 16px 24px;
  padding: 20px clamp(20px, 3vw, 28px);
  border-radius: var(--radius-card);
  background: var(--card); border: 1px solid var(--line);
}
.student-strip .txt { flex: 1 1 320px; }
.student-strip b { font-size: 16px; font-weight: 500; color: var(--text); }
.student-strip p { font-size: 14px; margin: 4px 0 0; }

/* social + contact */
.social-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 20px; }
.social {
  display: inline-flex; align-items: center; gap: 0.5em; padding: 10px 16px;
  border-radius: var(--radius-control); border: 1px solid var(--line);
  background: var(--card); color: var(--text);
  font-size: 14px; transition: border-color 0.15s;
}
.social:hover { border-color: var(--accent-line); text-decoration: none; }
.social .todo { color: var(--muted); font-size: 12.5px; }

/* FAQ — real questions, answered plainly. Also feeds FAQPage schema. */
.faq { margin-top: 36px; display: flex; flex-direction: column; gap: 12px; }
.faq details {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius-card); padding: 18px 22px;
}
.faq summary {
  cursor: pointer; font-weight: 500; font-size: 16.5px; color: var(--text);
  list-style: none; display: flex; justify-content: space-between; gap: 16px;
  align-items: center;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+"; color: var(--accent-ink); font-size: 20px; line-height: 1; flex: none;
}
.faq details[open] summary::after { content: "\2013"; }
.faq p { margin: 14px 0 0; font-size: 15px; }

/* quiz feature tile */
.quiz-tile { padding: clamp(26px, 4.5vw, 48px); }
.quiz-feats { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 22px; }
.quiz-frame {
  margin-top: 28px; border-radius: var(--radius-card); overflow: hidden;
  border: 1px solid var(--line-strong); background: var(--bg);
  position: relative; min-height: 420px; height: min(74vh, 700px);
}
.quiz-cover {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 18px; text-align: center; padding: 24px;
}
.quiz-cover .big { font-size: clamp(22px, 4.5vw, 32px); font-weight: 500; letter-spacing: -0.02em; }
.quiz-cover p { max-width: 30ch; font-size: 15px; }
.quiz-frame iframe { width: 100%; height: 100%; border: 0; display: block; }
.quiz-foot { display: flex; flex-wrap: wrap; gap: 12px; justify-content: space-between; align-items: center; margin-top: 16px; }
.quiz-foot small { color: var(--muted); font-size: 13px; max-width: 62ch; }

/* games / projects */
.game { display: flex; flex-direction: column; padding: 0; overflow: hidden; }
.game .art {
  aspect-ratio: 16 / 10; display: grid; place-items: center; position: relative;
  background: rgba(var(--accent-rgb), 0.10);
  color: var(--accent-ink);
  border-bottom: 1px solid var(--line);
}
.game .art > svg { width: 56px; height: 56px; stroke-width: 1.25; }
.game .art .soon {
  position: absolute; bottom: 10px; right: 10px; font-size: 12px;
  background: var(--solid); color: var(--muted); border: 1px solid var(--line);
  padding: 4px 10px; border-radius: var(--radius-pill);
}
.game .body { padding: 20px 22px 24px; display: flex; flex-direction: column; gap: 10px; flex: 1; }
.game .tags { display: flex; flex-wrap: wrap; gap: 6px; }
.game .tags .chip { font-size: 12px; padding: 4px 11px; }
.game p { font-size: 14.5px; margin: 0; }
.custom { padding: clamp(24px, 4vw, 40px); display: flex; flex-wrap: wrap; align-items: center; gap: 24px; }
.custom .txt { flex: 1 1 380px; }
.custom p { margin-top: 10px; max-width: 60ch; }

/* about */
.about-grid { display: grid; gap: var(--gap); margin-top: 36px; grid-template-columns: 1fr; }
@media (min-width: 840px) { .about-grid { grid-template-columns: 1.2fr 0.8fr; } }
.about-card { padding: clamp(24px, 4vw, 36px); }
.about-card p { margin-top: 12px; }
.avatar-ph {
  width: 88px; height: 88px; border-radius: 50%;
  background: rgba(var(--accent-rgb), 0.16);
  color: var(--accent-ink);
  display: grid; place-items: center;
  margin-bottom: 18px;
  object-fit: cover;
}
.avatar-ph svg { width: 40px; height: 40px; }
.c-rows { display: flex; flex-direction: column; gap: 4px; margin-top: 18px; }
.c-row { display: flex; gap: 14px; align-items: flex-start; padding: 12px 0; border-bottom: 1px solid var(--line); }
.c-row:last-child { border-bottom: none; }
.c-row .ci { flex: none; width: 26px; display: grid; place-items: center; color: var(--accent-ink); margin-top: 2px; }
.c-row .ci svg { width: 19px; height: 19px; }
.c-row b { font-size: 14.5px; font-weight: 500; display: block; color: var(--text); }
.c-row span { font-size: 14px; color: var(--muted); }
.c-row a { font-size: 14px; }

/* Copy-to-clipboard control for IDs with no deep link (WeChat). A <button>,
   not an <a>, because it performs an action and goes nowhere — but styled as
   a link so it reads the same as the LINE and email rows beside it. */
.idcopy {
  font: inherit; font-size: 14px; color: var(--link);
  background: none; border: 0; padding: 0; cursor: pointer;
  text-decoration: underline; text-underline-offset: 2px;
}
.idcopy:hover { color: var(--accent-ink); }

/* CTA band */
.cta-band { padding: clamp(28px, 5vw, 48px); text-align: center; }
.cta-band .sub { max-width: 48ch; margin-left: auto; margin-right: auto; }
.cta-band .btn-primary { margin-top: 26px; }

/* -----------------------------------------------------------------------
   12. FORMS — 10px radius on every control, per the corner scale
   ----------------------------------------------------------------------- */
.form-panel { padding: clamp(24px, 4.5vw, 40px); max-width: 720px; margin: 36px auto 0; }
.f-row { display: grid; gap: 16px; margin-bottom: 18px; }
@media (min-width: 640px) { .f-row.two { grid-template-columns: 1fr 1fr; } }

label.f-label, span.f-label {
  display: block; font-size: 14px; font-weight: 500; margin-bottom: 7px; color: var(--text);
}
label.f-label small, span.f-label small { color: var(--muted); font-weight: 400; }

input[type=text], input[type=email], input[type=tel], select, textarea {
  width: 100%; font: inherit; font-size: 16px; color: var(--text);
  background: var(--card); border: 1px solid var(--line-strong);
  border-radius: var(--radius-control); padding: 13px 15px;
  transition: border-color 0.15s;
  -webkit-appearance: none; appearance: none;
}
input::placeholder, textarea::placeholder { color: var(--muted); }
select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23888' stroke-width='2' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 15px center; padding-right: 40px;
}
textarea { min-height: 100px; resize: vertical; }
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--accent-line); }
input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--accent-line); outline-offset: 1px;
}

.opt-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.opt-chips label { position: relative; cursor: pointer; }
.opt-chips input { position: absolute; opacity: 0; pointer-events: none; }
.opt-chips span {
  display: inline-block; padding: 10px 17px; border-radius: var(--radius-pill);
  font-size: 14.5px; border: 1px solid var(--line-strong); background: var(--card);
  color: var(--text); transition: background-color 0.15s, color 0.15s, border-color 0.15s;
  user-select: none;
}
.opt-chips input:checked + span {
  background: var(--gm-yellow); color: var(--gm-yellow-text);
  border-color: var(--gm-yellow); font-weight: 500;
}
.opt-chips input:focus-visible + span { outline: 2px solid var(--accent-line); outline-offset: 2px; }

.consent { display: flex; gap: 12px; align-items: flex-start; margin: 22px 0 8px; }
.consent input { width: 20px; height: 20px; margin-top: 3px; accent-color: var(--gm-cyan-outline); flex: none; cursor: pointer; }
.consent label { font-size: 14px; cursor: pointer; color: var(--muted); }
.data-note { font-size: 13px; color: var(--muted); line-height: 1.6; margin-bottom: 22px; }
.data-note b { color: var(--text); font-weight: 500; }
.hp { position: absolute; left: -9999px; top: -9999px; height: 1px; width: 1px; overflow: hidden; }

.form-status { margin-top: 22px; border-radius: var(--radius-card); padding: 22px 24px; display: none; }
.form-status.show { display: block; }
.form-status.ok {
  background: rgba(var(--rgb-cyan), 0.10);
  border: 1px solid rgba(var(--rgb-cyan), 0.30);
}
/* Error red is reserved for error/warning states only, and this is one. */
.form-status.warn {
  background: rgba(var(--rgb-error), 0.10);
  border: 1px solid rgba(var(--rgb-error), 0.35);
}
.form-status h3 { margin-bottom: 8px; }
.form-status p { font-size: 15px; }
.form-status .acts { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 16px; }
.err { color: var(--gm-error); font-size: 13px; margin-top: 6px; display: none; }
:root[data-theme="light"] .err { color: #c62828; } /* #ff5252 on white is 2.6:1 */

/* -----------------------------------------------------------------------
   13. FOOTER
   ----------------------------------------------------------------------- */
footer { padding: 44px 0 56px; border-top: 1px solid var(--line); margin-top: 24px; }
footer .wrap-lg { display: flex; flex-direction: column; gap: 18px; }
.footer-nav { display: flex; flex-wrap: wrap; gap: 6px 18px; }
.footer-nav a { color: var(--muted); font-size: 14px; }
.footer-nav a:hover { color: var(--text); }
.footer-bottom { display: flex; flex-wrap: wrap; gap: 10px 18px; justify-content: space-between; align-items: center; }
/* NAP block — <address> is italic by UA default, which reads as an aside */
.nap { font-style: normal; color: var(--muted); font-size: 13.5px; line-height: 1.6; }
.nap b { font-weight: 500; }
footer p { color: var(--muted); font-size: 13.5px; margin: 0; }
footer .brandline { color: var(--text); font-weight: 500; }
footer .brandline .metric { color: var(--accent-ink); }

/* -----------------------------------------------------------------------
   14. REVEAL ON SCROLL
   These start invisible, so if the observer in shared.js fails the page is
   blank. prefers-reduced-motion short-circuits them to visible, and so does
   the no-JS fallback in each page's <noscript>.
   ----------------------------------------------------------------------- */
.reveal { opacity: 0; transform: translateY(16px); transition: opacity 0.6s ease, transform 0.6s ease; }
.reveal.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; }
}

/* -----------------------------------------------------------------------
   15. PRINT
   ----------------------------------------------------------------------- */
@media print {
  .topbar, .theme-toggle, .burger, .mobile-menu, .quiz-frame { display: none !important; }
  .reveal { opacity: 1; transform: none; }
  body { background: #fff; color: #000; }
}
