/* ============================================================
   EduMarkets — Base CSS: Variables, Typography, Grid
   ============================================================ */

/* Inter font loaded via <link> in index.html — no @import needed */

/* ── Colour tokens ── */
:root {
  /* Brand */
  --color-brand:        #1B3A5C;
  --color-accent:       #2E6DA4;
  --color-accent-light: #4B9FD4;
  /* Accent as INK, not as chrome. --color-accent is a fill/border colour: at
     #2E6DA4 it reads well as a background but only reaches 2.9-3.5:1 as text
     on the dark surfaces, under the 4.5:1 WCAG AA wants. This lighter accent
     is for `color:` only; fills, borders and chrome stay on --color-accent.
     Light theme keeps #2E6DA4, which passes on light surfaces. */
  --color-accent-text:  #5A9BD4;
  --color-light:        #D5E8F0;
  --sidebar-accent:     #14b8a6;
  --sidebar-accent-dim: rgba(20, 184, 166, 0.45);

  /* Dark mode (default) — GitHub-dark inspired, no halation against
     pure black; #0D1117 / #161B22 read as charcoal-blue rather than
     true black, which is sharper on Plotly canvases and carries the
     Bloomberg-feel without the brand colour. */
  --bg:          #0D1117;
  --bg-surface:  #161B22;
  --bg-header:   #1A1F26;
  --bg-elevated: #1C232C;
  --bg-input:    #20262F;
  --border:      #252830;
  --border-subtle: #1a1c22;
  --text:        #e8eaf0;
  --text-table:  #d4d8e6;
  --text-secondary: #cdd1e0;
  --text-muted:  #a8aec8;

  /* Semantic */
  --neutral:     #94a3b8;
  /* Scrollbar thumb. Separate token because the two themes need different
     weights: on dark this sits light against the background, on light it has
     to stay well above the border greys or it reads as a black bar. */
  --scrollbar-thumb: #94a3b8;
  --positive:    #22c55e;
  --negative:    #ef4444;
  --warning:     #f59e0b;
  --info:        #3b82f6;
  /* Extended palette for learn-content 8-colour card rotation */
  --lv-purple:   #a78bfa;
  --lv-pink:     #f472b6;
  --positive-bg: rgba(34, 197, 94, 0.08);
  --negative-bg: rgba(239, 68, 68, 0.08);
  --info-bg:     rgba(59, 130, 246, 0.08);
  --warning-bg:  rgba(245, 158, 11, 0.08);

  /* Typography */
  --font:        'Inter', system-ui, -apple-system, sans-serif;
  --font-mono:   'JetBrains Mono', 'Fira Code', monospace;

  /* Radius */
  --r-sm:   4px;
  --r-md:   8px;
  --r-lg:   12px;
  --r-xl:   16px;

  /* Vertical-rhythm scale — handbook + topic-surface spacing system.
     See `.scratch/ui-review/05-separation-system.md` (handbook) and
     `06-topic-surface-system.md` (topic surface) for the rulebooks.
     Tokens are multiples of 8 so they compose with the UI radius scale. */
  --space-block:           16px;  /* between paragraphs / atomic blocks */
  --space-subsection:      32px;  /* between callouts/key-facts/examples */
  --space-topic-section:   40px;  /* between major topic-surface sections */
  --space-section:         56px;  /* between handbook .ref-card-block sections */

  /* Platform typography scale — single source of truth. See
     `.scratch/ui-review/09-typography-system.md` for the rulebook.
     Applied via wrapper-scoped cascade rules in components.css.
     Module-local font-size declarations on body / title / label
     classes are overridden by those rules inside .learn-chapter-body
     and .topic-surface — pricer / dashboard / chrome surfaces keep
     their own sizes. */
  --text-body:    1.125rem;    /* 18px — body, paragraphs, list items (was 19px; reduced 2026-05-12 to sit closer to editorial-news body sizes) */
  --text-h1:      1.9rem;      /* chapter title (.learn-section-title) */
  --text-h2:      1.55rem;     /* section heading (.ref-card-title, .section-title) */
  --text-h3:      1.25rem;     /* sub-section / step title / callout title / [class*="-title"] / [class$="-subtitle"] */
  --text-h4:      1.0625rem;   /* small heading */
  --text-meta:    0.85rem;     /* eyebrow / caption / [class$="-label"] / [class$="-meta"] */
  --line-body:    1.7;
  --line-tight:   1.3;

  /* Reading measure — prose column cap inside .learn-chapter-body.
     46rem ≈ 736px ≈ ~72ch at 19px Newsreader. Per Bringhurst 60-75ch
     and Butterick 90ch absolute max. Full-width opt-out for tables,
     equations, and grid layouts in components.css. */
  --measure-prose: 46rem;

  /* Sticky-chrome heights — single source of truth. .app-header is
     64px (components.css:6+). --header-clearance adds breathing room
     for elements that float just below the header (formula panel,
     scroll-margin-top, etc.). */
  --header-height: 64px;
  --header-clearance: calc(var(--header-height) + 16px);

  /* Formula numeric — substituted-value ink in the formula panel.
     Distinct from --color-accent (chrome) and --text (regular ink).
     Light-mode override below. */
  --formula-numeric: #7ec8f0;

  /* Shadows */
  --shadow-sm:    0 1px 3px rgba(0,0,0,0.4);
  --shadow-md:    0 4px 12px rgba(0,0,0,0.5);
  --shadow-lg:    0 8px 24px rgba(0,0,0,0.6);
  --shadow-hover: 0 4px 16px rgba(0,0,0,0.25);

  /* Transitions */
  --transition: 160ms ease;

  /* Z-index layers */
  --z-dropdown:  100;
  --z-sticky:    200;
  --z-sidebar:   350;
  --z-overlay:   500;
  --z-modal:     600;
  --z-toast:     700;
  --z-max:       9999;

  /* Ecosystem tier colours */
  --tier-1: #a0aec0;
  --tier-2: #7c83f7;
  --tier-3: #22b8e0;
  --tier-4: #2dca8e;
  --tier-5: #f0a030;

  /* Backdrop blur */
  --blur-sm: 4px;
  --blur-md: 12px;
  --blur-lg: 20px;

  /* Focus ring */
  --focus-ring: 0 0 0 2px rgba(46, 109, 164, 0.2);

  /* Params sidebar width */
  --sidebar-width: 340px;
  /* Left gutter before the sidebar */
  --workspace-gutter: 28px;
}

