/* ===========================================================================
   Emgwen 2027 campaign site: shared stylesheet.
   Used by every issue page. Extracted from the approved healthcare page so a
   design change is one edit rather than one per page.
   Contrast rule that is easy to break: gold is text-safe only on the ink
   ground (9.7:1). On paper it measures 1.6:1. The light-ground accent is
   green (4.9:1), and the provisional marker is amber (5.2:1).
   Palette, updated 2026-09-11: pulled from the client's actual UDA logo file
   rather than the docx (gold F8C80F, green 179748, sampled directly from the
   PNG's pixels). Gold is used as-is, it already clears AA on dark ground with
   room to spare. Green is darkened about 17% from the logo's own shade,
   #179748 measures 3.53:1 on paper, short of the 4.5:1 small-text floor this
   token needs everywhere it is used; #137D3C clears both that and the 3:1
   large-text floor the same token needs on dark ground.

   The site's large "dominating" sections (.on-dark, plus .hero/.ihero/.foot,
   which carry the same treatment directly rather than through that class)
   moved from an ink ground to a gold one, 2026-09-11, following the
   reference at uda.ke, where yellow is the dominant colour. That site's own
   text on yellow (white headlines, 1.6:1; green labels, 2.4:1) both fail AA
   outright, so the treatment here is copied, the colours are not.
   --on-dark, --on-dark-dim and --rule-dark keep their names (every call
   site through the markup already references them) but are redefined to
   ink-based values: nothing on this site still uses a true ink ground that
   would need the old paper-based ones. --ink itself, at full opacity, is
   the ground's primary text colour (10.5:1 on gold), replacing --paper.
   --green-deep and --amber-deep are the choropleth ramp's own darkest
   shade and a matching darkened amber, 6.7:1 and 4.8:1 on gold, standing in
   for --green (3.3:1, large-text only) and --amber (3.5:1, large-text only)
   wherever the existing accent needed to survive at small sizes too.
   Components that sit in their own self-contained ink card regardless of
   what the section behind them does (.pathway/.road/.wards/.mapwrap, all
   explicitly background:var(--ink) on their own list items) are unaffected
   and still use --paper/--gold directly, untouched by any of this. */
