/* Shared accessibility + chrome helpers for Current Events Explained.
   Page-specific palettes stay in each HTML file's :root (--accent, etc.). */

/* ── Shared design tokens ─────────────────────────────────────────────────────
   Vocabulary, not layout. The audit of 2026-08-27 found 62 distinct font-size values
   site-wide (seven of them between .66 and .82rem), because eight self-contained pages
   each carry their own inline stylesheet and there was no shared scale to drift from.

   These are namespaced --ce-* so they can never collide with a page's own --accent,
   --ink or --paper, which stay inline and stay distinct per page (MEMORY.md §5).
   Component CSS still lives inline per page (MEMORY.md §1) — this file defines the
   words, not the sentences.

   Type is a 1.125 scale anchored on the reading size actually used in the articles
   (--ce-text-body 1.18rem), so adopting a token never changes prose size. */
:root{
  /* type */
  --ce-text-2xs: .68rem;
  --ce-text-xs:  .76rem;
  --ce-text-sm:  .86rem;
  --ce-text-md:  1rem;
  --ce-text-body:1.18rem;
  --ce-text-lg:  1.33rem;
  --ce-text-xl:  1.5rem;
  --ce-text-2xl: 2rem;

  /* spacing */
  --ce-space-1: 4px;
  --ce-space-2: 8px;
  --ce-space-3: 12px;
  --ce-space-4: 16px;
  --ce-space-6: 24px;
  --ce-space-8: 32px;

  /* radius — the site is a broadsheet, so these stay deliberately tight */
  --ce-radius-sm: 4px;
  --ce-radius:    8px;
  --ce-radius-pill: 50px;

  /* motion */
  --ce-motion-fast: .15s;
  --ce-motion-slow: .3s;
  --ce-ease: cubic-bezier(0.22, 1, 0.36, 1);

  /* the 44px touch floor, referenced rather than repeated */
  --ce-tap: 44px;
}

@font-face{
  font-family:'OpenDyslexic';
  font-style:normal;
  font-weight:400;
  font-display:swap;
  src:url('fonts/OpenDyslexic-Regular.woff2') format('woff2');
}