/* ── Light mode ── */
[data-theme="light"] {
  /* Accent inks. --color-accent-text holds the value the accent has always
     had here, so light rendering is unchanged; it is dark that needed the
     lighter ink. --color-accent-light had no light override at all and was
     failing at 2.6-2.9:1 as link text on these surfaces. */
  --color-accent-text:  #2E6DA4;
  --color-accent-light: #1C6EB0;

  --bg:          #f0f2f7;
  --bg-surface:  #ffffff;
  --bg-header:   #ffffff;
  --bg-elevated: #f8f9fc;
  --bg-input:    #f4f6fa;
  --border:      #dde1ec;
  --border-subtle: #e8ebf4;
  --formula-numeric: #1a6faa;
  --text:        #1B3A5C;
  --text-table:  #2d4a6a;
  --text-secondary: #374a5e;
  --text-muted:  #5e7082;
  --shadow-sm:  0 1px 3px rgba(27,58,92,0.08);
  --shadow-md:  0 4px 12px rgba(27,58,92,0.12);
  --shadow-lg:  0 8px 24px rgba(27,58,92,0.15);
  --sidebar-accent:     #0d9488;
  --sidebar-accent-dim: rgba(13, 148, 136, 0.50);

  /* Ecosystem tier colours (light) */
  --tier-1: #5a6578;
  --tier-2: #4f52cc;
  --tier-3: #0c7da3;
  --tier-4: #0a8c60;
  --tier-5: #c47e18;

  /* Semantic – adjusted for light backgrounds. positive and warning are
     deepened to clear 4.5:1 as normal-size text (P&L figures in tables, and
     warning prose); at #059669 and #d97706 they sat at 3.4 and 2.8. */
  --positive:    #047152;
  --negative:    #dc2626;
  --warning:     #B45309;
  --neutral:     #64748b;
  --scrollbar-thumb: #c2c8d6;
  --info:        #2563eb;
  /* Extended palette (learn-content) – darkened for light bg contrast */
  --lv-purple:   #7c3aed;
  --lv-pink:     #db2777;
  --positive-bg: rgba(5, 150, 105, 0.08);
  --negative-bg: rgba(220, 38, 38, 0.08);
  --info-bg:     rgba(37, 99, 235, 0.08);
  --warning-bg:  rgba(217, 119, 6, 0.08);
  --shadow-hover: 0 4px 16px rgba(27, 58, 92, 0.1);
}
[data-theme="light"] select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%234a5568'/%3E%3C/svg%3E") !important;
}

