/* MediaBias.fyi — v1.0 "Signal" — Kestrel Exams LLC
   Direction C, approved 2026-09-02. Near-black ground, one electric yellow,
   Bricolage Grotesque display over Public Sans body, poster scale, evidence as UI.

   THREE THINGS THAT ARE LOAD-BEARING, DO NOT "TIDY" THEM AWAY:
   1. Fonts are SELF-HOSTED in /fonts/. The `_headers` CSP forbids external
      origins, so an @import or a <link> to fonts.googleapis.com renders nothing.
   2. LOGICAL PROPERTIES ONLY. No left:/right:/margin-left/padding-right/text-align:left.
      Arabic is RTL and a `left:-9999px` skip link once made those pages 11,179px wide.
   3. Bricolage Grotesque and Public Sans cover latin + latin-ext ONLY. Arabic,
      Devanagari, Chinese and Cyrillic fall back to system faces by design; the
      :lang() stacks below name them so those pages get a chosen face, not a default.
   4. --accent is a FILL colour and --accent-text is an ON-GROUND colour. They are
      the same yellow in the dark theme, which is why swapping them looks harmless
      and is not. See the theme block below before touching either. */

/* ── fonts ────────────────────────────────────────────────── */
@font-face{font-family:"Bricolage Grotesque";font-style:normal;font-display:swap;font-weight:200 800;
  src:url(/fonts/bricolage-grotesque-latin-wght.woff2) format("woff2-variations");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Bricolage Grotesque";font-style:normal;font-display:swap;font-weight:200 800;
  src:url(/fonts/bricolage-grotesque-latin-ext-wght.woff2) format("woff2-variations");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"Public Sans";font-style:normal;font-display:swap;font-weight:100 900;
  src:url(/fonts/public-sans-latin-wght.woff2) format("woff2-variations");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Public Sans";font-style:normal;font-display:swap;font-weight:100 900;
  src:url(/fonts/public-sans-latin-ext-wght.woff2) format("woff2-variations");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}

/* ── tokens: shape and type, theme-independent ─────────────── */
:root{
  --radius:14px; --radius-lg:18px; --pill:999px;
  --maxw:1200px; --read:68ch;
  --body:"Public Sans",-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --disp:"Bricolage Grotesque","Arial Narrow","Segoe UI",Helvetica,Arial,sans-serif;
}

/* ── the two themes ───────────────────────────────────────
   DARK IS THE DESIGN OF RECORD: the near-black ground approved 2026-09-02, and
   what a visitor gets unless their machine asks otherwise. LIGHT IS A SECOND
   FULL PALETTE, not a filter over the first — every value below is chosen, and
   several are not simply the dark one inverted.

   A theme is picked in this order:
     1. data-theme on <html>, written by the masthead button and remembered in
        localStorage. The inline script in every <head> replays it before first
        paint; that script is why there is no flash of the wrong theme.
     2. otherwise the operating system, via prefers-color-scheme.
     3. otherwise dark.

   THE TWO ACCENT ROLES ARE NOT INTERCHANGEABLE:
     --accent       the electric yellow, and ONLY ever a FILL sitting behind
                    --accent-ink. Identical in both themes; the yellow blocks
                    are the brand and they stay yellow on paper.
     --accent-text  accent drawn ON the page ground: links, the big numerals,
                    hairlines, focus rings. Yellow in dark, deep gold in light,
                    because #f2e34a on a light ground is about 1.2:1 and
                    effectively invisible.
   Putting --accent on text over --bg is the exact mistake this split exists to
   prevent. If you want yellow BEHIND something, --accent is right. */
:root,:root[data-theme="dark"]{
  --ink:#f3f2ec; --ink-2:#b6b9c2; --ink-3:#7c808a; --ink-body:#d2d4da;
  --bg:#0b0d12; --surface:#14171f; --surface-2:#1b1f29; --line:#262a33;
  --accent:#f2e34a; --accent-ink:#0b0d12; --accent-text:#f2e34a;
  --accent-dim:#5c5717; --accent-soft:#1e1f14; --accent-hover:#fff;
  --good:#6ee7a8; --bad:#ff8f7d;
  color-scheme:dark;
}
/* The light palette appears TWICE on purpose: once for the operating-system
   preference, once for an explicit choice. CSS has no way to share one block
   between a media query and an attribute selector, so if you edit one, edit
   both. They must stay byte-identical apart from the selector. */
