/* ==========================================================================
   Ballot Trail — house style.

   Palette is the BB2G brand kit (ivory / gold / navy), not a guess:
   standard.bornbetween2generals.com/brand-kit.html.

   ⭐ THE RULE THAT KEEPS IT FROM GOING BROWN: on ivory, gold is a RULE and a
   MARK — never a word. Gold dark enough to read on ivory IS brown, so the
   moment gold becomes a text colour the whole app's accent turns brown.
   Links are ink with a gold underline. Eyebrows are neutral caps beside a
   short gold rule. The greys stay NEUTRAL and never mix toward the gold.
   --goldink is the one gold allowed to be a word, and only on ivory.
   ========================================================================== */

:root {
  /* ⚠⚠ THE ALIAS ARROW MUST POINT THE SAME WAY IN EVERY THEME BLOCK.
     This block used to make the BRAND name the primitive (--ink:#1c2333) and
     the SEMANTIC name the alias (--text:var(--ink)) — while the dark block did
     the exact reverse (--text:#eef2f9; --ink:var(--text)). Two blocks pointing
     at each other is a resolution cycle, and the browser fell back to the
     light literal: .btn--ghost computed #1c2333 on a #161b26 plate — 1.10:1,
     invisible, on every ghost button in dark mode. Caught by MEASURING the
     rendered page, not by reading the CSS, which looks perfectly reasonable.

     THE RULE: SEMANTIC tokens hold the literals. Brand names alias to them,
     never the other way round. test/gates.mjs enforces the direction. */

  /* semantic — the primitives */
  --ground:#f7f1e3; --surface:#fffdf8; --surface2:#faf5ea;
  --rule:#e6d9bc;   --rule2:#d8c79f;
  --text:#1c2333;   --text2:#4d5871; --text3:#5c6678;
  --head:#16294a;

  /* brand names alias to the semantic ones — one direction, always */
  --cream:var(--ground); --card:var(--surface); --panel:var(--surface2);
  --line:var(--rule);    --line2:var(--rule2);
  --ink:var(--text);     --sub:var(--text2);   --muted:var(--text3);
  --navy:var(--head);

  --cream2:#efe6d1; --navy2:#1f3a68; --blue:#3a5da9;
  --gold:#b8860b; --gold2:#caa12e; --gold3:#e4cd84; --goldsoft:#f3e8c6;
  --goldink:#7a5c12;
  --red:#b22234; --redsoft:#f7dfe2; --good:#25764f; --warn:#8f6410; --hot:#a8500f;
  --serif:Georgia,"Palatino Linotype","Times New Roman",serif;
  --display:"Didot","Bodoni 72","Bodoni MT","Playfair Display",Georgia,serif;
  --sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --mono:ui-monospace,SFMono-Regular,Menlo,Consolas,"Liberation Mono",monospace;
  --wrap:74rem;
}

/* ⚠ Dark mode OWNS ITS SURFACE TOKENS. A previous app shipped white-on-white
   at 1.12:1 because dark mode redefined --ink but left a surface hard-coded
   to a light literal. Every colour below is a token; none is a literal. */