.skip-link{
  position:absolute;left:8px;top:-48px;z-index:10000;
  background:var(--ink,#1a1a1a);color:#fff;
  padding:var(--ce-space-2) 14px;font-family:-apple-system,sans-serif;
  font-size:var(--ce-text-sm);font-weight:700;text-decoration:none;
}
.skip-link:focus{top:8px;outline:2px solid #fff;outline-offset:2px}

.a11y-controls{
  position:fixed;bottom:20px;right:20px;z-index:9999;
  display:flex;flex-direction:column;align-items:flex-end;gap:var(--ce-space-2);
}
.dyslexic-toggle{
  background:#111;color:#fff;border:none;border-radius:var(--ce-radius-pill);
  padding:12px var(--ce-space-4);font-size:var(--ce-text-sm);font-weight:800;min-height:var(--ce-tap);
  cursor:pointer;display:flex;align-items:center;gap:6px;
  font-family:-apple-system,sans-serif;
  box-shadow:0 4px 16px rgba(0,0,0,.25);
}
.dyslexic-toggle:hover{background:#222}
.dyslexic-toggle:focus-visible,.text-size-controls button:focus-visible{
  outline:2px solid #fff;outline-offset:2px;
}
.dyslexic-toggle.active{background:var(--accent,#a02c2c)}
.text-size-controls{
  display:flex;align-items:center;gap:6px;background:#111;
  border-radius:var(--ce-radius-pill);padding:var(--ce-space-1);
  box-shadow:0 4px 16px rgba(0,0,0,.25);
}
.text-size-controls button{
  background:transparent;color:#fff;border:none;border-radius:50%;
  width:32px;height:32px;font-family:-apple-system,sans-serif;font-weight:800;
  cursor:pointer;display:flex;align-items:center;justify-content:center;
  position:relative;touch-action:manipulation;
}
/* The A/A/A controls read at 32px but are 44px to the thumb. These are the accessibility
   controls themselves, so the students most likely to need them include those with the
   least precise aim — an invisible hit area fixes that without enlarging the chrome.
   The 6px gap keeps adjacent expanded areas from overlapping into mis-taps. */
.text-size-controls button::after{
  content:'';position:absolute;top:50%;left:50%;
  transform:translate(-50%,-50%);
  width:var(--ce-tap);height:var(--ce-tap);
}
.text-size-controls button:hover{background:rgba(255,255,255,.15)}
.text-size-controls .ts-small{font-size:.7rem}
.text-size-controls .ts-large{font-size:1.05rem}

/* Apply OpenDyslexic to reading text only — never maps, nav, buttons, or SVG. */
body.dyslexic,
body.dyslexic .article,
body.dyslexic .article p,
body.dyslexic .article li,
body.dyslexic .lede,
body.dyslexic .dek,
body.dyslexic .subhead,
body.dyslexic .lead-dek,
body.dyslexic .tier-card p,
body.dyslexic .tier-card h3,
body.dyslexic h1,
body.dyslexic h2,
body.dyslexic h3,
body.dyslexic h4,
body.dyslexic .callout,
body.dyslexic .vocab,
body.dyslexic .update-box p,
body.dyslexic .focus-pane p,
body.dyslexic .teacher-col,
body.dyslexic .about p,
body.dyslexic .suggest-lede,
body.dyslexic .suggest-form input,
body.dyslexic .suggest-form textarea,
body.dyslexic .suggest-form select{
  font-family:'OpenDyslexic',sans-serif !important;
}
body.dyslexic .section-nav,
body.dyslexic .masthead-top,
body.dyslexic .a11y-controls,
body.dyslexic button,
body.dyslexic .leaflet-container,
body.dyslexic svg,
body.dyslexic code{
  font-family:-apple-system,sans-serif !important;
}

/* ── Tap-to-open vocabulary tooltips ──────────────────────────────────────────
   The per-page .term tooltip reveals on :hover / :focus only. Neither exists on a
   touchscreen, so on a school tablet the students who most need a word defined were
   the least likely to see it. site.js adds .is-open on tap; these rules mirror the
   per-page :hover reveal. Loaded after each page's inline <style>, so equal
   specificity wins here without touching eight inline stylesheets.

   The tooltip is presentational only — the real accessible name stays on the
   .term-desc span behind aria-describedby, which is untouched. */
.term{touch-action:manipulation}
.term.is-open::after{
  opacity:1;visibility:visible;transform:translateX(-50%) translateY(0);
}
.term.is-open::before{opacity:1;visibility:visible}

/* Larger comfortable tap area on coarse pointers, without shifting the text baseline. */
@media (pointer:coarse){
  .term{padding:2px 1px;margin:0 -1px}
}

body.text-lg .article p,
body.text-lg .article ul li,
body.text-lg .lead-dek,
body.text-lg .subhead,
body.text-lg .tier-card p{font-size:1.32rem}
body.text-lg .stat-pair .desc,
body.text-lg .stat-trio .desc{font-size:.9rem}
body.text-xl .article p,
body.text-xl .article ul li,
body.text-xl .lead-dek,
body.text-xl .subhead,
body.text-xl .tier-card p{font-size:1.5rem}
body.text-xl .stat-pair .desc,
body.text-xl .stat-trio .desc{font-size:1rem}

/* Motion floor. Page-local CSS declares its own animation (.shake on a wrong quiz
   answer, the homepage ticker, photo and toast transitions) and none of the eight inline
   stylesheets carry their own reduced-motion guard, so the shared layer has to cover them.

   .shake is quiz feedback rather than decoration, so it is neutralised rather than left
   running: the answer is already marked correct/incorrect in text and colour, so no
   information is lost when the movement is removed. */
@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto}
  .ticker-inner{
    animation:none !important;transform:none !important;
  }
  .shake{animation:none !important}
  .lead-photo img,
  .tier-photo img,
  .progress-fill,
  .toast,
  .term::after,
  .term::before{animation:none !important;transition:none !important}
  .lead-story:hover .lead-photo img{transform:none !important}
}

/* ── "Before you read" entry blocks ───────────────────────────────────────────
   One per substantive section, between .sec-head and .article. Gives a student
   the section's spine and its real cost before they commit, which is what makes
   assigning individual sections workable.

   Defined here rather than in eight inline stylesheets because site.css loads
   after them: one rule, one place to change it. Colour comes from each page's
   own --accent, so the per-page palettes stay distinct. */
.before-read{
  max-width:700px;
  margin:0 auto;
  padding:18px 6vw 20px;
}
.before-read > p{
  font-family:'Source Serif 4',Georgia,serif;
  font-size:1.02rem;
  line-height:1.6;
  color:var(--ink-light,#4a4a4a);
  margin:0 0 10px;
}
.before-read > p:last-child{margin-bottom:0}

.br-head{
  display:flex !important;
  align-items:baseline;
  justify-content:space-between;
  gap:var(--ce-space-3,12px);
  margin-bottom:10px !important;
  padding-bottom:8px;
  border-bottom:1px solid var(--rule,#d4cfc4);
}
.br-head .tag{margin-bottom:0;color:var(--accent)}
.br-time{
  font-family:-apple-system,sans-serif;
  font-size:var(--ce-text-2xs,.68rem);
  font-weight:700;
  letter-spacing:.06em;
  text-transform:uppercase;
  color:var(--ink-faint,#767066);
  white-space:nowrap;
}
.br-first{
  font-family:-apple-system,sans-serif !important;
  font-size:var(--ce-text-xs,.76rem) !important;
  color:var(--ink-faint,#767066) !important;
}
.br-first a{color:var(--accent);font-weight:700}

/* The block is a quiet frame, not a card: a left rule matching .callout and
   .vocab, so it reads as part of the same editorial furniture. */
@media (min-width:701px){
  .before-read{
    border-left:3px solid var(--accent);
    padding-left:22px;
    margin-left:max(0px,calc(50vw - 350px));
    margin-right:auto;
    max-width:678px;
  }
}

/* The "Where Things Stand" pane is dark on every page, so the block inverts there.
   .on-dark rather than a page-specific selector, because all eight panes share it. */
.before-read.on-dark > p{color:rgba(255,255,255,.82)}
.before-read.on-dark .br-head{border-bottom-color:rgba(255,255,255,.18)}
.before-read.on-dark .br-time{color:rgba(255,255,255,.55)}
.before-read.on-dark .tag{color:#fff}
@media (min-width:701px){
  .before-read.on-dark{border-left-color:rgba(255,255,255,.35)}
}

/* ══ STUDY MODE ══════════════════════════════════════════════════════════
   Additive reading support. Reveals glosses that are already in the DOM and
   already read by screen readers; adds nothing to the prose itself.
   Spec: docs/plans/2026-08-28-study-mode-design.md */

.study-mode-toggle{
  display:inline-flex;align-items:center;gap:6px;
  padding:8px 14px;border:0;border-radius:4px;cursor:pointer;
  background:#333;color:#fff;
  font-family:-apple-system,sans-serif;font-size:.72rem;font-weight:700;
  letter-spacing:.03em;min-height:var(--ce-tap,44px);
}
.study-mode-toggle:hover{background:#222}
.study-mode-toggle.active{background:var(--accent,#a02c2c)}
.study-mode-toggle:focus-visible{outline:2px solid var(--accent,#a02c2c);outline-offset:2px}

/* Undo the sr-only clip so the definition renders inline, beside its term. */
body.study-mode .term-desc{
  position:static;width:auto;height:auto;
  padding:0;margin:0;overflow:visible;
  clip:auto;clip-path:none;white-space:normal;
  font-family:-apple-system,sans-serif;
  font-size:.84em;font-weight:400;line-height:1.5;
  color:var(--ink-light,#4a4a4a);
}
body.study-mode .term-desc::before{content:" — "}

/* The floating tooltip is redundant once the text is inline, and would
   otherwise cover the paragraph the reader is in. */
body.study-mode .term::after,
body.study-mode .term::before{display:none !important}
body.study-mode .term{border-bottom-style:solid;cursor:default}

/* Glosses promoted from a "Key Word" box (Task 4). */
body.study-mode .sm-gloss{
  font-family:-apple-system,sans-serif;
  font-size:.84em;color:var(--ink-light,#4a4a4a);
}
body.study-mode .sm-gloss::before{content:" — "}

/* Where a term occurs only inside a quotation, the gloss goes BESIDE the
   source, never inside it (S2). */
body.study-mode .sm-gloss-aside{
  margin:8px 0 0;padding:8px 12px;
  border-left:3px solid var(--accent,#a02c2c);
  font-family:-apple-system,sans-serif;
  font-size:.84rem;line-height:1.5;color:var(--ink-light,#4a4a4a);
}

/* Section bar (Task 5): fixed at the BOTTOM, not the top -- the site already
   has a sticky masthead and section-nav at the top, and body has
   overflow-x:hidden which breaks position:sticky for descendants anyway. */
#sm-bar{
  position:fixed;left:0;right:0;bottom:0;z-index:60;
  background:var(--ink,#1a1a1a);color:#f0ece4;
  font-family:-apple-system,sans-serif;font-size:.8rem;line-height:1.45;
  padding:10px 6vw;cursor:pointer;
  box-shadow:0 -4px 16px rgba(0,0,0,.18);
  display:flex;gap:10px;align-items:baseline;
}
#sm-bar .sm-bar-sec{font-weight:700;letter-spacing:.03em;opacity:.75;flex:0 0 auto}
#sm-bar .sm-bar-txt{flex:1 1 auto}
#sm-bar.is-open .sm-bar-txt{white-space:normal}
@media (max-width:640px){ #sm-bar{font-size:.76rem;padding:9px 5vw} }

/* Contrast fix: body.study-mode .term-desc inherits --ink-light (#4a4a4a),
   which is 1.96:1 on the dark panes (--ink #1a1a1a) used by .update-pane,
   .update-box and .focus-pane -- well under WCAG AA's 4.5:1. The site's
   original tooltip CSS already solved this exact problem per-page (see
   e.g. immigration.html's ".update-box .term::after{background:#fff;
   color:var(--ink)}"); this follows that precedent instead of inventing a
   new one. #d8d2c8 on #1a1a1a measures 11.58:1. */
body.study-mode .update-pane .term-desc,
body.study-mode .update-box .term-desc,
body.study-mode .focus-pane .term-desc{color:#d8d2c8}

/* ── Study Mode, fix round 3 (append-only; every rule below overrides an
   earlier one by source order, at equal specificity) ─────────────────────

   1. DARK-PANE CONTRAST, COMPLETED. The override above covers .term-desc
   but not the two nodes study mode INJECTS, which inherit the same
   --ink-light (#4a4a4a). space-race's "Artemis" gloss lands inside
   .update-pane (background:var(--ink) = #1a1a1a) and measured 1.96:1 --
   the identical WCAG failure the .term-desc override was written to end.
   Same remedy, same colour: #d8d2c8 on #1a1a1a = 11.58:1. (On the ordinary
   page background, #4a4a4a on --paper #fbf9f4 = 8.42:1, unchanged.) */
body.study-mode .update-pane .sm-gloss,
body.study-mode .update-box .sm-gloss,
body.study-mode .focus-pane .sm-gloss,
body.study-mode .update-pane .sm-gloss-aside,
body.study-mode .update-box .sm-gloss-aside,
body.study-mode .focus-pane .sm-gloss-aside{color:#d8d2c8}
/* The aside's left rule is --accent, which is a dark ink on a dark pane.
   Non-text, so not a WCAG 1.4.3 case, but it disappears; the pane's own
   convention for a divider on dark is a translucent white. */
body.study-mode .update-pane .sm-gloss-aside,
body.study-mode .update-box .sm-gloss-aside,
body.study-mode .focus-pane .sm-gloss-aside{border-left-color:rgba(255,255,255,.35)}

/* 2. FOCUS RING. The ring was outline:2px solid var(--accent) while
   .active sets background:var(--accent) -- the same colour, so a keyboard
   user saw NO focus indicator at all whenever Study Mode was on (1.00:1),
   and only ~1.7:1 when it was off. The neighbouring .dyslexic-toggle
   already solved this with a white ring; matching it keeps the two
   buttons in the same stack behaving the same way. #fff measures 12.63:1
   on the inactive #333, and 5.76:1 on the lowest-contrast page accent
   (#2e6a9a, iran) -- every page clears 3:1 for a non-text indicator. */
.study-mode-toggle:focus-visible{outline:2px solid #fff;outline-offset:2px}

/* 3. THE BAR vs. THE CONTROLS THAT SPAWN IT. .a11y-controls is
   fixed;bottom:20px;right:20px;z-index:9999 -- it sits ON TOP of the
   bar's right end, and .sm-bar-txt (flex:1 1 auto) ran underneath it.
   Reserve the width of the control stack (the widest button, "Aa Dyslexic
   Font", is ~160px, plus its 20px inset) so the summary stops short of
   it. The section label gets a cap and an ellipsis so it can never crowd
   the summary out of what's left on a narrow screen. */
#sm-bar{padding-right:200px}
#sm-bar .sm-bar-sec{flex:0 1 auto;max-width:40%;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* Collapsed, the bar is meant to be ONE line -- that was the design
   intent, but the base rule never set nowrap, so the collapsed bar
   already wrapped and `#sm-bar.is-open .sm-bar-txt{white-space:normal}`
   overrode nothing. Setting it here makes the collapsed state real and
   that rule live. min-width:0 is what lets a flex child ellipsis at all. */
#sm-bar .sm-bar-txt{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#sm-bar.is-open .sm-bar-txt{white-space:normal;overflow:visible}

/* Nothing reserved space for the bar, so it permanently covered the last
   ~40px of every page's footer. Scoped to body.study-mode: zero cost when
   the feature is off. (Sized for the collapsed bar; expanding it is a
   deliberate, momentary tap.) */
body.study-mode{padding-bottom:60px}

@media (max-width:640px){
  #sm-bar{padding-right:180px}
  body.study-mode{padding-bottom:56px}
}