@media(prefers-color-scheme:light){
  :root:not([data-theme="dark"]){
    --ink:#14161c; --ink-2:#4a4e58; --ink-3:#6b6f79; --ink-body:#2c3038;
    --bg:#f6f4ee; --surface:#fff; --surface-2:#efece2; --line:#ddd9cd;
    --accent:#f2e34a; --accent-ink:#0b0d12; --accent-text:#5f5400;
    --accent-dim:#5c5717; --accent-soft:#fbf7dc; --accent-hover:#000;
    --good:#0d7a44; --bad:#b02f18;
    color-scheme:light;
  }
}
:root[data-theme="light"]{
  --ink:#14161c; --ink-2:#4a4e58; --ink-3:#6b6f79; --ink-body:#2c3038;
  --bg:#f6f4ee; --surface:#fff; --surface-2:#efece2; --line:#ddd9cd;
  --accent:#f2e34a; --accent-ink:#0b0d12; --accent-text:#5f5400;
  --accent-dim:#5c5717; --accent-soft:#fbf7dc; --accent-hover:#000;
  --good:#0d7a44; --bad:#b02f18;
  color-scheme:light;
}
/* Scripts the two webfonts do not cover. Named on purpose, see note 3 above. */
:lang(ar){--body:"Segoe UI","Noto Naskh Arabic","Geeza Pro",Tahoma,sans-serif;--disp:var(--body)}
:lang(hi){--body:"Nirmala UI","Noto Sans Devanagari","Mangal",sans-serif;--disp:var(--body)}
:lang(zh-hans),:lang(zh){--body:"Microsoft YaHei","PingFang SC","Noto Sans SC","Hiragino Sans GB",sans-serif;--disp:var(--body)}
:lang(ru){--body:"Segoe UI","Noto Sans",Roboto,Helvetica,Arial,sans-serif;--disp:var(--body)}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
/* clip, NOT hidden. overflow-x:hidden makes the body a scroll container, which
   makes every view() timeline below resolve against a non-scrolling element and
   go silently inert. clip does the same visual job without creating a scrollport.
   Changing this back to hidden switches off every scroll animation on the site. */
html,body{overflow-x:clip}
body{margin:0;background:var(--bg);color:var(--ink);
  font:17px/1.6 var(--body);-webkit-font-smoothing:antialiased}
:lang(ar),:lang(hi),:lang(zh-hans){line-height:1.85}
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 40px}
a{color:var(--accent-text)}
a:hover{color:var(--accent-hover)}
h1,h2,h3{font-family:var(--disp);line-height:1.05;letter-spacing:-.03em;margin:0 0 .5em;font-weight:700}
h1{font-size:clamp(2.6rem,6.2vw,5.4rem);font-weight:800;letter-spacing:-.04em;text-wrap:pretty}
h2{font-size:clamp(1.6rem,3.2vw,2.4rem);font-weight:800}
h3{font-size:1.3rem}
p{margin:0 0 1em}
strong{color:var(--ink)}
:focus-visible{outline:3px solid var(--accent-text);outline-offset:2px}

