/* =============================================================
   AOE Centre — theme layer
   -------------------------------------------------------------
   Load this AFTER portal.css (and after style.css on the public
   site). It adds three things and changes nothing else:

     1. Eight surface roles as custom properties, in two modes.
     2. The pill switch used by the theme and language toggles.
     3. Dark-mode values for every component portal.css already
        defines, so an existing page flips without being rewritten.

   New pages are written against the roles only, so they need no
   entry in section 3 — they are correct in both modes by
   construction. That is the whole point of naming the roles.

   The mode lives on <html data-theme="light|dark">. aoe-theme.js
   sets it before first paint; nothing here assumes JS ran.
   ============================================================= */

/* ---------------------------------------------------------------
   1. THE EIGHT ROLES
   Light is the palette already in style.css. Dark is the palette
   already in portal.css under .quiz-body and .board-body. Nothing
   new is introduced — only named.
   --------------------------------------------------------------- */
:root {
  --bg:            #F5F2EA;   /* page behind everything            */
  --surface:       #FFFDF7;   /* cards, panels, question boxes     */
  --raised:        #FFFFFF;   /* a card inside a card; options     */
  --rule-c:        #E2DBCB;   /* every 1px border and divider      */
  --text:          #2B2721;   /* body copy, headings               */
  --dim:           #7C7466;   /* captions, meta, mono eyebrows     */
  --accent:        #A08C42;   /* numbers, links, left borders      */
  --header:        #9B9283;   /* masthead and hero band            */

  /* --- derived, so components never reach for a raw hex --- */
  --rule-strong:   #C6BBA7;   /* option and input borders          */
  --header-text:   #F5F2EA;
  --header-dim:    rgba(245,242,234,.82);
  --on-accent:     #F5F2EA;   /* text on an accent fill            */
  --body-copy:     #4A443B;   /* long prose, slightly off --text   */
  --shadow-card:   0 2px 8px rgba(43,39,33,.05);
  --shadow-lift:   0 3px 10px rgba(43,39,33,.06);

  /* --- the runner's question box and answer options --- */
  --qbox-bg:       #FFFFFF;
  --qbox-border:   #C6BBA7;
  --opt-bg:        #FFFFFF;
  --opt-border:    #C6BBA7;
  --opt-bg-sel:    #FFFFFF;

  /* --- meaning colours: fixed in both modes, lightness only --- */
  --correct:       #3F7A56;
  --correct-line:  #3F7A56;
  --correct-soft:  #F2F7F3;
  --wrong:         #B0442F;
  --wrong-line:    #B0442F;
  --wrong-soft:    #FDF3F1;
  --warn:          #C9922F;
  --warn-line:     #C9922F;
  --warn-soft:     #FBF4E6;
  --on-meaning:    #FFFFFF;   /* text on a filled meaning chip     */
}
html[data-theme="dark"] {
  --bg:            #211E19;
  --surface:       #2B2721;
  --raised:        #332F28;
  --rule-c:        #3E3931;
  --text:          #F5F2EA;
  --dim:           #A9A296;
  --accent:        #DFCD83;
  --header:        #1A1713;

  --rule-strong:   #3E3931;
  --header-text:   #F5F2EA;
  --header-dim:    #A9A296;
  --on-accent:     #2B2721;
  --body-copy:     #F5F2EA;
  --shadow-card:   none;
  --shadow-lift:   none;

  --qbox-bg:       rgba(245,242,234,.11);
  --qbox-border:   rgba(245,242,234,.32);
  --opt-bg:        #3d3830;
  --opt-border:    #5c554c;
  --opt-bg-sel:    #3a352d;

  --correct:       #7FC79A;
  --correct-line:  #5FA97C;
  --correct-soft:  rgba(95,169,124,.24);
  --wrong:         #E08A72;
  --wrong-line:    #C4553D;
  --wrong-soft:    rgba(196,85,61,.24);
  --warn:          #DCA94A;
  --warn-line:     #DCA94A;
  --warn-soft:     rgba(220,169,74,.18);
  --on-meaning:    #2B2721;
}

/* There is deliberately no prefers-color-scheme block here.
   aoe-theme.js resolves the system preference into an explicit
   data-theme on <html> before first paint, so exactly one of the
   two blocks above is ever live. Half-flipping — tokens dark but
   components still light — is the one state worth engineering
   away, and a visitor with JS off gets a coherent light page
   rather than an incoherent dark one. */

/* -------------------------------------------------------------
   2. THE PILL SWITCH
   Round means "this switches something". The theme and language
   toggles are the only full-radius objects in the product;
   buttons keep their 2px, cards and status pills stay square.
   ------------------------------------------------------------- */
.aoe-pill {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--rule-strong);
  border-radius: 999px;
  padding: 3px;
  background: var(--bg);
  flex: 0 0 auto;
  gap: 0;
}
.aoe-pill button {
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--dim);
  cursor: pointer;
  font-family: "Karla", sans-serif;
  font-size: 12.5px;
  line-height: 1.4;
  padding: 4px 13px;
  transition: background .15s ease, color .15s ease;
}
.aoe-pill button:hover:not(.on) { color: var(--text); }
.aoe-pill button.on {
  background: #DFCD83;
  color: #2B2721;
  font-weight: 700;
}
/* The theme switch labels are mono; the language switch labels are not. */
.aoe-pill.mono button {
  font-family: "IBM Plex Mono", "Consolas", monospace;
  font-size: 11px;
  letter-spacing: .12em;
  padding: 5px 13px;
  font-weight: 400;
}
.aoe-pill.mono button.on { font-weight: 500; }

/* On a coloured band (masthead, hero, admin bar) the pill sits on
   taupe in light mode and on near-black in dark mode. */
