/* Life in the UK study site — shared styles.
   Layout: header / left nav / main content / right ad column / footer.
   No popups. Offline-first. Print-friendly. */

:root{
  --ink:#1f2730; --muted:#5b6670; --line:#d7dde3; --paper:#fbfaf7;
  --bg:#eef1f4; --brand:#1f5c47; --brand-2:#0f8a7e; --accent:#9a5a00;
  --warn-bg:#fff8ec; --warn-bd:#e8c98a;
  --nav-w:230px; --ad-w:300px; --max:1850px;
  /* text scale: 1 = standard (default, pixel-identical to base site).
     Set via data-textsize attribute on <html> by the inline init script. */
  --ts:1;
  /* surfaces & shades reused by panels, hovers, fills. Light defaults match
     the previously hard-coded values throughout the file; dark mode below
     overrides them so panels stay visible against a dark page. */
  --card:#ffffff;
  --surface-2:#eef4f0;     /* sticky-bar / hover tint (brand-leaning) */
  --topbar-toggle:#15412f; /* "Menu" button on top bar */
  --on-brand:#ffffff;      /* text/icons that sit ON --brand or --brand-2 */
  --topbar-bg:var(--brand);
  --on-topbar:var(--on-brand);
  --unofficial-bg:#2a2f36; --unofficial-fg:#f3e7d0; --unofficial-strong:#ffd98a;
  --ad-bd:#c4ccd3; --ad-fg:#9aa3ab; --ad-ph:#b9c0c7; --ad-note:#aeb6bd;
  --cc-bg:#1f2730; --cc-fg:#eef1f4; --cc-link:#ffd98a; --cc-rej:#3a414a;
  --focus:var(--brand-2);
  --shadow:0 4px 14px rgba(0,0,0,.25);
  --ok-bg:#eef7f1; --ok-bd:#a9d6bc;
  --bad-bg:#fbecea; --bad-bd:#e0a3a3; --bad-fg:#c0392b;
  --seq-bg:#eef1ee; --seq-bd:#c5cdc7;
  --table-row-bd:#e7e2d4;
  --tag-bg:#eef4f0;
  --hooks-bg:#eef4f0; --hooks-bd:#c5d8cc;
  /* battle-map specific (so dark mode can re-tint the SVG land/sea) */
  --bm-sea:#dcebf3; --bm-land:#e9e2cf; --bm-land-stroke:#9aa17f;
  --bm-lbl-stroke:#fbfaf7;
  color-scheme:light;
}

/* ===== DARK THEME ============================================================
   Activated by <html data-theme="dark"> (set by an inline script in <head>
   before render to avoid FOUC). Only token overrides — no rule duplication. */
[data-theme="dark"]{
  --ink:#e8edf2;        /* body text — ~14:1 on --paper */
  --muted:#9aa5b1;      /* secondary — ~7:1 on --paper */
  --line:#2a3441;       /* card / divider borders */
  --paper:#1a2129;      /* main content surface */
  --bg:#0f1419;         /* page background */
  --brand:#5dc1ac;      /* lifted teal-green — ~8:1 on --paper */
  --brand-2:#7fd4c3;    /* brighter hover/focus accent */
  --accent:#e8b35a;     /* lifted amber — ~9:1 on --paper */
  --warn-bg:#2a2316;    /* warm dark panel */
  --warn-bd:#7a5e2c;

  --card:#202934;
  --surface-2:#22323a;          /* brand-tinted hover/strip */
  --topbar-toggle:#0d3325;
  --on-brand:#0f1419;           /* dark text on lifted teal — ~10:1 */
  --topbar-bg:#0c2e26;          /* dark green band — easier on the eyes than full brand */
  --on-topbar:#e8edf2;          /* near-white text on dark band — ~13:1 */
  --unofficial-bg:#13181f; --unofficial-fg:#f3e7d0; --unofficial-strong:#ffd98a;
  --ad-bd:#3a4554; --ad-fg:#8794a3; --ad-ph:#5b6776; --ad-note:#6b7785;
  --cc-bg:#0c1116; --cc-fg:#e8edf2; --cc-link:#ffd98a; --cc-rej:#2a3441;
  --shadow:0 4px 14px rgba(0,0,0,.55);
  --ok-bg:#16321f; --ok-bd:#3f7a55;
  --bad-bg:#3a1c1a; --bad-bd:#7a3a36; --bad-fg:#ff8a82;
  --seq-bg:#222a32; --seq-bd:#3a4554;
  --table-row-bd:#2a3441;
  --tag-bg:#22323a;
  --hooks-bg:#16261f; --hooks-bd:#2f5a47;
  --bm-sea:#152030; --bm-land:#28323d; --bm-land-stroke:#4a586a;
  --bm-lbl-stroke:#0f1419;
  color-scheme:dark;
}

/* ===== TEXT SIZE SCALE =======================================================
   Activated by <html data-textsize="large|larger"> (set by an inline script in
   <head> before render to avoid FOUC). Only --ts overrides — no duplication.
   Standard (no attribute or data-textsize="standard") leaves --ts at 1,
   which renders pixel-identically to the original px values via calc(). */