.skip{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.skip:focus{position:fixed;inset-inline-start:12px;inset-block-start:12px;width:auto;height:auto;
  clip-path:none;z-index:99;background:var(--accent);color:var(--accent-ink);padding:12px 18px;
  border-radius:var(--pill);font-weight:700;text-decoration:none}

/* ── masthead ─────────────────────────────────────────────
   .mast and .mainnav are separate elements in the markup; matching grounds and
   trimmed padding make them read as one two-line header bar. */
.mast{background:var(--bg);border-block-end:1px solid var(--line);padding:18px 0 14px}
.mast .wrap{display:flex;align-items:baseline;gap:18px;flex-wrap:wrap}
.mark{display:inline-flex;align-items:center;gap:10px;text-decoration:none;color:var(--ink)}
.mark::before{content:"";width:14px;height:14px;background:var(--accent-text);rotate:45deg;flex:none}
.mark-box{font-family:var(--disp);font-weight:800;letter-spacing:-.02em;
  font-size:clamp(1.35rem,2.6vw,1.6rem);color:var(--ink);text-transform:none}
.mark-w{text-transform:capitalize}
.mark-d{color:var(--accent-text)}
.mast-tag{margin:0;color:var(--ink-3);font-size:.9rem}

/* Hidden until the <head> script proves scripting is on: without it the button
   cannot do anything, and a dead control is worse than no control. */
.themebtn{display:none}
:root.js .themebtn{margin-inline-start:auto;align-self:center;flex:none;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;
  width:40px;height:40px;padding:0;border-radius:var(--pill);
  border:1px solid var(--line);background:transparent;color:var(--ink-2)}
.themebtn:hover{border-color:var(--accent-text);color:var(--accent-text)}
.themebtn svg{display:block}
/* The icon shows the theme you would GET, not the one you are in. The three
   blocks must stay in this order: the explicit choice has to beat the media
   query, and both selectors weigh the same, so only source order separates them. */
.themebtn .ic-sun{display:block}
.themebtn .ic-moon{display:none}
@media(prefers-color-scheme:light){
  :root:not([data-theme="dark"]) .themebtn .ic-sun{display:none}
  :root:not([data-theme="dark"]) .themebtn .ic-moon{display:block}
}
:root[data-theme="light"] .themebtn .ic-sun{display:none}
:root[data-theme="light"] .themebtn .ic-moon{display:block}
:root[data-theme="dark"] .themebtn .ic-sun{display:block}
:root[data-theme="dark"] .themebtn .ic-moon{display:none}

.mainnav{background:var(--bg);padding:0 0 4px}
.mainnav .wrap{display:flex;flex-wrap:wrap;gap:2px}
.mainnav a{color:var(--ink);text-decoration:none;font-size:.94rem;font-weight:600;
  padding:9px 13px;border-radius:8px;border-block-end:2px solid transparent}
.mainnav a:hover{color:var(--accent-text)}
.mainnav a.here{color:var(--accent-text);border-block-end-color:var(--accent-text)}
.subnav{background:var(--bg);padding:0 0 12px;border-block-end:1px solid var(--line)}
.subnav .wrap{display:flex;flex-wrap:wrap;gap:2px}
.subnav a{color:var(--ink-3);text-decoration:none;font-size:.84rem;font-weight:500;padding:5px 11px;border-radius:var(--pill)}
.subnav a:hover{color:var(--ink)}
.subnav a.here{background:var(--surface);color:var(--ink)}

.langbar{background:var(--bg);border-block-end:1px solid var(--line);padding:10px 0;font-size:.86rem}
.langbar .wrap{display:flex;flex-wrap:wrap;align-items:center;gap:4px}
.langlbl{color:var(--ink-3);margin-inline-end:8px;font-size:.7rem;letter-spacing:.12em;text-transform:uppercase;font-weight:700}
.langbar a{color:var(--ink-2);text-decoration:none;padding:5px 11px;border-radius:var(--pill);font-weight:600}
.langbar a:hover{background:var(--surface);color:var(--ink)}
.langbar a.on{background:var(--accent);color:var(--accent-ink)}

.reviewbar{background:var(--accent-soft);color:var(--accent-text);font-size:.88rem;padding:10px 0;
  text-align:center;border-block-end:1px solid var(--accent-dim)}

/* ── hero ─────────────────────────────────────────────────── */
.hero{background:var(--bg);border-block-end:1px solid var(--line);padding:76px 0 68px;position:relative;overflow:hidden}
.hero::after{content:"";position:absolute;inset-inline-end:-140px;inset-block-start:-90px;
  width:560px;height:560px;border-radius:50%;opacity:.3;pointer-events:none;
  box-shadow:inset 0 0 0 2px var(--accent-text),inset 0 0 0 40px var(--bg),inset 0 0 0 42px var(--accent-text),
             inset 0 0 0 100px var(--bg),inset 0 0 0 102px var(--accent-text)}
.hero .wrap{position:relative;z-index:1}
.hero h1{max-width:13ch;margin-block-end:.3em}
.hero .hl{color:var(--accent-text);display:block}
.hero .lede{font-family:var(--disp);font-size:clamp(1.3rem,2.6vw,2.05rem);line-height:1.18;
  font-weight:500;color:var(--accent-text);max-width:24ch}
.eyebrow{font-size:.75rem;letter-spacing:.13em;text-transform:uppercase;font-weight:700;color:var(--accent-text);margin-bottom:.9em}
.lede{font-size:1.15rem;color:var(--ink-2);max-width:var(--read)}
.cta-row{display:flex;gap:12px;flex-wrap:wrap;margin-top:28px}
.btn{display:inline-flex;align-items:center;justify-content:center;min-height:52px;padding:0 26px;
  border-radius:var(--pill);text-decoration:none;font-weight:700;font-size:1rem;
  border:1.5px solid var(--ink);color:var(--ink);background:transparent;cursor:pointer;font-family:inherit}
.btn:hover{background:var(--surface);color:var(--ink)}
.btn.primary{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
.btn.primary:hover{background:var(--accent-ink);border-color:var(--accent-ink);color:var(--accent)}

.page-head{padding:64px 0 10px}
.page-head .lede{font-size:1.2rem;max-width:52ch}
.band{padding:34px 0 52px}
.note{color:var(--ink-2);font-size:.97rem;max-width:var(--read)}
.small{font-size:.88rem}

/* ── cards ────────────────────────────────────────────────── */
.cards{display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(270px,1fr))}
.card{display:flex;flex-direction:column;gap:9px;background:var(--surface);border:1px solid var(--line);
  border-radius:var(--radius-lg);padding:24px;text-decoration:none;color:inherit}
.card:hover{border-color:var(--accent-text);background:var(--surface-2);color:inherit}
.card-tag{font-size:.7rem;letter-spacing:.12em;text-transform:uppercase;font-weight:700;color:var(--accent-text)}
.card h3{font-family:var(--disp);margin:0;font-size:1.4rem;font-weight:700;letter-spacing:-.02em;line-height:1.15}
.card p{color:var(--ink-2);font-size:.95rem;margin:0}
.card-go{margin-block-start:auto;padding-block-start:6px;font-weight:700;font-size:.9rem;color:var(--accent-text)}

/* ── the evidence ledger (was .stats) ─────────────────────
   Every figure sits over a named source. The v0.3 markup packs source, date and
   sample into one .src string, so this renders as a stacked row, not five columns. */
.stats{display:grid;gap:0;grid-template-columns:1fr;margin-bottom:26px;border-block-start:2px solid var(--accent-text)}
.stat{display:grid;grid-template-columns:250px minmax(0,1fr);gap:28px;align-items:baseline;
  background:transparent;border:0;border-block-end:1px solid var(--line);border-radius:0;padding:20px 0}
.stat .n{display:block;font-family:var(--disp);font-size:clamp(2.4rem,4.4vw,3.5rem);font-weight:800;
  letter-spacing:-.05em;line-height:.95;color:var(--ink);white-space:nowrap}
/* Some ledger entries are a comparison or a short phrase rather than one numeral
   ("36.6% to 3.3%", "6x faster"). nowrap in a 250px column clipped those, so a
   long value wraps and steps down instead. Set by the builder on length. */
.stat .n.long{white-space:normal;font-size:clamp(1.35rem,2.2vw,1.9rem);line-height:1.1;letter-spacing:-.02em}
.stat p{font-size:1rem;color:var(--ink-2);margin:0}
.src{display:block;margin-top:9px;font-size:.72rem;color:var(--ink-3);
  letter-spacing:.1em;text-transform:uppercase;font-weight:700}

/* ── the four moves, as a check sheet ─────────────────────── */
.moves{list-style:none;padding:0;margin:0;display:grid;gap:0;border-block-start:1px solid var(--line)}
.moves li{position:relative;background:transparent;border:0;border-block-end:1px solid var(--line);
  border-radius:0;padding:38px 0 38px 150px;display:grid;gap:12px}
[dir=rtl] .moves li{padding:38px 150px 38px 0}
.move-n{position:absolute;inset-inline-start:0;inset-block-start:32px;width:auto;height:auto;
  display:block;border-radius:0;background:none;color:var(--accent-text);
  font-family:var(--disp);font-size:clamp(3.6rem,7vw,6rem);font-weight:800;letter-spacing:-.05em;line-height:.85}
/* the markup numbers these 1-4; the design sets them 01-04 */
.move-n::before{content:"0"}
.moves h2{font-size:clamp(1.5rem,2.8vw,2.15rem);margin:0 0 .1em;font-weight:700}
.moves p{color:var(--ink-2);font-size:1.02rem;margin:0;max-width:60ch}
/* the "ask yourself" line: a box you tick, not a blockquote */
.ask{color:var(--ink)!important;font-weight:600;font-size:1rem!important;
  border:1px solid var(--accent-text);border-radius:var(--radius);padding:16px 18px 16px 52px;
  margin:6px 0 0!important;position:relative;max-width:52ch}
[dir=rtl] .ask{padding:16px 52px 16px 18px}
.ask::before{content:"";position:absolute;inset-inline-start:18px;inset-block-start:17px;
  width:22px;height:22px;border:1.5px solid var(--accent-text);border-radius:3px}
/* At desktop the "ask yourself" box sits beside the move, in a second column.
   Absolute, not a grid cell: the li's rows are auto-sized, so a spanning grid item
   redistributes its own height into them and opens a gap under the heading.
   This block MUST stay after the .ask rule above, which sets position:relative. */
@media(min-width:900px){
  .moves li{padding-inline-end:404px;min-height:212px}
  .moves .ask{position:absolute;inset-inline-end:0;inset-block-start:34px;width:360px;
    margin:0!important;max-width:none}
}

.callout{background:var(--accent);color:var(--accent-ink);border-radius:var(--radius-lg);
  padding:38px 34px;margin-bottom:44px}
.callout h2{margin-top:0;color:var(--accent-ink)}
.callout p{color:#2a2914}
.callout em{color:var(--accent-ink);font-style:italic}
.callout .btn{border-color:var(--accent-ink);color:var(--accent-ink)}
.callout .btn:hover{background:rgba(11,13,18,.08);color:var(--accent-ink)}
.callout .btn.primary{background:var(--accent-ink);border-color:var(--accent-ink);color:var(--accent)}
.callout .btn.primary:hover{background:#000;border-color:#000;color:var(--accent)}
.callout a{color:var(--accent-ink)}

/* ── founder block ────────────────────────────────────────── */
.founder{display:flex;gap:20px;align-items:center;margin:26px 0 8px;padding:20px;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-lg)}
.founder img{border-radius:50%;flex:none;display:block}
.founder-name{font-family:var(--disp);font-size:1.25rem;font-weight:700;letter-spacing:-.02em;margin:0 0 .25em}
.founder-role{font-size:.95rem;color:var(--ink-2);margin:0}
.founder-lg{margin:28px 0 0;gap:26px}
.founder-lg .founder-name{font-size:1.6rem}
.founder-lg .founder-role{font-size:1rem}
/* On a phone the block stacks AND the portrait shrinks. The width/height
   attributes on the <img> are the desktop sizes, so both axes must be named
   here or the aspect ratio locks the old height back in. */
@media(max-width:640px){
  .founder{flex-direction:column;align-items:flex-start;gap:14px;padding:18px}
  .founder img{width:84px;height:84px}
  .founder-lg{gap:16px}
  .founder-lg img{width:96px;height:96px}
  .founder-lg .founder-name{font-size:1.35rem}
  .founder-lg .founder-role{font-size:.95rem}
}

/* ── explainers ───────────────────────────────────────────── */
.prose-wide{max-width:820px}
.ex-sec{margin-bottom:44px}
.ex-sec h2{margin-bottom:.5em;padding-bottom:0;border-bottom:0;font-size:clamp(1.5rem,2.8vw,2.1rem)}
.ex-sec p{color:var(--ink-body);font-size:1.12rem;line-height:1.7}
.ex-sec strong{color:var(--ink)}
.ex-sec em{color:var(--ink)}
.takeaway{background:var(--accent);color:var(--accent-ink);border:0;border-radius:var(--radius-lg);
  padding:28px 30px;margin:44px 0 28px}
.tk-l{font-size:.72rem;letter-spacing:.13em;text-transform:uppercase;font-weight:700;color:var(--accent-dim);margin-bottom:.6em}
.takeaway p:last-child{margin:0;font-family:var(--disp);font-size:1.5rem;line-height:1.25;
  font-weight:700;letter-spacing:-.02em;color:var(--accent-ink)}
/* Links on any yellow ground must not be the yellow accent. */
.takeaway a,.gapline a,.codebox a{color:var(--accent-ink);text-decoration:underline;text-underline-offset:3px}
.takeaway a:hover,.gapline a:hover,.codebox a:hover{color:#000}
.ex-next{border-top:1px solid var(--line);padding-top:22px;margin-bottom:48px}
.ex-next p{color:var(--ink-2);font-size:.98rem;margin:0}

/* ── myths, tactics, resources ────────────────────────────── */
.myths{display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(340px,1fr))}
.myth{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-lg);padding:22px}
.m-l,.m-r{font-size:.68rem;letter-spacing:.13em;text-transform:uppercase;font-weight:700;margin-bottom:.4em}
.m-l{color:var(--bad)}
.m-r{color:var(--good);margin-top:1.1em}
.myth h2{font-family:var(--disp);font-size:1.2rem;margin-bottom:0;font-weight:700}
.myth p:last-child{color:var(--ink-2);font-size:.95rem;margin:0}
.tactics,.reslist{display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(300px,1fr))}
.tactic,.res{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-lg);padding:22px}
.tactic h2,.res h2{font-family:var(--disp);font-size:1.2rem;margin-bottom:.45em;font-weight:700}
.tactic p,.res p{font-size:.95rem;color:var(--ink-2);margin-bottom:.7em}
.t-tag{font-size:.68rem;letter-spacing:.12em;text-transform:uppercase;font-weight:700;color:var(--accent-text);margin-bottom:.5em}
.res-url,.contactline{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
.res-url{font-size:.82rem;color:var(--ink-3)}
.contactline{font-size:1.05rem;font-weight:700;color:var(--accent-ink);background:var(--accent);
  padding:13px 18px;border-radius:var(--pill);display:inline-block}
.res-fund{font-size:.85rem;color:var(--ink-3);margin-bottom:0}
.tactic{scroll-margin-top:24px}
a.anchor{color:inherit;text-decoration:none}
a.anchor:hover{color:var(--accent-text)}
.tactic:target{border-color:var(--accent-text);box-shadow:0 0 0 3px var(--accent-soft)}
.prose{max-width:var(--read)}
.prose ul{color:var(--ink-2);padding-inline-start:22px}
.prose li{margin-bottom:.45em}

/* ── the challenge, the headline test, the study ──────────── */
.quiz{max-width:820px}
.qcard{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-lg);padding:28px;overflow:hidden}
.qmeta{display:flex;justify-content:space-between;align-items:center;font-size:.83rem;color:var(--ink-3);margin-bottom:14px;gap:16px}
.qtag{font-weight:700;letter-spacing:.11em;text-transform:uppercase;color:var(--accent-text);font-size:.7rem}
.qbar{height:4px;background:var(--line);border-radius:2px;overflow:hidden;margin-bottom:22px}
.qbar i{display:block;height:100%;background:var(--accent-text);transition:width .3s}
.qtext{font-family:var(--disp);font-size:1.45rem;font-weight:700;line-height:1.2;letter-spacing:-.02em;margin-bottom:20px}
.opts{display:grid;gap:10px;margin-bottom:20px}
.opt{text-align:start;min-height:48px;padding:14px 17px;border:1.5px solid var(--line);border-radius:12px;
  background:transparent;color:var(--ink-2);font:inherit;font-size:.98rem;cursor:pointer}
