    /* Country-flag emoji polyfill — Windows fonts render regional indicator
       pairs (🇦🇿) as letters ("AZ") instead of flags. The unicode-range
       confines this font to flag codepoints only; everything else keeps
       Inter. Listed first in --font-body so it wins for those codepoints. */
    @font-face {
      font-family: 'TwFlags';
      unicode-range: U+1F1E6-1F1FF;
      src: url('https://cdn.jsdelivr.net/npm/country-flag-emoji-polyfill@0.1.8/dist/TwemojiCountryFlags.woff2') format('woff2');
      font-display: swap;
    }

    :root {
      /* Brand */
      --bg:        #FAF6EA;
      --bg-tint:   #FFFDF4;
      --card:      #FFFFFF;
      --ink:       #1A1610;
      --ink-soft:  #5C5345;
      --ink-mute:  #968A75;
      --line:      #E8DFC8;
      --line-soft: #F1EAD3;
      --accent-warm: #D67659;       /* terracotta — used for highlights */
      --accent-warm-soft: #F4D9C9;
      --accent-blue: #1F4D6B;       /* deep blue — secondary accent */
      --gold:      #B8923A;
      --shadow-sm: 0 2px 8px rgba(26,22,16,.04);
      --shadow-md: 0 12px 36px rgba(26,22,16,.08);
      --shadow-lg: 0 22px 60px rgba(26,22,16,.12);
      --radius:    14px;
      --radius-lg: 22px;
      --font-display: 'Fraunces', Georgia, 'Times New Roman', serif;
      --font-body:    'TwFlags', 'Inter', -apple-system, 'Segoe UI', Roboto, sans-serif;
    }

    /* ─── Dark theme ───
       Warm-tinted dark palette. Keeps the brand's cream/cocoa identity
       instead of going clinical-blue. Backgrounds are deep cocoa rather
       than pure black to reduce eye strain; ink is a soft cream so long
       reading sessions don't feel high-contrast.

       Strategy: override the same semantic tokens. Anywhere CSS says
       var(--card, #fff) the variable wins, so most existing rules adapt
       automatically. A small set of hardcoded #fff / white literals are
       targeted at the bottom of this file. */
    [data-theme="dark"] {
      --bg:        #14110D;
      --bg-tint:   #1A1611;
      --card:      #211D17;
      --ink:       #F2EBDB;
      --ink-soft:  #B5AC9A;
      --ink-mute:  #7E7866;
      --line:      #2E2920;
      --line-soft: #241F18;
      --accent-warm: #E89274;
      --accent-warm-soft: #3A2820;
      --accent-blue: #5DA0C2;
      --gold:      #D4A857;
      --shadow-sm: 0 2px 10px rgba(0,0,0,.35);
      --shadow-md: 0 12px 36px rgba(0,0,0,.55);
      --shadow-lg: 0 22px 60px rgba(0,0,0,.7);
      color-scheme: dark;
    }
    /* Light theme is the default; expose a class for symmetry so other
       CSS can scope :not([data-theme="dark"]) rules if needed. */
    [data-theme="light"] { color-scheme: light; }

    /* Lesson reader correctness colours need dark-tuned variants so the
       red/green callouts don't blowtorch the eye on a dark page.
       :root[data-theme=...] beats lessons.css's plain :root by one
       point of specificity, so source order doesn't matter. */
    :root[data-theme="dark"] {
      --read-wrong:    #E08470;
      --read-wrong-bg: #3A1F18;
      --read-right:    #6FBA8A;
      --read-right-bg: #18301F;
    }

    * { box-sizing: border-box; }

    html, body {
      margin: 0; padding: 0;
      font-family: var(--font-body);
      color: var(--ink);
      background: var(--bg);
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      font-feature-settings: "locl" 0;
    }

    body {
      min-height: 100vh;
      position: relative;
      overflow-x: hidden;
    }

    /* Ambient glow + paper grain — subtle, premium */
    body::before {
      content: ''; position: fixed; inset: 0; pointer-events: none; z-index: 0;
      background:
        radial-gradient(ellipse 60% 40% at 80% 5%, rgba(184, 146, 58, 0.10), transparent 70%),
        radial-gradient(ellipse 50% 50% at 10% 95%, rgba(214, 118, 89, 0.08), transparent 70%);
    }
    body::after {
      content: ''; position: fixed; inset: 0; pointer-events: none; z-index: 0;
      background-image: radial-gradient(circle at 1px 1px, rgba(26, 22, 16, 0.025) 1px, transparent 0);
      background-size: 3px 3px;
      mix-blend-mode: multiply;
    }

    a { color: inherit; text-decoration: none; }
    button { font-family: inherit; cursor: pointer; }
    img { display: block; max-width: 100%; }

    /* ── Layout shell ─────────────────────────────────────────────── */
    .shell { position: relative; z-index: 1; }
    /* Pre-route hint set by the inline <head> script — hides the public
       marketing shell from the very first paint when the URL is a portal
       route. Prevents the homepage from flashing during deep-link loads. */
    html.is-portal-init .shell { display: none !important; }
    html.is-portal-init body { background: var(--bg, #F4EEDF); }
    .container { max-width: 1180px; margin: 0 auto; padding: 0 2rem; }
    @media (max-width: 720px) { .container { padding: 0 1.25rem; } }

    /* ─── Theme toggle pill (used in profile settings modal) ─── */
    .theme-toggle {
      display: inline-flex;
      background: var(--bg-tint);
      border: 1px solid var(--line);
      border-radius: 999px;
      padding: 3px;
      gap: 2px;
    }
    .theme-btn {
      display: inline-flex; align-items: center; gap: .4rem;
      padding: .45rem .85rem;
      background: transparent;
      border: none;
      border-radius: 999px;
      font-family: var(--font-body);
      font-size: .82rem; font-weight: 600;
      color: var(--ink-mute);
      cursor: pointer;
      transition: color .15s, background .15s;
    }
    .theme-btn svg { display: block; }
    .theme-btn:hover { color: var(--ink); }
    .theme-btn.is-active {
      background: var(--card);
      color: var(--ink);
      box-shadow: var(--shadow-sm);
    }

    /* ─── Dark-mode targeted patches ───
       Most CSS uses var(--token) and adapts automatically. These rules
       handle the corners that don't: form controls, audio elements, and
       shadow-sm overrides on cards that needed extra contrast.

       NOTE: cards using literal white (#fff / #FFFFFF) without var
       fallback would still appear white in dark mode. We avoid hardcoded
       sweeps and just override the specific high-traffic places. */
    [data-theme="dark"] input,
    [data-theme="dark"] textarea,
    [data-theme="dark"] select {
      background: var(--bg-tint);
      color: var(--ink);
      border-color: var(--line);
    }
    [data-theme="dark"] input::placeholder,
    [data-theme="dark"] textarea::placeholder { color: var(--ink-mute); }

    [data-theme="dark"] input[type="checkbox"],
    [data-theme="dark"] input[type="radio"] {
      accent-color: var(--accent-warm);
    }

    /* Native audio player on dark — invert just enough to avoid pure
       white scrub bar on the 3-Part Speaking playback. */
    [data-theme="dark"] audio {
      filter: invert(.88) hue-rotate(180deg) saturate(.6);
    }

    /* Code chunks (used in placeholder-empty hints) */
    [data-theme="dark"] code {
      background: var(--bg-tint);
      color: var(--accent-warm);
      padding: 1px 5px;
      border-radius: 4px;
    }

    /* Selection highlight */
    [data-theme="dark"] ::selection {
      background: rgba(232, 146, 116, .35);
      color: var(--ink);
    }

    /* ─── Hardcoded-white safety net ───
       Targets the most common patterns where elements use literal #fff
       or `white` without a var() fallback. Applies a sane dark surface
       so the page never has glaring white rectangles. */
    [data-theme="dark"] [style*="background: #fff"],
    [data-theme="dark"] [style*="background:#fff"],
    [data-theme="dark"] [style*="background: white"],
    [data-theme="dark"] [style*="background-color: #fff"],
    [data-theme="dark"] [style*="background-color:#fff"] {
      background: var(--card) !important;
    }

    /* ─── Dark-mode component patches ───
       Components that hardcode dark-on-light colours (forest green text,
       maroon text, light gradients, etc.) become invisible on a dark
       page. Re-tune them here without touching the light theme. */

    /* Band pill on Profile writing trend — is-mid uses var(--ink) which
       inverts to cream in dark, leaving white text on cream. Pin the
       dark variant to a fixed dark grey + cream text for readability. */
    [data-theme="dark"] .pp-band-pill.is-mid {
      background: #3A332A;
      color: #F2EBDB;
      border-color: #3A332A;
    }
    [data-theme="dark"] .pp-band-pill.is-low {
      background: rgba(232, 146, 116, .15);
      color: #E89274;
      border-color: rgba(232, 146, 116, .45);
    }
    [data-theme="dark"] .pp-band-pill.is-high {
      background: #2A6B47;
      color: #fff;
      border-color: #2A6B47;
    }
    [data-theme="dark"] .pp-band-pill[data-latest="1"] {
      box-shadow: 0 0 0 3px rgba(242,235,219,.1);
    }

    /* Completed lesson card — light-green gradient bg goes invisible in
       dark; cream text on light green is unreadable. Re-tune to a deep
       forest with slightly brighter accent. */
    [data-theme="dark"] .course-card.is-completed {
      background: linear-gradient(180deg, #1A2D22 0%, #16261D 60%, #14221A 100%);
      border-color: rgba(111, 186, 138, .35);
      box-shadow: 0 0 0 1px rgba(111, 186, 138, .15) inset;
    }
    [data-theme="dark"] .course-card.is-completed:hover {
      border-color: #6FBA8A;
      box-shadow: 0 0 0 1px #6FBA8A inset, var(--shadow-md);
    }
    [data-theme="dark"] .course-card.is-completed .course-card-eyebrow {
      color: #6FBA8A !important;
    }
    [data-theme="dark"] .course-card.is-completed .course-card-eyebrow::before {
      color: #6FBA8A;
    }
    /* Category eyebrows — re-tune the dark hex codes to brighter ones so
       they stand out on the dark card bg. */
    [data-theme="dark"] .course-card.is-cat-grammar  .course-card-eyebrow { color: #6FA0C2; }
    [data-theme="dark"] .course-card.is-cat-vocab    .course-card-eyebrow { color: #7AB58A; }
    [data-theme="dark"] .course-card.is-cat-reading  .course-card-eyebrow { color: #66C2B5; }
    [data-theme="dark"] .course-card.is-cat-writing  .course-card-eyebrow { color: #E08470; }
    [data-theme="dark"] .course-card.is-cat-speaking .course-card-eyebrow { color: #E89274; }
    [data-theme="dark"] .course-card.is-cat-strategy .course-card-eyebrow { color: #C4955F; }

    /* Reader quiz feedback panel — was forest-green / maroon text,
       unreadable on dark. Brighten + lift the bg opacity. */
    [data-theme="dark"] .reader-quiz-feedback.is-correct {
      background: rgba(111, 186, 138, .12);
      color: #9FD4B0;
      border-color: rgba(111, 186, 138, .35);
    }
    [data-theme="dark"] .reader-quiz-feedback.is-wrong {
      background: rgba(224, 132, 112, .12);
      color: #F0AC9A;
      border-color: rgba(224, 132, 112, .35);
    }
    [data-theme="dark"] .reader-quiz-feedback.is-correct .reader-quiz-fb-icon { background: #6FBA8A; }
    [data-theme="dark"] .reader-quiz-feedback.is-wrong   .reader-quiz-fb-icon { background: #E08470; }

    /* Reader quiz options + multi rows — bump the correct/wrong bg
       opacity in dark so the tint actually shows. */
    [data-theme="dark"] .reader-quiz-option.is-correct,
    [data-theme="dark"] .reader-quiz-multi-row.is-correct {
      background: rgba(111, 186, 138, .14);
      border-color: #6FBA8A;
    }
    [data-theme="dark"] .reader-quiz-option.is-wrong,
    [data-theme="dark"] .reader-quiz-multi-row.is-wrong {
      background: rgba(224, 132, 112, .14);
      border-color: #E08470;
    }
    [data-theme="dark"] .reader-quiz-option.is-correct .reader-quiz-option-letter { background: #6FBA8A; }
    [data-theme="dark"] .reader-quiz-option.is-wrong   .reader-quiz-option-letter { background: #E08470; }
    [data-theme="dark"] .reader-quiz-dot.is-correct { background: #6FBA8A; }
    [data-theme="dark"] .reader-quiz-dot.is-wrong   { background: #E08470; }

    /* Lesson card body text — the title used `color: var(--ink)` which
       inverts correctly to cream, but ensures it stays readable on the
       completed card's deep-green bg. */
    [data-theme="dark"] .course-card,
    [data-theme="dark"] .course-card.is-completed { color: var(--ink); }

    /* Speaking — recording status pill text is dark maroon on light;
       brighten on dark. */
    [data-theme="dark"] .sp-rec-status-l { color: #F0AC9A; }
    [data-theme="dark"] .sp-rec-status {
      background: rgba(224, 132, 112, .12);
      border-color: rgba(224, 132, 112, .35);
    }

    /* Sentence-Upgrade Gym — orig + revised pill backgrounds need lift */
    [data-theme="dark"] .su-miss-yours   { background: rgba(224,132,112,.10); }
    [data-theme="dark"] .su-miss-correct { background: rgba(111,186,138,.10); }
    [data-theme="dark"] .su-bad-label    { color: #F0AC9A; }
    [data-theme="dark"] .su-prompt       { border-left-color: #E08470; }

    /* Task 2 / Rewrite annotations — dark-red/green text on dark bg.
       Brighten via theme-specific overrides. */
    [data-theme="dark"] .t2-anno-pop-issue   .t2-anno-pop-cat,
    [data-theme="dark"] .rw-anno-pop-issue   .rw-anno-pop-cat { color: #F0AC9A; }
    [data-theme="dark"] .t2-anno-pop-praise  .t2-anno-pop-cat,
    [data-theme="dark"] .rw-anno-pop-upgrade .rw-anno-pop-cat { color: #9FD4B0; }
    [data-theme="dark"] .t2-bullet.is-strength { background: rgba(111,186,138,.12); }
    [data-theme="dark"] .t2-bullet.is-fix      { background: rgba(224,132,112,.12); }

    /* SU summary hero — match dark theme moods for win/lose tiers */
    [data-theme="dark"] .su-summary-hero.is-elite { background: #1F4D33; }
    [data-theme="dark"] .su-summary-hero.is-good  { background: #1F4D33; }
    [data-theme="dark"] .su-summary-hero.is-mid   { background: #2A2521; }
    [data-theme="dark"] .su-summary-hero.is-weak  { background: #4D2419; }

    /* Comparison block (✗ wrong / ✓ right) in lesson reader.
       Backgrounds adapt via --read-wrong-bg / --read-right-bg, but the
       body + italic explanation text still need brighter shades so they
       read on the darker tinted backgrounds. */
    [data-theme="dark"] .rb-cmp-row.is-wrong {
      color: #F5E8DD;
      border-color: rgba(224, 132, 112, .35);
    }
    [data-theme="dark"] .rb-cmp-row.is-right {
      color: #E6F1E8;
      border-color: rgba(111, 186, 138, .35);
    }
    [data-theme="dark"] .rb-cmp-row.is-wrong .rb-cmp-text em { color: #F0AC9A; }
    [data-theme="dark"] .rb-cmp-row.is-right .rb-cmp-text em { color: #9FD4B0; }
    [data-theme="dark"] .rb-cmp-row strong,
    [data-theme="dark"] .rb-cmp-row b { color: inherit; font-weight: 700; }

    /* Reveal block (the "Show answer / Hide answer" question card from
       grammar lessons). Use the same brighter palette so the answer
       inside reads cleanly on the dark page. */
    [data-theme="dark"] .rb-reveal,
    [data-theme="dark"] .rb-reveal-card {
      background: var(--bg-tint);
      border-color: var(--line);
      color: var(--ink);
    }
    [data-theme="dark"] .rb-reveal-answer {
      background: rgba(111, 186, 138, .12);
      color: #E6F1E8;
      border-color: rgba(111, 186, 138, .35);
    }
    [data-theme="dark"] .rb-reveal-answer em { color: #9FD4B0; }


    /* ─── Thin custom scrollbars ─────────────────────────────────────────
       Hide the chunky Windows arrows + fat thumb. Keep a slim, subtle
       indicator so users can still see they can scroll. Touchpads /
       trackpads get the OS-default overlay scrollbar; this only affects
       browsers that show a persistent scrollbar (mostly Windows). */
    * {
      scrollbar-width: thin;                       /* Firefox */
      scrollbar-color: rgba(0,0,0,0.18) transparent;
    }
    [data-theme="dark"] * {
      scrollbar-color: rgba(255,255,255,0.22) transparent;
    }
    *::-webkit-scrollbar { width: 8px; height: 8px; }
    *::-webkit-scrollbar-track { background: transparent; }
    *::-webkit-scrollbar-thumb {
      background: rgba(0,0,0,0.18);
      border-radius: 999px;
      border: 2px solid transparent;
      background-clip: padding-box;
    }
    *::-webkit-scrollbar-thumb:hover { background-color: rgba(0,0,0,0.32); background-clip: padding-box; }
    [data-theme="dark"] *::-webkit-scrollbar-thumb { background-color: rgba(255,255,255,0.22); background-clip: padding-box; }
    [data-theme="dark"] *::-webkit-scrollbar-thumb:hover { background-color: rgba(255,255,255,0.36); background-clip: padding-box; }
    /* Hide the up/down arrow buttons that Windows still draws */
    *::-webkit-scrollbar-button { display: none; height: 0; width: 0; }
    *::-webkit-scrollbar-corner { background: transparent; }