/* ── Reset ── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* The hidden attribute means hidden (owner, 2026-08-26). The browser's own
   rule for it is a UA rule, so ANY author rule that sets display beats it,
   and this design system sets display on nearly everything: .btn,
   .app-header, every flex and grid container. Every element the JS hides
   by attribute therefore stayed on screen until someone noticed and wrote
   a re-assertion for that one selector. There are around twenty of those
   scattered through components.css, mm-sim.css and portfolio-sim.css, each
   the same fix for one element. This is that fix, once, for all of them.
   Nothing in this service shows an element that carries the attribute, so
   there is nothing for the !important to break; it is what normalize.css
   ships for the same reason. */
[hidden] { display: none !important; }
button, input, textarea, select, option { font-family: inherit; }
select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%238b8fa8'/%3E%3C/svg%3E") !important;
  background-repeat: no-repeat !important;
  background-position: right 8px center !important;
  padding-right: 24px !important;
}

html {
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Suppress iOS/Android grey tap flash — we render our own :active states. */
  -webkit-tap-highlight-color: transparent;
}

/* Remove the 300ms tap delay on common interactive elements. Allows the
   browser to keep pinch-to-zoom on the page itself. */
a, button, [role="button"], input[type="button"], input[type="submit"], label {
  touch-action: manipulation;
}

body {
  font-family: var(--font);
  background: var(--bg);
  color: var(--text);
  line-height: 1.6;
  min-height: 100vh;
  min-height: 100dvh;
  overflow-x: hidden;
  /* Numeric glyphs render as tabular (fixed-advance) and lining figures
     so columns of numbers — chart hovers, data tables, metric cards,
     decimal-aligned tooltips — stop jittering as digits change.
     Non-numeric text is unaffected. Inter and JetBrains Mono both
     ship full tabular/lining numeral support. */
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: 'tnum' 1, 'lnum' 1, 'zero' 1;
}

/* Plotly hover labels and tick labels render as inline SVG text where
   `font-variant-numeric` doesn't always inherit. Force via OpenType
   feature settings so tabular figures stay tabular inside charts. */
.js-plotly-plot .plotly text,
.js-plotly-plot .hoverlayer text,
.js-plotly-plot .annotation-text {
  font-feature-settings: 'tnum' 1, 'lnum' 1, 'zero' 1;
}

/* ── Scrollbar ──
   Standard properties only. Do NOT add ::-webkit-scrollbar rules back, here or
   in any module stylesheet. Measured 2026-07-24 (Firefox 153, Edge 150):
     - Firefox 153+ reads ::-webkit-scrollbar, and any non-zero width there
       switches off its overlay scrollbar, forcing a permanent 19px bar. This
       is what made the whole platform sprout thick scrollbars overnight.
     - Chromium ignores ::-webkit-scrollbar completely once scrollbar-color is
       set, falling back to 17px, so those rules buy nothing anyway.
   scrollbar-color is safe and does NOT cost the overlay, so the thumb can be
   tinted freely. Result: 2px overlay in Firefox, 12px in Chromium. */
* { scrollbar-width: thin; scrollbar-color: var(--scrollbar-thumb) transparent; }

/* ── Focus ── */
:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}
:focus:not(:focus-visible) {
  outline: none;
}