.opt:hover{border-color:var(--accent-text);color:var(--ink)}
.opt.sel{border-color:var(--accent-text);background:var(--accent-soft);color:var(--ink)}
.opt.correct{border-color:var(--good);background:color-mix(in srgb,var(--good) 16%,transparent);color:var(--ink)}
.opt.wrong{border-color:var(--bad);background:color-mix(in srgb,var(--bad) 16%,transparent);color:var(--ink)}
.opt:disabled{cursor:default}
.heads .head{font-family:var(--disp);font-size:1.15rem;font-weight:700;line-height:1.25;padding:18px}
.defect{font-size:.97rem;color:var(--ink-2);margin-bottom:.8em}
.conf{border-top:1px solid var(--line);padding-top:20px}
.conf label{display:flex;justify-content:space-between;align-items:baseline;gap:12px;
  font-weight:600;font-size:.97rem;margin-bottom:10px}
/* display:block and margin:0 are load-bearing. A range input carries a 2px UA
   margin on each side, so width:100% made it 4px wider than the card's content
   box at every width; .qcard{overflow:hidden} then clipped its right end. */
.conf input[type=range]{width:100%;margin:0;display:block;accent-color:var(--accent-text);height:24px}
/* After "Lock it in" the slider is replaced by what the reader actually said,
   so the verdict sits next to their own confidence rather than replacing it. */