html[data-theme="dark"] {
  --ground:#0e1119; --surface:#161b26; --surface2:#1c2230;
  --rule:#2c3547; --rule2:#3b465c;
  --text:#eef2f9; --text2:#b6c0d2; --text3:#8d99ad;
  --head:#e8eefb;
  --card:var(--surface); --panel:var(--surface2); --cream:var(--ground);
  --line:var(--rule); --line2:var(--rule2);
  --ink:var(--text); --sub:var(--text2); --muted:var(--text3); --navy:var(--head);
  --goldink:#e0bd63;         /* on a dark ground gold IS legible as a word */
  --gold3:#8a6a1c; --goldsoft:#2a2412;
  --redsoft:#3a1c22; --red:#e2606f; --good:#5fc794; --warn:#e0b45c; --hot:#e39057;
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0; background:var(--ground); color:var(--text);
  font:400 clamp(1rem,.34vw + .94rem,1.09rem)/1.62 var(--sans);
  -webkit-font-smoothing:antialiased;
}
img,video,svg{max-width:100%}
:focus-visible{
  /* two-tone ring: holds on ivory AND on the black bar */
  outline:2px solid var(--navy); outline-offset:2px;
  box-shadow:0 0 0 4px var(--goldsoft);
  border-radius:2px;
}
html[data-theme="dark"] :focus-visible{outline-color:var(--gold3);box-shadow:0 0 0 4px #000}

.wrap{width:min(100% - 2.5rem, var(--wrap)); margin-inline:auto}
.narrow{max-width:60rem}
.skip{position:absolute;left:-9999px}
.skip:focus{left:.75rem;top:.75rem;z-index:99;background:var(--navy);color:#fff;padding:.6rem 1rem}

/* ---------- type ---------- */
h1,h2,h3,h4{font-family:var(--serif);color:var(--head);line-height:1.16;margin:0 0 .5em;font-weight:600}
h1{font-family:var(--display);font-size:clamp(2.1rem,5.2vw,3.9rem);letter-spacing:-.012em;font-weight:400}
h2{font-size:clamp(1.5rem,2.6vw,2.15rem);margin-top:0}
h3{font-size:clamp(1.14rem,1.5vw,1.35rem)}
p,li{color:var(--text)}
.lede{font-family:var(--serif);font-size:clamp(1.12rem,1.5vw,1.4rem);line-height:1.5;color:var(--text2)}
a{color:var(--text);text-decoration-color:var(--gold2);text-underline-offset:.18em;text-decoration-thickness:.08em}
a:hover{text-decoration-color:var(--goldink)}

/* eyebrow: NEUTRAL caps + a short gold rule. Gold caps on ivory measure
   3.69:1 — an actual failure. These measure 5.66:1. */
.eyebrow{
  font:700 .72rem/1 var(--sans); letter-spacing:.26em; text-transform:uppercase;
  color:var(--text2); display:flex; align-items:center; gap:.7rem; margin:0 0 1rem;
}
.eyebrow::before{content:"";width:2.1rem;height:2px;background:var(--gold2);flex:none}
/* ⚠ 3.87:1 as #e8e2d4 — the kicker is 14px, so it needs 4.5:1, not the 3:1
   large-text allowance the headline gets. Measured, then raised. */
.hero .eyebrow{color:#fbf9f4}
.hero .eyebrow::before{background:var(--gold3)}

/* ---------- header ---------- */
.top{background:var(--surface);border-bottom:1px solid var(--rule);position:relative;z-index:20}
.top__in{display:flex;align-items:center;gap:1rem;padding:.85rem 0;flex-wrap:wrap}
.brand{display:flex;align-items:center;gap:.7rem;text-decoration:none;color:var(--head);font-family:var(--display);font-size:1.24rem}
.brand svg{width:44px;height:44px;flex:none}
.brand b{font-weight:400;letter-spacing:.01em}
.brand small{display:block;font:700 .58rem/1 var(--sans);letter-spacing:.24em;text-transform:uppercase;color:var(--text3)}
.top nav{margin-left:auto;display:flex;gap:.15rem;flex-wrap:wrap}
.top nav a{
  font:600 .82rem/1 var(--sans);letter-spacing:.02em;padding:.5rem .62rem;
  text-decoration:none;color:var(--text2);border-bottom:2px solid transparent;white-space:nowrap;
}
.top nav a:hover{color:var(--text);border-bottom-color:var(--gold2)}
.top nav a[aria-current="page"]{color:var(--head);border-bottom-color:var(--gold)}
/* ⚠ the nav stacks on phones — it must scroll, not wrap into a wall */
@media (max-width:760px){
  .top__in{flex-wrap:nowrap}
  .top nav{overflow-x:auto;flex-wrap:nowrap;-webkit-overflow-scrolling:touch;scrollbar-width:none}
  .top nav::-webkit-scrollbar{display:none}
}

/* ---------- hero ---------- */
.hero{color:#fff}
.hero__in{max-width:56rem}
.hero h1{color:#fff}
.hero p{color:#eae5da}
.hero .lede{color:#e6e0d3}
.bbm-hero__still,.bbm-hero .heroloop{filter:saturate(.55) contrast(1.06) brightness(.72)}

/* ---------- the black bar: the business card's bottom strip ---------- */
.bar{background:#0a0a0a;color:#e8cf90}   /* its own ground, its own ink */
.bar__in{display:flex;gap:1.4rem;flex-wrap:wrap;justify-content:center;padding:.8rem 0;
  font:700 .68rem/1.5 var(--sans);letter-spacing:.24em;text-transform:uppercase;text-align:center}

/* ---------- plates ---------- */
section{padding-block:clamp(2.6rem,6vw,4.6rem)}
section.tight{padding-block:clamp(1.6rem,3vw,2.4rem)}
.plate{background:var(--surface);border:1px solid var(--rule);border-radius:0;padding:clamp(1.1rem,2.4vw,1.7rem)}
.plate--panel{background:var(--surface2)}
.grid{display:grid;gap:1.05rem}
.g2{grid-template-columns:repeat(auto-fit,minmax(min(100%,20rem),1fr))}
.g3{grid-template-columns:repeat(auto-fit,minmax(min(100%,17rem),1fr))}
.g4{grid-template-columns:repeat(auto-fit,minmax(min(100%,13.5rem),1fr))}
.stack>*+*{margin-top:1rem}

.num{font-family:var(--display);font-size:clamp(1.9rem,3.4vw,2.7rem);line-height:1;color:var(--head);display:block}
.num small{display:block;font:700 .64rem/1.4 var(--sans);letter-spacing:.2em;text-transform:uppercase;color:var(--text3);margin-top:.5rem}

/* ---------- chips ---------- */
.chip{display:inline-flex;align-items:center;gap:.42rem;font:700 .64rem/1 var(--sans);
  letter-spacing:.14em;text-transform:uppercase;padding:.36rem .6rem;border:1px solid var(--rule2);
  background:var(--surface2);color:var(--text2)}
.chip::before{content:"";width:.46rem;height:.46rem;border-radius:50%;background:var(--text3);flex:none}
.chip--good::before{background:var(--good)} .chip--warn::before{background:var(--warn)}
.chip--hot::before{background:var(--hot)}   .chip--stop::before{background:var(--red)}
.chip--term{border-style:dashed}

/* ---------- tables ---------- */
.tw{overflow-x:auto;border:1px solid var(--rule);background:var(--surface)}
table{border-collapse:collapse;width:100%;font-size:.92rem;min-width:34rem}
th,td{text-align:left;padding:.62rem .8rem;border-bottom:1px solid var(--rule);vertical-align:top}
thead th{font:700 .66rem/1.3 var(--sans);letter-spacing:.16em;text-transform:uppercase;
  color:var(--text2);background:var(--surface2);position:sticky;top:0}
tbody tr:last-child td{border-bottom:0}
td code,th code{font-size:.86em}

/* ---------- code ---------- */
code{font-family:var(--mono);font-size:.88em;background:var(--surface2);
  border:1px solid var(--rule);padding:.08em .34em}
pre{margin:0;overflow-x:auto;background:#0d1117;color:#dfe6f0;border:1px solid var(--rule);
  padding:1rem 1.1rem;font:400 .82rem/1.62 var(--mono)}
pre code{background:none;border:0;padding:0;color:inherit;font-size:1em}
.k{color:#e4cd84} .s{color:#9ad39a} .c{color:#8d99ad;font-style:italic} .n{color:#84b6f4}

/* ---------- buttons ---------- */
/* ⚠⚠ AN ELEMENT WHOSE BACKGROUND DOES NOT FOLLOW THE THEME MUST NOT TAKE A
   FOREGROUND THAT DOES. .btn is near-black in BOTH themes, but --gold3 flips
   to a dark gold for dark grounds — so in dark mode this was #8a6a1c on
   #0a0a0a: 3.92:1, measured on the rendered page. The button carries its own
   ground, so it carries its own ink. Same for .bar. */
.btn{display:inline-flex;align-items:center;gap:.5rem;font:700 .8rem/1 var(--sans);
  letter-spacing:.1em;text-transform:uppercase;padding:.78rem 1.15rem;border-radius:0;
  border:1px solid #0a0a0a;background:#0a0a0a;color:#e8cf90;cursor:pointer;
  text-decoration:none;transition:background .18s,color .18s}
.btn:hover{background:#1c2333;color:#fff}
.btn--gold{background:linear-gradient(180deg,#f0d0a0,#d9b45e 30%,#a07020 64%,#7d5616);
  color:#17130a;border-color:#7d5616}
.btn--gold:hover{filter:brightness(1.08);color:#17130a}
.btn--ghost{background:transparent;color:var(--text);border-color:var(--rule2)}
.btn--ghost:hover{background:var(--surface2);color:var(--text)}
.btn[disabled]{opacity:.45;cursor:not-allowed}
.btnrow{display:flex;gap:.6rem;flex-wrap:wrap;align-items:center}

/* ---------- callouts ---------- */
.note{border-left:3px solid var(--gold2);background:var(--surface2);padding:.9rem 1.1rem}
.note--stop{border-left-color:var(--red);background:var(--redsoft)}
.note--good{border-left-color:var(--good)}
.note p:last-child,.note ul:last-child{margin-bottom:0}
.note p:first-child{margin-top:0}
.note b{color:var(--head)}

/* ---------- the boundary rail: the one idea the app exists for ---------- */
.rail{display:grid;gap:0;grid-template-columns:1fr auto 1fr;align-items:stretch;
  border:1px solid var(--rule);background:var(--surface)}
.rail__side{padding:1.1rem 1.2rem}
.rail__cut{width:3px;background:repeating-linear-gradient(180deg,var(--red) 0 10px,transparent 10px 18px);position:relative}
.rail__cut::after{content:"NEVER JOINED";position:absolute;top:50%;left:50%;
  transform:translate(-50%,-50%) rotate(90deg);white-space:nowrap;
  font:700 .6rem/1 var(--sans);letter-spacing:.2em;color:var(--red);
  background:var(--surface);padding:.35rem .5rem}
@media (max-width:720px){
  .rail{grid-template-columns:1fr}
  .rail__cut{width:auto;height:3px;background:repeating-linear-gradient(90deg,var(--red) 0 10px,transparent 10px 18px)}
  .rail__cut::after{transform:translate(-50%,-50%)}
}

/* ---------- footer ---------- */
.foot{background:var(--surface);border-top:1px solid var(--rule);padding-block:2.2rem;margin-top:2rem}
.foot p{color:var(--text2);font-size:.88rem;margin:.3rem 0}
/* the 4-star rule is a MARK, not a word: rendered as an aria-hidden graphic so
   it is decoration by construction rather than text that cannot pass 4.5:1 */
.foot .stars{display:flex;gap:.62rem;justify-content:center;margin:0 0 .9rem}
.foot .stars svg{width:13px;height:13px;fill:var(--gold2);display:block}

/* ---------- utility ---------- */
.mono{font-family:var(--mono);font-size:.84rem;word-break:break-all}
.tiny{font-size:.8rem;color:var(--text2)}
.center{text-align:center}
.mt0{margin-top:0}.mb0{margin-bottom:0}
hr.rule{border:0;border-top:1px solid var(--rule);margin:2rem 0}
hr.stars{border:0;text-align:center;margin:2rem 0;color:var(--gold2)}
hr.stars::before{content:"★ ★ ★ ★";letter-spacing:.6em}
.vis-hidden{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* ==========================================================================
   Fixes found by looking at the rendered page, not by reading the CSS.
   ========================================================================== */

/* ⚠ THE DARK-TYPE-ON-A-DARK-HERO TRAP. .btn--ghost takes its colour from
   --text, which is near-black ink — correct on ivory, invisible on the hero.
   Measured on the built page: rgb(28,35,51) on graded footage. A hero is a
   different ground and its controls need their own tokens. */
.hero .btn--ghost{color:#fbf9f4;border-color:rgba(251,249,244,.5);background:rgba(10,10,16,.28)}
.hero .btn--ghost:hover{background:rgba(251,249,244,.15);color:#fff;border-color:#fbf9f4}
.hero .btn--ghost:focus-visible{outline-color:#f0d0a0;box-shadow:0 0 0 4px rgba(0,0,0,.55)}

/* The lockup must not wrap AND must not be overlapped. ⚠ Adding min-width:0
   to let it shrink did the opposite of the intent: with nowrap the text then
   overflowed its own box and the nav — which has margin-left:auto — was drawn
   straight over the wordmark. The mark NEVER shrinks; the nav is the thing
   that gives way, by scrolling. */
.brand{flex:none}
.top nav{min-width:0;overflow-x:auto;scrollbar-width:none}
.top nav::-webkit-scrollbar{display:none}
.brand b{white-space:nowrap}
.brand small{white-space:nowrap}
@media (max-width:560px){
  .brand{font-size:1.06rem;gap:.5rem}
  .brand svg{width:34px;height:34px}
  .brand small{font-size:.5rem;letter-spacing:.16em}
}
/* the nav is a scroll rail on phones — give it a fading edge so it is
   discoverable that there is more to the right */
@media (max-width:760px){
  .top nav{
    mask-image:linear-gradient(90deg,#000 0,#000 calc(100% - 1.6rem),transparent 100%);
    padding-right:1.2rem;
  }
  .top__in{gap:.5rem}
  #themebtn{flex:none}
}