[data-textsize="large"]  { --ts:1.15; }
[data-textsize="larger"] { --ts:1.30; }

/* Auto-dark for first-time visitors who prefer dark, only when no explicit
   choice has been recorded (the inline init script sets data-theme up front,
   so this rule only matters before/without JS). */
@media (prefers-color-scheme:dark){
  :root:not([data-theme]){
    --ink:#e8edf2; --muted:#9aa5b1; --line:#2a3441; --paper:#1a2129;
    --bg:#0f1419; --brand:#5dc1ac; --brand-2:#7fd4c3; --accent:#e8b35a;
    --warn-bg:#2a2316; --warn-bd:#7a5e2c;
    --card:#202934; --surface-2:#22323a; --topbar-toggle:#0d3325; --on-brand:#0f1419;
    --topbar-bg:#0c2e26; --on-topbar:#e8edf2;
    --unofficial-bg:#13181f; --unofficial-fg:#f3e7d0; --unofficial-strong:#ffd98a;
    --ad-bd:#3a4554; --ad-fg:#8794a3; --ad-ph:#5b6776; --ad-note:#6b7785;
    --cc-bg:#0c1116; --cc-fg:#e8edf2; --cc-link:#ffd98a; --cc-rej:#2a3441;
    --shadow:0 4px 14px rgba(0,0,0,.55);
    --ok-bg:#16321f; --ok-bd:#3f7a55;
    --bad-bg:#3a1c1a; --bad-bd:#7a3a36; --bad-fg:#ff8a82;
    --seq-bg:#222a32; --seq-bd:#3a4554; --table-row-bd:#2a3441;
    --tag-bg:#22323a; --hooks-bg:#16261f; --hooks-bd:#2f5a47;
    --bm-sea:#152030; --bm-land:#28323d; --bm-land-stroke:#4a586a;
    --bm-lbl-stroke:#0f1419;
    color-scheme:dark;
  }
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0; background:var(--bg); color:var(--ink);
  font:calc(15.5px * var(--ts))/1.6 -apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif;
}
a{color:var(--brand)} a:hover{color:var(--brand-2)}
img{max-width:100%;height:auto}

/* ---- top bar + unofficial strip ---- */
.topbar{background:var(--topbar-bg);color:var(--on-topbar);padding:10px 18px;display:flex;
  align-items:center;gap:12px}
.topbar .logo{font-weight:800;letter-spacing:.2px;color:var(--on-topbar);text-decoration:none}
.topbar .tag{font-size:calc(12px * var(--ts));opacity:.85}
.unofficial{background:var(--unofficial-bg);color:var(--unofficial-fg);font-size:calc(12.5px * var(--ts));text-align:center;
  padding:6px 14px}
.unofficial b{color:var(--unofficial-strong)}
.unofficial a.disc-link{color:inherit;text-decoration:underline;text-underline-offset:2px}
.unofficial a.disc-link:hover b,.unofficial a.disc-link:focus-visible b{color:inherit}
.navtoggle{display:none;background:var(--topbar-toggle);color:var(--on-topbar);border:0;
  padding:7px 12px;border-radius:6px;font-size:calc(13px * var(--ts));cursor:pointer}

/* ---- theme toggle (always visible, sits between tag and navtoggle).
   Uses currentColor (= --on-brand) so it inverts cleanly with the topbar. */
.theme-toggle{margin-left:auto;background:transparent;color:inherit;
  border:1px solid currentColor;border-radius:6px;opacity:.85;
  padding:6px 10px;font-size:calc(12.5px * var(--ts));cursor:pointer;display:inline-flex;
  align-items:center;gap:6px;line-height:1}
.theme-toggle:hover{opacity:1;background:rgba(127,127,127,.18)}
.theme-toggle:focus-visible{outline:2px solid currentColor;outline-offset:2px;opacity:1}
.theme-toggle .ti{font-size:calc(14px * var(--ts));line-height:1}
/* navtoggle no longer owns the right edge — .theme-toggle does */
.topbar .navtoggle{margin-left:8px}

/* ---- text size control: segmented button group in topbar ---- */
.ts-group{margin-left:auto;display:inline-flex;border:1px solid currentColor;
  border-radius:6px;overflow:hidden;opacity:.85}
.ts-group:focus-within{opacity:1;outline:2px solid currentColor;outline-offset:2px}
.ts-btn{background:transparent;color:inherit;border:0;border-right:1px solid currentColor;
  padding:6px 9px;cursor:pointer;line-height:1;font-family:inherit;
  display:inline-flex;align-items:center;justify-content:center;min-width:28px}