.conf.locked{padding-block:14px 0}
.conf-said{margin:0;font-size:.95rem;color:var(--ink-2)}
.conf-said strong{font-family:var(--disp);font-variant-numeric:tabular-nums;color:var(--accent-text);font-size:1.05rem}
.confval{font-family:var(--disp);font-variant-numeric:tabular-nums;font-size:1.7rem;font-weight:800;
  letter-spacing:-.03em;color:var(--accent-text)}
.verdict{font-family:var(--disp);font-size:1.15rem;font-weight:700;margin-bottom:.5em}
.verdict.ok{color:var(--good)}
.verdict.no{color:var(--bad)}
.why{background:var(--surface-2);border-inline-start:3px solid var(--accent-text);border-radius:12px;
  padding:18px 20px;font-size:.97rem;color:var(--ink-body)}
.why p{margin:0}
.scorewrap{display:grid;gap:0;grid-template-columns:1fr 1fr;margin:22px 0;border:1px solid var(--line);border-radius:var(--radius-lg);overflow:hidden}
@media(max-width:520px){.scorewrap{grid-template-columns:1fr}}
.scorebox{background:transparent;border:0;border-inline-end:1px solid var(--line);border-radius:0;padding:26px 24px;text-align:start}
.scorebox:last-child{border-inline-end:0}
@media(max-width:520px){.scorebox{border-inline-end:0;border-block-end:1px solid var(--line)}}
.scorebox .n{display:block;font-family:var(--disp);font-size:clamp(3rem,7vw,4.6rem);font-weight:800;
  letter-spacing:-.05em;line-height:.9;font-variant-numeric:tabular-nums}