/* ── Typography ── */
h1 { font-size: 1.75rem; font-weight: 700; line-height: 1.25; letter-spacing: -0.02em; }
h2 { font-size: 1.35rem; font-weight: 600; line-height: 1.3;  }
h3 { font-size: 1.1rem;  font-weight: 600; }
/* h4 — mixed-case, weight-only differentiation. The previous rule
   (uppercase + 0.06em tracking + --text-secondary colour) is a T09
   AI-tell that survived globally; the `.eyebrow` class still owns
   that small-caps register where authors actually want it. */
h4 { font-size: 1rem; font-weight: 600; line-height: 1.35; color: var(--text); }
p  { font-size: 1rem; color: var(--text-secondary); }
a  { color: var(--color-accent-light); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ── Layout ── */
.app-wrapper {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
}

/* Workspace: sidebar + content, fills remaining height */
.workspace {
  display: flex;
  flex: 1 1 0;
  min-height: 0;
  overflow: hidden;
  padding-left: var(--workspace-gutter);
}

/* Module content divider line — single source of truth.
   Sits at the left edge of .workspace-content, so it serves as both the
   sidebar/content divider (when a sidebar is visible) and the page-edge
   line (when collapsed or absent). Edit here to change the line everywhere. */
.workspace-content {
  flex: 1;
  overflow-y: scroll;
  overflow-anchor: none;
  min-width: 0;
  display: flex;
  flex-direction: column;
  border-left: 1px solid var(--border);
}

.tab-content-area {
  padding: 16px 20px 48px;
  width: 100%;
  max-width: 1800px;
}
.tab-content-area:has(.ref-sub-tabs-wrap) {
  max-width: 1320px;
  margin: 0 auto;
}

/* ── Utility ── */
/* .sr-only is kept as a deliberate accessibility affordance (screen-reader-only
   text) even though no markup emits it today. */
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0,0,0,0); }
.flex    { display: flex; }
.text-sm { font-size: 0.875rem; }
.text-muted { color: var(--text-muted); }
.text-secondary { color: var(--text-secondary); }
.font-mono { font-family: var(--font-mono); }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hidden { display: none !important; }

/* ── Toast Notifications ── */
.em-toast-container {
  position: fixed;
  top: 72px;
  right: 16px;
  z-index: calc(var(--z-max) + 1);
  display: flex;
  flex-direction: column;
  gap: 8px;
  pointer-events: none;
}
.em-toast {
  pointer-events: auto;
  padding: 10px 16px;
  border-radius: 8px;
  font-size: 0.88rem;
  font-family: var(--font);
  max-width: 420px;
  cursor: pointer;
  animation: toast-in 0.3s ease;
  box-shadow: var(--shadow-md);
}
/* Toast with an action button (e.g. Undo) lays out as a row. */
.em-toast--action {
  display: flex;
  align-items: center;
  gap: 16px;
  justify-content: space-between;
}
.em-toast-action {
  flex-shrink: 0;
  background: none;
  border: 1px solid currentColor;
  color: inherit;
  font: inherit;
  font-weight: 600;
  padding: 3px 10px;
  border-radius: 6px;
  cursor: pointer;
  opacity: 0.85;
  transition: opacity 0.15s ease;
}
.em-toast-action:hover { opacity: 1; }
.em-toast-error {
  background: rgba(239, 68, 68, 0.15);
  border: 1px solid rgba(239, 68, 68, 0.4);
  color: #f87171;
}
.em-toast-success {
  background: rgba(34, 197, 94, 0.15);
  border: 1px solid rgba(34, 197, 94, 0.4);
  color: #34d399;
}
.em-toast-info {
  background: rgba(59, 130, 246, 0.15);
  border: 1px solid rgba(59, 130, 246, 0.4);
  color: #60a5fa;
}
.em-toast-exit {
  opacity: 0;
  transform: translateX(30px);
  transition: opacity 0.3s, transform 0.3s;
}
[data-theme="light"] .em-toast-error {
  background: rgba(239, 68, 68, 0.08);
  color: #dc2626;
}
[data-theme="light"] .em-toast-success {
  background: rgba(34, 197, 94, 0.08);
  color: #059669;
}
[data-theme="light"] .em-toast-info {
  background: rgba(59, 130, 246, 0.08);
  color: #2563eb;
}
@keyframes toast-in {
  from { opacity: 0; transform: translateX(30px); }
  to { opacity: 1; transform: translateX(0); }
}
@keyframes pulse {
  0%, 100% { opacity: 0.4; }
  50% { opacity: 0.15; }
}