.ts-btn:last-child{border-right:0}
.ts-btn:hover{background:rgba(127,127,127,.18)}
.ts-btn:focus-visible{outline:2px solid currentColor;outline-offset:-2px}
.ts-btn[aria-pressed="true"]{background:rgba(127,127,127,.28)}
/* Three "A" glyphs at increasing size; aria-hidden is set in HTML markup */
.ts-btn .ts-a{font-weight:700;line-height:1}
.ts-btn:nth-child(1) .ts-a{font-size:10px}
.ts-btn:nth-child(2) .ts-a{font-size:13px}
.ts-btn:nth-child(3) .ts-a{font-size:16px}
/* .theme-toggle retains margin-left:auto for when ts-group is absent (graceful
   degradation); when ts-group is present its own margin-left:auto takes over */
.topbar .ts-group ~ .theme-toggle{margin-left:8px}

/* ---- phone: text-size + theme controls relocated into the slide-out menu
   (site.js moves the live nodes here below 560px). Labelled rows; the
   margin-left:auto used in the topbar is neutralised so they sit left. ---- */
.nav-tools{display:flex;flex-direction:column;gap:10px;
  margin:2px 0 8px;padding:0 2px 12px;border-bottom:1px solid var(--line)}
.nav-tool{display:flex;align-items:center;gap:10px}
.nav-tool-lbl{min-width:72px;font-size:calc(11px * var(--ts));font-weight:700;
  text-transform:uppercase;letter-spacing:.05em;color:var(--muted)}
.nav-tools .ts-group,
.nav-tools .theme-toggle{margin-left:0;opacity:1}

/* ---- shell grid ---- */
.shell{max-width:var(--max);margin:0 auto;display:grid;
  grid-template-columns:var(--nav-w) minmax(0,1fr) var(--ad-w);
  gap:24px;padding:22px 24px}
nav.side{position:sticky;top:14px;align-self:start;background:var(--paper);
  border:1px solid var(--line);border-radius:10px;padding:10px}
nav.side a{display:block;padding:8px 10px;border-radius:7px;text-decoration:none;
  color:var(--ink);font-size:calc(14px * var(--ts))}
nav.side a:hover{background:var(--surface-2)}
nav.side a[aria-current="page"]{background:var(--brand);color:var(--on-brand);font-weight:600}
nav.side .grp{font-size:calc(11px * var(--ts));text-transform:uppercase;letter-spacing:.05em;
  color:var(--muted);margin:12px 8px 4px}

main{background:var(--paper);border:1px solid var(--line);border-radius:10px;
  padding:24px 30px;min-width:0}
main h1{font-size:calc(25px * var(--ts));margin:0 0 4px}
main h2{font-size:calc(17px * var(--ts));margin:26px 0 8px;border-bottom:1px solid var(--line);
  padding-bottom:5px}
.lede{color:var(--muted);font-size:calc(15px * var(--ts));margin:0 0 14px}
/* fluid layout: keep paragraph text a readable measure even when the
   content column is very wide (tables, cards, rail, map stay full width) */
main p{max-width:74ch}

/* ---- ad-free launch (2026-05-31; see docs/decisions.md) ----
   v1 ships with ads + cookie banner hidden. Markup intentionally stays in
   place so re-enabling is: delete this rule + set ADSENSE_CLIENT in site.js +
   update site/ads.txt with the real pub-id (and add Funding Choices CMP). */
.adcol,.cc,[data-cc-reopen]{display:none!important}
/* ...and drop the now-empty 300px ad track so content fills the width.
   Re-enabling ads: delete this rule too (base 3-col grid takes over again). */
.shell{grid-template-columns:var(--nav-w) minmax(0,1fr)}

/* ---- right ad column ---- */
.adcol{align-self:start;position:sticky;top:14px;display:flex;flex-direction:column;
  gap:12px}
.adslot{background:var(--card);border:1px dashed var(--ad-bd);border-radius:10px;min-height:250px;
  display:flex;align-items:center;justify-content:center;text-align:center;
  color:var(--ad-fg);font-size:calc(12px * var(--ts));padding:12px}
.adslot::before{content:"Advertisement";position:absolute;transform:translateY(-150px);
  font-size:calc(10px * var(--ts));letter-spacing:.08em;color:var(--ad-ph);text-transform:uppercase}
.adslot[data-state="pending-consent"] .ph{display:block}
.adcol .note{font-size:calc(11px * var(--ts));color:var(--ad-note);text-align:center}

/* ---- disclaimer banner (home) ---- */
.disclaimer{background:var(--warn-bg);border:1px solid var(--warn-bd);
  border-radius:10px;padding:14px 18px;margin:0 0 18px;font-size:calc(14px * var(--ts))}
.disclaimer b{color:var(--accent)}

/* ---- cards ---- */
.cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));
  gap:14px;margin:14px 0}
.card{background:var(--card);border:1px solid var(--line);border-radius:9px;padding:14px}
.cards .card.dim{display:none}
.card h3{margin:0 0 4px;font-size:calc(15px * var(--ts))}
.card .tag{display:inline-block;font-size:calc(11px * var(--ts));background:var(--tag-bg);color:var(--brand);
  border-radius:999px;padding:2px 9px;margin-right:5px}
.card .star{color:var(--accent);font-weight:700}