.scorebox:nth-child(2) .n{color:var(--accent-text)}
.scorebox .l{font-size:.72rem;color:var(--ink-3);letter-spacing:.11em;text-transform:uppercase;font-weight:700}
.gapline{border:0;background:var(--accent);color:var(--accent-ink);padding:22px 24px;
  border-radius:var(--radius-lg);margin-bottom:22px;font-weight:500}
.gapline p{color:var(--accent-ink)}
.picks{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(250px,1fr))}
.pickcard{display:block;text-align:start;min-height:48px;padding:20px;border:1.5px solid var(--line);
  border-radius:var(--radius-lg);background:transparent;color:var(--ink);font:inherit;cursor:pointer}
.pickcard:hover{border-color:var(--accent-text);background:var(--surface)}
.pickcard strong{display:block;font-family:var(--disp);font-size:1.2rem;font-weight:700;margin:6px 0 6px;letter-spacing:-.02em}
.pick-n{font-size:.67rem;letter-spacing:.12em;text-transform:uppercase;font-weight:700;color:var(--accent-text)}
.pick-b{font-size:.9rem;color:var(--ink-2);line-height:1.5}
.codebox{font-family:var(--disp);font-size:clamp(2.4rem,8vw,4rem);font-weight:800;letter-spacing:.02em;
  text-align:center;color:var(--accent-ink);background:var(--accent);border-radius:var(--radius-lg);
  padding:26px 18px;margin:8px 0 22px}
ul.plain{padding-inline-start:22px;color:var(--ink-2);font-size:.97rem}
ul.plain li{margin-bottom:.55em}
ul.plain strong{color:var(--ink)}

/* ── tactic detail pages ──────────────────────────────────
   These pages exist to be an example of a trustworthy page, not only to
   describe one. That is why the citation list is a first-class component with
   the sample size on the face of it, and why every page carries a section
   saying what it is NOT sure about. A page that claims sources should be
   checkable are the last place to hide a weak one. */

/* The numbered citation list. Each entry names publisher, date and N, because
   "sources: see below" is the failure mode this whole site argues against. */
.sources{list-style:none;counter-reset:src;padding:0;margin:0;border-block-start:1px solid var(--line)}
.sources li{counter-increment:src;position:relative;padding:16px 0 16px 44px;
  border-block-end:1px solid var(--line);font-size:.95rem;line-height:1.55}
[dir=rtl] .sources li{padding:16px 44px 16px 0}
.sources li::before{content:counter(src);position:absolute;inset-inline-start:0;inset-block-start:16px;
  font-family:var(--disp);font-weight:800;font-size:1rem;color:var(--accent-text);
  font-variant-numeric:tabular-nums}
.sources .s-t{font-weight:600;color:var(--ink)}
.sources .s-m{display:block;margin-block-start:5px;font-size:.78rem;color:var(--ink-3);
  letter-spacing:.07em;text-transform:uppercase;font-weight:700}
.sources a{overflow-wrap:anywhere}

/* Reference to a citation from the body text: a superscript that jumps to it. */
.ref{font-size:.72em;vertical-align:super;line-height:0;font-weight:700;
  text-decoration:none;padding-inline:1px}
.sources li:target{background:var(--accent-soft);box-shadow:0 0 0 3px var(--accent-soft)}

/* What the page is not sure about. Deliberately not styled as a warning: it is
   ordinary editorial content, which is the point being demonstrated. */
.caveat{border:1px dashed var(--line);border-radius:var(--radius-lg);padding:22px 24px;margin:26px 0}
.caveat h2{font-size:1.15rem;margin-block-end:.5em}
.caveat p,.caveat li{color:var(--ink-2);font-size:.95rem}
.caveat ul{margin:0;padding-inline-start:20px}
.caveat li{margin-block-end:.5em}

/* Page metadata: when it was written, when it was last checked. */
.pagemeta{display:flex;flex-wrap:wrap;gap:6px 22px;margin:0 0 26px;padding:0;list-style:none;
  font-size:.78rem;color:var(--ink-3);letter-spacing:.07em;text-transform:uppercase;font-weight:700}

/* The four-moves tie-in, so a tactic page always ends pointing at the method. */
.movetag{display:inline-block;font-size:.7rem;letter-spacing:.12em;text-transform:uppercase;
  font-weight:700;color:var(--accent-ink);background:var(--accent);
  padding:4px 10px;border-radius:var(--pill);margin-block-end:.7em}