:root{
  --gold:#F8C80F;
  --ink:#1E1E1E;
  --ink-2:#262626;
  --green:#137D3C;
  --green-deep:#0B4823;     /* on-gold accent, small text safe. 6.7:1 on gold */
  --amber:#8A6100;          /* provisional marker. 5.2:1 on paper, AA */
  --amber-deep:#6E4E00;     /* on-gold provisional marker. 4.8:1 on gold */
  --on-ink-dim:rgba(250,247,240,.55);  /* dim text for .pathway/.road/.ward's
    own still-ink card interiors, the old --on-dark-dim value kept under its
    own name: those cards stayed ink regardless of the section going gold
    around them, so they still need paper-based dim text, not the ink-based
    value --on-dark-dim was repointed to. */

  --paper:#FAF7F0;
  --rule:rgba(30,30,30,.16);
  --rule-dark:rgba(30,30,30,.18);      /* was paper-based; ink ground is gone */
  --muted:#6B6459;
  --on-dark:rgba(30,30,30,.72);        /* was paper-based; ink ground is gone */
  --on-dark-dim:rgba(30,30,30,.7);     /* was paper-based; ink ground is gone */

  --display:"Big Shoulders Display","Haettenschweiler","Arial Narrow",sans-serif;
  --body:"Schibsted Grotesk","Helvetica Neue",Helvetica,Arial,sans-serif;

  --gut:clamp(1.25rem,5vw,5.5rem);
  --max:72rem;
  --nav-h:88px;
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

body{
  margin:0;background:var(--paper);color:var(--ink);
  font-family:var(--body);
  font-size:clamp(1rem,.95rem + .25vw,1.075rem);
  line-height:1.65;overflow-x:hidden;font-synthesis-weight:none;
}
body::after{
  content:"";position:fixed;inset:0;z-index:200;pointer-events:none;opacity:.032;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
.wrap{max-width:var(--max);margin-inline:auto;padding-inline:var(--gut)}

.skip{position:absolute;left:-9999px;top:0;z-index:300;background:var(--gold);color:var(--ink);
  padding:.75rem 1.25rem;font-weight:700;font-size:.85rem;letter-spacing:.05em;text-transform:uppercase;text-decoration:none}
.skip:focus{left:0}
:focus-visible{outline:3px solid var(--green-deep);outline-offset:3px}
.on-dark :focus-visible{outline-color:var(--ink)}
.vh{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* ---------- Nav ----------
   White, added 2026-09-11, replacing the near-black bar every other section
   on the site used to share. Reference: uda.ke, whose own header is white
   with a green accent, yellow reserved for the sections beneath it. Nav
   text and links move from light-on-dark to dark-on-white, the opposite
   convention from before. */
/* No backdrop-filter (removed 2026-09-11): filter/backdrop-filter on an
   ancestor creates a new containing block for any position:fixed
   descendant, which silently confined .nav__panel and .nav__overlay
   (nested inside .nav via .nav__menu, so <summary> could be a direct
   child of <details>) to the nav bar's own 96px box instead of the
   viewport. The background is already 96% opaque, so the blur it was
   softening was faint to begin with. */
.nav{position:sticky;top:0;z-index:100;background:rgba(255,255,255,.96);
  border-bottom:1px solid var(--rule)}
/* Separates the white nav from the gold section beneath it. Green rather
   than a gold/green split: a gold bar directly above a gold hero would
   have nothing to separate. */
.nav::before{content:"";display:block;height:8px;background:var(--green)}
.nav__bar{display:flex;align-items:center;justify-content:space-between;gap:1rem;min-height:var(--nav-h)}
/* Candidate name and party mark share one flex slot, added 2026-09-11, so
   .nav__bar keeps its original two-child space-between layout rather than
   needing a three-column rework. */
.nav__id{display:flex;align-items:center;gap:.9rem;min-width:0}
/* Display face, not the body one, and bigger, 2026-09-11: the plain
   grotesque at 1rem read as fine print next to how bold the rest of the
   page is. Big Shoulders Display is the same face every headline on the
   site already uses, condensed enough to grow like this without pushing
   .nav__links out of the bar. position:relative + overflow:hidden sets
   up the sheen sweep below, the same technique the data bars already
   use, not a new animation style. */
.nav__mark{
  font-family:var(--display);font-weight:900;font-size:1.5rem;letter-spacing:-.01em;
  color:var(--ink);text-decoration:none;white-space:nowrap;
  position:relative;overflow:hidden;display:inline-block;
}
.nav__mark span{color:var(--green-deep)}
.nav__mark::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(100deg,
    transparent 30%,
    rgba(19,125,60,.35) 50%,
    transparent 70%);
  transform:translateX(-115%);
}
.js .nav__mark::after{animation:navMarkSheen 5s ease-in-out infinite}
@keyframes navMarkSheen{
  0%,15%{transform:translateX(-115%)}
  55%,100%{transform:translateX(115%)}
}
@media (prefers-reduced-motion:reduce){.js .nav__mark::after{animation:none}}
/* .nav__party (the logo in the bar) removed 2026-09-11: it lives in the
   slide-in panel now instead (.nav__panel-brand, enlarged there),
   reachable from the toggle already beside this name. */

/* ---------- Nav: side slide-in menu, added 2026-09-11 ----------
   Replaces the inline .nav__links row (kept the bar from staying compact
   on mobile: a full links row stacked under a large logo on every small
   screen). One panel, one interaction pattern, at every width, rather
   than a second nav mode that only exists below some breakpoint.

   <details>/<summary>, not a checkbox: this site's whole second claim,
   alongside R1's sourcing discipline, is R2, no forms, no inputs, nothing
   collected, checked by the standing audit on every page. <details>
   reaches every link with zero scripting, a mouse, a touch, or a
   keyboard, the same as a checkbox toggle would, without introducing the
   one form-associated element that claim exists to rule out. */
.nav__menu{position:relative}
.nav__toggle{
  display:inline-flex;align-items:center;justify-content:center;
  width:44px;height:44px;padding:0;flex-shrink:0;cursor:pointer;
  list-style:none;
}
.nav__toggle::marker,.nav__toggle::-webkit-details-marker{display:none}
.nav__toggle:focus-visible{outline:3px solid var(--green-deep);outline-offset:3px}
.nav__toggle-bars,.nav__toggle-bars::before,.nav__toggle-bars::after{
  content:"";display:block;width:22px;height:2px;background:var(--ink);border-radius:1px;
}
.nav__toggle-bars{position:relative}
.nav__toggle-bars::before{position:absolute;left:0;top:-7px}
.nav__toggle-bars::after{position:absolute;left:0;top:7px}

/* The browser's own UA stylesheet hides every non-summary child of a
   closed <details> (effectively display:none). Overridden here because
   that hiding is instant, no transition plays across a display:none
   boundary, and the .nav__panel slide needs one. Visibility (not the
   transform alone) does the actual hiding while closed instead, which
   keeps a display:none-to-block jump out of the picture entirely. */
.nav__menu > .nav__overlay,.nav__menu > .nav__panel{display:block!important}

.nav__overlay{position:fixed;inset:0;z-index:150;background:rgba(30,30,30,.5);
  opacity:0;pointer-events:none;cursor:default;transition:opacity .3s ease}
.nav__menu[open] > .nav__overlay{opacity:1;pointer-events:auto}

/* White, changed 2026-09-11 (was deliberately dark): matches the header
   bar it slides out from instead of contrasting with it, and carries an
   enlarged logo (.nav__panel-brand) the same way the footer does. Every
   colour is the ordinary light-ground pairing used everywhere else on
   the site (ink text, green accent), nothing new to verify. visibility
   keeps the panel's links out of tab order while closed; the 0s duration
   with a delay on close, none on open, means it only becomes untabbable
   once the slide-out has actually finished.
   Opacity added to the transition (also 2026-09-11): a slide alone read
   as a hard cut in from the edge, fading in alongside it softens the
   entrance and exit the same way. */
.nav__panel{
  position:fixed;top:0;right:0;bottom:0;z-index:200;
  width:min(20rem,85vw);background:#fff;color:var(--ink);
  display:flex;flex-direction:column;overflow-y:auto;
  transform:translateX(100%);opacity:0;visibility:hidden;
  transition:transform .3s ease,opacity .3s ease,visibility 0s .3s;
  box-shadow:-8px 0 24px rgba(0,0,0,.18);
}
.nav__menu[open] > .nav__panel{
  transform:translateX(0);opacity:1;visibility:visible;
  transition:transform .3s ease,opacity .3s ease,visibility 0s;
}
.nav__panel-head{display:flex;align-items:center;justify-content:space-between;
  padding:1.1rem 1.25rem;border-bottom:1px solid var(--rule)}
.nav__panel-title{font-size:.72rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  color:var(--muted)}
.nav__close{display:inline-flex;align-items:center;justify-content:center;
  width:44px;height:44px;border:0;background:transparent;color:var(--ink);
  font-size:1.6rem;line-height:1;cursor:pointer}
.nav__panel-brand{padding:1.5rem 1.25rem;border-bottom:1px solid var(--rule)}
.nav__panel-brand img{height:96px;width:auto;display:block}
.nav__panel-links{list-style:none;margin:0;padding:.5rem 0}
.nav__panel-links a{display:block;padding:1rem 1.25rem;color:var(--muted);
  text-decoration:none;font-size:.92rem;font-weight:600;letter-spacing:.06em;text-transform:uppercase;
  border-left:3px solid transparent;transition:color .2s,border-color .2s,background .2s}
.nav__panel-links a:hover{color:var(--ink)}
.nav__panel-links a[aria-current="page"],.nav__panel-links a[aria-current="true"]{
  color:var(--green);border-left-color:var(--green);background:rgba(19,125,60,.06)}
html.nav-open{overflow:hidden}
@media (min-width:47.99rem){.nav__panel{width:22rem}}

/* ---------- Type ---------- */
h1,h2,h3{font-family:var(--display);font-weight:900;margin:0;line-height:.95;letter-spacing:-.012em}
.eyebrow{font-family:var(--body);font-size:.7rem;font-weight:600;letter-spacing:.22em;text-transform:uppercase;
  color:var(--muted);display:flex;align-items:center;gap:.9rem;margin:0 0 1.75rem}
.eyebrow::after{content:"";flex:1;height:1px;background:var(--rule)}
.eyebrow .n{color:var(--green);font-variant-numeric:tabular-nums}
/* Gold, replacing ink, 2026-09-11: the site's large "dominating" sections
   move to the same yellow the reference site (uda.ke) uses for its own
   feature blocks. Text moves from --paper to --ink (10.5:1 on gold), the
   opposite convention from the ink ground this replaces. Components nested
   in their own dark card (pathway/road/wards/mapwrap, all explicitly
   background:var(--ink) on their own list items) are unaffected, they sit
   on their own ink island regardless of what the section behind them does,
   so their paper/gold text is untouched. Only text sitting directly on the
   section's own background needed new colours, below and in Base.astro /
   the page templates' inline styles. */
.on-dark{background:var(--gold);color:var(--ink)}
.on-dark .eyebrow{color:var(--on-dark-dim)}
.on-dark .eyebrow::after{background:var(--rule)}
.on-dark .eyebrow .n{color:var(--green-deep)}
section{padding-block:clamp(3rem,7vw,5rem);scroll-margin-top:calc(var(--nav-h) + 40px)}

/* ---------- Issue hero ---------- */
.ihero{background:var(--gold);color:var(--ink);padding-block:clamp(2.5rem,6vw,4.5rem) clamp(2.5rem,6vw,4rem)}
.ihero__back{display:inline-block;font-size:.68rem;font-weight:600;letter-spacing:.16em;text-transform:uppercase;
  color:var(--green-deep);text-decoration:none;margin-bottom:1.5rem}
.ihero__back:hover{text-decoration:underline}
/* Small poster-matched label above the H1, added 2026-09-11 (R5) for the
   Protect/Empower/Prosper pillar pages. Same treatment as .hero__manifabel
   on the homepage, reused rather than inventing a third small-caps style. */
.ihero__eyebrow{font-size:.68rem;font-weight:600;letter-spacing:.2em;text-transform:uppercase;color:var(--green-deep);margin:0 0 1rem}
.ihero h1{font-size:clamp(3rem,11vw,6.5rem);text-transform:uppercase;letter-spacing:-.02em;margin:0 0 1.2rem}
.ihero__thesis{font-family:var(--body);font-weight:600;font-size:clamp(1.18rem,3vw,1.7rem);
  line-height:1.3;letter-spacing:-.015em;max-width:26ch;margin:0 0 1.2rem}
.ihero__intro{color:var(--on-dark-dim);max-width:60ch;margin:0;font-size:.98rem}

/* ---------- Issue featured photo ---------- */
.issue-photo{margin:0;background:var(--paper);padding-block:clamp(1.5rem,4vw,2.5rem) 0}
.issue-photo picture{display:block;max-width:var(--max);margin-inline:auto;padding-inline:var(--gut)}
.issue-photo img{width:100%;height:auto;display:block;border:1px solid var(--rule)}
.issue-photo figcaption{position:relative;max-width:var(--max);margin-inline:auto;
  padding:0 var(--gut) 0 calc(var(--gut) + .7rem);
  margin-top:.6rem;font-size:.8rem;color:var(--muted)}
.issue-photo figcaption::before{content:"";position:absolute;top:0;bottom:0;left:var(--gut);width:3px;background:var(--green)}

/* ---------- Provenance marks ---------- */
.src{display:block;font-size:.68rem;line-height:1.45;letter-spacing:.01em;margin-top:.7rem}
.src b{font-weight:700;text-transform:uppercase;letter-spacing:.12em;font-size:.62rem}
.src--ok{color:var(--green)}
.src--prov{color:var(--amber)}
.on-dark .src--ok{color:var(--green-deep)}
.on-dark .src--prov{color:var(--amber-deep)}
.tag{display:inline-block;font-size:.6rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  padding:.2em .5em;border-radius:2px;vertical-align:middle;margin-left:.5rem}
.tag--ok{color:var(--green);border:1px solid rgba(19,125,60,.45)}
.tag--prov{color:var(--amber);border:1px solid rgba(138,97,0,.45)}
/* Same catch-all as table.data above: --green/--amber are large-text-only
   on gold (3.3:1 / 3.5:1), and these tags are .6rem, small. */
.on-dark .tag--ok{color:var(--green-deep);border-color:rgba(11,72,35,.45)}
.on-dark .tag--prov{color:var(--amber-deep);border-color:rgba(110,78,0,.45)}

/* ---------- Data table with inline bars ---------- */
.figblock{margin:0 0 clamp(2rem,4vw,3rem)}
.figblock h3{font-size:clamp(1.4rem,3.4vw,1.9rem);text-transform:uppercase;margin:0 0 .5rem}
.figblock__lede{margin:0 0 1.4rem;color:var(--muted);max-width:56ch;font-size:.95rem}
/* Catch-all, added 2026-09-11: some instances already carry an inline
   style="color:var(--on-dark-dim)" per section, this covers every other
   one the same way instead of auditing each page for a missed inline
   override. --muted measures 3.7:1 on gold, short of 4.5:1. */
.on-dark .figblock__lede{color:var(--on-dark-dim)}

table.data{width:100%;border-collapse:collapse;font-variant-numeric:tabular-nums}
table.data caption{text-align:left;font-size:.66rem;font-weight:700;letter-spacing:.16em;
  text-transform:uppercase;color:var(--muted);padding-bottom:.7rem}
table.data th,table.data td{text-align:left;padding:.6rem .5rem;border-bottom:1px solid var(--rule);vertical-align:middle}
table.data th{font-size:.64rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}
table.data td.num{text-align:right;font-weight:600;white-space:nowrap}
table.data tr.total td{border-bottom:none;border-top:2px solid var(--ink);font-weight:700}
table.data tr.total td:first-child{text-transform:uppercase;font-size:.8rem;letter-spacing:.1em}
/* Catch-all for any table.data inside an .on-dark (now gold) section: caption
   and th default to --muted, which measures only 3.7:1 on gold, short of the
   4.5:1 small-text floor both need. A per-table inline override would have
   worked too and some tables already carry one, but this covers every table
   the same way regardless of whether it was hand-patched, added 2026-09-11
   after "required against present" on protect.astro turned up without one. */
.on-dark table.data caption,.on-dark table.data th{color:var(--on-dark-dim)}
.on-dark table.data th[scope="row"]{color:var(--ink);font-weight:700}
.barcell{width:46%;padding-right:0!important}
.bar{display:block;height:12px;background:var(--green);border-radius:1px}
.bar--alt{background:var(--amber)}
.bar--ghost{background:rgba(30,30,30,.14)}
.barpair{display:grid;gap:3px}
.barkey{display:flex;flex-wrap:wrap;gap:.4rem 1.2rem;margin-top:1rem;font-size:.68rem;color:var(--muted)}
.on-dark .barkey{color:var(--on-dark-dim)}
.barkey i{display:inline-block;width:14px;height:10px;margin-right:.4rem;vertical-align:middle;border-radius:1px}
@media (max-width:40rem){
  .barcell{display:none}
  table.data th.barhead{display:none}
}

/* ---------- Ward cards ---------- */
.wards{display:grid;gap:1px;background:var(--rule);border-block:1px solid var(--rule);list-style:none;margin:0;padding:0}
.ward{background:var(--paper);padding:clamp(1.25rem,3vw,1.75rem) 0}
.ward h4{font-family:var(--display);font-weight:900;font-size:1.35rem;text-transform:uppercase;margin:0 0 .35rem;letter-spacing:-.005em}
.ward p{margin:0;font-size:.9rem;line-height:1.55;color:var(--muted)}
.ward__stat{font-family:var(--display);font-weight:900;font-size:1.6rem;color:var(--green);line-height:1;margin-bottom:.4rem;display:block}

/* ---------- Commitments ---------- */
.commit{list-style:none;margin:0;padding:0;border-top:1px solid var(--rule-dark)}
.commit li{display:grid;grid-template-columns:2.6rem 1fr;gap:1rem;align-items:baseline;padding:1rem 0;border-bottom:1px solid var(--rule-dark)}
.commit b{font-family:var(--display);font-weight:900;color:var(--green-deep);font-size:1.3rem;line-height:1;font-variant-numeric:tabular-nums}
.commit span{font-size:clamp(.98rem,2.2vw,1.1rem);line-height:1.45}

/* ---------- Roadmap ---------- */
.road{list-style:none;margin:0;padding:0;display:grid;gap:1px;background:var(--rule);border-block:1px solid var(--rule)}
.road li{background:var(--paper);padding:1.15rem 0;display:grid;gap:.3rem}
.road .phase{font-size:.64rem;font-weight:700;letter-spacing:.16em;text-transform:uppercase;color:var(--green)}
.road .act{font-size:.95rem;line-height:1.5}
.road .out{font-size:.85rem;color:var(--muted);line-height:1.5}

/* ---------- Sources ---------- */
.sources{list-style:none;margin:0;padding:0;display:grid;gap:1rem}
.sources li{padding-left:1.1rem;border-left:2px solid var(--green);font-size:.88rem;line-height:1.55;color:var(--muted)}
/* --muted is tuned for the paper ground (5.5:1). On ink it measures 2.85:1
   and fails AA, so the dark context gets its own value. */
.on-dark .sources li{color:var(--on-dark-dim)}
.on-dark .sources li{border-left-color:var(--green-deep)}
.sources b{color:var(--ink);font-weight:600;display:block}
.note{margin:clamp(1.75rem,4vw,2.5rem) 0 0;padding:1.1rem 1.2rem;border:1px solid rgba(138,97,0,.35);
  background:rgba(138,97,0,.05);font-size:.87rem;line-height:1.6;color:var(--ink)}
.note b{display:block;font-size:.64rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--amber);margin-bottom:.4rem}
/* On-.on-dark variant, added 2026-09-11 (R5), re-tuned the same day for the
   ink-to-gold section change: an ink wash rather than a paper one, so the
   note reads as a shaded box against gold rather than a near-invisible one
   (paper-on-gold is close to white-on-yellow, the exact failure mode this
   whole palette change is deliberately avoiding). */
.on-dark .note{border-color:rgba(30,30,30,.3);background:rgba(30,30,30,.06);color:var(--on-dark-dim)}
.on-dark .note b{color:var(--green-deep)}

/* ---------- Map placeholder ---------- */
.mapslot{border:1.5px dashed rgba(19,125,60,.4);background:rgba(19,125,60,.04);padding:clamp(1.5rem,4vw,2.25rem);
  display:grid;gap:.5rem;text-align:center;place-items:center}
.mapslot strong{font-size:.64rem;letter-spacing:.16em;text-transform:uppercase;color:var(--green)}
.mapslot span{font-size:.86rem;color:var(--muted);max-width:46ch;line-height:1.55}

/* ---------- Next issues ---------- */
.next{display:grid;gap:1px;background:var(--rule-dark);border-block:1px solid var(--rule-dark);margin:0;padding:0;list-style:none}
.next a{display:block;background:var(--ink);padding:1.4rem clamp(1rem,3vw,1.6rem);text-decoration:none;transition:background .3s}
.next a:hover{background:var(--ink-2)}
.next .n{font-family:var(--display);font-weight:900;font-size:1.8rem;color:var(--gold);opacity:.4;line-height:1;display:block;margin-bottom:.3rem}
.next h3{font-family:var(--display);font-weight:900;font-size:1.25rem;text-transform:uppercase;color:var(--paper);margin:0}

/* ---------- Footer ---------- */
.foot{background:var(--gold);color:var(--ink);padding-block:clamp(2.5rem,6vw,3.5rem) 1.75rem}
.foot__base{display:flex;flex-wrap:wrap;gap:.75rem 2rem;justify-content:space-between;font-size:.74rem;color:var(--on-dark-dim)}
.foot a{color:var(--green-deep)}
.ph{display:inline-block;border:1px dashed rgba(11,72,35,.5);color:var(--green-deep);padding:.24em .6em;
  font-size:.7rem;font-weight:600;letter-spacing:.1em;text-transform:uppercase;border-radius:2px}

/* ---------- Reveal (transform only, never opacity) ---------- */
.js .rv{transform:translateY(20px);transition:transform .7s cubic-bezier(.2,.7,.3,1)}
.js .rv.in{transform:none}
@media (prefers-reduced-motion:reduce){
  .js .rv{transform:none;transition:none}
  *{animation-duration:.01ms!important;transition-duration:.01ms!important}
}

/* ---------- Responsive ---------- */
@media (min-width:38rem){
  .wards{grid-template-columns:1fr 1fr}
  /* Uniform padding-inline on every cell, added 2026-09-11. The prior
     :nth-child(odd){padding-left:0} traded a "double gutter" at the grid's
     own outer edge for an asymmetric card, flush left, full padding
     everywhere else. Harmless on the old ink-on-ink card grid; visibly
     uneven once the section around the card went gold (R7) and the card's
     edges became a real, visible boundary rather than blending in. */
  .ward{padding-inline:1.5rem}
  /* Three issue pages as of R5, each linking to the other two, so this is
     always exactly 2 items. repeat(3,1fr) here would leave an empty third
     cell, the same orphan the homepage pillars grid was already fixed for. */
  .next{grid-template-columns:repeat(2,1fr)}
}
@media (min-width:52rem){
  .split{display:grid;grid-template-columns:1.1fr .9fr;gap:clamp(2rem,4vw,3.5rem);align-items:start}
  .road{grid-template-columns:repeat(2,1fr)}
  .road li{padding-inline:1.5rem}
}

@media print{
  .nav,body::after,.next{display:none!important}
  body,.on-dark,.ihero,.foot{background:#fff!important;color:#000!important}
  section{padding-block:1.2rem;break-inside:avoid}
  .js .rv{transform:none}
}

/* ---------- Pathway (education): a sequence, not a list ---------- */
.pathway{list-style:none;margin:0;padding:0;display:grid;gap:1px;background:var(--rule);border-block:1px solid var(--rule)}
.pathway li{background:var(--paper);padding:1.1rem 0;display:grid;gap:.25rem;align-content:start}
.pathway .step{font-family:var(--display);font-weight:900;font-size:1.4rem;color:var(--green);line-height:1}
.pathway .lbl{font-family:var(--display);font-weight:900;font-size:1.1rem;text-transform:uppercase;letter-spacing:-.005em;line-height:1.05}
.pathway .desc{font-size:.82rem;color:var(--muted);line-height:1.5}
.on-dark .pathway{background:var(--rule-dark);border-color:var(--rule-dark)}
.on-dark .pathway li{background:var(--ink)}
.on-dark .pathway .step{color:var(--gold)}
.on-dark .pathway .lbl{color:var(--paper)}
.on-dark .pathway .desc{color:var(--on-ink-dim)}
@media (min-width:38rem){
  .pathway{grid-template-columns:repeat(2,1fr)}
  .pathway li{padding-inline:1.25rem}
}
@media (min-width:60rem){
  .pathway{grid-template-columns:repeat(6,1fr)}
  .pathway li{padding-inline:.9rem}
}

/* ---------- Proposal marker: for things that do not exist yet ---------- */
.proposed{display:inline-block;font-size:.58rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  color:var(--amber);border:1px solid rgba(138,97,0,.45);padding:.18em .45em;border-radius:2px;margin-left:.45rem;vertical-align:middle}
.on-dark .proposed{color:var(--amber-deep);border-color:rgba(110,78,0,.5)}
/* ---------- Dark-ground variants ----------
   .road and .wards were authored for the paper ground. Reusing them inside
   .on-dark left paper text on a paper background: contrast 1.00, invisible.
   These variants exist so the components are safe in both contexts. */
.on-dark .road{background:var(--rule-dark);border-color:var(--rule-dark)}
.on-dark .road li{background:var(--ink)}
.on-dark .road .phase{color:var(--gold)}
.on-dark .road .act{color:var(--paper)}
.on-dark .road .out{color:var(--on-ink-dim)}
.on-dark .wards{background:var(--rule-dark);border-color:var(--rule-dark)}
.on-dark .wards .ward{background:var(--ink)}
.on-dark .ward h3,.on-dark .ward h4{color:var(--paper)}
.on-dark .ward p{color:var(--on-ink-dim)}
.on-dark .ward__stat{color:var(--gold)}

/* Ward headings may be h3 or h4 depending on the section's heading depth. */
.ward h3{font-family:var(--display);font-weight:900;font-size:1.35rem;text-transform:uppercase;margin:0 0 .35rem;letter-spacing:-.005em}
/* ---------- Ward map ----------
   Real boundaries, not an approximation. Ward polygons from an open dataset
   of Kenya county assembly boundaries, cross-validated two ways: the ward
   codes (770 to 773) and constituency code (155) match the IEBC register
   exactly, and each computed polygon area falls within 1 to 4 percent of the
   published ward area, totalling 373.6 km2 against an official 368.
   Shaded by verified 2022 electorate. Label colours are chosen per fill so
   every one clears 4.5:1, asserted at generation time. */
.wardmap{display:block;width:100%;height:auto;margin:0}
.wardmap .ward{transition:opacity .25s ease}
.wardmap .wlabel{font-family:var(--display);font-weight:900;font-size:30px;text-anchor:middle;letter-spacing:.01em}
.wardmap .wnum{font-family:var(--body);font-weight:600;font-size:21px;text-anchor:middle;font-variant-numeric:tabular-nums}
@media (hover:hover){
  .wardmap:hover .ward{opacity:.55}
  .wardmap .ward:hover{opacity:1}
}
.mapwrap{background:var(--paper);border:1px solid var(--rule);padding:clamp(.75rem,2.5vw,1.5rem)}
.on-dark .mapwrap{background:var(--ink-2);border-color:var(--rule-dark)}
.mapkey{display:flex;flex-wrap:wrap;gap:.5rem 1.4rem;margin:1rem 0 0;font-size:.7rem;color:var(--muted);align-items:center}
.mapkey i{display:inline-block;width:16px;height:11px;margin-right:.45rem;vertical-align:middle;border-radius:1px;border:1px solid rgba(30,30,30,.15)}
@media (max-width:30rem){
  .wardmap .wlabel{font-size:40px}
  .wardmap .wnum{font-size:30px}
}
/* Replaced the old .mapkey swatch legend. It listed four bare numbers whose
   only link to a ward was a colour chip, so its accessible text read
   "Shaded by registered voters 9,571 9,736 19,374 28,259": meaning carried
   by colour alone, failing WCAG 1.4.1, and redundant because every ward is
   already labelled with its name and figure inside the map. */
.mapnote{margin:.9rem 0 0;font-size:.8rem;color:var(--muted);line-height:1.5}
.on-dark .mapnote{color:var(--on-dark-dim)}
/* ---------- Data bars: grow on first view ----------
   Animates transform, not width, so it runs on the compositor and never
   triggers layout on a mid-range phone.

   Critically, the bar is at FULL WIDTH in the markup. JavaScript collapses it
   only after confirming it can animate. If the script never runs, or motion is
   reduced, the bars are simply there. The alternative, animating width up from
   zero in CSS, would leave every bar invisible in exactly the environments
   where the earlier opacity fade failed: backgrounded tabs and in-app
   browsers. Same mistake, different property. */
.js .bar--anim{
  transform:scaleX(0);
  transform-origin:left center;
  transition:transform .85s cubic-bezier(.22,.61,.36,1);
  will-change:transform;
}
.js .bar--anim.bar--in{transform:none}

/* The requirement bar settles first, then the present-provision bar fills in
   against it, so the gap is the thing the eye lands on last. */
.js .barpair .bar--ghost.bar--anim{transition-duration:.6s}

@media (prefers-reduced-motion:reduce){
  .js .bar--anim{transform:none;transition:none}
}
/* ---------- Data bars: continuous sheen ----------
   A highlight travels along each filled bar on a loop, forever.

   Three deliberate constraints:
   1. It animates transform on a pseudo-element, not background-position, so
      it composites instead of repainting the bar every frame.
   2. It PAUSES whenever its table is off screen. Sixteen perpetually
      animating layers on a mid-range Android is a real battery cost, and
      nobody is watching a bar they cannot see.
   3. prefers-reduced-motion stops it completely. WCAG 2.2.2 asks for a way
      to stop motion lasting beyond five seconds; the OS setting is that way.

   Ghost bars carry the requirement, not the achievement, so they stay still.
   Only actual provision shimmers. */
.bar{position:relative;overflow:hidden}
.bar::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(100deg,
    transparent 25%,
    rgba(255,255,255,.55) 50%,
    transparent 75%);
  transform:translateX(-115%);
}
.js .bar--sheen::after{animation:barSheen 2.9s linear infinite}
.js .bar--rest::after{animation-play-state:paused}
.bar--ghost::after{display:none}

@keyframes barSheen{
  from{transform:translateX(-115%)}
  to{transform:translateX(115%)}
}

@media (prefers-reduced-motion:reduce){
  .js .bar--sheen::after{animation:none}
}
/* ---------- Footer party block and follow line, added 2026-09-11 (R5) ----
   Shared across every page via Base.astro. Party affiliation is confirmed
   content (R5) and ships unconditionally. Given its own prominent row,
   not folded into the small-print line: a logo sized to match the .74rem
   copyright text reads as a credit, not as the party mark it actually is.
   No adjacent "UDA"/"Kazi Ni Kazi" text (removed 2026-09-11): the logo
   already carries its own name, prominence comes from size instead.
   The follow links are handled with the same honesty rule as everything
   else on this site, real data ships, unverified data stays a marked gap
   rather than a guess. See Base.astro for why Facebook has no href. */
.foot__follow{font-size:.74rem;color:var(--on-dark-dim)}
/* Logo and the copyright/social text side by side, added 2026-09-11
   (replacing them stacked, which the previous fix's inline-block still
   left half the footer's width sitting empty beside the logo, just
   without a line drawn across it). .foot__partyblock's own right border
   takes over the divider role the old bottom one had. */
.foot__row{display:flex;align-items:center;gap:1.75rem;flex-wrap:wrap;
  margin-bottom:clamp(1.5rem,4vw,2.25rem);padding-bottom:clamp(1.5rem,4vw,2.25rem)}
.foot__partyblock{padding-right:1.75rem;border-right:1px solid var(--rule-dark)}
.foot__partyblock img{height:96px;width:auto;display:block}
.foot__base{flex:1;min-width:0;flex-direction:column;align-items:flex-start;gap:.5rem}
.foot__follow a{color:var(--green-deep);text-decoration:none}
.foot__follow a:hover{text-decoration:underline}