/* ---- filter chips ---- */
.chips{display:flex;flex-wrap:wrap;gap:8px;margin:10px 0 16px}
.chip{border:1px solid var(--line);background:var(--card);border-radius:999px;
  padding:6px 13px;font-size:calc(13px * var(--ts));cursor:pointer;user-select:none;color:var(--ink)}
.chip[aria-pressed="true"]{background:var(--brand);color:var(--on-brand);border-color:var(--brand)}
.chip:focus-visible{outline:2px solid var(--brand-2);outline-offset:2px}
.count{font-size:calc(12.5px * var(--ts));color:var(--muted);margin-left:6px}

/* ---- expand-in-place (details) ---- */
details.x{border:1px solid var(--line);border-radius:8px;background:var(--card);
  margin:8px 0;padding:0 14px}
details.x>summary{cursor:pointer;padding:11px 0;font-weight:600;list-style:none}
details.x>summary::-webkit-details-marker{display:none}
details.x>summary::after{content:"  +";color:var(--muted);float:right}
details.x[open]>summary::after{content:"  –"}
details.x .body{padding:0 0 14px;color:var(--ink)}

/* ---- timeline (vertical: reads top-to-bottom) ----
   A single column with a continuous spine down the left. Era labels are full
   width section headers; events are cards strung along the spine, each with a
   node dot. Filtering removes non-matches (.dim). */
.rail{position:relative;display:flex;flex-direction:column;gap:14px;
  padding:6px 0 18px 0;margin-left:6px;
  border-left:3px solid var(--brand-2)}
.era,h2.era{margin:18px 0 2px;padding:0 0 0 18px;font-weight:700;
  color:var(--brand);font-size:calc(15px * var(--ts));text-transform:uppercase;
  letter-spacing:.04em}
.era:first-child,h2.era:first-child{margin-top:4px}
.ev{position:relative;margin-left:18px;background:var(--card);border:1px solid var(--line);
  border-radius:9px;padding:12px 14px}
/* node dot sitting on the spine */
.ev::before{content:"";position:absolute;left:-25px;top:16px;width:11px;
  height:11px;border-radius:50%;background:var(--brand-2);
  border:2px solid var(--paper);box-shadow:0 0 0 1px var(--brand-2)}
.ev .yr{font-size:calc(19px * var(--ts));font-weight:800;color:var(--brand)}
.ev h4,.ev h3{margin:2px 0 5px;font-size:calc(15px * var(--ts))}
.ev p{margin:0;font-size:calc(13.5px * var(--ts));color:var(--muted);max-width:70ch}
.ev img.ev-img{display:block;width:100%;max-width:280px;height:150px;
  object-fit:cover;border-radius:6px;border:1px solid var(--line);margin:6px 0}
.ev.key{border-color:var(--accent);box-shadow:0 0 0 1px var(--warn-bd)}
.ev.key::before{background:var(--accent);box-shadow:0 0 0 1px var(--accent)}
.ev.nottested{opacity:.7}
.ev .nt{display:inline-block;font-size:calc(10px * var(--ts));background:var(--tag-bg);color:var(--muted);
  border-radius:4px;padding:1px 6px;margin-top:6px}
.ev.dim{display:none}

/* ---- tables ---- */
table.t{border-collapse:collapse;width:100%;font-size:calc(13.5px * var(--ts));margin:8px 0 16px}
table.t th{text-align:left;font-size:calc(11px * var(--ts));text-transform:uppercase;
  letter-spacing:.04em;color:var(--muted);border-bottom:2px solid var(--line);
  padding:6px 8px}
table.t td{border-bottom:1px solid var(--table-row-bd);padding:7px 8px;vertical-align:top}
/* horizontal-scroll wrapper for genuinely wide data tables (e.g. the 5-column
   image-credits table) so they stay reachable on phones without overflowing
   the page. No visible effect once the table already fits (tablet/desktop). */
.tscroll{overflow-x:auto;-webkit-overflow-scrolling:touch}

/* ---- images: inline portrait + captioned figure ---- */
img.pic{float:right;width:116px;height:auto;border-radius:6px;
  margin:2px 0 8px 12px;border:1px solid var(--line);background:var(--card)}
.card img.pic{float:none;display:block;width:100%;max-width:160px;margin:0 0 8px}
figure.ph{margin:14px 0;max-width:520px}
figure.ph img{width:100%;height:auto;border-radius:8px;border:1px solid var(--line);
  display:block}
/* Inline content SVGs (e.g. the Union Flag diagram) carry a fixed pixel
   width="NNN" attribute as their intended desktop size. WebKit/Safari and
   Samsung Internet do NOT shrink such an SVG from `max-width:100%` alone when
   it has a viewBox but no height attribute — it keeps the fixed width and
   overflows narrow phones. Forcing width:100% (capping at the intended size via
   max-width) plus height:auto makes it scale down everywhere while preserving
   the viewBox aspect ratio. */