.aoe-pill.on-band {
  border-color: rgba(245,242,234,.4);
  background: rgba(43,39,33,.18);
}
.aoe-pill.on-band button { color: rgba(245,242,234,.8); }
.aoe-pill.on-band button:hover:not(.on) { color: #fff; }
.aoe-pill.on-band button.on { background: #DFCD83; color: #2B2721; }
html[data-theme="dark"] .aoe-pill.on-band {
  border-color: #3E3931;
  background: rgba(245,242,234,.06);
}
html[data-theme="dark"] .aoe-pill.on-band button { color: var(--text); }
html[data-theme="dark"] .aoe-pill.on-band button.on { background: #DFCD83; color: #2B2721; }

/* The language toggle takes the same shape, so the header carries
   one idea rather than two competing control styles. */
#aoe-lang {
  display: inline-flex;
  align-items: center;
  border: 1px solid rgba(245,242,234,.4);
  border-radius: 999px;
  overflow: visible;
  padding: 3px;
  background: rgba(43,39,33,.18);
  margin-left: 4px;
}
#aoe-lang button {
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: rgba(245,242,234,.8);
  cursor: pointer;
  font-family: "Karla", sans-serif;
  font-size: 12.5px;
  padding: 4px 13px;
  line-height: 1.4;
}
#aoe-lang button.on { background: #DFCD83; color: #2B2721; font-weight: 700; }
#aoe-lang button:hover:not(.on) { color: #fff; }
html[data-theme="dark"] #aoe-lang { border-color: #3E3931; background: rgba(245,242,234,.06); }
html[data-theme="dark"] #aoe-lang button { color: var(--text); }
html[data-theme="dark"] #aoe-lang button.on { background: #DFCD83; color: #2B2721; font-weight: 700; }

/* Both switches sit inside the same cluster wherever they appear. */
.aoe-switches { display: flex; gap: 10px; align-items: center; }

@media (prefers-reduced-motion: reduce) {
.aoe-pill button { transition: none; }
}

/* -------------------------------------------------------------
   3. DARK VALUES FOR WHAT portal.css ALREADY DEFINES
   Everything below is an override, never a new component. Light
   mode is untouched: these rules only apply under data-theme=dark.
   ------------------------------------------------------------- */
html[data-theme="dark"] body { background: var(--bg); color: var(--text); }

/* header, hero, footer */
html[data-theme="dark"] .top,
html[data-theme="dark"] .masthead { background: var(--header); border-bottom-color: var(--rule-c); }
html[data-theme="dark"] .hero { background: var(--header); }
html[data-theme="dark"] .hero h1 { color: var(--text); }
html[data-theme="dark"] .hero .lede { color: var(--dim); }
html[data-theme="dark"] .masthead nav a { color: var(--dim); }
html[data-theme="dark"] .masthead nav a:hover { color: var(--text); border-bottom-color: var(--accent); }
html[data-theme="dark"] footer { background: var(--header); color: var(--dim); }
html[data-theme="dark"] footer a { color: var(--dim); }
html[data-theme="dark"] .bar { background: var(--header); color: var(--text); }
html[data-theme="dark"] .bar h1 { color: var(--text); }
html[data-theme="dark"] .bar a { color: var(--accent); }
html[data-theme="dark"] .nav-portal { border-color: var(--rule-c); }

/* bands and prose */
html[data-theme="dark"] .band-cream { background: var(--bg); }
html[data-theme="dark"] .band-panel { background: var(--surface); border-top-color: var(--rule-c); border-bottom-color: var(--rule-c); }
html[data-theme="dark"] .band-taupe { background: var(--header); }
html[data-theme="dark"] .prose,
html[data-theme="dark"] .section-intro,
html[data-theme="dark"] .compare td,
html[data-theme="dark"] .update p { color: var(--dim); }
html[data-theme="dark"] .ticks li { border-bottom-color: var(--rule-c); }
html[data-theme="dark"] .eyes i { background: var(--rule-c); }
html[data-theme="dark"] .group-head { border-bottom-color: var(--rule-strong); }
html[data-theme="dark"] .eyebrow { color: var(--accent); }

/* cards and panels */
html[data-theme="dark"] .card { background: var(--surface); border-color: var(--rule-c); }
html[data-theme="dark"] .card.quiet { background: transparent; }
html[data-theme="dark"] .card.fresh { border-left-color: var(--accent); }
html[data-theme="dark"] .sub,
html[data-theme="dark"] .tip,
html[data-theme="dark"] .dim,
html[data-theme="dark"] .cycsub,
html[data-theme="dark"] .cycnote,
html[data-theme="dark"] .secline,
html[data-theme="dark"] .minisub,
html[data-theme="dark"] .minifoot,
html[data-theme="dark"] .crumbline,
html[data-theme="dark"] .catmeta,
html[data-theme="dark"] .es-k { color: var(--dim); }
html[data-theme="dark"] .introbox { background: var(--raised); border-left-color: var(--accent); }
html[data-theme="dark"] .soonbox { background: var(--raised); border-color: var(--rule-c); }
html[data-theme="dark"] .howto li,
html[data-theme="dark"] .rules li { color: var(--body-copy); }
html[data-theme="dark"] .msg { background: var(--surface); border-left-color: var(--correct-line); }
html[data-theme="dark"] .msg.err { border-left-color: var(--wrong-line); color: var(--wrong); }

/* buttons */
html[data-theme="dark"] .btn { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
html[data-theme="dark"] .btn:hover { background: var(--text); border-color: var(--text); color: var(--bg); }
html[data-theme="dark"] .btn.ghost { background: transparent; color: var(--text); border-color: var(--rule-c); }
html[data-theme="dark"] .btn.ghost:hover { background: var(--text); color: var(--bg); }
html[data-theme="dark"] .btn.danger { color: var(--wrong); border-color: var(--wrong); background: transparent; }
html[data-theme="dark"] .btn.danger:hover { background: var(--wrong-line); color: #fff; }
html[data-theme="dark"] .btn-outline { background: transparent; color: var(--text); border-color: var(--rule-c); }
html[data-theme="dark"] .btn-outline:hover { background: var(--text); color: var(--bg); }
html[data-theme="dark"] .btn-dark { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }

/* tabs, chips, pills */
html[data-theme="dark"] .tabs a { background: var(--surface); border-color: var(--rule-c); color: var(--dim); }
html[data-theme="dark"] .tabs a.on { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
html[data-theme="dark"] .chips a { border-color: var(--rule-c); color: var(--dim); }
html[data-theme="dark"] .chips a.on { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
html[data-theme="dark"] .pill { border-color: var(--rule-c); color: var(--text); }
html[data-theme="dark"] .pill.good { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
html[data-theme="dark"] .pill.bad { background: var(--wrong-line); border-color: var(--wrong-line); color: #fff; }
html[data-theme="dark"] .tag { border-color: var(--rule-c); color: var(--text); }
html[data-theme="dark"] .tag-promo,
html[data-theme="dark"] .tag-highlight { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
html[data-theme="dark"] .tag-solid { background: var(--text); border-color: var(--text); color: var(--bg); }
html[data-theme="dark"] .tag-outline { border-color: var(--rule-strong); color: var(--dim); }
html[data-theme="dark"] .donetag { color: var(--accent); border-color: var(--accent); }

/* tables */
html[data-theme="dark"] table.data th { color: var(--dim); border-bottom-color: var(--rule-strong); }
html[data-theme="dark"] table.data td { border-bottom-color: var(--rule-c); }
html[data-theme="dark"] table.mini td { border-bottom-color: var(--rule-c); }
html[data-theme="dark"] table.mini td:first-child { color: var(--dim); }
html[data-theme="dark"] table.compare th,
html[data-theme="dark"] table.compare td { border-bottom-color: var(--rule-c); }
html[data-theme="dark"] table.compare tbody th { color: var(--dim); }
html[data-theme="dark"] table.data.rankt tr.me { background: rgba(223,205,131,.16); }

/* inputs */
html[data-theme="dark"] .card input,
html[data-theme="dark"] .card select,
html[data-theme="dark"] .card textarea,
html[data-theme="dark"] .codebox,
html[data-theme="dark"] .codeout,
html[data-theme="dark"] .lead-grid input,
html[data-theme="dark"] .lead-grid select {
  background: var(--raised);
  border-color: var(--rule-c);
  color: var(--text);
}
html[data-theme="dark"] .card label { color: var(--dim); }
html[data-theme="dark"] ::placeholder { color: var(--dim); opacity: 1; }

/* subject cards on the dashboard */
html[data-theme="dark"] .sec { background: var(--surface); border-color: var(--rule-c); border-top-color: var(--rule-c); }
html[data-theme="dark"] .sec.open { border-top-color: var(--accent); }
html[data-theme="dark"] .sec.soon { border-top-color: var(--warn); }
html[data-theme="dark"] .sec .blurb,
html[data-theme="dark"] .sec .state { color: var(--dim); }
html[data-theme="dark"] .sec.open .state { color: var(--accent); }
html[data-theme="dark"] .sec.soon .state { color: var(--wrong); }
html[data-theme="dark"] .sec .until.muted,
html[data-theme="dark"] .sec .until.expired { color: var(--dim); }
html[data-theme="dark"] .barline { background: var(--rule-c); }
html[data-theme="dark"] .barline span { background: var(--accent); }
html[data-theme="dark"] .secstats { color: var(--dim); }
html[data-theme="dark"] .secstats b { color: var(--accent); }
html[data-theme="dark"] .streak .cap { color: var(--text); }
html[data-theme="dark"] .streak .cap small { color: var(--dim); }
html[data-theme="dark"] .streak .n { color: var(--accent); }

/* grouped categories */
html[data-theme="dark"] .catgroup { background: var(--surface); border-color: var(--rule-c); }
html[data-theme="dark"] .catgroup summary:hover { background: var(--raised); }
html[data-theme="dark"] .catgroup summary::before { color: var(--accent); }

/* practice set cards and the cycle box */
html[data-theme="dark"] .setcard { background: var(--raised); border-color: var(--rule-c); }
html[data-theme="dark"] .setcard p { color: var(--dim); }
html[data-theme="dark"] .setcard .meta,
html[data-theme="dark"] .setcard .best { color: var(--accent); }
html[data-theme="dark"] .setcard .best { color: var(--dim); }
html[data-theme="dark"] .cyclebox { background: var(--surface); border-color: var(--rule-c); border-left-color: var(--accent); }
html[data-theme="dark"] .cycbar { background: var(--rule-c); }
html[data-theme="dark"] .cycbar span { background: var(--accent); }

/* mini scoreboards */
html[data-theme="dark"] .boardbox { background: var(--raised); border-color: var(--rule-c); }
html[data-theme="dark"] .boardtabs button { border-color: var(--rule-c); color: var(--dim); }
html[data-theme="dark"] .boardtabs button.on { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
html[data-theme="dark"] .miniboard td { border-bottom-color: var(--rule-c); }
html[data-theme="dark"] .miniboard .rk { color: var(--dim); }
html[data-theme="dark"] .miniboard .pt { color: var(--accent); }
html[data-theme="dark"] .miniboard tr.me { background: rgba(223,205,131,.2); }
html[data-theme="dark"] .miniboard tr.gaprow td { color: var(--dim); }

/* charts and meters */
html[data-theme="dark"] .dashchart rect.on { fill: var(--accent); }
html[data-theme="dark"] .dashchart rect.off { fill: var(--rule-c); }
html[data-theme="dark"] .dashchart line.base { stroke: var(--rule-c); }
html[data-theme="dark"] .dashaxis { color: var(--dim); }
html[data-theme="dark"] .substats { border-top-color: var(--rule-c); border-bottom-color: var(--rule-c); }
html[data-theme="dark"] .substat b { color: var(--accent); }
html[data-theme="dark"] .substat span { color: var(--dim); }
html[data-theme="dark"] .weak .wt { color: var(--text); }
html[data-theme="dark"] .weak .wb { background: var(--rule-c); }
html[data-theme="dark"] .weak .wb i { background: var(--warn); }
html[data-theme="dark"] .weak .wn { color: var(--dim); }
html[data-theme="dark"] .score-track { background: var(--rule-c); }
html[data-theme="dark"] .score-track span { background: var(--accent); }
html[data-theme="dark"] .adv-bar { background: var(--rule-c); }
html[data-theme="dark"] .adv-bar span { background: var(--accent); }

/* competitions */
html[data-theme="dark"] .compline { border-bottom-color: var(--rule-c); }
html[data-theme="dark"] .compline .cdates { color: var(--dim); }

/* noticeboard, related, routes, teaser */
html[data-theme="dark"] .update { background: var(--surface); border-color: var(--rule-c); border-left-color: var(--accent); }
html[data-theme="dark"] .update time { color: var(--dim); }
html[data-theme="dark"] .related a { background: var(--surface); border-color: var(--rule-c); }
html[data-theme="dark"] .related a:hover { border-color: var(--accent); }
html[data-theme="dark"] .related .id { color: var(--accent); }
html[data-theme="dark"] .route { background: var(--surface); border-color: var(--rule-c); border-top-color: var(--rule-c); }
html[data-theme="dark"] .route.feature { border-top-color: var(--accent); box-shadow: none; }
html[data-theme="dark"] .route p { color: var(--dim); }
html[data-theme="dark"] .teaser { background: var(--surface); border-color: var(--rule-c); }
html[data-theme="dark"] .teaser-body p { color: var(--dim); }
html[data-theme="dark"] .teaser-side { background: var(--header); }
html[data-theme="dark"] .branchcard { background: var(--surface); border-color: var(--rule-c); border-top-color: var(--accent); }
html[data-theme="dark"] .branchcard h3 { color: var(--text); }
html[data-theme="dark"] .branchcard p { color: var(--dim); }
html[data-theme="dark"] .branchcard:hover { box-shadow: none; border-color: var(--accent); }

/* static question review blocks (portal + placement test) */
html[data-theme="dark"] .qcard { background: var(--surface); border-color: var(--rule-c); border-left-color: var(--rule-c); }
html[data-theme="dark"] .qcard.answered { border-left-color: var(--accent); }
html[data-theme="dark"] .qcard.result.right { border-left-color: var(--correct-line); }
html[data-theme="dark"] .qcard.result.wrong { border-left-color: var(--wrong-line); }
html[data-theme="dark"] .qtext { color: var(--text); }
html[data-theme="dark"] .qnum,
html[data-theme="dark"] .qopt .mark { color: var(--dim); }
html[data-theme="dark"] .qopt { background: var(--opt-bg); border-color: var(--opt-border); color: var(--text); }
html[data-theme="dark"] .qopt:hover { border-color: var(--accent); background: var(--opt-bg-sel); }
html[data-theme="dark"] .qopt.ans { background: var(--correct-soft); border-color: var(--correct-line); }
html[data-theme="dark"] .qopt.yours { background: var(--wrong-soft); border-color: var(--wrong-line); }
html[data-theme="dark"] .qopt .letter { color: var(--accent); }
html[data-theme="dark"] .why { background: var(--raised); border-left-color: var(--accent); color: var(--body-copy); }
html[data-theme="dark"] .passage { background: var(--raised); border-color: var(--rule-c); border-left-color: var(--rule-strong); color: var(--body-copy); }
html[data-theme="dark"] .passage .passage-tag { color: var(--dim); }

/* content check */
html[data-theme="dark"] .droparea { background: var(--raised); border-color: var(--rule-c); }
html[data-theme="dark"] .droparea.over { border-color: var(--accent); background: var(--surface); }
html[data-theme="dark"] .linky { color: var(--accent); }
html[data-theme="dark"] .verdict.ok { border-left-color: var(--correct-line); }
html[data-theme="dark"] .verdict.warn { border-left-color: var(--warn-line); }
html[data-theme="dark"] .verdict.bad { border-left-color: var(--wrong-line); }
html[data-theme="dark"] .tnum { color: var(--accent); }

/* essay marking */
html[data-theme="dark"] .es-task { background: var(--raised); border-color: var(--rule-c); border-left-color: var(--rule-c); }
html[data-theme="dark"] .es-task.on { background: var(--surface); border-left-color: var(--accent); }
html[data-theme="dark"] .es-tmeta { color: var(--accent); }
html[data-theme="dark"] .es-thint { color: var(--dim); }
html[data-theme="dark"] .es-mark { background: var(--surface); border-color: var(--rule-c); border-top-color: var(--accent); }
html[data-theme="dark"] .es-mk-name,
html[data-theme="dark"] .es-mk-top { color: var(--dim); }
html[data-theme="dark"] .es-mk-val { color: var(--text); }
html[data-theme="dark"] .es-mk-val small { color: var(--dim); }
html[data-theme="dark"] .es-mk-band { color: var(--accent); }
html[data-theme="dark"] .es-mk-bar { background: var(--rule-c); }
html[data-theme="dark"] .es-mk-bar span { background: var(--accent); }
html[data-theme="dark"] .es-honest { background: var(--surface); border-color: var(--rule-c); border-left-color: var(--accent); color: var(--body-copy); }
html[data-theme="dark"] .es-note { background: var(--surface); border-color: var(--rule-c); border-left-color: var(--rule-c); }
html[data-theme="dark"] .es-note.sev-high { border-left-color: var(--wrong); }
html[data-theme="dark"] .es-note.sev-med { border-left-color: var(--warn); }
html[data-theme="dark"] .es-note.sev-low { border-left-color: var(--rule-strong); }
html[data-theme="dark"] .es-sev { border-color: var(--rule-c); color: var(--text); }
html[data-theme="dark"] .sev-high .es-sev { background: var(--wrong); border-color: var(--wrong); color: var(--on-meaning); }
html[data-theme="dark"] .sev-med .es-sev { background: var(--warn); border-color: var(--warn); color: var(--on-meaning); }
html[data-theme="dark"] .es-crit { color: var(--dim); }
html[data-theme="dark"] .es-detail,
html[data-theme="dark"] .es-fix { color: var(--body-copy); }
html[data-theme="dark"] .es-quote { background: var(--bg); border-left-color: var(--rule-c); color: #DAD3C6; }
html[data-theme="dark"] .es-model { background: var(--raised); border-left-color: var(--accent); color: var(--text); }
html[data-theme="dark"] .es-cell { border-bottom-color: var(--rule-c); }
html[data-theme="dark"] .es-v,
html[data-theme="dark"] .es-bn { color: var(--text); }
html[data-theme="dark"] .es-bl { color: var(--dim); }
html[data-theme="dark"] .es-bt { background: var(--rule-c); }
html[data-theme="dark"] .es-bt i { background: var(--accent); }
html[data-theme="dark"] .es-essay { background: var(--surface); border-color: var(--rule-c); color: var(--text); }
html[data-theme="dark"] .es-upcard { background: var(--surface); border-color: var(--rule-c); }
html[data-theme="dark"] .es-before { color: var(--dim); }
html[data-theme="dark"] .es-after { color: var(--text); }
html[data-theme="dark"] .es-before span,
html[data-theme="dark"] .es-after span { border-color: var(--rule-c); }
html[data-theme="dark"] .es-after span { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
html[data-theme="dark"] .es-teacher { background: #1e2b23; border-color: var(--correct-line); border-left-color: var(--correct-line); }
html[data-theme="dark"] .es-tlabel { color: var(--correct); }
html[data-theme="dark"] .es-tmark { color: var(--text); }
html[data-theme="dark"] .es-tcomment { color: var(--text); }

/* -------------------------------------------------------------
   4. THE RUNNER, MADE THEMEABLE
   .quiz-body hard-codes ink in portal.css. Point it at the roles
   instead so the same markup serves both modes. The smartboard
   (.board-body) deliberately stays dark: it is a projector
   display in a lit room, not a page anyone chooses a theme for.
   ------------------------------------------------------------- */
html[data-theme="dark"] .quiz-body { background: var(--bg); color: var(--text); }
html[data-theme="dark"] .quizbar {
  background: var(--surface);
  border-bottom: 1px solid var(--rule-c);
}
html[data-theme="dark"] .qexit { color: var(--dim); }
html[data-theme="dark"] .qexit:hover { color: var(--accent); }
html[data-theme="dark"] .qdots i { background: var(--rule-c); }
html[data-theme="dark"] .qdots i.now { background: var(--accent); transform: scale(1.35); }
html[data-theme="dark"] .qdots i.ok { background: var(--correct-line); }
html[data-theme="dark"] .qdots i.no { background: var(--wrong-line); }
html[data-theme="dark"] .qscore .pts { color: var(--accent); }
html[data-theme="dark"] .qscore .cmb { color: var(--dim); }
html[data-theme="dark"] .qcount { color: var(--dim); }

/* The question stem sits in a box matching the options, with a
   border strong enough to read on either ground. */
html[data-theme="dark"] .qbig {
  color: var(--text);
  background: var(--qbox-bg);
  border: 1px solid var(--qbox-border);
  box-shadow: var(--shadow-card);
  padding: 34px 36px;
  max-width: 940px;
}
html[data-theme="dark"] .qbtn {
  background: var(--opt-bg);
  border-color: var(--opt-border);
  color: var(--text);
}
html[data-theme="dark"] .qbtn:hover:not(:disabled) {
  background: var(--opt-bg-sel);
  border-color: var(--accent);
  box-shadow: var(--shadow-lift);
  transform: translateY(-2px);
}
html[data-theme="dark"] .qbtn .k { color: var(--accent); }
html[data-theme="dark"] .qbtn.right { background: var(--correct-soft); border-color: var(--correct-line); }
html[data-theme="dark"] .qbtn.wrongpick { background: var(--wrong-soft); border-color: var(--wrong-line); }
html[data-theme="dark"] .qbtn.fade { opacity: .5; }
html[data-theme="dark"] .qhint { color: var(--dim); }
html[data-theme="dark"] .fbcard { background: var(--surface); border-color: var(--rule-c); }
html[data-theme="dark"] .fbmark.right { color: var(--correct); }
html[data-theme="dark"] .fbmark.wrong { color: var(--wrong); }
html[data-theme="dark"] .fbwhy { color: var(--body-copy); }
html[data-theme="dark"] .endpct { color: var(--accent); }
html[data-theme="dark"] .endsub { color: var(--dim); }
html[data-theme="dark"] .endstats b { color: var(--text); }
html[data-theme="dark"] .endstats span { color: var(--dim); }
html[data-theme="dark"] .endverdict { color: var(--body-copy); }
html[data-theme="dark"] .quiz-body .section-head { color: var(--text); }
html[data-theme="dark"] .quiz-body .btn.ghost { color: var(--text); border-color: var(--rule-strong); }
html[data-theme="dark"] .quiz-body .btn.ghost:hover { background: var(--text); color: var(--bg); }
/* the runner's primary action is gold in both modes */
html[data-theme="dark"] .quiz-body .btn,
html[data-theme="dark"] .btn.gold { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
html[data-theme="dark"] .quiz-body .btn:hover,
html[data-theme="dark"] .btn.gold:hover { background: var(--text); border-color: var(--text); color: var(--bg); }

/* passage panels */
html[data-theme="dark"] .passpanel {
  background: var(--surface);
  border: 1px solid var(--rule-c);
  border-left: 3px solid var(--accent);
}
html[data-theme="dark"] .passlabel { color: var(--accent); }
html[data-theme="dark"] .passpanel .passtext { color: var(--text); }
html[data-theme="dark"] .passhint { color: var(--dim); }
html[data-theme="dark"] .quiz-body .passbox { background: var(--surface); border-color: var(--rule-c); }
html[data-theme="dark"] .quiz-body .passbox summary { color: var(--accent); }
html[data-theme="dark"] .quiz-body .passbox .passtext { color: var(--text); }

/* -------------------------------------------------------------
   5. READING SETS — passage left, questions right
   Desktop only. Below 900px, and on any phone regardless of
   width, it falls back to the stacked layout: passage above,
   questions under it. Never side by side on a handset.
   ------------------------------------------------------------- */
/* The passage exists once in the DOM. Stacked is the default and
   the fallback; the two-column layout is an enhancement applied
   only where it is actually wanted. */
html[data-theme="dark"] .readpass {
  max-width: 1000px;
  margin: 0 auto 34px;
  background: var(--surface);
  border: 1px solid var(--rule-c);
  border-left: 3px solid var(--accent);
  padding: 26px 30px;
}
html[data-theme="dark"] .readq { max-width: 1000px; margin: 0 auto; }

/* Passage left, questions right — desktop only.
   any-pointer:fine means a mouse or trackpad is present, so a
   phone or tablet never gets this however wide it reports itself
   in landscape. A browser too old to understand the query fails
   the whole rule and keeps the stacked layout, which is the safe
   direction to fail in. */
@media (min-width: 900px) and (any-pointer: fine) {
html[data-theme="dark"] body.split .readsplit {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 0;
    align-items: start;
  }
html[data-theme="dark"] body.split .readpass {
    max-width: none;
    margin: 0;
    border: 0;
    border-right: 1px solid var(--rule-c);
    padding: 26px 30px 40px;
    position: sticky;
    top: 0;
    max-height: 100vh;
    overflow-y: auto;
  }
html[data-theme="dark"] body.split .readq { max-width: none; margin: 0; padding: 26px 30px 40px; }
html[data-theme="dark"] body.split .quizmain { padding: 0; }
html[data-theme="dark"] body.split .quizwrap { max-width: none; }
  /* in a column the questions read left-aligned, not centred */
html[data-theme="dark"] body.split .qcount,
html[data-theme="dark"] body.split .qhint { text-align: left; }
html[data-theme="dark"] body.split .qbig {
    text-align: left; font-size: 26px; padding: 30px 32px;
    margin: 0 0 24px; max-width: none;
  }
html[data-theme="dark"] body.split .qgrid { grid-template-columns: 1fr; gap: 12px; }
}

/* paragraph currently under discussion */
html[data-theme="dark"] .passtext .para { display: block; margin: 0 0 16px; padding: 2px 0; }
html[data-theme="dark"] .passtext .para b { color: var(--accent); font-weight: 500; }
html[data-theme="dark"] .passtext .para.here {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border-left: 2px solid var(--accent);
  padding: 2px 0 2px 12px;
}
@supports not (background: color-mix(in srgb, red 10%, transparent)) {
html[data-theme="dark"] .passtext .para.here { background: rgba(160,140,66,.1); }
html[data-theme="dark"] .passtext .para.here { background: rgba(223,205,131,.12); }
}
html[data-theme="dark"] .textsize {
  font-family: "IBM Plex Mono", monospace;
  font-size: 11px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--dim); border: 1px solid var(--rule-strong);
  padding: 4px 9px; background: transparent; cursor: pointer;
}
html[data-theme="dark"] .textsize:hover { border-color: var(--accent); color: var(--accent); }
html[data-theme="dark"] .passhead { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 16px; }
html[data-theme="dark"] .readpass .passtext { font-size: 17px; line-height: 1.9; color: var(--text); white-space: normal; }
html[data-theme="dark"] .readpass .passtext.big { font-size: 19.5px; line-height: 2.05; }

/* the left half of the runner's top bar: exit link and the switch */
html[data-theme="dark"] .qbleft { display: flex; align-items: center; gap: 14px; }

/* answered-so-far list in the question column */
html[data-theme="dark"] .answered { margin-top: 26px; padding-top: 22px; border-top: 1px solid var(--rule-c); }
html[data-theme="dark"] .answered .alabel {
  font-family: "IBM Plex Mono", monospace; font-size: 11px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--dim); margin: 0 0 12px;
}
html[data-theme="dark"] .answered ol { list-style: none; padding: 0; margin: 0; display: grid; gap: 10px; }
html[data-theme="dark"] .answered li {
  display: flex; gap: 12px; align-items: baseline; font-size: 14px;
  color: var(--body-copy); border-left: 2px solid var(--correct-line); padding-left: 12px;
}
html[data-theme="dark"] .answered li.no { border-left-color: var(--wrong-line); }
html[data-theme="dark"] .answered li b { font-family: "IBM Plex Mono", monospace; font-size: 12px; color: var(--correct); font-weight: 400; }
html[data-theme="dark"] .answered li.no b { color: var(--wrong); }

/* -------------------------------------------------------------
   6. SMALL SHARED PIECES THE NEW PAGES NEED
   Named the same way portal.css names things, so the two files
   read as one stylesheet.
   ------------------------------------------------------------- */

/* a bar chart of days, used on the dashboard and in the report */
html[data-theme="dark"] .daybars { display: flex; align-items: flex-end; gap: 4px; height: 130px; border-bottom: 1px solid var(--rule-c); }
html[data-theme="dark"] .daybars span { flex: 1; background: var(--accent); min-height: 2px; }
html[data-theme="dark"] .daybars span.off { background: var(--rule-c); }
html[data-theme="dark"] .dayticks { display: flex; gap: 4px; padding-top: 5px; }
html[data-theme="dark"] .dayticks span { flex: 1; }
html[data-theme="dark"] .dayticks span.lesson { height: 3px; background: var(--text); }
html[data-theme="dark"] .dayaxis {
  display: flex; justify-content: space-between; padding: 8px 2px 0;
  font-family: "IBM Plex Mono", monospace; font-size: 11px;
  letter-spacing: .12em; text-transform: uppercase; color: var(--dim);
}

/* numbered report blocks */
html[data-theme="dark"] .rblock { background: var(--surface); border: 1px solid var(--rule-c); padding: 26px 28px; margin-bottom: 16px; }
html[data-theme="dark"] .rblock.lead { border-top: 3px solid var(--accent); }
html[data-theme="dark"] .rblock.close { border-left: 3px solid var(--correct-line); }
html[data-theme="dark"] .rnum {
  font-family: "IBM Plex Mono", monospace; font-size: 11px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--accent); margin: 0 0 16px;
}
html[data-theme="dark"] .rblock.close .rnum { color: var(--correct); }
html[data-theme="dark"] .rfigs { display: grid; grid-template-columns: repeat(4, 1fr); border-top: 1px solid var(--rule-c); border-bottom: 1px solid var(--rule-c); }
html[data-theme="dark"] .rfig { padding: 18px; border-right: 1px solid var(--rule-c); }
html[data-theme="dark"] .rfig:first-child { padding-left: 0; }
html[data-theme="dark"] .rfig:last-child { padding-right: 0; border-right: 0; }
html[data-theme="dark"] .rfig b { font-family: "Marcellus", serif; font-size: 32px; color: var(--accent); display: block; line-height: 1; font-weight: 400; }
html[data-theme="dark"] .rfig .lbl {
  font-family: "IBM Plex Mono", monospace; font-size: 11px; letter-spacing: .13em;
  text-transform: uppercase; color: var(--dim); display: block; margin-top: 8px;
}
html[data-theme="dark"] .rfig .delta { font-size: 12.5px; display: block; margin-top: 6px; }
html[data-theme="dark"] .rfig .delta.up { color: var(--correct); }
html[data-theme="dark"] .rfig .delta.down { color: var(--wrong); }
html[data-theme="dark"] .rfig .vs { font-size: 12.5px; color: var(--dim); display: block; }
html[data-theme="dark"] .rnote { margin: 14px 0 0; font-size: 13.5px; line-height: 1.7; color: var(--body-copy); }
html[data-theme="dark"] .verdictpill {
  display: inline-block; font-family: "IBM Plex Mono", monospace; font-size: 11px;
  letter-spacing: .13em; text-transform: uppercase; padding: 3px 9px; border: 1px solid var(--rule-c);
  color: var(--dim);
}
html[data-theme="dark"] .verdictpill.secure { border-color: var(--correct-line); color: var(--correct); }
html[data-theme="dark"] .verdictpill.intervene { background: var(--wrong-line); border-color: var(--wrong-line); color: var(--on-meaning); }
html[data-theme="dark"] .verdictpill.watch { background: var(--warn-line); border-color: var(--warn-line); color: var(--on-meaning); }
html[data-theme="dark"] .verdictpill.none { border-style: dashed; }
@media (max-width: 760px) {
html[data-theme="dark"] .rfigs { grid-template-columns: 1fr 1fr; }
html[data-theme="dark"] .rfig { border-right: 0; padding: 16px 0; border-bottom: 1px solid var(--rule-c); }
}

/* the two switches, parked in the top-right of the homepage hero */
html[data-theme="dark"] .hero-switches {
  position: absolute;
  right: 14px;
  top: 12px;
  z-index: 3;
}
@media (max-width: 760px) {
  /* on a phone the hero is short and the switches would collide with
     the headline, so they sit in the flow above it instead */
html[data-theme="dark"] .hero-switches { position: static; margin-bottom: 20px; }
}

/* a compact hero band: the essay and board pages carry a breadcrumb
   and a title, not a full hero */
html[data-theme="dark"] .hero-tight { padding: 30px 0 34px; }
html[data-theme="dark"] .hero-tight h1 { font-size: clamp(28px, 4vw, 40px); }
html[data-theme="dark"] .crumbrow {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 14px; margin-bottom: 12px; flex-wrap: wrap;
}
html[data-theme="dark"] .crumbrow .crumb { margin: 0; }
html[data-theme="dark"] .crumbrow .crumb { color: var(--dim); }

/* two-up block row used by the report and the essay page */
html[data-theme="dark"] .twoup { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 16px; }
@media (max-width: 760px) {
html[data-theme="dark"] .twoup { grid-template-columns: 1fr; } }

/* print: the report and essay pages are meant to survive it */
@media print {
html[data-theme="dark"] .rblock,
html[data-theme="dark"] .es-note,
html[data-theme="dark"] .es-mark { break-inside: avoid; }
.aoe-switches,
.aoe-pill,
#aoe-lang { display: none !important; }
html[data-theme="dark"] .rblock { border-color: #ccc; }
html[data-theme="dark"] body { background: #fff; color: #000; }
}


/* =============================================================
   7. KEYBOARD, SCREEN READERS AND THE 11px FLOOR      (0906a)
   -------------------------------------------------------------
   UI-IDEAS #6 and #7, in the one stylesheet every themed page on
   this site loads. It sits after portal.css and style.css, so it
   wins over both; the same block is appended to aoe-app.css,
   which loads last of all, so it also wins over that file's own
   small type. Two copies, because there are two load positions
   to beat — not because either is optional.
   ============================================================= */

/* --- 1. the skip link ---------------------------------------
   Injected by the shared script on any page that has not
   printed one itself (aoe-ui.php prints it server-side, so a
   page with JS off still has it). Off-screen until it is
   tabbed to, and then it is the first thing on the page. */
.aoe-skip {
  position: fixed; left: -9999px; top: 0; z-index: 999;
  background: var(--accent, #A08C42); color: #F5F2EA;
  font-family: "IBM Plex Mono", "Consolas", monospace;
  font-size: 12px; letter-spacing: .12em; text-transform: uppercase;
  padding: 12px 18px; text-decoration: none; border-radius: 0 0 2px 0;
}
.aoe-skip:focus, .aoe-skip:focus-visible { left: 0; top: 0; }
/* the target is given tabindex=-1 so the focus really lands there;
   it must not then draw a ring of its own */
[data-skip-target]:focus { outline: none; }

/* --- 2. ONE focus ring, and only for a keyboard --------------
   :focus-visible, never :focus. The @supports guard means a
   browser too old to understand :focus-visible keeps the ring
   it has today rather than losing focus altogether — the safe
   direction to fail in. */
:focus-visible {
  outline: 2px solid var(--accent, #A08C42);
  outline-offset: 2px;
}
@supports selector(:focus-visible) {
  :focus:not(:focus-visible) { outline: none; }
  /* the 3px gold halo on a form field was on :focus, so it fired
     on every mouse click into a box */
  input:focus:not(:focus-visible),
  select:focus:not(:focus-visible),
  textarea:focus:not(:focus-visible) { box-shadow: none; }
  .team .tname:focus:not(:focus-visible) { outline: none; }
}
input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--accent, #A08C42); outline-offset: 1px;
}
/* a control on a dark band needs the light half of the palette */
.top :focus-visible, .hero :focus-visible, .bar :focus-visible,
.band-taupe :focus-visible, .rail :focus-visible,
.quiz-body :focus-visible, .board-body :focus-visible,
.pk-body :focus-visible, .aoe-tabs :focus-visible {
  outline-color: #EFE0A8;
}

/* --- 3. nothing under 11px -----------------------------------
   Every mono label on the site, floored at 11px; every sentence
   at 13px. The sizes below were 9px to 10.5px, which is under
   what a phone can render as a word rather than a texture. */
.tag, .passage .passage-tag, .qopt .mark, .plat-tag, .route-tag,
.setcard.planned .pill, .donetag, .qscore .cmb, .endstats span,
table.data th, .pill, .sec .state, .substat span, .boardtabs button,
.dashaxis, .minifoot, .es-tmeta, .es-mk-name, .es-sev, .es-crit,
.es-before span, .es-after span, .es-tlabel, .nbadge,
.rail-vert, .rail-label, .rail-fambtn .fam-count, .way-kicker,
.aoe-pill.mono button, .textsize, .rnum, .rfig .lbl, .verdictpill,
.emeta, table.mini.keyval td:first-child, .setfoot, .aoe-tip,
.fsec > .fsechead, .smallprint > summary, .aoe-fresh button,
.st-tag, .st-set > .lb, .st-seg button small, .st-head .meta,
.st-kick, .st-table th, .st-more-lb {
  font-size: 11px;
}
/* sentences, not labels */
.lang-note, .rail-foot, .pk-note, .es-quote, .es-mk-top,
.rfig .delta, .rfig .vs, .btn.tiny {
  font-size: 13px;
}

/* --- 4. 中文 reads differently -------------------------------
   Spaced Chinese reads as broken, and Chinese body copy needs
   more room between lines than English does. i18n.js puts .zh
   on <html> in the zh branch of apply(); these are the two
   lines that class exists for. */
html.zh body { line-height: 1.8; }
html.zh .eyebrow,
html.zh .tag, html.zh .passage .passage-tag, html.zh .qopt .mark,
html.zh .plat-tag, html.zh .route-tag, html.zh .donetag,
html.zh .qscore .cmb, html.zh .endstats span, html.zh table.data th,
html.zh .pill, html.zh .sec .state, html.zh .substat span,
html.zh .boardtabs button, html.zh .dashaxis, html.zh .minifoot,
html.zh .es-tmeta, html.zh .es-mk-name, html.zh .es-sev,
html.zh .es-crit, html.zh .es-tlabel, html.zh .rail-label,
html.zh .rail-fambtn .fam-count, html.zh .way-kicker,
html.zh .aoe-pill.mono button, html.zh .rnum, html.zh .rfig .lbl,
html.zh .verdictpill, html.zh .emeta, html.zh .setfoot,
html.zh .fsec > .fsechead, html.zh .smallprint > summary,
html.zh .crumb, html.zh .crumbline, html.zh .catmeta,
html.zh .qcount, html.zh .cycleline, html.zh .aoe-tabs span,
html.zh label, html.zh .card label {
  letter-spacing: .04em;
}