/* ── Mobile Responsive ─────────────────────────────────────────────────── */

@media (max-width: 768px) {
  .workspace { padding-left: 0; }
  .tab-content-area img,
  .tab-content-area svg:not(.js-plotly-plot svg) { max-width: 100%; height: auto; }
  pre, code, .learn-formula-box, .learn-formula-inline,
  .learn-example-body { overflow-x: auto; }
}

@media (max-width: 480px) {
  h1 { font-size: 1.4rem; }
  h2 { font-size: 1.15rem; }
  h3 { font-size: 1rem; }
  .tab-content-area { padding: 12px 12px 24px; }
  .em-toast { max-width: 90vw; }
}

/* ── Print stylesheet ────────────────────────────────────────────────────────
   Phase 1: handbook chapters + glossary print/export. The on-screen Newsreader
   serif body carries straight into print — this block strips the chrome, forces
   light mode, sizes the type for paper, controls page breaks, and styles the
   JS-injected cover / disclaimer / running-footer artifacts (see
   js/shared/print-export.js, wired from reference-tab.js). Other surfaces
   (pricers, dashboards) get the generic chrome-strip + light mode here too;
   they just don't get the cover/disclaimer (no `.ref-sub-panel.active` →
   print-export.js no-ops). See .scratch/ui-review/48-print-spec.md. */

@page {
  margin: 16mm 14mm 20mm;   /* extra at the bottom = clearance for the fixed running footer */
}

/* The branded artifacts are display:none on screen; only print shows them. */
.em-print-cover,
.em-print-disclaimer,
.em-print-footer { display: none; }