figure.ph svg{width:100%;max-width:320px;height:auto;display:block}
figure.ph figcaption{font-size:calc(11.5px * var(--ts));color:var(--muted);margin-top:5px}
figure.ph figcaption a{color:var(--muted)}
@media print{img.pic,figure.ph img{max-width:130px}}

/* ---- footer ---- */
footer.site{max-width:var(--max);margin:6px auto 26px;padding:16px 18px;
  color:var(--muted);font-size:calc(12.5px * var(--ts));display:flex;flex-wrap:wrap;gap:6px 18px}
footer.site a{color:var(--muted)}
footer.site .disc{flex-basis:100%;color:var(--muted);opacity:.85}

/* ---- cookie consent (non-modal bottom bar, NOT a popup) ---- */
.cc{position:fixed;left:0;right:0;bottom:0;background:var(--cc-bg);color:var(--cc-fg);
  padding:14px 18px;display:none;align-items:center;gap:14px;flex-wrap:wrap;
  z-index:50;font-size:calc(13px * var(--ts));box-shadow:0 -2px 12px rgba(0,0,0,.25)}
.cc.show{display:flex}
.cc p{margin:0;flex:1 1 320px}
.cc a{color:var(--cc-link)}
.cc button{border:0;border-radius:7px;padding:9px 16px;font-size:calc(13px * var(--ts));
  cursor:pointer;font-weight:600}
.cc .acc{background:var(--brand-2);color:var(--on-brand)}
.cc .rej{background:var(--cc-rej);color:var(--cc-fg)}
.cc .acc,.cc .rej{min-width:120px}

/* ---- responsive: nav collapses to in-page slide-down (no popup) ---- */
@media (max-width:1080px){
  .shell{grid-template-columns:minmax(0,1fr)}
  .adcol{position:static;flex-direction:row;flex-wrap:wrap}
  .adslot{flex:1 1 280px;min-height:120px}
  nav.side{position:static}
  .navtoggle{display:block}
  nav.side{display:none}
  nav.side.open{display:block}
}
@media (max-width:560px){
  main{padding:18px 16px}
  .topbar .tag{display:none}
  /* controls move into the menu (site.js), so the logo + Menu are all that
     remain; push Menu to the right edge. */
  .topbar .navtoggle{margin-left:auto}
  /* battle tables: tighten cell padding so the 3 columns breathe on a phone.
     The year column stays slim via auto-layout — every year is now a short
     value (the D-Day row shows "1944", with its full date in the description),
     so no single cell stretches the column. Auto-layout also scales cleanly
     with the text-size control, unlike fixed percentages. */
  .battlemap th,.battlemap td{padding-left:5px;padding-right:5px}
  /* generic data tables (table.t): on phones drop to a smaller font + tight
     padding so wide 5-column tables (e.g. four-nations "at a glance") fit
     without overflowing, and break-word so the raw URLs in the image-credits
     table wrap instead of pushing the table off-screen. Smaller font means
     short words like "Edinburgh" still fit their column without mid-word breaks. */
  table.t{font-size:calc(11.5px * var(--ts))}
  table.t th{font-size:calc(10px * var(--ts))}
  table.t th,table.t td{padding:6px 5px;overflow-wrap:break-word}
  /* Scroll-wrapped tables (.tscroll: four-nations "Nations at a glance" and the
     image-credits table) do NOT need the phone font reduction above — they have
     a horizontal-scroll frame, so they can keep the site's standard table size
     (matching every other table and the surrounding body text) and simply
     scroll sideways for their wide columns. Restore full size here so they no
     longer read as "shrunken". The generic 11.5px reduction still applies to the
     simple 2-3 column tables that rely on fitting the viewport. */
  .tscroll table.t{font-size:calc(13.5px * var(--ts))}
  .tscroll table.t th{font-size:calc(11px * var(--ts))}
  /* four-nations "Nations at a glance": 5 wide columns (incl. long flag-element
     sentences) can't fit a phone at a readable size without shrinking the font
     or breaking words — and at the larger text size it's impossible. So the
     table is wrapped in .tscroll and given a comfortable min-width: the text
     stays full-size (matching every other table) with NO broken words, and the
     table scrolls sideways within the frame instead of overflowing the page.
     min-width comfortably holds the longest words even at the larger text size. */
  table.t.t-glance{min-width:480px}
}