/* Index of the twelve, on /tactics/ */
.t-more{display:block;margin-block-start:10px;font-weight:700;font-size:.9rem;color:var(--accent-text);text-decoration:none}
.tactic:hover .t-more{text-decoration:underline;text-underline-offset:3px}

/* ── footer ───────────────────────────────────────────────── */
.site-foot{background:var(--bg);border-block-start:1px solid var(--line);color:var(--ink-2);
  margin-top:56px;padding:34px 0;text-align:start}
.foot-lead{font-weight:600;color:var(--ink);margin-bottom:.6em}
.foot-links{display:flex;flex-wrap:wrap;gap:6px 20px;font-size:.92rem}
.foot-links a{color:var(--ink-2);text-decoration:none;font-weight:600}
.foot-links a:hover{color:var(--accent-text)}
.foot-fine{font-size:.8rem;color:var(--ink-3);margin:16px 0 0}
.foot-fine a{color:var(--ink-2);text-decoration:underline;text-underline-offset:3px}
.foot-fine a:hover{color:var(--accent-text)}

/* ── scroll motion ────────────────────────────────────────
   PROPOSAL, 2026-09-02. Not yet in the site.

   Zero JavaScript and zero libraries. Every effect on the two reference sites
   is driven by a bundled animation framework, which rule 1 forbids — so this is
   built on native CSS scroll-driven animations instead. It costs about 40 lines
   and nothing at runtime: the browser runs these off the compositor thread.

   THREE GUARDS, all mandatory, all load-bearing:

   1. prefers-reduced-motion: no-preference — motion is opt-out at the OS level.
   2. @supports ((animation-timeline: view()) and (animation-range: entry)) —
      BOTH halves are required. Some browsers ship animation-timeline without
      animation-range, and testing only the first lets those run the animation
      with no range and pin content at its start state, which means invisible
      text. The second test is what filters them out.
   3. Only transform and opacity are animated, so nothing here can cause layout
      or paint work while scrolling.

   NO JAVASCRIPT FALLBACK, deliberately. Firefox does not support scroll-driven
   animations as of 2026-09. Firefox visitors get the site exactly as it is now,
   which is a complete, working site — this is decoration, and decoration does
   not justify shipping an IntersectionObserver polyfill to make up for it.

   Ranges are `entry`, which completes the moment an element is fully in the
   viewport. An earlier draft used `cover N%` and shipped a real bug: near the
   end of a document the page runs out of scroll before the range finishes, so
   the last few blocks froze part-way through the fade and sat permanently at
   60-85% opacity. On a page whose job is to be read, a decorative animation
   that can leave text half-visible is not a trade worth making. If you add a
   selector here, check the bottom of the longest page before believing it.

   Nothing fades out on the way past, either: content that disappears when you
   scroll back to it is hostile on a reference page.

   Durations are `auto`, and that is not a style choice. A scroll-driven
   animation takes its progress from the range, not from a clock. Writing a time
   value here still attaches the animation to the timeline — it looks correct in
   the computed styles — but it stops tracking the scroll, so the effect quietly
   does nothing. That is exactly how the first version of this file failed. */

@media (prefers-reduced-motion: no-preference) {
  @supports ((animation-timeline: view()) and (animation-range: entry)) {

    /* 1 — reading progress. Earns its place on the long pages: several tactic
       and explainer pages run past 5,000px, where "how much is left" is real
       information rather than ornament. */
    .progress{position:fixed;inset-block-start:0;inset-inline-start:0;z-index:60;
      width:100%;height:3px;background:var(--accent-text);transform-origin:0 50%;
      animation:mb-progress auto linear;animation-timeline:scroll(block root)}
    @keyframes mb-progress{from{transform:scaleX(0)}to{transform:scaleX(1)}}

    /* 2 — sections arrive. 14px of rise, finished by the time the block is a
       third of the way up the viewport. The animation shorthand resets
       animation-timeline, so the timeline is declared after it, every time. */
    @keyframes mb-rise{from{opacity:0;transform:translateY(14px)}}
    .ex-sec, .card, .myth, .tactic, .res, .stat, .sheet, .founder, .sources li{
      animation:mb-rise auto ease-out backwards;
      animation-timeline:view();
      animation-range:entry;
    }

    /* 3 — the poster numerals. The 01–04 on the check sheet and the big figures
       in the evidence ledger are the loudest thing on the page, so they get a
       slightly larger move: they slide in from the inline edge. Logical
       property, so it mirrors correctly in Arabic without a second rule. */
    @keyframes mb-numeral{from{opacity:0;transform:translateX(-18px)}}
    [dir=rtl] .move-n{--mb-dir:18px}
    .moves .move-n, .stat .n, .scorebox .n{
      animation:mb-numeral auto ease-out backwards;
      animation-timeline:view();
      animation-range:entry;
    }
    [dir=rtl] .moves .move-n{animation-name:mb-numeral-rtl}
    @keyframes mb-numeral-rtl{from{opacity:0;transform:translateX(18px)}}

    /* 4 — the yellow blocks land rather than rise. A callout is a full-bleed
       panel, so a translate reads as a jolt; a small scale reads as arrival. */
    @keyframes mb-land{from{opacity:0;transform:scale(.985)}}
    .takeaway, .callout, .gapline, .codebox{
      animation:mb-land auto ease-out backwards;
      animation-timeline:view();
      animation-range:entry;
    }
  }
}