@media print {
  html { background: #fff; color-scheme: light; }
  *, *::before, *::after { box-shadow: none !important; text-shadow: none !important; }

  /* Force readable colours — @media print does NOT honour prefers-color-scheme,
     and [data-theme="dark"] sets the dark token values, so re-declare to light. */
  :root,
  [data-theme="dark"],
  [data-theme="light"] {
    --bg: #fff;
    --bg-surface: #fff;
    --bg-header: #fff;
    --bg-elevated: #fff;
    --bg-input: #f5f5f5;
    --text: #000;
    --text-secondary: #333;
    --text-muted: #666;
    --border: #ccc;
    --border-subtle: #ddd;
    --color-accent: #1B3A5C;
    --color-accent-text: #1B3A5C;
    --positive: #1a6b34;
    --negative: #a3001f;
    --warning: #8a5800;
    --info: #1d5fa0;
  }

  /* ── Hide: app chrome, overlays, banners ───────────────────────────────── */
  .app-header,                       /* topbar incl. the Search… ⌘K box */
  .params-sidebar,
  .options-sidebar,
  .sidebar-toggle-btn,
  .sidebar-mobile-toggle,
  .sidebar-backdrop,
  .module-switcher-overlay,
  .module-transition-overlay,
  .cmd-palette-overlay,
  .em-toast-container,
  #boot-overlay,
  #em-session-bar,
  #contact-modal,
  .settings-dropdown,
  .iro-dialog-overlay,
  .pref-overlay,
  .guided-flow-card,
  .wt-overlay,
  .wt-prompt,
  .explain-popover,
  /* ── Hide: handbook / glossary / reference chrome ───────────────────────── */
  .ref-sub-tabs-wrap,                /* the sub-tab bar — and the Print control nested in it */
  .ref-print,
  .ref-print-menu,
  .learn-nav,                        /* chapter-TOC sidebar */
  .learn-nav-toggle,                 /* mobile "Chapters" disclosure button */
  .learn-nav-next,                   /* "next chapter →" pager */
  .glossary-rail,                    /* glossary category nav + A–Z bar */
  .glossary-controls,
  .glossary-search-row,
  .glossary-az-anchor,
  .glossary-card-meta,
  .pricer-link,
  .learn-pricer-link,
  /* ── Hide: interactive affordances inside content ───────────────────────── */
  .formula-btn,
  .explain-btn,
  .test-yourself-toggle,
  .challenge-btn,
  .remove-btn,
  .chart-fullscreen-btn,
  .related-topics,
  .sidebar-disclaimer {
    display: none !important;
  }

  /* ── Full-width content column — no grid, no scroll containers ──────────── */
  .app-wrapper,
  .workspace,
  #module-mount { display: block !important; }
  .workspace { padding-left: 0 !important; }
  .workspace-content,
  .tab-content-area {
    overflow: visible !important;
    margin: 0 !important;
    padding: 0 !important;
    max-width: none !important;
    width: auto !important;
  }
  .tab-panel { display: none !important; }
  .tab-panel.active { display: block !important; overflow: visible !important; }
  .ref-sub-panel { display: none !important; }
  .ref-sub-panel.active { display: block !important; }
  .learn-layout { display: block !important; }       /* was 200px 1fr — kill the dead TOC column */
  .learn-content { overflow: visible !important; padding: 0 !important; }
  .glossary-layout,
  .glossary-wrap { display: block !important; }

  /* ── "Print this chapter" mode (set by print-export.js before window.print) ── */
  body.em-print-chapter .learn-chapter:not(.em-print-target) { display: none !important; }
  body.em-print-chapter .em-print-target { break-before: avoid; page-break-before: avoid; }

  /* ── Typography for paper — inherit the Newsreader serif, shrink for print ── */
  .learn-chapter-body,
  .glossary-card-term,
  .glossary-card-def { font-size: 11pt !important; line-height: 1.55 !important; }
  .learn-section-title,
  .learn-chapter-body h2 { font-size: 16pt !important; line-height: 1.25 !important; }
  .learn-chapter-body h3 { font-size: 13pt !important; }
  .learn-chapter-body h4 { font-size: 11.5pt !important; }
  .learn-key-sym,
  .learn-key-def { font-size: 11pt !important; line-height: 1.5 !important; }
  .glossary-section-label { font-size: 12pt !important; }
  .learn-chapter-body { max-width: none !important; }   /* @page margin owns the measure now */
  .learn-chapter-body p,
  .learn-key-def { orphans: 3; widows: 3; }

  /* ── Page breaks ───────────────────────────────────────────────────────── */
  .learn-chapter { break-before: page; page-break-before: always; margin-bottom: 0 !important; }
  .learn-chapter:first-child { break-before: avoid; page-break-before: avoid; }   /* ch.1 follows the cover */
  .learn-chapter-body h2,
  .learn-chapter-body h3,
  .learn-section-title { break-after: avoid; page-break-after: avoid; }
  .learn-chapter-body figure,
  .learn-chapter-body .figure,
  .learn-chapter-body .data-table-wrap,
  .learn-chapter-body .learn-callout,
  .learn-chapter-body .callout,
  .learn-chapter-body .learn-example,
  .learn-chapter-body .learn-key-facts,
  .learn-chapter-body .learn-formula-box,
  .glossary-card { break-inside: avoid; page-break-inside: avoid; }
  .glossary-section-label { break-after: avoid; page-break-after: avoid; }

  /* ── Charts — Plotly bakes theme colours into SVG attributes (which DO print),
     so a dark-mode chart prints as a dark box. Drop the plot, keep the figure
     caption, leave a one-line trace. Crisp chart images in print = Phase 2. ── */
  .js-plotly-plot { display: none !important; }
  .chart-wrap { break-inside: avoid; page-break-inside: avoid; }
  .figure-caption { display: block !important; }
  .chart-wrap::after {
    content: "[chart — available in the online handbook]";
    display: block;
    margin-top: 4px;
    color: #666;
    font-style: italic;
    font-size: 9pt;
  }

  /* ── Search highlight — no highlighter pen / accent ring in the PDF ─────── */
  mark.search-hl,
  .glossary-match {
    background: transparent !important;
    box-shadow: none !important;
    padding: 0 !important;
    color: inherit !important;
  }

  /* ── Tables — borders + a grey header band read clearer on paper ────────── */
  .data-table-wrap { overflow-x: visible !important; border: none !important; }
  .data-table { border-collapse: collapse; }
  .learn-chapter-body .data-table,
  .learn-chapter-body .data-table th,
  .learn-chapter-body .data-table td { font-size: 9.5pt !important; }
  .data-table th,
  .data-table td {
    border: 1px solid #ccc !important;
    padding: 4px 8px !important;
    background: #fff !important;
    color: #000 !important;
  }
  .data-table th {
    background: #f0f0f0 !important;
    font-weight: 600 !important;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  /* ── Cards / callouts / formulas / badges ──────────────────────────────── */
  .card {
    border: 1px solid #ddd !important;
    background: #fff !important;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  .card-value { color: #000 !important; }
  .callout,
  .learn-callout {
    border: 1px solid #ddd !important;
    background: #fafafa !important;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  .learn-formula-box,
  .learn-formula-inline,
  .katex {
    color: #000 !important;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  .badge {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
    border: 1px solid currentColor;
  }
  .metrics-row { display: flex !important; flex-wrap: wrap !important; gap: 8px !important; }

  /* ── Links — in-document xrefs stay as styled-but-dead text; external links
     get their URL footnoted (the one place that earns its keep). ──────────── */
  .learn-chapter-body a[href^="#"],
  .xref-link,
  .glossary-card-term a { color: var(--color-accent-text) !important; text-decoration: none !important; }
  .learn-chapter-body a[href^="http"]::after,
  .glossary-card-def a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 8pt;
    color: #666;
    word-break: break-all;
  }

  /* ── Remove hover effects ──────────────────────────────────────────────── */
  *:hover { background: inherit !important; color: inherit !important; }

  /* ── The JS-injected branded artifacts ─────────────────────────────────── */
  .em-print-cover {
    display: block;
    margin: 0 0 12mm;
    padding-bottom: 6mm;
    border-bottom: 1px solid #ccc;
    break-after: avoid;
    page-break-after: avoid;
  }
  .em-print-cover .em-print-wordmark {
    display: block;
    font-family: 'Newsreader', 'Inter', system-ui, serif;
    font-size: 20pt;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: #1B3A5C;
  }
  .em-print-cover .em-print-doctitle {
    display: block;
    font-family: 'Newsreader', 'Inter', system-ui, serif;
    font-size: 14pt;
    color: #000;
    margin-top: 2.5mm;
  }
  .em-print-cover .em-print-meta {
    display: block;
    font-family: 'Inter', system-ui, sans-serif;
    font-size: 8.5pt;
    color: #666;
    margin-top: 2mm;
  }
  .em-print-disclaimer {
    display: block;
    margin-top: 12mm;
    padding-top: 5mm;
    border-top: 1px solid #ccc;
    font-family: 'Inter', system-ui, sans-serif;
    font-size: 8.5pt;
    line-height: 1.5;
    color: #555;
    break-inside: avoid;
    page-break-inside: avoid;
  }
  .em-print-disclaimer .em-print-copyright { display: block; margin-top: 2.5mm; }
  .em-print-footer {
    display: block;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 6mm;
    text-align: center;
    font-family: 'Inter', system-ui, sans-serif;
    font-size: 7.5pt;
    color: #888;
  }
}

/* ── Reduced motion ──
   Users who turn on "Reduce motion" in iOS / Android / OS settings
   expect us to strip non-essential animation. We collapse every
   animation and transition to a near-instant duration so structural
   states still update (sidebar opens, modal appears) but without the
   long ease-in-out movement that can trigger vestibular issues. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ── View Transitions ──
   Tab switches inside a module use document.startViewTransition() in
   js/main.js for a smooth cross-fade between the outgoing and incoming
   panel. The browser default duration is ~250ms which feels slightly
   sluggish for tab navigation; 200ms matches the CSS-keyframe fallback
   used on browsers without view-transition support. */
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 200ms;
}
@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation-duration: 0.01ms !important;
  }
}