/* ---- print ---- */
@media print{
  body{background:#fff}
  .topbar,.navtoggle,.adcol,.cc,nav.side{display:none!important}
  .shell{display:block;max-width:100%;padding:0}
  main{border:0;border-radius:0;padding:0}
  .disclaimer{border:1px solid #999}
  details.x[open]{break-inside:avoid}
  a[href]::after{content:""}
}

/* ---- non-interactive sequence pills (e.g. monarch house order) ---- */
.seqrow{display:flex;flex-wrap:wrap;gap:6px;margin:8px 0 14px}
.seq{display:inline-block;font-size:calc(12.5px * var(--ts));color:var(--muted);
  background:var(--seq-bg);border:1px dashed var(--seq-bd);border-radius:6px;
  padding:4px 10px;cursor:default}

/* ---- screen-reader-only utility: visually hidden but announced ---- */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}

/* ---- keyboard focus parity for native expanders ---- */
details.x>summary:focus-visible{outline:2px solid var(--brand-2);
  outline-offset:2px;border-radius:6px}

/* ---- battle-map page styles (moved out of the page body so the HTML is
   valid; scoped to .battlemap so they never affect the rest of the site) ---- */
.battlemap{--bm-line:var(--line);position:relative}
.battlemap .grid{display:flex;gap:28px;align-items:flex-start;flex-wrap:wrap}
/* min-width uses min(…,100%) so on a narrow phone (e.g. Samsung Z Flip 5 ~360px,
   where the content box is < the fixed floor) the columns shrink to fit and
   stack full-width instead of forcing horizontal overflow. The map SVG is
   width:100%;height:auto so it scales down cleanly. */
.battlemap .mapcol{flex:1 1 540px;min-width:min(340px,100%)}
.battlemap .sidecol{flex:1 1 380px;min-width:min(300px,100%)}
.battlemap svg{width:100%;height:auto;display:block}
.battlemap .sea-bg{fill:var(--bm-sea)}
.battlemap .land{fill:var(--bm-land);stroke:var(--bm-land-stroke);stroke-width:0.8;stroke-linejoin:round}
/* In-SVG map labels are pinned at fixed coordinates, so their font size is
   FIXED (not multiplied by --ts): scaling them with the reading-size control
   overruns the viewBox and clips labels (e.g. "Battle of Britain" -> "Battle
   of Brit"). The reflowing battle TABLE below the map remains the scalable,
   accessible equivalent. */
.battlemap .lbl{font:600 11.5px/1.1 Segoe UI,Arial,sans-serif;paint-order:stroke;stroke:var(--bm-lbl-stroke);stroke-width:3px}
.battlemap .abroad-arrow line,.battlemap .abroad-arrow polygon{stroke:var(--accent);fill:var(--accent);stroke-width:2}
.battlemap .abroad-arrow text{font:600 11px Segoe UI,Arial,sans-serif;fill:var(--accent)}
.battlemap .abroad-arrow text.dim{fill:var(--accent);opacity:.7;font-weight:500}
.battlemap .legend{display:flex;flex-wrap:wrap;gap:6px 16px;margin:12px 0 0;font-size:calc(12.5px * var(--ts));color:var(--ink)}
.battlemap .legend span{display:inline-flex;align-items:center;gap:6px}
.battlemap .sw{width:13px;height:13px;border-radius:3px;display:inline-block;border:1px solid var(--paper);box-shadow:0 0 0 1px var(--line)}
.battlemap table{border-collapse:collapse;width:100%;font-size:calc(13px * var(--ts));margin:6px 0 18px}
.battlemap th{text-align:left;font-size:calc(11px * var(--ts));text-transform:uppercase;letter-spacing:.04em;color:var(--muted);border-bottom:2px solid var(--bm-line);padding:5px 8px}
.battlemap td{border-bottom:1px solid var(--table-row-bd);padding:6px 8px;vertical-align:top;overflow-wrap:break-word}
/* Year column shrinks to its own content (width:1% + nowrap) so it never
   hogs space; the freed width flows to Battle and "Who won" via auto-layout. */
.battlemap td.yr{font-weight:700;white-space:nowrap;color:var(--ink);width:1%;padding-right:10px}
.battlemap th:first-child{width:1%;white-space:nowrap}
/* Battle cell: a flex row so the colour dot is a fixed first item and the
   name wraps BESIDE it (never under it / never orphaned), while still being
   free to wrap — so the table never forces itself wider than the screen
   (which pushed the "Who won" text off-frame at larger text sizes). */
.battlemap .bw{display:flex;gap:7px}
.battlemap .bw .dot{flex:0 0 auto;margin:5px 0 0 0}
.battlemap .why{color:var(--muted)}
.battlemap .loc{color:var(--accent);font-weight:600}
.battlemap .dot{width:9px;height:9px;border-radius:50%;display:inline-block;margin-right:7px;vertical-align:middle}
.battlemap .dot.land{background:#c0392b}
.battlemap .dot.sea{background:#1d6fb8}
.battlemap .dot.air{background:#0f8a7e}
.battlemap h2{font-size:calc(14px * var(--ts));text-transform:uppercase;letter-spacing:.05em;color:var(--muted);margin:20px 0 4px;border-bottom:1px solid var(--bm-line);padding-bottom:4px}
.battlemap .abroad-box{background:var(--warn-bg);border:1px solid var(--warn-bd);border-radius:8px;padding:4px 14px 10px}
.battlemap .abroad-box h2{color:var(--accent);border-color:var(--warn-bd)}
.battlemap .hooks{background:var(--hooks-bg);border:1px solid var(--hooks-bd);border-radius:8px;padding:10px 16px;font-size:calc(13px * var(--ts))}
.battlemap .hooks li{margin:4px 0}
.battlemap .hooks b{color:var(--brand)}
.battlemap .foot{margin-top:22px;font-size:calc(11.5px * var(--ts));color:var(--muted);border-top:1px solid var(--bm-line);padding-top:10px}
@media print{
  .battlemap .grid{gap:14px}
  .battlemap h2{break-after:avoid}
  .battlemap tr,.battlemap .abroad-box,.battlemap .hooks{break-inside:avoid}
}

/* ---- timeline: filtered-out events are removed, not greyed ---- */
.rail .ev.dim{display:none}
.scrollcue{display:flex;align-items:center;gap:8px;font-size:calc(12.5px * var(--ts));
  color:var(--brand);background:var(--hooks-bg);border:1px solid var(--hooks-bd);
  border-radius:8px;padding:7px 12px;margin:0 0 10px}
.scrollcue b{color:var(--brand)}

/* ---- monarch portrait thumbnail shown next to the name ---- */
img.mono{width:84px;height:112px;object-fit:cover;object-position:50% 12%;
  border-radius:8px;border:1px solid var(--line);float:left;
  margin:0 12px 2px 0;background:var(--card)}

/* ---- contact form fields (full width so long placeholders are visible) ---- */
form input[type="text"],
form textarea{
  display:block;width:100%;max-width:560px;
  padding:8px 11px;font:inherit;font-size:calc(14px * var(--ts));
  color:var(--ink);background:var(--card);
  border:1px solid var(--line);border-radius:6px}
form textarea{resize:vertical}
form input[type="text"]:focus,
form textarea:focus{outline:2px solid var(--brand-2);outline-offset:1px;
  border-color:var(--brand-2)}

/* ---- battle-map hover/focus info (transient label, not a popup) ---- */
.battlemap .bm-pin{cursor:pointer}
.battlemap .bm-pin:focus-visible{outline:2px solid var(--brand-2);outline-offset:2px}
.battlemap .bm-tip{position:absolute;transform:translate(-50%,-100%);
  max-width:260px;background:#1f2730;color:#fff;font-size:calc(12px * var(--ts));line-height:1.4;
  padding:8px 10px;border-radius:7px;pointer-events:none;opacity:0;
  transition:opacity .12s;z-index:20;box-shadow:var(--shadow)}
[data-theme="dark"] .battlemap .bm-tip{background:#000;border:1px solid var(--line)}
.battlemap .bm-tip.show{opacity:1}
@media print{.battlemap .bm-tip{display:none}}

/* ---- practice tests ---- */
.quiz-app{margin:18px 0 8px}
.quiz-loading{color:var(--muted);font-size:calc(14px * var(--ts))}
.quiz-msg{background:var(--warn-bg);border:1px solid var(--warn-bd);
  border-radius:8px;padding:12px 16px;font-size:calc(14px * var(--ts));margin:0 0 14px}
.quiz-note{color:var(--muted);font-size:calc(13.5px * var(--ts))}

/* shared call-to-action button (reuses brand tokens) */
.btn-quiz{display:inline-block;background:var(--brand);color:var(--on-brand);border:0;
  border-radius:8px;padding:11px 20px;font-size:calc(15px * var(--ts));font-weight:600;
  cursor:pointer;margin:10px 0}
.btn-quiz:hover{background:var(--brand-2);color:var(--on-brand)}
.btn-quiz:focus-visible{outline:2px solid var(--brand-2);outline-offset:2px}
.btn-quiz.ghost{background:var(--card);color:var(--brand);border:1px solid var(--line)}
.btn-quiz.ghost:hover{background:var(--surface-2)}
.btn-quiz.small{padding:6px 12px;font-size:calc(13px * var(--ts));margin:0}
.btn-quiz.big{padding:14px 28px;font-size:calc(17px * var(--ts));margin:0}

/* ---- homepage practice-test CTA ---- */
.home-cta{margin:20px 0 8px}
.home-cta-note{margin:8px 0 0;color:var(--muted);font-size:calc(13.5px * var(--ts))}
@media (max-width:560px){
  .home-cta .btn-quiz{display:block;width:100%;text-align:center;box-sizing:border-box}
}
.card.featured{border:2px solid var(--brand);background:var(--tag-bg)}
.card.featured h3{color:var(--brand)}

/* ---- test picker grid ---- */
.test-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(68px,1fr));
  gap:7px;margin:10px 0 18px}
.test-pick{display:flex;flex-direction:column;align-items:center;gap:2px;
  background:var(--card);border:1px solid var(--line);border-radius:7px;
  padding:7px 4px;cursor:pointer;font:inherit;color:var(--ink)}
.test-pick:hover{background:var(--surface-2);border-color:var(--brand-2)}
.test-pick:focus-visible{outline:2px solid var(--brand-2);outline-offset:2px}
.test-pick .tp-num{font-size:calc(17px * var(--ts));font-weight:800;color:var(--brand);line-height:1.1}
.test-pick .tp-state{font-size:calc(11px * var(--ts));color:var(--muted);line-height:1.1}
.test-pick.done{background:var(--ok-bg);border-color:var(--ok-bd)}
.test-pick.done .tp-state{color:var(--brand);font-weight:700}

/* ---- runner bar ---- */
.quiz-bar{display:flex;align-items:center;justify-content:space-between;
  gap:12px;flex-wrap:wrap;background:var(--hooks-bg);border:1px solid var(--hooks-bd);
  border-radius:8px;padding:10px 14px;margin:6px 0 16px}
.quiz-bar strong{font-size:calc(15px * var(--ts));color:var(--brand)}
.quiz-live{font-size:calc(13.5px * var(--ts));font-weight:600;color:var(--ink)}

/* ---- per-question fieldset ---- */
.quiz-form{border:0;margin:0;padding:0}
fieldset.quiz-q{border:1px solid var(--line);border-radius:10px;background:var(--card);
  margin:0 0 14px;padding:14px 16px;min-width:0}
fieldset.quiz-q.correct{border-color:var(--ok-bd);box-shadow:0 0 0 1px var(--ok-bd)}
fieldset.quiz-q.wrong{border-color:var(--bad-bd);box-shadow:0 0 0 1px var(--bad-bd)}
/* Float the legend into normal flow: a fieldset's first <legend> is otherwise
   special-cased to straddle the top border (display:block does NOT undo this —
   only float/absolute does), which made the question text sit on the card edge
   and the .correct/.wrong border+shadow ring cut across it. */
fieldset.quiz-q legend{display:block;float:left;width:100%;margin:0;padding:0 0 8px}
fieldset.quiz-q::after{content:"";display:block;clear:both}
.quiz-num{display:block;font-size:calc(11px * var(--ts));text-transform:uppercase;
  letter-spacing:.05em;color:var(--muted);margin-bottom:4px}
.quiz-stem{display:block;font-size:calc(15.5px * var(--ts));font-weight:600;color:var(--ink)}
.quiz-inst{display:inline-block;font-size:calc(12px * var(--ts));font-weight:700;color:var(--accent);
  background:var(--warn-bg);border:1px solid var(--warn-bd);border-radius:6px;
  padding:2px 8px;margin-top:6px}

label.quiz-opt{display:flex;align-items:flex-start;gap:10px;
  border:1px solid var(--line);border-radius:8px;padding:10px 12px;
  margin:8px 0 0;cursor:pointer;font-size:calc(14.5px * var(--ts));background:var(--paper)}
label.quiz-opt:hover{background:var(--surface-2)}
label.quiz-opt input{margin:2px 0 0;flex:0 0 auto;width:18px;height:18px;
  accent-color:var(--brand)}
label.quiz-opt:focus-within{outline:2px solid var(--brand-2);outline-offset:2px}
.quiz-opt-text{flex:1 1 auto}
.quiz-opt-mark{flex:0 0 1.1em;font-weight:800;text-align:center}
/* instant-feedback states (set once the question locks) */
.quiz-q.locked label.quiz-opt{cursor:default}
label.quiz-opt.opt-correct{background:var(--ok-bg);border-color:var(--ok-bd)}
label.quiz-opt.opt-correct .quiz-opt-mark{color:var(--brand)}
label.quiz-opt.opt-wrong{background:var(--bad-bg);border-color:var(--bad-bd)}
label.quiz-opt.opt-wrong .quiz-opt-mark{color:var(--bad-fg)}
.quiz-fb{font-size:calc(13.5px * var(--ts));margin:10px 0 0}
.quiz-fb.ok{color:var(--brand)}
.quiz-fb.bad{color:var(--bad-fg)}
.quiz-fb:empty{display:none}

/* ---- result panel ---- */
.quiz-results{margin-top:10px;scroll-margin-top:14px}
.quiz-results:focus{outline:none}
.quiz-score{border:1px solid var(--line);border-radius:10px;padding:16px 18px;
  margin:8px 0 18px}
.quiz-score.pass{background:var(--ok-bg);border-color:var(--ok-bd)}
.quiz-score.fail{background:var(--warn-bg);border-color:var(--warn-bd)}
.quiz-score h2{margin:0 0 4px;border:0;padding:0;font-size:calc(20px * var(--ts))}
.quiz-score.pass h2{color:var(--brand)}
.quiz-score.fail h2{color:var(--accent)}
.quiz-score-line{font-size:calc(15px * var(--ts));font-weight:600;margin:0 0 6px}
.quiz-score .quiz-note{margin:0 0 8px}
.quiz-actions{display:flex;gap:12px;flex-wrap:wrap;margin-top:6px}

@media (max-width:560px){
  .test-grid{grid-template-columns:repeat(auto-fill,minmax(58px,1fr));gap:6px}
  .quiz-actions{flex-direction:column;align-items:stretch}
  .quiz-actions .btn-quiz{width:100%;text-align:center}
}
@media print{
  .quiz-bar,.btn-quiz,.test-grid{display:none!important}
  fieldset.quiz-q{break-inside:avoid}
}