/* ── print sheets ─────────────────────────────────────────
   On screen these follow the dark design; @media print inverts the whole page,
   because a near-black flood fill is unusable on paper. */
.sheets{max-width:880px;margin:0 auto;padding:0 40px}
.sheet{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-lg);
  padding:38px 34px;margin-bottom:28px}
.sh-kicker{font-size:.72rem;letter-spacing:.15em;text-transform:uppercase;font-weight:700;color:var(--accent-text);margin-bottom:.5em}
.sh-h{font-family:var(--disp);font-size:2rem;font-weight:800;letter-spacing:-.03em;margin-bottom:.7em}
.sh-moves{padding-inline-start:24px;margin:0 0 20px}
.sh-moves li{margin-bottom:.8em;color:var(--ink-2)}
.sh-moves strong{color:var(--ink)}
.sh-grid{list-style:none;padding:0;margin:0 0 20px;display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}
.sh-grid li{border-inline-start:3px solid var(--accent-text);padding-inline-start:13px}
.sh-grid strong{display:block;font-size:.97rem}
.sh-grid span{font-size:.87rem;color:var(--ink-3)}
.sh-script{padding-inline-start:24px;margin:0 0 18px}
.sh-script li{margin-bottom:.85em;color:var(--ink-2)}
.sh-script strong{color:var(--ink)}
.sh-note{background:var(--surface-2);border-inline-start:3px solid var(--accent-text);border-radius:12px;
  padding:15px 17px;font-size:.95rem;color:var(--ink-2)}
.sh-foot{font-size:.8rem;color:var(--ink-3);border-top:1px solid var(--line);padding-top:14px;margin:20px 0 0}

@media print{
  .noprint,.mast,.mainnav,.subnav,.langbar,.reviewbar,.site-foot,.hero::after,.progress{display:none!important}
  html,body{background:#fff!important;color:#000!important;font-size:12pt}
  *{color:#000!important;background:transparent!important;box-shadow:none!important}
  .sheets{max-width:none;padding:0}
  .sheet{border:none;padding:0;margin:0;page-break-after:always;break-after:page}
  .sheet:last-child{page-break-after:auto;break-after:auto}
  .sh-kicker,.sh-grid li,.sh-moves li,.sh-script li,.sh-grid span,.sh-foot{color:#000!important}
  .sh-grid li{border-inline-start:3px solid #000}
  .sh-note{background:#f2f2f2!important;border-inline-start:3px solid #000}
  .ask::before{border-color:#000}
  .ask,.takeaway,.callout,.gapline,.codebox{border:1px solid #000!important}
  a{color:#000!important;text-decoration:none}
}

/* ── the header on a phone ────────────────────────────────
   Measured 2026-09-02 at 390x800 on /check/: masthead 126 + main nav 94 +
   subnav 112 + language bar 128 = 460px, which is 58% of the viewport, and the
   h1 did not start until y=500. A visitor on a phone saw navigation and nothing
   else on first paint, on the page every call to action points at. Adding the
   three new languages made it worse, not better.

   The fix is to stop the three link rows wrapping. Each becomes one row that
   scrolls sideways. Nothing is removed and no link is lost — the rows are
   shorter because they are one line instead of three. */
/* The rows stop wrapping from 820px down, because the language bar still wrapped
   to two lines on a tablet (96px). The masthead trims only on a real phone. */
@media(max-width:640px){
  .mast{padding:12px 0 10px}
  .mast .wrap{gap:12px;align-items:center}
  /* the wordmark already says this; on a phone it costs a whole line */
  .mast-tag{display:none}
}
@media(max-width:820px){
  .mainnav .wrap,.subnav .wrap,.langbar .wrap{
    flex-wrap:nowrap;overflow-x:auto;overscroll-behavior-inline:contain;
    scrollbar-width:none;-ms-overflow-style:none}
  .mainnav .wrap::-webkit-scrollbar,
  .subnav .wrap::-webkit-scrollbar,
  .langbar .wrap::-webkit-scrollbar{display:none}
  .mainnav a,.subnav a,.langbar a,.langlbl{flex:none;white-space:nowrap}
  .mainnav{padding-block-end:2px}
  .subnav{padding-block-end:8px}
  .langbar{padding-block:8px}

  /* Start the language row scrolled to the language you are actually reading in.
     Without this a Hindi visitor lands on a row beginning "English Espanol
     Francais" with their own language nine items off-screen, and cannot tell it
     is selected. Chromium honours this natively; site.js does the same job in
     one line for everyone else. */
  .langbar a.on{scroll-initial-target:nearest}
}

/* ── narrow ───────────────────────────────────────────────── */
@media(max-width:820px){
  .wrap{padding:0 20px}
  .sheets{padding:0 20px}
  .hero{padding:48px 0 44px}
  .hero::after{width:340px;height:340px;inset-inline-end:-160px}
  .page-head{padding:40px 0 6px}
  .stat{grid-template-columns:1fr;gap:8px}
  .moves li{padding:26px 0}
  [dir=rtl] .moves li{padding:26px 0}
  .move-n{position:static;font-size:3.4rem}
  .cta-row .btn{flex:1 1 100%}
  .qcard,.sheet{padding:22px 20px}
  .callout{padding:26px 22px}
}
@media(prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}
