/* Self-hosted: no request leaves the visitor's browser for a font. Faster, and no
   third party sees their IP address just to render text on this page. */
/* The Ledger, 25 Aug 2026. Bodoni is gone: the display face is now Archivo set
   heavy and tight, which is the single biggest reason this no longer reads as a
   stock editorial template. Newsreader drops to 300 and becomes the READING
   face — long copy on a dark ground needs the lighter weight. Plex Mono carries
   every label, number tag and eyebrow. */
@font-face{font-family:'Newsreader';font-style:normal;font-weight:300;font-display:swap;src:url(fonts/newsreader-latin-300-normal.woff2) format('woff2')}
@font-face{font-family:'Newsreader';font-style:normal;font-weight:400;font-display:swap;src:url(fonts/newsreader-latin-400-normal.woff2) format('woff2')}
@font-face{font-family:'Newsreader';font-style:normal;font-weight:600;font-display:swap;src:url(fonts/newsreader-latin-600-normal.woff2) format('woff2')}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:400;font-display:swap;src:url(fonts/ibm-plex-mono-latin-400-normal.woff2) format('woff2')}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:500;font-display:swap;src:url(fonts/ibm-plex-mono-latin-500-normal.woff2) format('woff2')}
@font-face{font-family:'Newsreader';font-style:italic;font-weight:400;font-display:swap;src:url(fonts/newsreader-latin-400-italic.woff2) format('woff2')}
@font-face{font-family:'Archivo';font-style:normal;font-weight:400;font-display:swap;src:url(fonts/archivo-latin-400-normal.woff2) format('woff2')}
@font-face{font-family:'Archivo';font-style:normal;font-weight:500;font-display:swap;src:url(fonts/archivo-latin-500-normal.woff2) format('woff2')}
@font-face{font-family:'Archivo';font-style:normal;font-weight:600;font-display:swap;src:url(fonts/archivo-latin-600-normal.woff2) format('woff2')}
@font-face{font-family:'Archivo';font-style:normal;font-weight:700;font-display:swap;src:url(fonts/archivo-latin-700-normal.woff2) format('woff2')}
/* ============================================================
   CEO ROCK'S — single stylesheet, shared by all six pages.
   One type scale. Every size on the site comes from a token
   below; there are no font-size values in the markup.
   ============================================================ */
:root{
  /* ---- colour ---- */
  /* THE LEDGER -- set 25 Aug 2026. A dark ground with bone text, warm brown used
     only as a HIGHLIGHT: links, eyebrows, bullet marks, the progress bar, small
     chips. Nothing large is filled brown -- big panels are neutral (--panel).
     Rocky's instruction, verbatim: "just highlights of brown here and there ...
     not overly slap the whole website in brown".
     Token NAMES are unchanged from the light palette so every component rule
     still resolves; only the values moved. Re-run the rendered-DOM contrast
     audit after touching anything here.
     Previous palette (Warm Stone) if this needs reverting:
       --paper:#FAF7F2; --paper2:#F0EAE0; --paper3:#E7DFD2; --card:#FFFFFF;
       --ink:#2B2320; --ink2:#1F1917; --deep:#4A3A32; --brown:#795E4D; --brown2:#61483A;
       --muted:#5C4E46; --soft:#6D6158; --rule:#E0D6C9; --rule2:#CDC0B1;
       --cream:#F7F1E9; --tan:#C8AC94; --tan2:#D6C6B4; --tan3:#EEE2D4;
       --onDark:#EDE2D7; --onDark2:#D8CCC1; --onBrown:#FAF3EC; --lineDark:#5E4838; */

  /* ---------------------------------------------------------------------
     WARM STONE, restored 2 September 2026 on Rocky's instruction. The site
     was built on this palette, switched to near black, and is now back.
     Token NAMES are unchanged, so every component rule still resolves and no
     layout moved. What DID move is the meaning of four tokens: --cream,
     --onDark, --onDark2 and --onBrown are "text on a DARK ground". On a dark
     page that was most of the body text. On this one it is only correct
     inside .sec-brown, the nav, the footer and .btn-dark. Everything else had
     to be repointed at --ink, and the contrast harness in the build notes is
     what found them.
     ------------------------------------------------------------------ */
  /* grounds, lightest first */
  --ink2:#1F1917;                       /* footer, the floor of the page */
  --paper:#FAF7F2;                      /* the page itself, and text on a bone button */
  --deep:#4A3A32;                       /* hero, calculator, nav bar -- barely lifted */
  --paper2:#F0EAE0;                     /* alternate bands */
  --inkBg:#241D1A;                      /* modal, pop-out form, .sec-ink band, <option> */
  --card:#FFFFFF;                       /* cards */
  --panel:#F0EAE0; --panel2:#E7DFD2;    /* the neutral fills that used to be brown */
  --paper3:#E7DFD2;

  /* type */
  --ink:#2B2320;                        /* body text, and the ground of an inverted button */
  --cream:#F7F1E9;                      /* text on a dark ground; also the light button */
  --muted:#5C4E46; --soft:#6D6158;
  --onDark:#EDE2D7; --onDark2:#D8CCC1; --onBrown:#FAF3EC;

  /* rules */
  --rule:#E0D6C9; --rule2:#CDC0B1; --lineDark:#5E4838;

  /* the highlight, used sparingly */
  --brown:#795E4D; --brown2:#61483A;
  --tan:#C8AC94; --tan2:#D6C6B4; --tan3:#EEE2D4;
  --chartdim:#9C8A79;                   /* the recessive half of every figure */
  /* semantic pair. -D suffix = the variant for a dark band. Measured, not guessed:
     --good on --card 5.7:1, on --paper3 4.7:1; --bad on --card 6.1:1, on --paper3 4.6:1. */
  --good:#436A39;  --bad:#95502F;
  --goodD:#8FB682; --badD:#DC9A80;

  /* ---- families ---- */
  --f-disp:Archivo,-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif;
  --f-ser:Newsreader,Georgia,"Times New Roman",serif;
  --f-sans:Archivo,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --f-mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;

  /* ---- type scale: the only sizes used anywhere ---- */
  --t-label:11px;                       /* eyebrows, buttons, nav, meta */
  --t-fine:13px;                        /* notes, disclaimers */
  --t-small:15px;                       /* dense card copy */
  --t-body:17px;                        /* default */
  --t-lead:clamp(18px,1.2vw,20px);      /* lead paragraphs */
  --t-h4:20px;
  --t-h3:clamp(23px,1.9vw,29px);        /* PRODUCT + CARD TITLES — the things that must stand out */
  --t-h2:clamp(28px,3.3vw,42px);        /* section headings — no longer dwarf the products */
  --t-h1:clamp(36px,4.8vw,58px);
  --t-num:clamp(32px,3.6vw,42px);       /* prices, calculator output */
  --t-big:clamp(40px,5.4vw,72px);       /* proof figures */
  --t-mq:clamp(22px,2.8vw,34px);        /* marquee */

  /* ---- rhythm ---- */
  --lh-tight:1.06; --lh-head:1.18; --lh-body:1.62; --lh-lead:1.66;
  --tr-label:.16em; --tr-disp:-.035em;
  --s1:8px; --s2:14px; --s3:20px; --s4:28px; --s5:40px; --s6:56px; --s7:80px;
  --wrap:1200px;
}

*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{background:var(--paper);color:var(--ink);font-family:var(--f-sans);
  font-size:var(--t-body);line-height:var(--lh-body);-webkit-font-smoothing:antialiased;overflow-x:hidden}
img{max-width:100%;height:auto;display:block}
/* Links are bone, not brown. Brown is a mark, not a text colour -- Rocky:
   "a hint of brown, not too much brown". It survives on the progress bar,
   bullet marks, the featured tier's rule, small chips and hover states. */
a{color:var(--brown);text-decoration:none}
a:hover{color:var(--brown2);text-decoration:underline;text-underline-offset:3px}
:focus-visible{outline:2px solid var(--tan);outline-offset:3px}
.wrap{max-width:var(--wrap);margin:0 auto;padding:0 32px}
section{padding:var(--s7) 0}

/* ---------- headings: one size each, every page ---------- */
h1,h2,h3,h4{font-family:var(--f-disp);letter-spacing:var(--tr-disp);text-wrap:balance}
h1{font-size:var(--t-h1);line-height:.98;font-weight:700}
h2{font-size:var(--t-h2);line-height:1.02;font-weight:700}
h3{font-size:var(--t-h3);line-height:1.1;font-weight:600;letter-spacing:-.028em}
h4{font-size:var(--t-h4);line-height:1.2;font-weight:600;letter-spacing:-.02em}
/* Archivo ships no italic, so an <em> anywhere was being faked by the browser
   — a slanted grotesque, which looks exactly as bad as it sounds. Every italic
   now resolves to Newsreader, which we do ship, and a serif italic against the
   heavy sans is the contrast this design wanted anyway.
   Same for <strong> inside serif copy: Newsreader 600 is now a real file
   instead of a synthesised bold. */
em,i,cite{font-family:var(--f-ser);font-style:italic;font-weight:400}
h1 em,h2 em,h3 em,h4 em{font-family:var(--f-ser);font-style:italic;font-weight:400;
  letter-spacing:-.012em}
.lead strong,.prose strong,.faq .a strong,.lead b{font-family:var(--f-ser);font-weight:600}
.disp{font-family:var(--f-disp);line-height:var(--lh-tight);letter-spacing:var(--tr-disp)}

/* ---------- text roles ---------- */
/* Newsreader at 300 is the reading weight on a dark ground; 400 blooms. */
.lead{font-family:var(--f-ser);font-weight:300;font-size:var(--t-lead);line-height:var(--lh-lead);color:var(--muted)}
.body{font-size:var(--t-body);line-height:var(--lh-body)}
.small{font-size:var(--t-small);line-height:1.58}
.note{font-size:var(--t-fine);line-height:1.6;color:var(--soft)}
.lbl{font-family:var(--f-mono);font-size:var(--t-label);font-weight:500;letter-spacing:var(--tr-label);text-transform:uppercase;line-height:1.4}
.eyebrow{font-family:var(--f-mono);color:var(--soft);margin-bottom:var(--s2)}
.prose p+p{margin-top:var(--s2)}
.prose p{color:var(--muted)}
.muted{color:var(--muted)}
.measure{max-width:62ch}
.measure-s{max-width:46ch}

/* on dark grounds */
.sec-deep,.sec-ink,.hero,.hero-sm,.news,.calc{color:var(--cream)}
.sec-deep .eyebrow,.sec-ink .eyebrow,.hero .eyebrow,.news .eyebrow,.calc .eyebrow{color:var(--tan)}
.sec-brown .eyebrow{color:var(--tan3)}
.sec-deep .lead,.sec-ink .lead,.hero .lead,.hero-sm .lead,.news .lead{color:var(--onDark)}
.sec-brown .lead{color:var(--onBrown)}
.sec-deep .small,.sec-ink .small,.calc .small{color:var(--onDark2)}
.sec-brown .small{color:var(--onBrown)}
.sec-deep .note,.sec-ink .note,.hero .note,.news .note,.calc .note{color:#B9A693}
/* The muted note colours above and at .calc-note/.footer fine print are hand-
   paired to --deep / --brown / --ink2 and were relifted with the Warm Stone
   palette on 25 Aug 2026 to hold 4.5:1. Move a background, recheck these. */
.sec-brown .note{color:#ECE0D5}
.sec-deep h2,.sec-deep h3,.sec-ink h2,.sec-ink h3,.hero h1,.hero-sm h1,.news h2,.calc h2{color:var(--cream)}
.sec-brown h2,.sec-brown h3{color:var(--cream)}
.sec-deep a,.sec-ink a,.news a{color:var(--tan3)}
.sec-deep a:hover,.sec-ink a:hover,.news a:hover{color:#fff}

/* ---------- buttons ---------- */
.btn{display:inline-block;padding:17px 34px;font-family:var(--f-mono);font-size:var(--t-label);font-weight:500;
  letter-spacing:var(--tr-label);text-transform:uppercase;cursor:pointer;border:1px solid transparent;
  transition:.18s ease;text-align:center;font-family:var(--f-sans);line-height:1.4}
.btn:hover{transform:translateY(-2px);box-shadow:0 10px 26px rgba(0,0,0,.55)}
.btn-light{background:var(--cream);color:var(--deep);border-color:var(--deep)}
.btn-light:hover{background:var(--tan3);color:var(--deep)}
.btn-dark{background:var(--ink);color:var(--paper)}
.btn-dark:hover{background:var(--brown);color:#fff}
.btn-brown{background:var(--brown);color:var(--cream);border-color:var(--brown)}
.btn-brown:hover{background:var(--ink);color:var(--paper)}
.btn-line{border-color:var(--tan);color:var(--cream)}
.btn-line:hover{background:var(--cream);color:var(--deep)}
.btn-lineD{border-color:var(--ink);color:var(--ink)}
.btn-lineD:hover{background:var(--ink);color:var(--paper)}
.btn-row{display:flex;gap:var(--s2);flex-wrap:wrap;margin-top:var(--s4)}
.btn-row.center{justify-content:center}

/* ---------- section grounds ---------- */
.sec-deep{background:var(--deep)}
.sec-ink{background:var(--inkBg)}
.sec-p2{background:var(--paper2)}
.sec-p3{background:var(--paper3)}
.sec-brown{background:var(--brown);color:var(--cream)}

/* ---------- section heading blocks ---------- */
.sec-head{max-width:62ch;margin:0 auto var(--s6);text-align:center}
.sec-head .lead{margin-top:var(--s2)}
.sec-head-l{margin-bottom:var(--s5);max-width:62ch}
.sec-head-l .lead{margin-top:var(--s2)}
.sec-head-split{display:flex;justify-content:space-between;align-items:flex-end;gap:var(--s5);
  flex-wrap:wrap;margin-bottom:var(--s5)}
.sec-head-split .lead{max-width:38ch}

/* ---------- nav ---------- */
header{position:sticky;top:0;z-index:50;background:var(--deep);border-bottom:1px solid var(--lineDark)}
.nav{display:flex;align-items:center;justify-content:space-between;padding:16px 32px;max-width:var(--wrap);margin:0 auto;gap:var(--s3)}
.nav img{height:32px;width:auto}
.nav ul{display:flex;gap:26px;list-style:none;align-items:center}
.nav a{color:var(--tan2);font-size:var(--t-label);font-weight:600;letter-spacing:.16em;text-transform:uppercase}
.nav a:hover{color:var(--cream)}
.nav a.on{color:var(--cream);border-bottom:1px solid var(--tan);padding-bottom:3px}
.nav .btn{padding:12px 22px;background:var(--cream);color:var(--deep)}
.nav .btn:hover{background:var(--brown);color:var(--paper)}
#navtoggle{display:none;background:none;border:0;cursor:pointer;padding:8px}
#navtoggle span{display:block;width:24px;height:2px;background:var(--tan2);margin:5px 0}
/* Eight items in the bar now that the Journal has come out of the footer.
   Between the burger breakpoint and a comfortable laptop width the row was
   wrapping onto two lines, which pushed the whole header down. It tightens
   through that range instead of breaking. */
@media(min-width:901px) and (max-width:1180px){
  .nav{padding-inline:20px;gap:var(--s2)}
  .nav ul{gap:16px}
  .nav a{letter-spacing:.10em}
  .nav .btn{padding:11px 14px}
}
/* nine items now. Under 1000px the row still fits but was almost touching
   the rate card button, so it gives back a little more. */
@media(min-width:901px) and (max-width:1000px){
  .nav ul{gap:12px}
  .nav a{letter-spacing:.06em;font-size:10px}
  .nav .btn{padding:10px 12px;font-size:10px}
}

/* ---------- heroes ---------- */
.hero{background:var(--deep);padding:var(--s7) 0 0;text-align:center}
.hero h1{max-width:19ch;margin:var(--s3) auto;text-wrap:balance}
.hero .lead{max-width:58ch;margin:0 auto}
.hero .btn-row{justify-content:center;margin:var(--s5) 0 var(--s2)}
.hero-sm{background:var(--deep);padding:var(--s7) 0 var(--s6);text-align:center}
.hero-sm h1{max-width:21ch;margin:var(--s3) auto var(--s3)}
.hero-sm .lead{max-width:58ch;margin:0 auto}
.hero-sm .btn-row{justify-content:center}
.crumb{font-size:var(--t-label);font-weight:600;letter-spacing:var(--tr-label);text-transform:uppercase;color:var(--tan)}
.crumb a{color:var(--tan)}
.crumb a:hover{color:var(--cream)}
.heroimg{margin-top:var(--s6);height:300px;
  background:repeating-linear-gradient(135deg,var(--lineDark) 0 10px,var(--lineDark) 10px 20px);
  display:flex;align-items:flex-end;padding:16px}
.heroimg span{font-size:var(--t-label);font-weight:600;letter-spacing:var(--tr-label);text-transform:uppercase;color:#BCA590}

/* ---------- marquee ---------- */
.mq{overflow:hidden;padding:14px 0}
.mqt{display:flex;width:max-content;animation:sl 34s linear infinite}
.mqt.rev{animation:slr 29s linear infinite}
.mqg{display:flex;align-items:center}
.mqi{font-family:var(--f-disp);font-size:var(--t-mq);font-weight:500;white-space:nowrap;
  padding:0 22px;color:var(--ink);line-height:1.25}
.mqd{color:var(--tan);font-size:var(--t-body)}
@keyframes sl{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@keyframes slr{from{transform:translateX(-50%)}to{transform:translateX(0)}}

/* ---------- grids ---------- */
.g2{display:grid;grid-template-columns:1fr 1.15fr;gap:var(--s6);align-items:center}
.g2.top{align-items:start}
.g2.even{grid-template-columns:1fr 1fr}
.g3{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s3)}
.g4{display:grid;grid-template-columns:repeat(4,1fr);gap:18px}
.row2{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.stack{display:flex;flex-direction:column;gap:var(--s3)}
.stack-s{display:flex;flex-direction:column;gap:var(--s2)}

/* ---------- doors ---------- */
.doors{display:grid;grid-template-columns:1fr 1fr;gap:0}
.door{padding:var(--s6) 52px;display:flex;flex-direction:column;gap:18px;min-height:340px;transition:.2s ease}
.door:hover{filter:brightness(1.1)}
.door-ink{background:var(--inkBg);color:var(--cream)}
.door-brown{background:var(--brown);color:var(--cream)}
.door h2{max-width:16ch}
.door-ink h2{color:var(--cream)}
.door-brown h2{color:var(--cream)}
.door p{font-size:var(--t-small);line-height:1.58;max-width:42ch}
.door-ink p{color:var(--onDark2)}
.door-brown p{color:var(--onBrown)}
.door .go{margin-top:auto;align-self:flex-start;padding-bottom:5px;
  font-size:var(--t-label);font-weight:600;letter-spacing:var(--tr-label);text-transform:uppercase}
.door-ink .go{color:var(--cream);border-bottom:1px solid var(--brown)}
.door-brown .go{color:var(--cream);border-bottom:1px solid var(--tan3)}

/* ---------- tiers ---------- */
.tier{padding:36px 32px;display:flex;flex-direction:column;gap:var(--s2);
  border:1px solid var(--rule2);background:var(--card);color:var(--ink);transition:.2s ease}
.tier:hover{transform:translateY(-4px);box-shadow:0 14px 34px rgba(0,0,0,.25)}
.tier.feature{background:var(--brown);border-color:#8A6B55;color:var(--cream)}
.tier h3{color:inherit}
.tier .lbl{color:var(--brown)}
.tier.feature .lbl{color:var(--tan3)}
.tier .price{font-family:var(--f-disp);font-size:var(--t-num);font-weight:500;line-height:1;color:inherit}
.tier .price span{font-size:var(--t-small);font-family:var(--f-sans);font-weight:500;letter-spacing:0}
.tier p{font-size:var(--t-small);line-height:1.58;color:var(--muted)}
.tier.feature p{color:var(--onBrown)}
.tier ul{list-style:none;display:flex;flex-direction:column;gap:9px;padding-top:var(--s2);
  border-top:1px solid var(--rule2);margin-top:4px}
.tier.feature ul{border-color:var(--lineDark)}
.tier li{display:flex;gap:10px;font-size:var(--t-small);line-height:1.5;color:var(--muted)}
.tier.feature li{color:var(--onBrown)}
.tier li::before{content:"";flex-shrink:0;width:7px;height:7px;background:var(--tan);margin-top:.52em}
.tier.feature li::before{background:var(--tan3)}
.tier .btn{margin-top:auto}

/* ---------- cards ---------- */
.card{background:var(--card);border:1px solid var(--rule2);padding:30px 28px;
  display:flex;flex-direction:column;gap:12px;transition:.2s ease;position:relative}
.card::before{content:"";position:absolute;top:-1px;left:-1px;right:-1px;height:3px;
  background:var(--brown);opacity:0;transition:opacity .2s ease}
.card:hover{transform:translateY(-4px);box-shadow:0 16px 34px rgba(35,25,18,.14);border-color:var(--brown)}
.card:hover::before{opacity:1}
.card p{font-size:var(--t-body);line-height:1.6;color:var(--muted)}
.card .lbl{color:var(--brown)}
.card .tag{color:var(--soft)}
.card .p{font-size:var(--t-label);font-weight:600;letter-spacing:var(--tr-label);
  text-transform:uppercase;color:var(--brown);margin-top:auto}
.card.hi{border-color:var(--brown);border-width:2px}
.card.hi::before{opacity:1;height:4px}

/* ---------- pillars (border-top blocks) ---------- */
.pillar{border-top:3px solid var(--brown);padding-top:var(--s3)}
.pillar h3{margin-bottom:9px}
.pillar p{font-size:var(--t-body);line-height:1.6;color:var(--muted)}

/* ---------- numbered steps ---------- */
.step{display:grid;grid-template-columns:88px 1fr 1.3fr;gap:34px;padding:var(--s4) 0;
  border-top:1px solid var(--rule2);align-items:start}
.step:last-child{border-bottom:1px solid var(--rule2)}
.step .num{font-family:var(--f-disp);font-size:var(--t-h3);color:var(--brown);line-height:1.2}
.step h3{font-size:var(--t-h3)}
.step p{font-family:var(--f-sans);font-weight:400;font-size:var(--t-body);
  line-height:1.65;color:var(--muted)}

/* ---------- key/value rows ---------- */
.vrow{display:grid;grid-template-columns:180px 1fr;gap:18px;padding:16px 0;border-top:1px solid var(--lineDark)}
.vrow:last-child{border-bottom:1px solid var(--lineDark)}
.vrow p{font-size:var(--t-small);line-height:1.58;color:var(--tan2);align-self:center}
.kv{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s3);
  border-top:1px solid var(--rule);padding-top:var(--s3);margin-top:6px}
.kv .lbl{color:var(--brown);margin-bottom:5px}
.kv p{font-size:var(--t-small)}

/* ---------- dash lists ---------- */
.dash{list-style:none;display:flex;flex-direction:column;gap:12px}
.dash li{display:block;position:relative;padding-left:24px;
  font-size:var(--t-body);line-height:1.6;color:var(--muted)}
.dash li strong{color:var(--ink);font-weight:600}
.sec-deep .dash li strong,.sec-ink .dash li strong,.sec-brown .dash li strong{color:#fff}
.dash li::before{content:"";position:absolute;left:0;top:.58em;
  width:8px;height:8px;background:var(--brown)}
.sec-brown .dash li::before,.sec-deep .dash li::before,.sec-ink .dash li::before{background:var(--tan)}
.dash.small li{font-size:var(--t-small)}

/* ---------- services accordion ---------- */
.svc{border-top:1px solid var(--rule2)}
.svc details{border-bottom:1px solid var(--rule2)}
.svc summary{display:grid;grid-template-columns:42px 1fr auto 28px;gap:var(--s3);align-items:baseline;
  padding:24px 8px 24px 0;cursor:pointer;list-style:none;transition:.18s ease;position:relative}
.svc summary::-webkit-details-marker{display:none}
.svc summary:hover{background:var(--paper2);padding-left:12px}
.svc .n{font-size:var(--t-label);font-weight:600;letter-spacing:var(--tr-label);color:var(--brown)}
.svc .t{font-family:var(--f-disp);font-size:var(--t-h3);font-weight:600;line-height:1.2;letter-spacing:0}
.svc .pr{font-size:var(--t-label);font-weight:600;letter-spacing:.16em;text-transform:uppercase;
  color:var(--brown);text-align:right}
.svc .pl{font-family:var(--f-disp);font-size:var(--t-h3);color:var(--brown);text-align:right;line-height:1}
.svc details[open] .pl{visibility:hidden}
.svc details[open] summary::after{content:"\2013";font-family:var(--f-disp);font-size:var(--t-h3);
  color:var(--brown);position:absolute;right:8px;top:24px}
.svc .body{display:grid;grid-template-columns:42px 1fr 250px;gap:var(--s3);padding:0 8px 26px 0}
.svc .body p{font-family:var(--f-sans);font-weight:400;font-size:var(--t-body);
  line-height:1.65;color:var(--muted)}
.svc .body p+p{margin-top:10px}
.svc .who{font-size:var(--t-small);line-height:1.55;color:var(--muted);font-family:var(--f-sans)}
.svc .who-l{color:var(--soft);margin-bottom:6px}

/* ---------- FAQ ---------- */
.faq{border-top:1px solid var(--rule2)}
.faq details{border-bottom:1px solid var(--rule2)}
.faq summary{display:flex;justify-content:space-between;align-items:baseline;gap:var(--s3);
  padding:22px 4px;cursor:pointer;list-style:none;font-family:var(--f-disp);
  font-size:var(--t-h4);font-weight:600;line-height:1.3;transition:.16s ease}
.faq summary::-webkit-details-marker{display:none}
.faq summary:hover{color:var(--brown)}
.faq summary::after{content:"+";font-family:var(--f-disp);color:var(--brown);flex-shrink:0;line-height:1}
.faq details[open] summary::after{content:"\2013"}
.sec-deep .faq summary::after{color:var(--tan)}
.faq .a{padding:0 4px 24px;max-width:76ch}
.faq .a p{font-size:var(--t-body);line-height:var(--lh-body);color:var(--muted)}
.faq .a p+p{margin-top:12px}
.sec-deep .faq,.sec-deep .faq details{border-color:var(--lineDark)}
.sec-deep .faq summary{color:var(--cream)}
.sec-deep .faq .a p{color:var(--onDark)}

/* ---------- rate table ---------- */
.tscroll{overflow-x:auto;-webkit-overflow-scrolling:touch;border:1px solid var(--rule)}
table.rt{width:100%;border-collapse:collapse;background:var(--card);min-width:600px}
table.rt caption{text-align:left;padding:16px 20px;font-size:var(--t-label);font-weight:600;
  letter-spacing:var(--tr-label);text-transform:uppercase;color:var(--brown);
  background:var(--paper2);border-bottom:1px solid var(--rule)}
table.rt th,table.rt td{padding:14px 20px;text-align:left;border-bottom:1px solid var(--rule);
  font-size:var(--t-small);line-height:1.5}
table.rt thead th{font-family:var(--f-sans);font-size:var(--t-label);font-weight:600;
  letter-spacing:.12em;text-transform:uppercase;color:var(--soft);background:var(--paper2)}
table.rt tbody th{font-family:var(--f-disp);font-size:var(--t-h4);font-weight:600;
  letter-spacing:0;white-space:nowrap}
table.rt tbody tr:last-child th,table.rt tbody tr:last-child td{border-bottom:0}
table.rt td.num{font-variant-numeric:tabular-nums;white-space:nowrap}

/* ---------- forms ---------- */
.form{display:flex;flex-direction:column;gap:16px}
.field{display:flex;flex-direction:column;gap:7px}
.field label{font-size:var(--t-label);font-weight:600;letter-spacing:var(--tr-label);
  text-transform:uppercase;color:var(--soft)}
.field input,.field textarea,.field select{background:transparent;border:0;border-bottom:1px solid var(--rule2);
  color:var(--ink);font-family:inherit;font-size:16px;padding:9px 0;width:100%}
.field textarea{min-height:96px;resize:vertical}
.field input:focus,.field textarea:focus,.field select:focus{outline:0;border-bottom-color:var(--brown)}
/* A native select popup is painted by the operating system, and it brings its
   own white ground. The <option> rows were given a dark background here, but
   the <optgroup> LABEL was not, so it took the select's pale text onto that
   white band and became almost invisible. color-scheme tells the browser to
   draw the whole native popup dark, and the explicit optgroup rule covers the
   browsers that ignore it. */
.field select,.calc select{color-scheme:dark}
.field select option,.calc select option{background:var(--inkBg);color:var(--cream)}
.field select optgroup,.calc select optgroup{background:var(--deep);color:var(--tan);
  font-weight:600;font-style:normal}
.field select optgroup option,.calc select optgroup option{color:var(--cream);font-weight:400}
.field.onLight label{color:var(--brown)}
.sec-brown .field label{color:var(--tan3)}
/* A pale card holding a form, dropped onto the brown band. It was an inline
   style, so .sec-brown .field label reached inside it and painted the labels
   --tan3 on --panel: 1.07:1. Named, the card can say it is a light ground. */
.formcard{background:var(--panel);padding:34px 32px;border:1px solid var(--rule2)}
@media(max-width:640px){.formcard{padding:26px 20px}}
.sec-brown .formcard .field label,.formcard .field label{color:var(--soft)}
.sec-brown .formcard .field input,.sec-brown .formcard .field textarea,
.sec-brown .formcard .field select,.formcard .field input,.formcard .field textarea,
.formcard .field select{color:var(--ink);border-bottom-color:var(--soft)}   /* 5.01:1 on --panel */
.sec-brown .formcard .field label.ck,.formcard .field label.ck{color:var(--muted)}
.formcard .note,.formcard p{color:var(--muted)}
.formcard a{color:var(--brown)}
.field.onLight input{color:var(--ink);border-bottom-color:var(--soft)}   /* --rule2 was 1.67:1 */
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
/* The skip link is the FIRST tab stop on every page and there was no focus rule
   anywhere in this file, so it stayed clipped to a 1x1 box: a sighted keyboard
   user tabbed onto a link they could not see and the focus ring vanished with
   it. The bypass only worked for screen readers, which is the one group that
   needed it least. */
.sr:focus{position:fixed;top:10px;left:10px;width:auto;height:auto;clip:auto;
  clip-path:none;overflow:visible;padding:12px 18px;background:var(--cream);
  color:var(--ink);font-weight:600;font-size:14px;z-index:9999;
  outline:2px solid var(--brown);outline-offset:2px}

/* A dark form panel dropped onto a light page. Was an inline style on
   contact.html, which put it out of reach of the on-dark form rules. */
.darkpanel{background:var(--deep);padding:38px 34px}
@media(max-width:640px){.darkpanel{padding:28px 22px}}

/* ---------- placeholders ---------- */
.ph{background:repeating-linear-gradient(135deg,var(--panel2) 0 10px,var(--panel) 10px 20px);
  display:flex;align-items:flex-end;padding:14px;min-height:240px}
.ph span{font-size:var(--t-label);font-weight:600;letter-spacing:var(--tr-label);
  text-transform:uppercase;color:var(--soft)}
.ph.tall{min-height:420px}
.ph.down{margin-top:30px}

/* ---------- pull quote / callout ---------- */
/* A callout is the point of the section, so it looks like one: a dark panel
   with a tan chip label, not a white box with a thin line down the side. */
.callout{position:relative;padding:34px 38px 34px 42px;background:var(--deep);
  border-left:6px solid var(--brown);overflow:hidden}
.callout::after{content:"";position:absolute;top:0;right:0;width:120px;height:100%;
  background:linear-gradient(115deg,transparent 55%,rgba(196,164,136,.10) 55%);pointer-events:none}
.callout p{font-size:var(--t-body);line-height:1.65;color:var(--onDark);max-width:72ch}
.callout p+p{margin-top:12px}
.callout p strong{color:#fff;font-weight:600}
.callout .lbl{display:inline-block;color:var(--deep);background:var(--tan);
  padding:6px 12px;margin-bottom:16px}
.callout a{color:var(--tan3);text-decoration:underline;text-underline-offset:2px}
.callout a:hover{color:#fff}
/* on an already dark ground, invert so it still separates */
/* .hero-sm is var(--deep) and so is .callout, so a callout dropped into a hero
   rendered as an invisible panel: dark text on its own dark ground. Five
   separate agents hit this on the same day while adding short-answer boxes to
   the search pages, and each worked around it by moving the box out of the
   hero. Adding .hero-sm here means the next one does not have to. */
.hero-sm .callout,
.sec-deep .callout,.sec-ink .callout{background:var(--paper);border-left-color:var(--brown)}
.hero-sm .callout p,.sec-deep .callout p,.sec-ink .callout p{color:var(--muted)}
.hero-sm .callout p strong,.sec-deep .callout p strong,.sec-ink .callout p strong{color:var(--ink)}
.hero-sm .callout .lbl,.sec-deep .callout .lbl,.sec-ink .callout .lbl{color:var(--paper);background:var(--brown)}
.hero-sm .callout::after,.sec-deep .callout::after,.sec-ink .callout::after{
  background:linear-gradient(115deg,transparent 55%,rgba(110,78,59,.07) 55%)}
.hero-sm .callout a,.sec-deep .callout a,.sec-ink .callout a{color:var(--brown)}

/* ---------- newsletter ---------- */
.news{background:var(--deep);padding:var(--s6) 0}
.news .inner,#start .inner,#alerts .inner,.formsec .inner{display:grid;grid-template-columns:1fr 1fr;gap:var(--s6);align-items:center}
/* The journal alerts sign up. Same two column layout as the newsletter band but
   on the alternate ground, because it is a second, narrower promise: a note when
   a piece goes up, nothing else. Kept separate from the weekly list on purpose,
   so somebody can take one without the other. 30 August 2026. */
#alerts form{display:flex;gap:12px;flex-wrap:wrap;margin-top:var(--s3)}

#start .inner,.formsec .inner{align-items:start}
#start .inner > div:first-child,.formsec .inner > div:first-child{padding-top:2px}
.news form{display:flex;gap:12px;flex-wrap:wrap;margin-top:var(--s3)}
.news input,#alerts input{flex:1;min-width:220px;background:transparent;border:0;border-bottom:1px solid var(--lineDark);
  color:var(--cream);font-family:inherit;font-size:16px;padding:11px 0}
.news input:focus,#alerts input:focus{outline:0;border-bottom-color:var(--tan)}

/* ---------- footer ---------- */
footer{background:var(--ink2);padding:var(--s6) 0;color:#9C8A79}
.fnav{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--s5);flex-wrap:wrap}
.fcol{display:flex;flex-direction:column;gap:10px;min-width:150px}
.fcol .lbl{color:var(--tan);margin-bottom:2px}
.fcol a{color:#B3A493;font-size:var(--t-small)}
.fcol a:hover{color:var(--cream)}
.fbrand{display:flex;flex-direction:column;align-items:flex-start;gap:14px;max-width:28ch}
.fbrand p{font-size:var(--t-small);line-height:1.55;color:#9C8A79}
.disclaim{border-top:1px solid var(--lineDark);margin-top:var(--s5);padding-top:var(--s4);
  font-size:var(--t-fine);line-height:1.7;color:#918171}
.disclaim p+p{margin-top:10px}
.disclaim a{color:#B3A493;text-decoration:underline;text-underline-offset:2px}
.disclaim a:hover{color:var(--cream)}

/* ---------- motion + interaction ---------- */
@media print{.rv{opacity:1!important;transform:none!important}}
.rv{opacity:0;transform:translateY(18px);
  transition:opacity .7s cubic-bezier(.2,.7,.3,1),transform .7s cubic-bezier(.2,.7,.3,1)}
.rv.in{opacity:1;transform:none}
.rv-d1{transition-delay:.08s}.rv-d2{transition-delay:.16s}
.count{font-variant-numeric:tabular-nums}
.progress{position:fixed;top:0;left:0;height:2px;background:var(--brown);z-index:200;width:0;transition:width .1s linear}

/* ---------- modal ---------- */
.modal{position:fixed;inset:0;background:rgba(16,13,11,.72);backdrop-filter:blur(6px);z-index:300;
  display:flex;align-items:center;justify-content:center;padding:24px;opacity:0;pointer-events:none;
  transition:opacity .25s ease}
.modal.on{opacity:1;pointer-events:auto}
.modal-box{background:var(--paper);max-width:640px;width:100%;max-height:86vh;overflow-y:auto;
  padding:44px 42px;transform:translateY(14px) scale(.98);transition:transform .28s cubic-bezier(.2,.7,.3,1)}
.modal.on .modal-box{transform:none}
.modal-close{position:absolute;top:22px;right:26px;background:none;border:0;color:var(--cream);
  font-size:34px;cursor:pointer;line-height:1;padding:6px}

.modal p{font-size:var(--t-body);line-height:var(--lh-body);color:var(--muted);margin-bottom:12px}
.modal ul{margin:12px 0 12px 20px;color:var(--muted);font-size:var(--t-small);line-height:1.6}
.modal li{margin:7px 0}

/* ---------- calculator ---------- */
.calc{background:var(--deep);padding:44px 42px}
.calc-grid{display:grid;grid-template-columns:1fr 1fr;gap:26px}
.calc label{display:block;font-size:var(--t-label);font-weight:600;letter-spacing:var(--tr-label);
  text-transform:uppercase;color:var(--tan);margin-bottom:9px}
.calc select,.calc input[type=number]{width:100%;background:var(--inkBg);border:1px solid var(--lineDark);
  color:var(--cream);font-family:inherit;font-size:16px;padding:13px 14px;appearance:none;cursor:pointer}
.calc select:focus,.calc input:focus{outline:0;border-color:var(--tan)}
.calc option{background:var(--inkBg)}
.calc input[type=range]{width:100%;accent-color:var(--tan);cursor:pointer}
.calc-out{margin-top:30px;padding-top:26px;border-top:1px solid var(--lineDark);
  display:flex;justify-content:space-between;align-items:flex-end;gap:24px;flex-wrap:wrap}
.calc-num{font-family:var(--f-disp);font-size:var(--t-num);font-weight:500;line-height:1;letter-spacing:-.02em}
.calc-num.sm{font-size:var(--t-h2);color:var(--tan2)}
.calc-note{font-size:var(--t-fine);line-height:1.6;color:#BCA590;margin-top:16px}
.calc-note.fine{color:#BAA593}
.pill-row{display:flex;gap:8px;flex-wrap:wrap;margin-top:10px}
.pill{border:1px solid var(--rule2);background:transparent;color:var(--ink);padding:9px 15px;
  font-size:var(--t-label);font-weight:600;letter-spacing:.14em;text-transform:uppercase;
  cursor:pointer;transition:.16s ease;font-family:var(--f-sans);line-height:1.4}
.pill.on{background:var(--ink);color:var(--paper);border-color:var(--ink)}
.pill:hover{border-color:var(--brown)}   /* 5.58:1; the dark rows keep --tan below */

/* ---------- journal ---------- */
.jgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}
/* The journal index groups twelve pieces into four sections, and a three column
   grid leaves 4 cards as 3+1 and 2 cards as 2+gap. Both read as a mistake.
   These two modifiers make each section fill its own row. 30 August 2026. */
.jgrid.j4{grid-template-columns:repeat(4,1fr)}
.jgrid.j2{grid-template-columns:repeat(2,1fr)}
@media(max-width:1100px){.jgrid.j4{grid-template-columns:repeat(2,1fr)}}
@media(max-width:760px){.jgrid.j4,.jgrid.j2{grid-template-columns:1fr}}
.jcard{background:var(--card);border:1px solid var(--rule);display:flex;flex-direction:column;transition:.22s ease}
.jcard:hover{transform:translateY(-4px);box-shadow:0 14px 32px rgba(61,46,36,.12);border-color:var(--brown)}
/* The thumb was a CSS stripe pattern standing in for art that did not exist.
   It now holds a real cover. The ratio is declared so the row does not jump
   while the file arrives, and the whole card is one link, so the image is
   decoration: its alt is empty and the heading underneath does the naming. */
.jthumb{aspect-ratio:1200/620;background:var(--panel);position:relative;overflow:hidden}
.jthumb img{width:100%;height:100%;object-fit:cover;display:block}
/* The category chip used to sit on the artwork and covered part of it.
   It reads better above the headline, where it also lines up across cards
   whose covers have different compositions. */
.jbody .jtag{font-family:var(--f-mono);font-size:var(--t-label);letter-spacing:var(--tr-label);
  text-transform:uppercase;color:var(--brown);margin-bottom:2px}
/* the same cover the journal card uses, at the top of the piece itself */
.artcover{max-width:var(--wrap);margin:0 auto var(--s6);padding:0 clamp(18px,4vw,60px)}
.artcover img{width:100%;height:auto;display:block;border:1px solid var(--rule2)}
.jcard h3{font-size:var(--t-h4,20px);line-height:1.24}
.jcard:hover .jthumb img{transform:scale(1.03)}
.jthumb img{transition:transform .4s ease}
.jbody{padding:26px 24px;display:flex;flex-direction:column;gap:10px;flex:1}
.jbody p{font-size:var(--t-small);line-height:1.58;color:var(--muted)}
.jmeta{margin-top:auto;font-size:var(--t-label);font-weight:600;letter-spacing:.16em;
  text-transform:uppercase;color:var(--brown)}

/* ---------- guide cover ---------- */
.coverwrap{background:var(--deep);color:var(--cream);padding:52px;display:flex;align-items:center;justify-content:center;min-height:460px}
.cover{background:var(--lineDark);width:100%;max-width:320px;aspect-ratio:794/1123;display:flex;
  flex-direction:column;justify-content:center;padding:34px;gap:14px}
.cover .lbl{color:var(--tan3)}
.cover .ttl{font-family:var(--f-disp);color:var(--cream);font-size:var(--t-h2);line-height:1.05}
.cover .by{color:var(--tan2);   /* 5.9:1 on --lineDark */
  font-size:var(--t-fine);margin-top:auto;letter-spacing:.18em;text-transform:uppercase}

/* ---------- responsive ---------- */
@media(max-width:900px){
  section{padding:var(--s6) 0}
  .wrap{padding:0 22px}
  .g2,.g2.even,.g3,.g4,.kv,.news .inner,#start .inner,#alerts .inner,.formsec .inner,.calc-grid,.jgrid,.doors,.row2{grid-template-columns:1fr}
  .g2,.g3{gap:34px}
  .g4,.kv{gap:22px}
  .doors .door{padding:44px 24px;min-height:0}
  .nav ul{display:none}
  .nav ul.open{display:flex;position:absolute;top:100%;left:0;right:0;background:var(--deep);
    flex-direction:column;padding:22px 24px;gap:18px;border-bottom:1px solid var(--lineDark);align-items:flex-start}
  #navtoggle{display:block}
  .nav .btn{padding:10px 16px}
  .svc summary{grid-template-columns:1fr auto;gap:12px}
  .svc .n,.svc .pl{display:none}
  .svc .body{grid-template-columns:1fr;gap:14px}
  .step{grid-template-columns:1fr;gap:12px}
  .step .num{font-size:var(--t-label);letter-spacing:var(--tr-label)}
  .vrow{grid-template-columns:1fr;gap:6px}
  .heroimg{height:200px;margin-top:var(--s5)}
  .hero,.hero-sm{padding-top:var(--s6)}
  .calc{padding:30px 24px}
  .modal-box{padding:32px 24px}
  .fnav{gap:var(--s4)}
  .hero .btn-row,.hero-sm .btn-row{flex-direction:column;align-items:stretch}
  .hero .btn-row .btn,.hero-sm .btn-row .btn{width:100%}
  .btn{padding:15px 24px}
}
@media(prefers-reduced-motion:reduce){
  *{animation:none!important;transition:none!important}
  .btn:hover,.card:hover,.tier:hover,.jcard:hover{transform:none}
  html{scroll-behavior:auto}
  .rv{opacity:1;transform:none}
  .modal-box{transform:none}
}

/* ============================================================
   Role classes are authoritative.
   Component rules like .card p or .svc .body p would otherwise
   out-specify .lbl / .note / .small / .lead and pull a label to
   body size. The repeated class raises specificity above every
   component paragraph rule so each role has exactly one size,
   one weight and one family on every page.
   ============================================================ */
.lbl.lbl.lbl{font-family:var(--f-sans);font-size:var(--t-label);font-weight:600;
  letter-spacing:var(--tr-label);text-transform:uppercase;line-height:1.4}
.note.note.note{font-family:var(--f-sans);font-size:var(--t-fine);font-weight:400;line-height:1.6}
.small.small.small{font-family:var(--f-sans);font-size:var(--t-small);font-weight:400;line-height:1.58}
.lead.lead.lead{font-family:var(--f-ser);font-size:var(--t-lead);font-weight:400;line-height:var(--lh-lead)}
.crumb.crumb.crumb{font-family:var(--f-sans);font-size:var(--t-label);font-weight:600;
  letter-spacing:var(--tr-label);text-transform:uppercase}
.jmeta.jmeta.jmeta{font-family:var(--f-sans);font-size:var(--t-label);font-weight:600;
  letter-spacing:.16em;text-transform:uppercase}
.card .p,.card .p.p{font-family:var(--f-sans);font-size:var(--t-label);font-weight:600;
  letter-spacing:var(--tr-label);text-transform:uppercase}
.modal h2{font-size:var(--t-h2);margin-bottom:12px}

/* ============================================================
   PRODUCT GRID — replaces the one-off services accordion.
   Everything visible at once. No clicking to find a price.
   ============================================================ */
.pgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
.prod{background:var(--card);border:1px solid var(--rule2);padding:0;display:flex;
  flex-direction:column;transition:.22s ease;position:relative;overflow:hidden}
.prod:hover{transform:translateY(-5px);box-shadow:0 18px 40px rgba(35,25,18,.16);border-color:var(--brown)}
.prod-top{display:flex;align-items:center;justify-content:space-between;
  padding:22px 26px;background:var(--paper2);border-bottom:1px solid var(--rule2)}
.prod:hover .prod-top{background:var(--brown)}
.prod-n{font-family:var(--f-sans);font-size:var(--t-label);font-weight:700;
  letter-spacing:var(--tr-label);color:var(--brown)}
.prod:hover .prod-n{color:var(--tan3)}
.prod-ico{width:44px;height:44px;flex-shrink:0}
.prod-ico rect,.prod-ico circle,.prod-ico path,.prod-ico line,.prod-ico polyline{
  stroke:var(--brown);fill:none;stroke-width:1.6;stroke-linecap:square}
.prod:hover .prod-ico rect,.prod:hover .prod-ico circle,.prod:hover .prod-ico path,
.prod:hover .prod-ico line,.prod:hover .prod-ico polyline{stroke:var(--tan3)}
.prod-ico .fill{fill:var(--brown);stroke:none}
.prod:hover .prod-ico .fill{fill:var(--tan3)}
.prod-body{padding:26px;display:flex;flex-direction:column;gap:12px;flex:1}
.prod-body h3{color:var(--ink)}
.prod-price{font-family:var(--f-disp);font-size:var(--t-num);font-weight:500;
  line-height:1;color:var(--brown);letter-spacing:-.01em}
.prod-price small{font-family:var(--f-sans);font-size:var(--t-small);font-weight:600;
  letter-spacing:.02em;color:var(--soft)}
.prod-desc{font-size:var(--t-body);line-height:1.6;color:var(--muted)}
.prod-who{margin-top:auto;padding-top:16px;border-top:1px solid var(--rule)}
.prod-who .lbl{color:var(--soft);display:block;margin-bottom:5px}
.prod-who span.w{font-size:var(--t-small);line-height:1.5;color:var(--muted)}
.prod .btn{margin:0 26px 26px;text-align:center}
.prod.cta{background:var(--deep);border-color:var(--deep)}
.prod.cta .prod-top{background:#3F2E23;border-bottom-color:var(--lineDark)}
.prod.cta h3,.prod.cta .prod-price{color:var(--cream)}
.prod.cta .prod-desc{color:var(--onDark)}
.prod.cta .prod-who{border-top-color:var(--lineDark)}
.prod.cta .prod-who span.w{color:var(--onDark2)}
.prod.cta:hover .prod-top{background:var(--brown)}

/* ============================================================
   TABS — one panel at a time instead of four stacked tables
   ============================================================ */
.tabs{display:flex;gap:0;flex-wrap:wrap;border-bottom:2px solid var(--rule2);margin-bottom:var(--s5)}
.tab{background:none;border:0;border-bottom:3px solid transparent;margin-bottom:-2px;
  padding:16px 26px;cursor:pointer;font-family:var(--f-sans);font-size:var(--t-label);
  font-weight:700;letter-spacing:var(--tr-label);text-transform:uppercase;
  color:var(--soft);transition:.18s ease}
.tab:hover{color:var(--ink)}
.tab.on{color:var(--brown);border-bottom-color:var(--brown)}
.panel{display:none}
.panel.on{display:block;animation:fade .35s ease}
@keyframes fade{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}

/* ---- rate bands as cards ---- */
.bands{display:grid;grid-template-columns:repeat(5,1fr);gap:16px}
.band{background:var(--card);border:1px solid var(--rule2);padding:26px 22px;
  display:flex;flex-direction:column;gap:10px;transition:.2s ease}
.band:hover{border-color:var(--brown);transform:translateY(-4px);box-shadow:0 14px 30px rgba(35,25,18,.12)}
.band .tier{font-family:var(--f-disp);font-size:var(--t-h3);font-weight:600;color:var(--ink);
  background:none;border:0;padding:0;display:block;letter-spacing:0}
.band .range{font-family:var(--f-sans);font-size:var(--t-label);font-weight:700;
  letter-spacing:var(--tr-label);text-transform:uppercase;color:var(--soft)}
.band .fee{font-family:var(--f-disp);font-size:var(--t-h3);font-weight:500;color:var(--brown);
  line-height:1.15;border-top:1px solid var(--rule);padding-top:12px;margin-top:2px}
.band .why{font-size:var(--t-small);line-height:1.5;color:var(--muted)}

/* ---- format multipliers as tiles ---- */
.mults{display:grid;grid-template-columns:repeat(4,1fr);gap:16px}
.mult{background:var(--card);border:1px solid var(--rule2);padding:26px 22px;transition:.2s ease}
.mult:hover{border-color:var(--brown);transform:translateY(-4px)}
.mult .x{font-family:var(--f-disp);font-size:var(--t-num);font-weight:500;color:var(--brown);
  line-height:1;display:block;margin-bottom:12px;letter-spacing:-.01em}
.mult h4{color:var(--ink);margin-bottom:8px}
.mult p{font-size:var(--t-small);line-height:1.5;color:var(--muted)}

/* ---- usage rights as proportional bars ---- */
.bars{display:flex;flex-direction:column;gap:2px}
.bar{display:grid;grid-template-columns:230px 1fr 150px;gap:22px;align-items:center;
  padding:18px 20px;background:var(--card);border:1px solid var(--rule);transition:.18s ease}
.bar:hover{border-color:var(--brown);background:#fff}
.bar .what{font-family:var(--f-disp);font-size:var(--t-h4);font-weight:600;color:var(--ink);line-height:1.25}
.bar .track{display:block;height:22px;background:var(--paper3);position:relative;overflow:hidden}
.bar .fill{display:block;height:100%;background:var(--brown);width:0;
  transition:width 1s cubic-bezier(.2,.7,.3,1)}
.bar.in .fill{width:var(--w)}
.bar .fill.zero{background:var(--rule2)}
.bar .add{font-family:var(--f-disp);font-size:var(--t-h3);font-weight:500;color:var(--brown);
  text-align:right;line-height:1;white-space:nowrap}
.bar .mean{grid-column:1/-1;font-size:var(--t-small);line-height:1.5;color:var(--muted);
  padding-top:4px;margin-top:-4px}

/* ---- category ranking ---- */
.cats{display:grid;grid-template-columns:repeat(2,1fr);gap:16px}
.cat{background:var(--card);border:1px solid var(--rule2);padding:24px;display:flex;
  flex-direction:column;gap:10px;border-left:5px solid var(--brown);transition:.2s ease}
.cat:hover{transform:translateX(4px);box-shadow:0 10px 26px rgba(35,25,18,.10)}
.cat.top{border-left-color:var(--good)}
.cat.mid{border-left-color:var(--brown)}
.cat.low{border-left-color:var(--bad)}
.cat h4{color:var(--ink)}
.cat .where{font-family:var(--f-sans);font-size:var(--t-label);font-weight:700;
  letter-spacing:var(--tr-label);text-transform:uppercase}
.cat.top .where{color:var(--good)}
.cat.mid .where{color:var(--brown)}
.cat.low .where{color:var(--bad)}
.cat p{font-size:var(--t-small);line-height:1.55;color:var(--muted)}

/* ============================================================
   PROOF STRIP — big figures on the homepage
   ============================================================ */
.proof{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s5)}
.proof .fig{font-family:var(--f-disp);font-size:var(--t-big);font-weight:500;line-height:1;
  color:var(--ink);letter-spacing:-.02em;display:block;margin-bottom:12px}
.proof .cap{font-size:var(--t-body);line-height:1.55;color:var(--muted)}
.proof .lbl{color:var(--brown);margin-bottom:14px}

@media(max-width:1000px){
  .pgrid{grid-template-columns:repeat(2,1fr)}
  .bands{grid-template-columns:repeat(2,1fr)}
  .mults{grid-template-columns:repeat(2,1fr)}
}
@media(max-width:900px){
  .pgrid,.bands,.mults,.cats,.proof{grid-template-columns:1fr}
  .bar{grid-template-columns:1fr;gap:10px;padding:20px}
  .bar .add{text-align:left}
  .bar .track{height:16px}
  .tabs{margin-bottom:var(--s4)}
  .tab{padding:13px 16px}
  .prod .btn{margin:0 20px 20px}
  .prod-body{padding:22px 20px}
  .prod-top{padding:18px 20px}
}

/* ============================================================
   Buttons and list items win over the on-dark link/text rules.
   .sec-deep a would otherwise repaint a .btn-light label, and
   .dash li would otherwise override the panel's inherited colour.
   ============================================================ */
a.btn.btn-light,.btn.btn-light{background:var(--cream);color:var(--deep);border-color:var(--deep)}
a.btn.btn-light:hover,.btn.btn-light:hover{background:var(--tan3);color:var(--deep)}
a.btn.btn-dark,.btn.btn-dark{background:var(--ink);color:var(--paper)}
a.btn.btn-dark:hover,.btn.btn-dark:hover{background:var(--brown);color:#fff}
a.btn.btn-brown,.btn.btn-brown{background:var(--brown);color:var(--cream);border-color:var(--brown)}
a.btn.btn-brown:hover,.btn.btn-brown:hover{background:var(--ink);color:var(--paper)}
a.btn.btn-line,.btn.btn-line{background:transparent;border-color:var(--tan);color:var(--cream)}
a.btn.btn-line:hover,.btn.btn-line:hover{background:var(--cream);color:var(--deep)}
a.btn.btn-lineD,.btn.btn-lineD{background:transparent;border-color:var(--ink);color:var(--ink)}
a.btn.btn-lineD:hover,.btn.btn-lineD:hover{background:var(--ink);color:var(--paper)}
.sec-deep .dash li,.sec-ink .dash li,.news .dash li{color:var(--onDark)}
.sec-brown .dash li{color:var(--onBrown)}
.door .go{color:inherit}
.prod-price.word{font-size:var(--t-h3)}
.band .fee{display:flex;flex-direction:column;gap:1px}
.band .fee span{white-space:nowrap;display:block}
.band .range{white-space:nowrap}

/* ============================================================
   SELL PANELS — for the four-point "why work this way" blocks.
   A bulleted list buried the point; these give each one a
   number, a heading and room to breathe.
   ============================================================ */
.sells{display:grid;grid-template-columns:repeat(2,1fr);gap:16px}
.sells.one{grid-template-columns:1fr}
.sell{background:var(--card);border:1px solid var(--rule2);border-top:3px solid var(--brown);
  padding:26px 24px;display:flex;flex-direction:column;gap:9px;transition:.2s ease}
.sell:hover{transform:translateY(-3px);box-shadow:0 14px 30px rgba(35,25,18,.12)}
.sell-n{font-family:var(--f-sans);font-size:var(--t-label);font-weight:700;
  letter-spacing:var(--tr-label);color:var(--brown)}
.sell h4{color:var(--ink);line-height:1.25}
.sell p{font-size:var(--t-small);line-height:1.58;color:var(--muted)}
.sec-deep .sell,.sec-ink .sell{background:#2C221B;border-color:var(--lineDark);border-top-color:var(--tan)}
.sec-deep .sell h4,.sec-ink .sell h4{color:var(--cream)}
.sec-deep .sell p,.sec-ink .sell p{color:var(--onDark)}
.sec-deep .sell-n,.sec-ink .sell-n{color:var(--tan)}
.sell{background:var(--panel2);border-color:var(--rule2);border-top-color:var(--brown)}
.sec-brown .sell{background:var(--brown2);border-color:#6B5041;border-top-color:var(--tan3)}
.sec-brown .sell h4{color:#fff}
.sec-brown .sell p{color:var(--onBrown)}
.sec-brown .sell-n{color:var(--tan3)}
@media(max-width:900px){.sells{grid-template-columns:1fr}}
.fbrand{align-items:flex-start}
.fbrand img{height:35px;width:auto;align-self:flex-start;flex:0 0 auto}

/* ============================================================
   TOUCH TARGETS
   Anything a finger has to hit needs to be at least 44px tall.
   Measured before this block: form inputs 37px, selects 38px,
   calculator pills 35px, the nav button 37px. All now 44+.
   Text inputs also stay at 16px so iOS does not zoom the page
   in when someone taps into a field.
   ============================================================ */
.calc input[type=range]{font-size:16px;height:44px;padding:0;background:transparent}
@media(max-width:900px){
  .field input,.field select,.field textarea,
  .news input,#alerts input,.calc select,.calc input[type=number]{
    min-height:46px;font-size:16px}
  .field input,.field select{padding:12px 0}
  .field textarea{padding:12px 0;min-height:110px}
  .calc select,.calc input[type=number]{padding:13px 14px}
  .pill{min-height:46px;padding:12px 16px;display:inline-flex;align-items:center}
  .btn{min-height:48px;display:inline-flex;align-items:center;justify-content:center}
  .nav .btn{min-height:44px;padding:10px 16px}
  #navtoggle{min-height:44px;min-width:44px;display:flex;flex-direction:column;
    align-items:center;justify-content:center}
  .modal-close{min-height:48px;min-width:48px;display:flex;align-items:center;justify-content:center}
  .tab{min-height:48px;display:inline-flex;align-items:center}
  .form button[type=submit]{width:100%}
  .news form button{width:100%}
  /* stop the newsletter input and button cramming on the narrowest phones */
  .news input,#alerts input{min-width:100%;flex:1 1 100%}
}
@media(max-width:380px){
  .wrap{padding:0 16px}
  .prod-body,.calc,.modal-box{padding-left:18px;padding-right:18px}
  .tab{padding:13px 12px}
}

/* ============================================================
   BRAND BANNER — static on mobile and under reduced motion.
   A sideways-scrolling row is unreadable on a 390px screen and
   freezes completely if the viewer has Reduce Motion switched
   on, which is what made it look broken on his phone.
   ============================================================ */
.mqstatic{display:none}
@media(max-width:900px){
  .mq{display:none}
  .mqstatic{display:flex;flex-wrap:wrap;justify-content:center;gap:0;
    max-width:640px;margin:0 auto;padding:0 6px}
  .mqstatic span{font-family:var(--f-disp);font-size:var(--t-h4);font-weight:500;
    color:var(--deep);line-height:1.35;padding:9px 14px;white-space:nowrap;position:relative}
  .mqstatic span+span::before{content:"";position:absolute;left:-1px;top:50%;
    transform:translateY(-50%);width:3px;height:3px;background:var(--tan);border-radius:50%}
}
@media(prefers-reduced-motion:reduce){
  .mq{display:none}
  .mqstatic{display:flex;flex-wrap:wrap;justify-content:center;
    max-width:820px;margin:0 auto}
  .mqstatic span{font-family:var(--f-disp);font-size:var(--t-h3);font-weight:500;
    color:var(--deep);line-height:1.35;padding:10px 16px;white-space:nowrap;position:relative}
  .mqstatic span+span::before{content:"";position:absolute;left:-1px;top:50%;
    transform:translateY(-50%);width:3px;height:3px;background:var(--tan);border-radius:50%}
}

/* ---- form results ------------------------------------------------------- */
/* The copy column beside a long form. Without this it ends after three
   paragraphs and leaves several hundred pixels of empty page next to the
   fields, which is the same emptiness the g2 section heads were fixing.
   Sticky also keeps "this is an application, not a booking" on screen while
   somebody is actually filling it in, which is when they need to read it. */
@media(min-width:961px){
  .formsec .inner > div:first-child{position:sticky;top:104px;align-self:start}
}

/* ---- checkbox group, for a question with more than one right answer -----
   The content day application asks what to arrange, and people need several
   of them, so a select would force them to pick the least wrong one. Two
   columns on desktop, one on a phone, and the whole row is the hit area so a
   thumb does not have to find a 24px box. */
.field>.label{font-size:var(--t-label);font-weight:700;letter-spacing:var(--tr-label);
  text-transform:uppercase;color:var(--soft);display:block;margin-bottom:10px}
.checks{display:grid;grid-template-columns:1fr 1fr;gap:10px 20px}
.field label.ck{display:flex;align-items:flex-start;gap:10px;cursor:pointer;
  font-size:var(--t-small);line-height:1.45;color:var(--muted);
  text-transform:none;letter-spacing:0;font-weight:400;margin:0}
.field label.ck input{width:19px;height:19px;min-width:19px;flex:0 0 auto;margin-top:1px;
  accent-color:var(--brown);cursor:pointer}
.field label.ck:hover{color:var(--ink)}
.field label.ck input:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
@media(max-width:720px){ .checks{grid-template-columns:1fr} }

/* ---- footer social row --------------------------------------------------
   Sized to the 44px touch target rather than to the 20px glyph, so a thumb on
   a phone hits it without aiming. */
.fsoc{display:flex;gap:6px;margin-top:16px}
.fsoc a{display:inline-flex;align-items:center;justify-content:center;
  width:40px;height:40px;margin-left:-9px;color:var(--onDark2);
  border:1px solid transparent;transition:color .16s ease,border-color .16s ease}
.fsoc a:first-child{margin-left:-9px}
.fsoc svg{width:21px;height:21px;display:block}
.fsoc a:hover{color:var(--tan)}
.fsoc a:focus-visible{outline:2px solid var(--focus);outline-offset:3px;
  border-color:var(--tan);color:var(--tan)}

.form-msg{font-size:var(--t-small);line-height:1.55;margin-top:14px;padding:12px 14px;display:none}
.form-msg.ok,.form-msg.bad{display:block}
.form-msg.ok{background:#E9EFE5;color:#2F4A28;border-left:3px solid var(--good)}   /* 8.42:1 */
.form-msg.bad{background:#F6E7DF;color:#7A3F22;border-left:3px solid var(--bad)}  /* 6.80:1 */
.sec-deep .form-msg.ok,.sec-ink .form-msg.ok,.sec-brown .form-msg.ok,.news .form-msg.ok,
.calc .form-msg.ok,.darkpanel .form-msg.ok,.fmbox .form-msg.ok{
  background:#16241A;color:var(--goodD);border-left-color:#7FA372}
.sec-deep .form-msg.bad,.sec-ink .form-msg.bad,.sec-brown .form-msg.bad,.news .form-msg.bad,
.calc .form-msg.bad,.darkpanel .form-msg.bad,.fmbox .form-msg.bad{
  background:#2A1A16;color:var(--badD);border-left-color:#D08A6E}
.news .form-msg{margin-top:12px}
/* When a form has sent, everything you filled in goes and the confirmation
   stands on its own. This used to name .news, which is the band the
   newsletter sits in on ten pages. The pop-out copies that same form into a
   dialog OUTSIDE that band, so in the copy the rule matched nothing but the
   button: people pressed send, got the thank-you, and were still looking at
   their own email address in a live box. Match the form, not where it sits. */
form.sent .field,
form.sent label,
form.sent input:not([type=hidden]),
form.sent select,
form.sent textarea,
form.sent button{display:none}
form.sent .form-msg{margin-top:0}
.sell h3{font-size:var(--t-h4);color:var(--ink);line-height:1.25}
.sec-deep .sell h3,.sec-ink .sell h3{color:var(--cream)}
.sec-brown .sell h3{color:#fff}

/* .hero-sm was missing from the on-dark colour rules, so an eyebrow or a note
   placed inside one inherited its light-ground colour. */
.hero-sm .eyebrow{color:var(--tan)}
.hero-sm .note{color:#B9A693}
.hero-sm .muted{color:var(--onDark)}
.kit-hero,.kit-hero .lead,.kit-hero .note,.kit-hero .lbl{text-align:left}
.kit-hero .btn-row{justify-content:flex-start}

/* ---- one featured product, not a grid ---------------------------------- */
.feat{display:grid;grid-template-columns:210px 1fr;gap:var(--s6);align-items:center}
.feat-img{display:block;transition:.22s ease}
.feat-img img{display:block;width:100%;border:1px solid var(--rule2);box-shadow:0 14px 34px rgba(35,25,18,.16)}
.feat-img:hover{transform:translateY(-4px)}
.feat-txt{display:flex;flex-direction:column;gap:var(--s2);max-width:60ch}
.feat-txt h2{margin:0}
.feat-buy{display:flex;align-items:center;gap:var(--s3);flex-wrap:wrap;margin-top:var(--s2)}
.feat-price{font-family:var(--f-disp);font-size:var(--t-num);font-weight:500;line-height:1;color:var(--brown)}
.feat-more{font-size:var(--t-label);font-weight:700;letter-spacing:var(--tr-label);
  text-transform:uppercase;color:var(--brown);border-bottom:1px solid var(--rule2);padding-bottom:3px}
.feat-more:hover{color:var(--ink);border-bottom-color:var(--ink)}
@media(max-width:900px){
  .feat{grid-template-columns:1fr;gap:var(--s4);justify-items:start}
  .feat-img{max-width:180px}
}

/* ---- product cards ------------------------------------------------------
   These were lost when the generator was rebuilt: the shell was extracted from
   index.html, which never carried them. Defined here so every page gets them. */
.pgrid3{display:grid;grid-template-columns:repeat(3,1fr);gap:22px;align-items:stretch}
.pcard{background:var(--card);border:1px solid var(--rule2);display:flex;flex-direction:column;
  overflow:hidden;transition:.22s ease}
.pcard:hover{transform:translateY(-5px);box-shadow:0 18px 40px rgba(35,25,18,.16);border-color:var(--brown)}
.pcard img{display:block;width:100%;aspect-ratio:1/1;object-fit:cover;
  border-bottom:1px solid var(--rule2);background:var(--paper2)}
/* the body holds the button too, so a card always reads as one block */
.pcard .pb{padding:24px 22px 24px;display:flex;flex-direction:column;gap:9px;flex:1}
.pcard h3{color:var(--ink);margin:0}
.pcard .status{font-size:var(--t-label);font-weight:700;letter-spacing:var(--tr-label);
  text-transform:uppercase;margin:0}
.pcard .status.live{color:var(--good)}
.pcard .status.free{color:var(--good)}
.pcard .status.soon{color:var(--brown)}
.pcard .status.plan{color:var(--soft)}
.pcard p{font-size:var(--t-small);line-height:1.55;color:var(--muted);margin:0}
.pmeta{font-size:var(--t-label)!important;font-weight:700;letter-spacing:var(--tr-label);
  text-transform:uppercase;color:var(--soft)!important;margin-top:-2px!important}
.pcard .price{font-family:var(--f-disp);font-size:var(--t-h3);font-weight:500;color:var(--brown);
  line-height:1;margin-top:auto;padding-top:14px}
.pcard .btn{margin-top:16px;text-align:center;width:100%}
/* one-off service cards */
.prod-img{display:block;width:100%;aspect-ratio:1/1;object-fit:cover;
  border-bottom:1px solid var(--rule2);background:var(--paper2)}
.prod:hover .prod-img{filter:brightness(1.04)}
.hero-buy{display:grid;grid-template-columns:1fr 1fr;gap:var(--s6);align-items:center}
.hero-buy img{width:100%;max-width:420px;border:1px solid var(--rule2)}
/* the book plate carries its own frame and shadow, so no second border */
.hero-buy.imgfirst img{border:0;max-width:460px}
/* a card with no price still lines its button up with the others */
.pcard .pb:not(:has(.price)) .btn{margin-top:auto}
/* the four facts under the book */
.specs{display:grid;grid-template-columns:repeat(2,1fr);gap:14px 26px;margin:4px 0 2px;
  border-top:1px solid var(--rule2);border-bottom:1px solid var(--rule2);padding:18px 0}
.specs dt{font-size:var(--t-label);font-weight:700;letter-spacing:var(--tr-label);
  text-transform:uppercase;color:var(--soft);margin-bottom:3px}
.specs dd{font-size:var(--t-small);color:var(--ink);margin:0}
@media(max-width:1000px){.pgrid3{grid-template-columns:repeat(2,1fr)}}
@media(max-width:900px){
  .pgrid3{grid-template-columns:1fr}
  .hero-buy{grid-template-columns:1fr;gap:var(--s4)}
  .hero-buy.imgfirst > *:last-child{order:-1}
  .pcard img{aspect-ratio:16/10}
  .specs{grid-template-columns:1fr 1fr}
}

.ctile{background:var(--card);border:1px solid var(--rule2);display:flex;flex-direction:column;
  overflow:hidden;transition:.22s ease}
.ctile:hover{transform:translateY(-4px);box-shadow:0 16px 34px rgba(35,25,18,.14);border-color:var(--brown)}
.ctile.pending{background:transparent;border-style:dashed;border-color:var(--rule2)}
.ctile.pending:hover{transform:none;box-shadow:none;border-color:var(--rule2)}
.cimg{aspect-ratio:4/5;background:repeating-linear-gradient(135deg,var(--panel2) 0 10px,var(--panel) 10px 20px);
  display:flex;align-items:flex-end;padding:16px}
.cimg span{font-size:var(--t-label);font-weight:700;letter-spacing:var(--tr-label);
  text-transform:uppercase;color:var(--soft)}
.cb{padding:22px 20px;display:flex;flex-direction:column;gap:8px;flex:1}
.cb h3{color:var(--ink)}
.chandle{font-family:var(--f-sans);font-size:var(--t-small)!important;color:var(--brown)!important;font-weight:600}
.cb p{font-size:var(--t-small);line-height:1.55;color:var(--muted)}
.ctile .btn{margin:0 20px 20px}
.cgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
@media(max-width:1000px){.cgrid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:900px){.cgrid{grid-template-columns:1fr}}
.fee-table{width:100%;border-collapse:collapse;background:var(--card);border:1px solid var(--rule2)}
.fee-table th{font-size:var(--t-label);font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  color:var(--soft);text-align:left;padding:14px 18px;background:var(--paper2);border-bottom:1px solid var(--rule)}
.fee-table td{padding:14px 18px;border-bottom:1px solid var(--rule);font-size:var(--t-body)}
.fee-table tr:last-child td{border-bottom:0}
.fee-table td.n{font-family:var(--f-disp);font-size:var(--t-h4);font-weight:600;white-space:nowrap}
.fee-table td.f{font-family:var(--f-disp);font-size:var(--t-h4);color:var(--brown);white-space:nowrap}

.kit-hero{display:grid;grid-template-columns:.85fr 1.15fr;gap:var(--s7);align-items:center}
.kit-hero .shot{position:relative}
.kit-hero .shot img{width:100%;box-shadow:0 30px 60px rgba(20,14,10,.45);border:1px solid rgba(255,255,255,.08)}
.kit-price{display:flex;align-items:baseline;gap:14px;flex-wrap:wrap}
.kit-price .n{font-family:var(--f-disp);font-size:var(--t-big);font-weight:500;line-height:1;color:var(--cream)}
.kit-price .u{font-size:var(--t-label);font-weight:700;letter-spacing:var(--tr-label);
  text-transform:uppercase;color:var(--tan)}
.spread{display:grid;grid-template-columns:repeat(4,1fr);gap:18px}
.spread figure{margin:0}
.spread img{width:100%;border:1px solid var(--rule2);background:#fff;transition:.22s ease}
.spread figure:hover img{transform:translateY(-5px);box-shadow:0 16px 34px rgba(35,25,18,.16)}
.spread figcaption{font-size:var(--t-label);font-weight:700;letter-spacing:var(--tr-label);
  text-transform:uppercase;color:var(--soft);margin-top:12px}
.inside{display:grid;grid-template-columns:70px 1fr;gap:var(--s3) var(--s4);align-items:start}
.inside .pt{font-family:var(--f-disp);font-size:var(--t-h3);color:var(--brown);line-height:1.1}
.inside .bd{border-bottom:1px solid var(--rule);padding-bottom:var(--s3)}
.inside .bd:last-child{border-bottom:0}
.inside h3{margin:0 0 6px}
.inside p{font-size:var(--t-body);line-height:1.6;color:var(--muted);margin:0}
.forwho{display:grid;grid-template-columns:1fr 1fr;gap:20px}
.forwho .c{padding:28px 26px;border:1px solid var(--rule2);background:var(--card)}
.forwho .c.yes{border-left:5px solid var(--good)}
.forwho .c.no{border-left:5px solid var(--bad)}
.forwho .t{font-size:var(--t-label);font-weight:700;letter-spacing:var(--tr-label);
  text-transform:uppercase;margin-bottom:14px}
.forwho .yes .t{color:var(--good)}.forwho .no .t{color:var(--bad)}
@media(max-width:1000px){.spread{grid-template-columns:repeat(2,1fr)}}
@media(max-width:900px){.kit-hero,.forwho{grid-template-columns:1fr}.kit-hero{gap:var(--s5)}
  .inside{grid-template-columns:1fr;gap:var(--s2)}.inside .pt{font-size:var(--t-label);letter-spacing:var(--tr-label)}}

/* ---- click-to-enlarge -------------------------------------------------- */
.zoomer{display:block;width:100%;padding:0;border:0;background:none;cursor:zoom-in;position:relative}
.zoomer img{display:block}
.mag{position:absolute;left:50%;bottom:14px;transform:translateX(-50%) translateY(6px);
  background:rgba(0,0,0,.82);color:var(--cream);font-size:var(--t-label);font-weight:700;
  letter-spacing:var(--tr-label);text-transform:uppercase;padding:8px 14px;white-space:nowrap;
  opacity:0;transition:.2s ease;pointer-events:none}
.zoomer:hover .mag,.zoomer:focus-visible .mag{opacity:1;transform:translateX(-50%)}
.lb{position:fixed;inset:0;z-index:400;background:rgba(12,10,8,.94);display:flex;
  align-items:center;justify-content:center;flex-direction:column;gap:18px;padding:28px 20px 20px;
  opacity:0;pointer-events:none;transition:opacity .22s ease}
.lb.on{opacity:1;pointer-events:auto}
.lb img{max-width:min(94vw,760px);max-height:78vh;width:auto;height:auto;
  box-shadow:0 30px 70px rgba(0,0,0,.6);background:#fff}
.lb-cap{color:var(--onDark);font-size:var(--t-small);text-align:center;max-width:60ch;line-height:1.5}
.lb-count{color:var(--tan);font-size:var(--t-label);font-weight:700;letter-spacing:var(--tr-label);
  text-transform:uppercase}
.lb-x{position:absolute;top:16px;right:20px;background:none;border:0;color:var(--cream);
  font-size:34px;line-height:1;cursor:pointer;padding:10px;min-width:48px;min-height:48px}
.lb-nav{position:absolute;top:50%;transform:translateY(-50%);background:rgba(23,18,16,.7);
  border:1px solid var(--lineDark);color:var(--cream);width:52px;height:52px;cursor:pointer;
  font-family:var(--f-disp);font-size:24px;line-height:1;transition:.16s ease}
.lb-nav:hover{background:var(--brown);border-color:var(--brown)}
.lb-prev{left:14px}.lb-next{right:14px}
@media(max-width:900px){
  .lb img{max-height:66vh}
  .lb-nav{width:46px;height:46px}
  .mag{opacity:1;transform:translateX(-50%);font-size:9px;padding:6px 10px}
  /* The tracker shots are landscape, so on a phone the thumbnail is about a
     third the height of the portrait ones and this badge was covering the
     picture rather than sitting on it. There is no hover on a phone anyway,
     and the whole tile is the button. */
  .spread .zoomer img[height="562"] + .mag{display:none}
}

/* ---- density pass ------------------------------------------------------
   Every section carried 80px top and bottom, so 160px of nothing sat between
   each one and the pages ran far longer than the content justified. One token
   now controls the vertical rhythm across all thirteen pages. */
:root{--secY:38px;--secYs:30px;--wrap:1360px}

/* On a 2560px monitor a 1260px column left roughly 650px of nothing down each
   side, which read as a page that had not loaded properly rather than as air.
   The column now steps up with the screen. Prose does not get wider with it:
   every text block is capped in ch by .measure, .sec-head-l .lead, .callout p
   and friends, so what actually widens is the grids, the tables and the card
   rows, which is the part that was cramped. */
@media(min-width:1560px){ :root{--wrap:1480px} }
@media(min-width:1900px){ :root{--wrap:1620px} }
@media(min-width:2200px){ :root{--wrap:1760px} }
section{padding:var(--secY) 0}
.sec-head{margin-bottom:var(--s4)!important}
.sec-head-l,.sec-head-split{margin-bottom:var(--s4)}
.sec-head .lead,.sec-head-l .lead,.sec-head-split .lead{margin-top:8px}
.sec-head h2,.sec-head-l h2,.sec-head-split h2{line-height:1.08}
.hero-sm{padding:var(--s4) 0 var(--s3)}
/* 42px headings stacked to three lines and pushed every section head past
   250px on their own. 38 still reads as a display size and costs a line less. */
:root{--t-h2:clamp(26px,2.7vw,38px)}
.sec-head{max-width:74ch}
.sec-head-l,.sec-head-split{max-width:none}
.sec-head-l .lead{max-width:70ch}
.news{padding:var(--s5) 0}
.callout{padding:var(--s3) var(--s4)}
.callout p{max-width:78ch}
.callout .lbl{display:inline-block}
/* one or two creators should not sit in a third of the page looking lost,
   and a 9:11 crop made every card 950px tall */
.cgrid{justify-content:center}
.ctile .cimg{aspect-ratio:4/5}
/* the diagonal-stripe .cimg is the empty-state placeholder: flex, padded and
   bottom-aligned. A real photograph has to fill the frame instead. */
.ctile .cimg.shot{display:block;padding:0;background:var(--paper2)}
.ctile .cimg.shot img{width:100%;height:100%;object-fit:cover;object-position:50% 22%;display:block}
@media(max-width:900px){.cgrid{grid-template-columns:1fr}}

/* the first creator, on their own, as a feature rather than a lonely card */
.cfeat{display:grid;grid-template-columns:minmax(0,440px) 1fr;gap:var(--s5);
  align-items:center;max-width:1000px;margin:0 auto}
.cfeat .cshot{aspect-ratio:4/5;overflow:hidden;border:1px solid var(--rule2);
  background:var(--paper2)}
.cfeat .cshot img{width:100%;height:100%;object-fit:cover;object-position:50% 22%;display:block}
.cfeat h3{font-size:var(--t-h2);margin:4px 0 2px}
.cfeat .chandle{color:var(--brown);font-weight:600;margin-bottom:10px}
.cfeat .note{margin-top:4px}
@media(max-width:900px){
  .cfeat{grid-template-columns:1fr;gap:var(--s3)}
  .cfeat .cshot{max-width:340px}
}

/* a sample tile has to be unmistakably a sample */
.ctile.sample{border-style:dashed}
.ctile.sample .cimg{opacity:.75}
.samplenote{text-align:center;font-size:var(--t-small);color:var(--brown);
  margin:0 auto var(--s3);max-width:52ch}

/* ---- accordions in two columns ------------------------------------------
   Seven collapsed rows stacked one per line ate a whole screen for a list
   nobody had opened yet. Above 1000px they run in two columns, which halves
   the height without touching the type. */
@media(min-width:1000px){
  .faq{display:grid;grid-template-columns:1fr 1fr;column-gap:var(--s5);
    align-items:start;border-top:0}
  .faq details{border-top:1px solid var(--rule2)}
  .sec-deep .faq details,.sec-ink .faq details{border-top-color:var(--lineDark)}
  .faq details[open]{grid-column:1/-1}
}
.faq summary{padding:12px 4px}
.faq .a{padding:0 4px 14px}

/* forms: same fields, less air between them */
.form{gap:13px}
.field{gap:5px}
.field input,.field select{padding:9px 0}
.field textarea{min-height:86px}

/* three fields across, wrapping to one on a phone */
.row3{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s3)}
@media(max-width:900px){.row3{grid-template-columns:1fr}}

/* the fifth category tile is the point of the section, so it reads differently */
.g5{display:grid;grid-template-columns:repeat(5,1fr);gap:var(--s4)}
/* the work page before anyone has cleared their name */
.cempty{max-width:62ch;margin:0 auto;text-align:center;padding:var(--s5) var(--s4);
  background:var(--card);border:1px dashed var(--rule2)}
.cempty h3{font-size:var(--t-h3);margin:6px 0 14px}
.cempty p{color:var(--muted)}
.cempty .note{margin-top:16px}
.cempty a{color:var(--brown);text-decoration:underline;text-underline-offset:2px}

/* what you actually get, on the homepage cards */
.gets{list-style:none;margin:12px 0 0;padding:0;display:flex;flex-direction:column;gap:8px}
.gets li{position:relative;padding-left:19px;font-size:var(--t-small);line-height:1.5;
  color:var(--muted)}
.gets li::before{content:"";position:absolute;left:0;top:.55em;width:7px;height:7px;
  background:var(--brown)}
.gets strong{color:var(--ink);font-weight:600}
.card .btn{margin-top:16px;align-self:flex-start}
/* .hi is a light card with a brown border, not a dark one, so it keeps the
   same on-paper colours as its neighbours */

/* ---- work: categories as rows of real brand names ----------------------- */
.catrows{border-top:1px solid var(--rule2)}
.catrow{display:grid;grid-template-columns:230px 1fr 40px;gap:var(--s4);align-items:center;
  padding:var(--s3) 0;border-bottom:1px solid var(--rule2)}
.catrow h3{font-size:var(--t-h4);margin:0}
.catrow .note{margin-top:3px}
.tags{display:flex;flex-wrap:wrap;gap:7px}
.tags span{font-size:var(--t-label);font-weight:600;letter-spacing:.06em;text-transform:uppercase;
  color:var(--ink);background:var(--card);border:1px solid var(--rule2);padding:6px 11px;
  white-space:nowrap}
.catrow .cn{font-family:var(--f-disp);font-size:var(--t-h3);color:var(--brown);text-align:right;
  line-height:1;font-variant-numeric:tabular-nums}
@media(max-width:900px){
  .catrow{grid-template-columns:1fr auto;gap:var(--s2) var(--s3);padding:var(--s3) 0}
  .catrow .tags{grid-column:1/-1}
}

/* the band under the four that says a new category is not a problem */
.anycat{display:grid;grid-template-columns:1fr 1.25fr;gap:var(--s5);align-items:center;
  margin-top:var(--s5);padding:var(--s4);background:var(--card);border-left:3px solid var(--brown)}
.anycat h3{font-size:var(--t-h3);margin:6px 0 0;max-width:20ch}
.anycat p{font-size:var(--t-small);line-height:1.6;color:var(--muted);margin:0}
@media(max-width:900px){.anycat{grid-template-columns:1fr;gap:var(--s3);padding:var(--s3)}}

/* ---- how it runs: three steps that look like a sequence ----------------- */
.steps{position:relative;counter-reset:stp}
.step{display:grid;grid-template-columns:64px 1fr 1.25fr;gap:var(--s4);
  padding:var(--s4) 0;border-top:1px solid var(--rule2);align-items:start;position:relative}
.step .num{counter-increment:stp;font-family:var(--f-disp);font-size:var(--t-h3);
  color:var(--paper);line-height:1;display:flex;align-items:center;justify-content:center;
  width:52px;height:52px;background:var(--brown);border-radius:50%;font-variant-numeric:tabular-nums}
/* the thread running down through the numbers */
.step::before{content:"";position:absolute;left:26px;top:calc(var(--s4) + 52px);
  bottom:0;width:1px;background:var(--rule2)}
.step:last-child{border-bottom:1px solid var(--rule2)}
.step:last-child::before{display:none}
.step h3{font-size:var(--t-h3);margin:10px 0 0}
/* A .step is a three-column grid: number, heading, text. A single <p> lands in
   the text column by auto-placement, but a SECOND one wraps round into the
   number column and renders about one word per line. So splitting a long step
   into two paragraphs needs a wrapper, and the wrapper has to be told which
   column it is in. Without this, one page went from 10 phone screens to 15. */
.step > .prose{grid-column:3;min-width:0}
.step p{margin-top:12px}
.sec-deep .step,.sec-ink .step{border-color:var(--lineDark)}
.sec-deep .step::before,.sec-ink .step::before{background:var(--lineDark)}
@media(max-width:900px){
  .step{grid-template-columns:44px 1fr;gap:var(--s3);padding:var(--s3) 0}
  .step .num{width:40px;height:40px;font-size:var(--t-small)}
  .step h3{grid-column:2;margin:8px 0 0}
  .step > .prose{grid-column:2}
  .step p{grid-column:2}
  .step::before{left:20px;top:calc(var(--s3) + 40px)}
}

/* ---- accordions, at a sensible size ------------------------------------- */
.faq summary{font-size:17px}
.faq .a p{font-size:var(--t-small)}
.svc summary{font-size:var(--t-h4);padding:14px 4px}

/* ---- footer: same links, less of the screen ----------------------------- */
footer{padding:var(--s5) 0 var(--s4)}
.fnav{gap:var(--s4) var(--s5)}
.fcol{gap:7px;min-width:130px}
.fcol a{font-size:var(--t-fine)}
.fbrand{gap:11px}
.fbrand img{height:26px!important;width:auto!important}
.fbrand p{font-size:var(--t-fine);line-height:1.5}
.disclaim{margin-top:var(--s4);padding-top:var(--s3);line-height:1.6}
@media(max-width:900px){
  :root{--secY:var(--secYs)}
  footer{padding:var(--s4) 0 var(--s3)}
  .fnav{gap:var(--s3) var(--s4)}
}

/* ---- forms that open in place ------------------------------------------- */
.fmodal{position:fixed;inset:0;z-index:350;background:rgba(12,10,8,.82);backdrop-filter:blur(5px);
  display:flex;align-items:flex-start;justify-content:center;padding:5vh 20px;
  opacity:0;pointer-events:none;transition:opacity .22s ease;overflow-y:auto}
.fmodal.on{opacity:1;pointer-events:auto}
.fmbox{background:var(--inkBg);width:100%;max-width:620px;padding:44px 42px;position:relative;
  transform:translateY(16px);transition:transform .26s cubic-bezier(.2,.7,.3,1)}
.fmodal.on .fmbox{transform:none}
.fmbox h2{color:var(--cream);margin-bottom:10px}
.fmbox .lead{color:var(--onDark);margin-bottom:var(--s4)}
.fmbox .eyebrow{color:var(--tan)}
.fm-x{position:absolute;top:14px;right:16px;background:none;border:0;color:var(--cream);
  font-size:30px;line-height:1;cursor:pointer;min-width:48px;min-height:48px}
.fm-x:hover{color:var(--tan)}
.fm-alt{margin-top:var(--s4);padding-top:var(--s3);border-top:1px solid var(--rule2);
  font-size:var(--t-fine);line-height:1.6;color:#9C8A79}
.fm-alt a{color:var(--tan3);text-decoration:underline;text-underline-offset:2px}
/* whatever form gets copied in, it lays out the same way in here: one column,
   full-width fields, one full-width button. The newsletter form is a two-up
   flex row where it normally lives, which looked broken inside the box. */
.fmbox [data-fm-slot] form{display:flex;flex-direction:column;gap:16px;margin:0}
.fmbox [data-fm-slot] .fields,.fmbox [data-fm-slot] .row2{grid-template-columns:1fr}
.fmbox [data-fm-slot] input,.fmbox [data-fm-slot] textarea,.fmbox [data-fm-slot] select{
  width:100%;box-sizing:border-box}
.fmbox [data-fm-slot] .btn,.fmbox [data-fm-slot] button[type=submit]{
  width:100%;text-align:center}
.fmbox [data-fm-slot] label.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
/* The box is dark whatever the form looked like on the page. The rate-card form
   is styled .onLight because it sits on paper, and its near-black text vanished
   in here until you highlighted it. Everything in the slot is forced on-dark. */
.fmbox [data-fm-slot] input,.fmbox [data-fm-slot] textarea,.fmbox [data-fm-slot] select,
.fmbox [data-fm-slot] .field.onLight input,.fmbox [data-fm-slot] .field.onLight textarea,
.fmbox [data-fm-slot] .field.onLight select{
  color:var(--cream)!important;caret-color:var(--brown);border-bottom-color:var(--chartdim)!important;
  background:transparent}                                  /* 5.0:1 on --inkBg */
.fmbox [data-fm-slot] label,.fmbox [data-fm-slot] .field.onLight label{color:var(--tan)!important}
.fmbox [data-fm-slot] ::placeholder{color:var(--tan2);opacity:1}   /* 9.95:1 on --inkBg */
/* Whatever section the box clones from was written for the ground it sits on,
   which after the Warm Stone change is usually paper. Inside the box it is not,
   so every piece of copy that travels with the form is repointed on-dark too.
   Found by opening the pop-out on all 54 pages, not by reading the markup. */
.fmbox [data-fm-slot] p,.fmbox [data-fm-slot] li,.fmbox [data-fm-slot] .note,
.fmbox [data-fm-slot] .small,.fmbox [data-fm-slot] .lead{color:var(--onDark)}
.fmbox [data-fm-slot] h2,.fmbox [data-fm-slot] h3,.fmbox [data-fm-slot] h4,
.fmbox [data-fm-slot] strong,.fmbox [data-fm-slot] b{color:var(--cream)}
.fmbox [data-fm-slot] .lbl,.fmbox [data-fm-slot] .eyebrow,
.fmbox [data-fm-slot] span.label,.fmbox [data-fm-slot] legend{color:var(--tan)}
.fmbox [data-fm-slot] a{color:var(--tan3)}
.fmbox [data-fm-slot] option{background:var(--inkBg);color:var(--cream)}
.fmbox [data-fm-slot] :focus{border-bottom-color:var(--tan)!important}
/* Chrome paints autofilled fields pale blue with black text */
.fmbox [data-fm-slot] input:-webkit-autofill{
  -webkit-text-fill-color:var(--cream);caret-color:var(--brown);
  -webkit-box-shadow:0 0 0 40px var(--inkBg) inset;transition:background-color 9999s}
.fmbox [data-fm-slot] .form-msg{margin-top:14px}
@media(max-width:900px){.fmbox{padding:34px 22px}.fmodal{padding:2vh 12px}}

/* ============================================================
   REFINEMENT PASS — contrast, focus, motion, and four pieces
   of polish. Nothing here invents a colour: every value is an
   existing token, or a token promoted out of a hard-coded
   value that was already in this sheet.
   ============================================================ */
:root{
  /* --field was already the calculator's input colour, written twice as a raw
     hex. Naming it lets the newsletter field use the same on-dark field. */
  --field:var(--lineDark);
  /* the focus ring. One token, reassigned per ground below, so a ring is
     never painted in a colour the ground swallows. */
  --focus:var(--brown);
  /* how far the brand marquee fades out at each edge */
  --mqFade:clamp(56px,7vw,150px);
}

/* ---- 1. WCAG AA: light-ground tokens sitting on dark grounds ------------
   All three failures were the same mistake — a colour picked for cream paper
   used on a brown or near-black panel. Fixed with the on-dark tokens that
   already exist, not with new colours. Ratios measured, not estimated. */

/* the "08" step number: --brown on var(--rule2) was 1.73:1 */
.prod.cta .prod-n{color:var(--tan)}                              /* 5.54:1 */
/* its arrow icon had the same problem and is not text, so no audit caught it */
.prod.cta .prod-ico rect,.prod.cta .prod-ico circle,.prod.cta .prod-ico path,
.prod.cta .prod-ico line,.prod.cta .prod-ico polyline{stroke:var(--tan)}
.prod.cta .prod-ico .fill{fill:var(--tan)}
/* "· 15 mins": --soft on --deep was 2.3:1 */
.prod.cta .prod-price small{color:var(--tan2)}                   /* 7.79:1 */
/* these two only reach a legible colour through an inline style in the page.
   Stated here as well so the card survives that style being tidied away. */
.prod.cta .prod-body>.lbl,.prod.cta .prod-who .lbl{color:var(--tan)}
/* marquee separator: --tan on --paper2 was 1.8:1 */
.mqd{color:var(--brown)}                                         /* 5.76:1 */
/* The same dot in the static fallback, which is what anyone with Reduce Motion
   switched on actually sees. It moves from the front of the FOLLOWING name to
   the back of the PRECEDING one at the same time: the static list wraps over
   five lines on a phone, and a leading dot was starting three of them. Hung off
   the name before it, a dot can never begin a line. Same position, same gap. */
.mqstatic span+span::before{content:none}
.mqstatic span:not(:last-child)::after{content:"";position:absolute;right:-1px;top:50%;
  transform:translateY(-50%);width:3px;height:3px;background:var(--brown);border-radius:50%}

/* ---- 2. the focus ring, per ground --------------------------------------
   :focus-visible painted --brown everywhere. On --deep that is 1.98:1, on
   --ink 2.49:1, and on --brown itself 1:1 — an invisible focus ring on every
   dark band, every dialog, the header, the footer and both marquee-adjacent
   forms. --focus inherits, so it is set once per ground and everything
   nested inside picks it up. */
.sec-deep,.sec-ink,.hero,.hero-sm,.news,.calc,header,footer,
.door-ink,.prod.cta,.callout,.coverwrap,.darkpanel,
.modal,.fmodal,.lb{--focus:var(--tan)}
/* on brown, --tan only reaches 3.2:1; cream is unambiguous at 7.5:1 */
.sec-brown,.door-brown,.tier.feature,.sec-brown .sell{--focus:var(--cream)}
/* light panels sitting inside a dark section hand the brown ring back */
.modal-box,.sec-deep .callout,.sec-ink .callout,.hero-sm .callout,.formcard,
.sec-deep .card,.sec-ink .card,.sec-deep .prod,.sec-ink .prod{--focus:var(--brown)}
:focus-visible{outline:2px solid var(--focus);outline-offset:3px}
/* Form fields had outline:0 on :focus at a specificity that beat
   :focus-visible, so a keyboard user got no ring at all on any input on the
   site — only a 1px border tint. The ring comes back here, at a specificity
   that wins, while the border tint stays. */
.field input:focus-visible,.field textarea:focus-visible,.field select:focus-visible,
.news input:focus-visible,#alerts input:focus-visible,.calc select:focus-visible,
.calc input:focus-visible,
.fmbox [data-fm-slot] :focus-visible{outline:2px solid var(--focus);outline-offset:3px}

/* ---- 3. the layout shift on the homepage feature ------------------------
   .feat collapses to one column with justify-items:start, which makes the
   anchor shrink-to-fit. max-width gave it nothing to fit to, so it rendered
   at 2x2 — the border and no content — until the cover loaded, then jumped
   to 180x254. A definite width reserves the box, and the img's width/height
   attributes supply the ratio, so the height is reserved with it. */
@media(max-width:900px){
  .feat-img{width:min(180px,100%);max-width:none}
}

/* ---- 4. the marquee no longer hits the viewport edge with a hard cut -----
   A brand name sliced mid-word against nothing is the one cheap-looking
   thing on the page. Both edges now fade into the ground.
   .mq is display:none under prefers-reduced-motion and under 900px, so this
   never touches the .mqstatic fallback — the frozen-marquee path stays
   exactly as it was. */
.mq{
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 var(--mqFade),
    #000 calc(100% - var(--mqFade)),transparent 100%);
          mask-image:linear-gradient(90deg,transparent 0,#000 var(--mqFade),
    #000 calc(100% - var(--mqFade)),transparent 100%);
}

/* ---- 5. the newsletter field looks like a field --------------------------
   A transparent box with a --lineDark hairline under it read as loose text
   on the dark band. It now uses the same on-dark field the calculator has
   used all along, so this is the site's existing field language, not a new
   one, and it stands the same height as the button beside it. */
.news form{align-items:stretch}
.news input,#alerts input{background:var(--field);border:1px solid var(--lineDark);
  color:var(--cream);padding:13px 16px}
.news input::placeholder,#alerts input::placeholder{color:var(--tan2);opacity:1}   /* 5.85:1 */
.news input:focus,#alerts input:focus{border-color:var(--tan)}

/* ---- 6. the recommended tier looks recommended ---------------------------
   .hi differed from its neighbours by one pixel of border. Its own eyebrow
   becomes a chip — the same chip the callouts already use — pulled flush to
   the card's left edge, with the vertical padding cancelled so the heading
   still lines up with the two cards either side. Plus a resting shadow, so
   it sits a little forward of them before anyone hovers anything. */
.card.hi{box-shadow:0 12px 30px rgba(35,25,18,.11)}
.card.hi:hover{box-shadow:0 20px 42px rgba(35,25,18,.18)}
.card.hi .tag{color:var(--paper);background:var(--brown);   /* 6.57:1 */
  align-self:flex-start;padding:7px 14px;margin:-7px 0 -7px -28px}
@media(max-width:380px){.card.hi .tag{margin-left:-28px}}

/* ---- 7. hover states that were not snapping ------------------------------
   .prod-top repaints to --brown on hover with no transition on it, so the
   header of every service card flicked instead of turning. */
.prod-top{transition:background-color .22s ease}

/* ---- 2b. two grounds the ground-class list cannot reach ------------------
   A .door is itself the link, full-bleed on its own dark panel, so its ring
   has to paint inside it — offset outwards it would land on the cream
   section behind, or on the neighbouring door, since .doors has no gap. */
.door:focus-visible{outline-offset:-5px}
/* The on-dark form is the .field component, and it appears inside panels that
   carry their ground as an inline style rather than a class, so it has to
   claim the ring itself. .field.onLight is the one variant that sits on paper,
   and a form holding those is a form on paper — including its submit button,
   which is a child of the form and not of any field. */
/* Deleted 2 Sept 2026: .form,.field{--focus:var(--tan)}. On the near-black
   palette every form was on a dark ground; now most are on paper, where --tan
   is 2.01:1. The ring falls through to the :root --brown on paper, and the
   ground classes above still hand --tan to the forms that are on a dark band. */
.field.onLight,.form:has(.field.onLight){--focus:var(--brown)}
/* except in the pop-out box, where every field is forced on-dark anyway */
.fmbox [data-fm-slot] .field.onLight,
.fmbox [data-fm-slot] .form:has(.field.onLight){--focus:var(--tan)}

/* ============================================================
   HANDOFFS — four things the other agents found.
   ============================================================ */

/* ---- 8. WCAG 1.4.1 (Level A): links told apart by colour alone -----------
   In running prose the text around a link is --muted and the link is --brown:
   1.38:1 between them. A normal contrast audit misses this because both are
   fine against the paper — the failure is link against SURROUNDING TEXT. The
   sheet already answers this in .callout, .disclaim and .cempty with an
   underline, so that is the pattern extended, not a new one.

   Scoped to running text inside <main>. A link that is its own block — a nav
   item, a footer column, a button, a door, a card's call to action — is told
   apart by position and styling and must not pick up a rule here, which is
   why this keys off p / li / dd / figcaption / table cells rather than off a.
   Measured before: 9 distinct contexts, 30 links, worst 1:1. */
main p a:not(.btn),main li a:not(.btn),main dd a:not(.btn),
main figcaption a:not(.btn),main td a:not(.btn),main th a:not(.btn){
  text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:2px}
/* the non-colour cue on hover and focus: the rule thickens */
main p a:not(.btn):hover,main li a:not(.btn):hover,main dd a:not(.btn):hover,
main figcaption a:not(.btn):hover,main td a:not(.btn):hover,main th a:not(.btn):hover,
main p a:not(.btn):focus-visible,main li a:not(.btn):focus-visible{
  text-decoration-thickness:2px}

/* ---- 9. the portrait slot on About --------------------------------------
   Replaces .ph.tall in the #story column when Rocky's photograph lands. The
   box is reserved from the ratio, not from the file, so this cannot repeat
   the .feat-img shift: the space is held whether the image has loaded, is
   still loading, or never arrives. object-fit means a photograph that is not
   exactly 4:5 crops instead of reflowing the page around it. */
.portrait{display:block;width:100%;height:auto;aspect-ratio:4/5;object-fit:cover;
  object-position:50% 22%;background:var(--paper2);border:1px solid var(--rule2)}

/* ---- 10. the face on the homepage dark band ------------------------------
   Degrades to nothing: with no <img> inside it the element does not render at
   all, so the band looks finished rather than empty. On --deep it gets the
   plate treatment the Starter Kit hero already uses — hairline and a deep
   shadow — rather than a border that would read as a box. */
:root{--plateLine:rgba(255,255,255,.08)}
.kit-hero .shot img{border-color:var(--plateLine)}
.hero-face{display:none}
.hero-face:has(img){display:block;max-width:290px;margin:0 auto var(--s5)}
.hero-face img{display:block;width:100%;height:auto;aspect-ratio:4/5;object-fit:cover;
  object-position:50% 22%;background:var(--panel);
  border:1px solid var(--plateLine);box-shadow:0 26px 54px rgba(12,9,7,.5)}

/* ---- 11. .row3 stops crushing its own labels -----------------------------
   Three equal columns of a 546px form panel are 169px each. "Link to your
   deck or brief" needs about 230px as an 11px tracked label, so it wrapped to
   two lines, and its placeholder needs 237px, so it was cut mid-word. Three
   across when three genuinely fit, fewer when they do not — which also stops
   the next field added to a .row3 hitting the same wall. */
.row3{grid-template-columns:repeat(auto-fit,minmax(230px,1fr))}
/* a three-field row will not fit three across in a 546px form panel, so it
   sits two-up with the third laid across the bottom rather than stranded in
   half a row. Keyed off "the third field is the last one", so a .row3 with a
   different number of fields falls back to the auto-fit line above. */
@media(min-width:900px){
  .row3:has(> :nth-child(3):last-child){grid-template-columns:1fr 1fr}
  .row3:has(> :nth-child(3):last-child) > :last-child{grid-column:1/-1}
}
/* and a placeholder longer than its box now reads as truncated rather than
   sliced through a letter */
.field input,.field select,.news input{text-overflow:ellipsis}

/* ============================================================
   DENSITY, SCALE AND SHARPENING — pass E
   ------------------------------------------------------------
   Rocky: "this website is so big ... the text, the sections,
   the headers, the footers." Measured: 114 phone screens across
   eleven pages, 22.4 of them on Services alone.

   Nothing here deletes a word. The height comes out of four
   places, in this order of yield:
     1. line-height, and one step off the body size
     2. grids that collapsed to one column while two or four
        still fitted
     3. image and placeholder boxes reserving square footage
        they never needed
     4. component padding

   Everything new is a token. No font-size lands in markup.
   ============================================================ */

:root{
  /* One step down on body, and a leading that reads as edited
     prose rather than as a draft. 16px is the floor and this
     sits on it: density below that costs readability, which is
     not a trade worth making. */
  --t-body:16px;
  --t-lead:clamp(17px,1.05vw,19px);
  --lh-body:1.5;
  --lh-lead:1.46;
  --lh-copy:1.46;          /* dense card copy: .small and its family */
  --lh-head:1.12;
  --lh-tight:1.04;
  /* sharper, more architectural display setting */
  --tr-disp:-.022em;
  --tr-label:.16em;

  /* the spacing scale, one notch tighter throughout */
  --s2:12px; --s3:18px; --s4:24px; --s5:34px; --s6:46px; --s7:64px;

  /* header height, declared so the anchor offset can track it */
  --hdrH:62px;
}

/* ---- 1. leading -------------------------------------------------------
   Twenty-odd components hard-coded 1.55 to 1.7. Restated once against a
   token so the whole sheet has one rhythm instead of nine. */
.small,.small.small.small,.door p,.tier p,.vrow p,.svc .who,.fbrand p,
.jbody p,.cat p,.sell p,.form-msg,.pcard p,.cb p,.band .why,.mult p,
.prod-who span.w,.gets li,.tier li,.bar .mean,.anycat p,.lb-cap,
.samplenote,.specs dd,.kv p,.dash.small li{line-height:var(--lh-copy)}
.callout p,.proof .cap,.step p,.svc .body p,.card p,.pillar p,.dash li,
.inside p,.modal p,.prod-desc,.faq .a p,.fee-table td,.cempty p,
.calc-note,.note,.note.note.note,.disclaim{line-height:var(--lh-body)}
.lead,.lead.lead.lead{line-height:var(--lh-lead)}
.mqi{line-height:1.15}

/* ---- 2. the header ----------------------------------------------------
   74px of permanent chrome on every page, and the first thing Rocky
   named. Twelve pixels come out of it outright, and it now gets out of
   the way while you read down a long page and returns the moment you
   scroll up. It moves on a transform, so it shifts nothing in the
   layout and cannot cost a point of CLS. */
.nav{padding:11px 32px}
.nav img{height:28px}
header{transition:transform .26s cubic-bezier(.3,.7,.2,1),box-shadow .26s ease,border-color .26s ease}
header.hdr-off{transform:translateY(-100%)}
/* the scrolled state is a sharper edge, not a different size */
header.hdr-scrolled{box-shadow:0 10px 30px rgba(12,9,7,.30);border-bottom-color:var(--brown)}
/* an anchor no longer lands underneath the sticky bar */
html{scroll-padding-top:calc(var(--hdrH) + 8px)}
@media(prefers-reduced-motion:reduce){
  header{transition:none}
  header.hdr-off{transform:none}   /* never moves for anyone who asked it not to */
}

/* ---- 3. the footer ----------------------------------------------------
   Four columns that stacked into six rows on a phone. Two columns, a
   tighter link rhythm, and a brand block that no longer claims a row of
   its own. Every link keeps its touch target: the padding does that
   work, the leading does not. */
footer{padding:var(--s5) 0 var(--s4)}
.fcol{gap:2px;min-width:120px}
.fcol .lbl{margin-bottom:5px}
.fcol a{font-size:var(--t-fine);line-height:1.35;display:block;padding:3px 0}
.fbrand{gap:9px}
.fbrand p{font-size:var(--t-fine)}
.disclaim{margin-top:var(--s4);padding-top:var(--s3)}
.disclaim p+p{margin-top:7px}
@media(max-width:900px){
  .fnav{display:grid;grid-template-columns:1fr 1fr;gap:var(--s4);align-items:start}
  .fbrand{grid-column:1/-1;max-width:46ch}
  .fcol a{padding:6px 0}
  footer{padding:var(--s4) 0 var(--s3)}
}

/* ---- 4. grids that gave up too early ----------------------------------
   Below 900px every grid in the sheet collapsed to a single column,
   including ones whose items are 60px tall. Where two still fit at
   360px, two is what they get. */
@media(max-width:900px){
  .row2{grid-template-columns:1fr 1fr;gap:12px}
  .specs{gap:10px 18px}
  .g2,.g3{gap:var(--s4)}
  .g4,.kv{gap:var(--s3)}
  .stack{gap:14px}
  .stack-s{gap:10px}
}
/* the pop-out form box stays one column whatever the page does */
.fmbox [data-fm-slot] .row2{grid-template-columns:1fr}

/* ---- 5. the service grid ----------------------------------------------
   Eight services in three columns ran to three rows of about 970px, each
   under a square photograph. Four columns is two rows, and a 3:2 plate is
   a photograph rather than a tile. The page now reads as a price list you
   can take in, which is the one job it has. */
@media(min-width:1080px){.pgrid{grid-template-columns:repeat(4,1fr);gap:18px}}
.prod-img,.pcard img{aspect-ratio:3/2}
.prod-body{padding:20px;gap:9px}
.prod-top{padding:16px 20px}
.prod .btn{margin:0 20px 20px}
.prod-who{padding-top:12px}
.prod-price{line-height:.95}
@media(max-width:900px){
  .prod-body{padding:18px}
  .prod .btn{margin:0 18px 18px}
  .prod-top{padding:14px 18px}
}

/* ---- 6. cards, tiers and panels: same components, less upholstery ------ */
.card{padding:22px 20px;gap:9px}
.card .btn{margin-top:12px}
.tier{padding:24px 22px;gap:10px}
.tier ul{gap:7px;padding-top:12px}
.tier li{gap:9px}
.sell{padding:20px 18px;gap:7px}
.sells{gap:12px}
.pcard .pb{padding:18px;gap:7px}
.pcard .price{padding-top:10px}
.pcard .btn{margin-top:12px}
.jbody{padding:18px;gap:7px}
.cb{padding:18px 16px;gap:6px}
.ctile .btn{margin:0 16px 16px}
.band{padding:20px 18px;gap:8px}
.mult{padding:20px 18px}
.cat{padding:18px 20px;gap:8px}
.gets{gap:6px;margin-top:9px}
.dash{gap:9px}
.callout{padding:var(--s3) var(--s4)}
.pillar{padding-top:var(--s2)}
.door{padding:var(--s5) 44px;gap:14px;min-height:300px}
@media(max-width:900px){
  .door{padding:30px 22px;gap:11px;min-height:0}
  .card{padding:20px 18px}
  .tier{padding:22px 20px}
}

/* ---- 7. placeholders stop reserving a whole screen --------------------
   .ph and .jthumb are the diagonal-stripe empty states. Four of them in
   a .row2 were 1,062px of nothing on a phone. They keep their shape,
   they just stop holding a screenful of it. */
.ph{min-height:190px;padding:12px}
.ph.tall{min-height:330px}
.ph.down{margin-top:22px}
.heroimg{height:230px;margin-top:var(--s5)}
.coverwrap{padding:34px;min-height:0}
@media(max-width:900px){
  .ph{min-height:150px}
  .ph.tall{min-height:250px}
  .ph.down{margin-top:12px}
  .heroimg{height:160px}
  .coverwrap{padding:24px}
}

/* ---- 8. the Journal index, as an index --------------------------------
   Twelve cards, each a 170px stripe above a stacked title. On a phone
   they are rows now: a square plate, the headline beside it, the meta
   under it. It is the shape a contents page has always been, and it is
   130px a card shorter. */
@media(max-width:700px){
  /* a 92px side column crops a designed cover into a stripe, so the image
     goes full width and loses a little height instead */
  .jcard{display:flex}
  .jthumb{aspect-ratio:1200/500}
  .jbody{padding:20px 18px;gap:8px}
  .jgrid{gap:14px}
}

/* ---- 9. heroes and section heads --------------------------------------
   Two full-width stacked buttons under every hero cost 110px for two
   words. Side by side they cost 48px and look decided. */
.hero{padding:var(--s6) 0 0}
.hero h1{margin:var(--s3) auto var(--s2)}
.hero-sm h1{margin:var(--s2) auto var(--s2)}
.sec-head{margin-bottom:var(--s4)!important}
.sec-head .lead,.sec-head-l .lead,.sec-head-split .lead{margin-top:6px}
.btn-row{margin-top:var(--s3);gap:10px}
.hero .btn-row{margin:var(--s4) 0 var(--s1)}
@media(max-width:900px){
  .hero,.hero-sm{padding-top:var(--s5)}
  .hero .btn-row,.hero-sm .btn-row{flex-direction:row;flex-wrap:wrap;justify-content:center}
  .hero .btn-row .btn,.hero-sm .btn-row .btn{width:auto;flex:1 1 auto;min-width:0}
  .btn{padding:14px 18px}
}
/* at the very narrowest, two tracked labels will not share a line */
@media(max-width:359px){
  .hero .btn-row .btn,.hero-sm .btn-row .btn{flex:1 1 100%}
}

/* ---- 10. the brand banner --------------------------------------------- */
.mq{padding:9px 0}
@media(max-width:900px){
  .mqstatic span{padding:6px 11px;line-height:1.25}
}

/* ---- 11. forms, the calculator and the newsletter ---------------------- */
.form{gap:11px}
.field{gap:4px}
.field textarea{min-height:76px}
.news{padding:var(--s5) 0}
.news form{margin-top:var(--s3)}
.calc{padding:30px 28px}
.calc-grid{gap:16px}
.calc label{margin-bottom:6px}
.calc-out{margin-top:20px;padding-top:18px}
.calc-note{margin-top:10px}
@media(max-width:900px){
  .calc{padding:22px 18px}
  .field textarea{min-height:88px}
}

/* ---- 12. steps, rows and tables ---------------------------------------- */
.step{padding:var(--s3) 0;gap:var(--s4)}
.step h3{margin:6px 0 0}
.step p{margin-top:8px}
.catrow{padding:var(--s2) 0}
.inside .bd{padding-bottom:var(--s2)}
.inside{gap:var(--s2) var(--s4)}
.vrow{padding:11px 0}
table.rt th,table.rt td{padding:11px 16px}
.fee-table th,.fee-table td{padding:11px 16px}
.bar{padding:13px 16px}
.faq summary{padding:11px 4px}
.faq .a{padding:0 4px 12px}
.svc summary{padding:12px 4px}
.svc .body{padding-bottom:20px}
.anycat{margin-top:var(--s4);padding:var(--s3)}
.tabs{margin-bottom:var(--s4)}
.tab{padding:13px 22px}

/* ============================================================
   DENSITY PASS E — second cut
   ------------------------------------------------------------
   The first cut took the obvious height out. This one takes the
   chrome: section rhythm, page gutters, card upholstery, the
   footer's link rhythm, and the last of the loose leading.

   What is deliberately NOT touched, because Rocky asked for a
   page that reads as MORE designed rather than smaller:
     - the heading scale. h1 36 / h2 26 / h3 23 over a 16px body
       is what makes a phone screen scannable. Shrinking the
       headings would have bought 933px and cost the hierarchy
       that is doing the work.
     - the label tracking. .16em on an 11px uppercase label is
       the house voice.
     - anything below 16px in running copy.
   ============================================================ */

:root{
  /* 1.5 was set for a 17px body. At 16px the same colour of text
     comes at 1.45, which is 11 lines back on a long page. */
  --lh-body:1.45;
  --lh-copy:1.44;
  --lh-lead:1.44;
}

/* The service plates are square artwork with the service name set into
   the middle of the frame, so the crop stays centred — the default. What
   they cannot survive is a 2:1 window, which shows half the square and
   slices a three-line title through the middle. One ratio, 3:2, at every
   width: it is the shortest window the artwork actually fits in. */

/* the newsletter band, on eight of the eleven pages */
.news .inner,#start .inner,#alerts .inner,.formsec .inner{gap:var(--s3)}
.news form{margin-top:14px}

/* ---- desktop rhythm --------------------------------------------------- */
@media(min-width:901px){
  :root{--secY:32px}
  .wrap{padding:0 28px}
}

/* ---- phone ------------------------------------------------------------- */
@media(max-width:900px){
  :root{--secY:24px}
  /* 22px gutters on a 390px screen cost a character a line on every
     paragraph in the site. 18 still reads as a margin. */
  .wrap{padding:0 18px}

  .btn{min-height:44px;padding:13px 16px}
  .btn-row{margin-top:14px;gap:9px}
  .stack{gap:12px}
  .g2,.g3{gap:var(--s3)}
  .sec-head{margin-bottom:var(--s3)!important}
  .sec-head-l,.sec-head-split{margin-bottom:var(--s3)}
  .hero,.hero-sm{padding-top:26px}
  .hero h1,.hero-sm h1{margin:10px auto}

  /* upholstery: 16-18px is the floor at which a card still reads
     as a card rather than as a box drawn round some text */
  .callout{padding:16px 18px}
  .sell{padding:17px 16px}
  .card{padding:18px 16px}
  .tier{padding:18px 17px}
  .prod-body{padding:16px}
  .prod .btn{margin:0 16px 16px}
  .jbody{padding:13px 15px}
  .pcard .pb{padding:16px}
  .cb{padding:15px 14px}
  .band,.mult{padding:17px 15px}
  .cat{padding:15px 16px}
  .ph{min-height:130px}
  .ph.tall{min-height:210px}

  /* four short panels sat one per row for 850px. Two per row is
     two rows, and they are panels, not paragraphs. */
  .sells{grid-template-columns:1fr 1fr;gap:10px}
  /* three figures, three columns — this is the one block on the
     site that is SUPPOSED to read as a row of numbers */
  .proof{grid-template-columns:repeat(3,1fr);gap:14px}
  .proof .fig{margin-bottom:8px}
  .proof .lbl{margin-bottom:8px}
  .g4,.g5{grid-template-columns:1fr 1fr}

  /* footer */
  .fnav{gap:16px 18px}
  .fcol a{padding:3px 0;line-height:1.3}
  .fcol .lbl{margin-bottom:3px}
  footer{padding:20px 0 15px}
  .disclaim{margin-top:16px;padding-top:14px}
  .news{padding:26px 0}
}

/* ---- multi-column blocks: never below their own min-content ------------
   1fr has a min-content floor, so a two-up .sells at 320px was pushed
   38px past the viewport by the widest word in it. minmax(0,1fr) lets the
   track actually shrink, and the narrowest phones keep the single column
   they were always going to need. Measured at 320/360/375/390/430/768. */
@media(max-width:900px){
  .sells,.proof,.g4,.g5{grid-template-columns:1fr}
}
@media(min-width:361px) and (max-width:900px){
  .sells{grid-template-columns:repeat(2,minmax(0,1fr))}
  .g4,.g5{grid-template-columns:repeat(2,minmax(0,1fr))}
  .proof{grid-template-columns:repeat(3,minmax(0,1fr))}
}
@media(max-width:900px){
  .row2{grid-template-columns:repeat(2,minmax(0,1fr))}
}

/* ---- the proof strip, as a set of rows ---------------------------------
   Three figures side by side on a 390px screen gave each caption a 105px
   column and four two-word lines. As rows — the figure held in a fixed
   column, the label and the caption beside it, hairlines between — it is
   the same height, reads as a record rather than as three squeezed
   columns, and the numerals line up with each other. */
@media(max-width:900px){
  :root{--t-big:38px}
  .proof{grid-template-columns:1fr;gap:0}
  .proof>div{display:grid;grid-template-columns:108px minmax(0,1fr);
    column-gap:16px;row-gap:2px;align-items:start;padding:13px 0;
    border-top:1px solid var(--lineDark)}
  .proof>div:last-child{border-bottom:1px solid var(--lineDark)}
  .proof .fig{grid-row:1/span 2;margin-bottom:0}
  .proof .lbl{margin-bottom:2px}
}

/* ============================================================
   SHARPENING PASS E — the "futuristic" half of the brief
   ------------------------------------------------------------
   Read as: more precisely engineered. Not neon, not glass, not
   rounded, not dark-mode. Everything below is either an optical
   correction or a state change made more decisive.
   ============================================================ */

/* ---- 1. every figure on the site lines up ------------------------------
   These are prices, fees, multipliers and counts. Proportional numerals
   put a 1 and a 7 on different widths, so a column of prices read as
   ragged even though it was aligned. Tabular figures are what a price
   list has always used. */
.prod-price,.tier .price,.pcard .price,.feat-price,.calc-num,.band .fee,
.mult .x,.bar .add,.proof .fig,.kit-price .n,.fee-table td.n,.fee-table td.f,
.inside .pt,.step .num,.svc .pl,.cover .ttl{font-variant-numeric:tabular-nums}

/* ---- 2. no orphans in running copy -------------------------------------
   text-wrap:pretty asks the browser to avoid leaving one word alone on
   the last line. Headings already balance; this is the paragraph half.
   Browsers that do not support it ignore the declaration and nothing
   changes, so there is nothing to fall back to. */
.lead,.prose p,.card p,.prod-desc,.callout p,.faq .a p,.step p,
.sell p,.pcard p,.jbody p,.cb p,.cat p,.band .why,.mult p,.proof .cap,
.dash li,.gets li,.note,.small{text-wrap:pretty}

/* ---- 3. state changes that snap ----------------------------------------
   Every card lifted 4-5px over 220ms, which reads as floating. Half the
   travel at two thirds the duration reads as a mechanism: the card
   registers the pointer rather than drifting under it. The shadow and
   the border still carry the depth. */
.card,.tier,.prod,.pcard,.jcard,.ctile,.band,.mult,.cat,.sell,
.spread figure img,.feat-img{transition-duration:.15s}
.card:hover,.pcard:hover,.jcard:hover,.ctile:hover,.band:hover,
.mult:hover,.sell:hover,.spread figure:hover img,.feat-img:hover{
  transform:translateY(-3px)}
.prod:hover,.tier:hover{transform:translateY(-3px)}
.btn{transition-duration:.15s}
.btn:hover{transform:translateY(-1px);box-shadow:0 5px 14px rgba(35,25,18,.22)}
/* the accordion arrow and the tab underline are the two places a state
   change is the only feedback, so they get the crispest timing */
.tab{transition:color .12s ease,border-color .12s ease}
.faq summary,.svc summary{transition:color .12s ease,background-color .12s ease}

/* ---- 4. plates that were reserving more than they needed ---------------
   The guide cover, the creator portrait and the hero band are display
   objects, not content. They keep their proportions at a size that fits
   a phone screen alongside the text they belong to. */
@media(max-width:900px){
  .cover{max-width:225px}
  .coverwrap{padding:18px}
  .cfeat .cshot{max-width:250px}
  .heroimg{height:140px}
  .news{padding:22px 0}
  .news .inner,#start .inner,#alerts .inner,.formsec .inner{gap:14px}
  .calc{padding:18px 16px}
  .calc-grid{gap:12px}
  .tabs{margin-bottom:16px}
  .tab{padding:12px 14px}
}

/* ============================================================
   HANDOFFS TAKEN BACK IN — pass E
   ============================================================ */

/* ---- A. an anchor no longer lands under the sticky bar ------------------
   Measured: every in-page link on the site dropped its target 59-77px
   behind the header, and F has just added a jump index to services that
   makes it obvious. The header does not change height on scroll — it
   translates out of the way — so one offset per breakpoint is correct and
   there is nothing to overcorrect for.

   Header measured: 64px above 900, 67px below it, 76px at 320 where the
   bar wraps. scroll-padding-top drives fragment navigation; the
   scroll-margin-top on the targets themselves covers scrollIntoView and
   the browsers that honour only that. */
:root{--hdrH:64px}
@media(max-width:900px){:root{--hdrH:68px}}
@media(max-width:360px){:root{--hdrH:77px}}
html{scroll-padding-top:calc(var(--hdrH) + 10px)}
[id]{scroll-margin-top:calc(var(--hdrH) + 10px)}

/* ---- B. links on the dark grounds the rule list missed -----------------
   .sec-deep / .sec-ink / .news were covered. .hero, .hero-sm, .calc and
   .sec-brown were not, so a plain <a> in any of them painted --brown:
   1.98:1 on --deep, 1:1 on --brown. No such link exists in the markup
   today, which is why no audit caught it — it is a trap for the next
   person to put one there, and it is what stopped F adding a contents
   nav to the small hero.
     --tan3 var(--tan3) on --deep var(--panel)  = 11.6:1
     --tan3 var(--tan3) on --brown var(--brown2) =  5.8:1
   Buttons keep their own colours: a.btn.* is already stated at a
   specificity this cannot reach. */
.hero a,.hero-sm a,.calc a,.sec-brown a,.coverwrap a{color:var(--tan3)}
.hero a:hover,.hero-sm a:hover,.calc a:hover,
.sec-brown a:hover,.coverwrap a:hover{color:#fff}
/* the breadcrumb keeps the quieter tan it was designed in (7.4:1) */
.hero-sm .crumb a,.hero .crumb a{color:var(--tan)}
.hero-sm .crumb a:hover,.hero .crumb a:hover{color:var(--cream)}

/* ---- C. the service grid tiles to the number of services there are -----
   Four columns was right for eight tiles: two clean rows. F has since
   cut the grid to six, which tiled 4+2 and left a ragged row. Six wants
   three. The rule keys off the seventh child, so the grid re-tiles
   itself if the number of services changes again — 3 up to six, 4 from
   seven, and nobody has to remember to come back and edit this. */
@media(min-width:1080px){
  .pgrid{grid-template-columns:repeat(3,minmax(0,1fr));gap:20px}
  .pgrid:has(> :nth-child(7)){grid-template-columns:repeat(4,minmax(0,1fr));gap:18px}
  /* A grid of two tiles in three columns left a third of the row empty.
     Two columns, held to the width three would have given them, so the
     tiles are the same size as every other tile on the page and the row
     is not ragged. */
  .pgrid:not(:has(> :nth-child(3))){grid-template-columns:repeat(2,minmax(0,1fr));max-width:826px}
}

/* ---- a focus ring must never fade in -----------------------------------
   .btn, .door, .card, .tier, .prod and a dozen more declare
   `transition:.2s ease`, and a transition with no property list animates
   ALL of them — including `outline`. So for the first ~200ms of every Tab
   press the ring was still interpolating out of the UA default: 3px, at
   offset 0, in currentColor. On .btn-light that is --deep on --deep, a
   ring you cannot see, at exactly the moment a keyboard user needs it.

   Measured with real Tab traversal, 140 focusable elements across 14
   pages: 29 rings reading below 3:1 mid-transition. Settled they were
   always correct — but "correct 200ms later" is not correct.

   Killing the transition only while an element is showing a focus ring
   keeps every hover animation exactly as it was.

   The selector is repeated for the same reason .lbl.lbl.lbl is repeated
   further up this sheet: a single :focus-visible is one class worth of
   specificity, so any component written as `.parent child{transition:...}`
   out-ranks it and gets its fading ring back. .formfold summary did
   exactly that. Three raises this above any component selector likely to
   be written here, without reaching for !important. */
:focus-visible:focus-visible:focus-visible{transition:none}

/* The "what's in it" dialog's close button is absolutely positioned against
   .modal, not against .modal-box, so it sits in the top corner of the
   translucent scrim rather than on the panel. --tan on that scrim over
   paper is 3.6:1 — over the line, but only just, and it changes with
   whatever is behind the overlay. Cream is 7.2:1 on the same scrim over
   paper and 16:1 over a dark section, so the ring is unambiguous whatever
   the dialog was opened on top of. */
.modal .modal-close{--focus:var(--cream)}

/* ---- the last layout shift on the site ---------------------------------
   Measured on index at 390px: a single 0.0239 shift 124ms into load, the
   whole page above the fold jumping up 26px — one line of the hero lead.
   Cause: font-display:swap paints the lead in Georgia first, and
   Newsreader sets 5% narrower than Georgia at the same size, so the
   fallback took one line more and gave it back on swap.

   Measured, not guessed, with both faces rendering the same string at
   17px in this browser:
       Newsreader          643.9px
       Georgia             677.3px   ->  95.07%
       Times New Roman     611.8px   -> 105.25%

   A metric-matched fallback face per candidate, so whichever one the
   device actually has sets to Newsreader's width and the line count
   never changes. line-height is a unitless multiple everywhere in this
   sheet, so width is the only thing that can move a line, and
   size-adjust alone is enough — no ascent/descent overrides needed.

   local() reads a font already installed on the device. Nothing is
   requested from anywhere, so the "no third-party requests" position in
   the privacy policy still holds. If neither font is present the stack
   falls through to the plain generics it always had. */
@font-face{font-family:'Newsreader fb';src:local('Georgia');size-adjust:95.07%}
@font-face{font-family:'Newsreader fb2';src:local('Times New Roman');size-adjust:105.25%}
:root{--f-ser:Newsreader,'Newsreader fb','Newsreader fb2',Georgia,"Times New Roman",serif}

/* ---- the four brand tiles on the homepage --------------------------------
   These carried background and padding as inline styles, which beat every
   selector in this sheet — so the vertical rhythm work could not reach them
   and they sat at 26px while everything around them tightened. Same look,
   now owned by the stylesheet, and they follow the scale on small screens
   like the rest of the page. */
.btile{background:var(--brown2);padding:24px}
@media(max-width:640px){.btile{padding:18px}}

/* ---- a form folded behind its own disclosure -----------------------------
   Native <details>, so it opens with no JavaScript and stays in the DOM for
   the pop-out to clone. The summary is styled as a button because that is
   what it behaves like; the default triangle marker is removed in both
   syntaxes since Safari still wants the -webkit- one. */
.formfold{align-self:start}
.formfold summary{display:inline-block;cursor:pointer;list-style:none;
  padding:15px 30px;font-family:var(--f-sans);font-size:var(--t-label);font-weight:700;
  letter-spacing:var(--tr-label);text-transform:uppercase;line-height:1.4;
  background:var(--brown);color:var(--cream);border:1px solid transparent;transition:.18s ease}
.formfold summary::-webkit-details-marker{display:none}
.formfold summary::marker{content:""}
.formfold summary:hover{background:var(--cream);color:var(--deep)}
.formfold[open] summary{margin-bottom:var(--s3)}

/* ---- the alternative-route band at the foot of a page --------------------
   One row: what it is on the left, the way in on the right. Replaces a full
   second section that repeated a heading, a lead and the footer's contact
   details under the primary form. The heading is set at h3 scale so it reads
   as subordinate to the section above it without needing a smaller tag. */
.altend{padding-top:var(--s5);padding-bottom:var(--s5)}
.altend-row{display:flex;align-items:center;justify-content:space-between;
  gap:var(--s5);flex-wrap:wrap}
.altend-txt{max-width:46ch;display:flex;flex-direction:column;gap:6px}
.altend h2{font-size:var(--t-h3)}
.altend-act{flex:0 0 auto}
.altend .formfold[open]{width:min(560px,100%)}
@media(max-width:760px){
  .altend-row{flex-direction:column;align-items:flex-start;gap:var(--s3)}
  .altend-act{width:100%}
  .altend .formfold summary{width:100%;text-align:center}
}

/* ---- optional detail, folded inside a form -------------------------------
   Quieter than .formfold: this sits INSIDE a panel and must not compete with
   the submit button, so it is a rule and a label rather than a filled block.
   Native <details>, so it needs no script and the fields inside still post
   whether it is open or shut. */
.moredetail{border-top:1px solid rgba(255,255,255,.14);padding-top:var(--s2);margin-top:2px}
.moredetail summary{cursor:pointer;list-style:none;display:flex;align-items:baseline;
  gap:10px;flex-wrap:wrap;font-family:var(--f-sans);font-size:var(--t-label);font-weight:700;
  letter-spacing:var(--tr-label);text-transform:uppercase;color:var(--tan3)}
.moredetail summary::-webkit-details-marker{display:none}
.moredetail summary::marker{content:""}
.moredetail summary::before{content:"+";font-size:15px;font-weight:400;line-height:1}
.moredetail[open] summary::before{content:"\2212"}
.moredetail summary:hover{color:#fff}
.moredetail summary span{font-size:var(--t-fine);font-weight:400;letter-spacing:0;
  text-transform:none;color:var(--onBrown);opacity:.85}
.moredetail[open] summary{margin-bottom:var(--s2)}
.moredetail > .row2 + .row2{margin-top:11px}

/* ---- "+ many more" on a category row -------------------------------------
   The named brands are a sample, not the roster. This reads as a note rather
   than another brand: no box, no border, so it cannot be mistaken for one of
   the names beside it. */
.tags .more{border:0;background:none;padding-left:2px;color:var(--soft);
  font-style:italic;text-transform:none;letter-spacing:0;font-family:var(--f-ser);font-weight:400}

/* ---- the creator list, however many there are ----------------------------
   Rocky adds creators one at a time as each person gives permission, so this
   has to look deliberate at one, at two, and at ten. It keys off the count
   with :only-child rather than needing the markup to change shape:

     one   -> a wide feature, photograph beside the story
     two+  -> a grid of cards that reflows on its own

   Older rules for .ctile/.cgrid above were written for a different markup
   shape (.cimg, buttons padded from the tile edge). These come later and are
   scoped to the current structure, .cshot + .cbody. */
.cgrid{display:flex;flex-wrap:wrap;gap:var(--s5);align-items:stretch;justify-content:center;
  /* Flex, not grid, for one reason: eleven tiles across three columns leaves a
     short last row, and CSS grid cannot centre it. justify-content on a grid
     centres the TRACKS, so the leftover items still sit at the start of them
     with a hole on the right. Flex wrap centres every row independently.
     Capped at 340px, not 1fr: two tiles across 1440px would stretch to 585px
     each and a 4:5 portrait then stands 731px tall and swamps the section. */
  }
.cgrid > .ctile{flex:0 1 340px;min-width:270px}
.cgrid > .ctile{background:var(--card);border:1px solid var(--rule2);
  display:flex;flex-direction:column;overflow:hidden;height:100%}
.cgrid > .ctile .cshot{aspect-ratio:4/5;overflow:hidden;background:var(--paper2)}
.cgrid > .ctile .cshot img{width:100%;height:100%;object-fit:cover;
  object-position:50% 22%;display:block}
.cgrid > .ctile .cbody{display:flex;flex-direction:column;gap:8px;padding:24px;flex:1}
.cgrid > .ctile .cbody .btn{margin:0}
.cgrid > .ctile .cbody .btn-row{margin-top:auto;padding-top:var(--s2)}
.cgrid > .ctile .cbody .note{margin-top:2px}

/* one creator: a feature, not a lonely card sitting in a wide grid */
/* the capped track above would otherwise pin the lone feature to 340px */
.cgrid:has(> .ctile:only-child){max-width:1000px;margin:0 auto;
  grid-template-columns:minmax(0,1fr)}
.cgrid > .ctile:only-child{display:grid;grid-template-columns:minmax(0,420px) 1fr;
  gap:var(--s5);align-items:center;background:none;border:0;overflow:visible}
.cgrid > .ctile:only-child:hover{transform:none;box-shadow:none;border-color:transparent}
.cgrid > .ctile:only-child .cshot{border:1px solid var(--rule2)}
.cgrid > .ctile:only-child .cbody{padding:0}
.cgrid > .ctile:only-child h3{font-size:var(--t-h2)}
.cgrid > .ctile:only-child .cbody .btn-row{margin-top:var(--s2)}

@media(max-width:760px){
  .cgrid > .ctile:only-child{grid-template-columns:1fr;gap:var(--s3)}
  .cgrid > .ctile:only-child .cshot{max-width:300px}
}

/* ==========================================================================
   PRINT
   The sheet previously carried one print rule. Browsers drop backgrounds by
   default, so every dark band printed near-white text onto white paper —
   measured at 92 unreadable text nodes on the services page alone, which is
   the one somebody actually prints to take into a meeting.

   The approach: force the dark grounds to ink-on-paper rather than trying to
   make the browser print the background, since the visitor controls that
   setting and most will leave it off.
   ========================================================================== */
@media print{
  /* nothing that is navigation, chrome or an overlay belongs on paper */
  header,.progress,.modal,.fmodal,.lb,.fmbox,
  #navtoggle,.mq,.mqstatic,.btn-row,.sr,
  footer .fnav{display:none!important}

  html,body{background:#fff!important;color:#000!important;font-size:11pt}
  .wrap{max-width:none;padding:0 12mm}
  section{padding:10mm 0!important;break-inside:auto}

  /* the dark bands, inverted to paper */
  .sec-deep,.sec-ink,.sec-brown,.hero,.hero-sm,.news,.calc,footer,.darkpanel,
  .tier,.door,.door-ink,.door-brown,.callout,.btile,.altend,.formcard,.coverwrap,.cover{
    background:#fff!important;color:#000!important;border-color:#999!important;
    box-shadow:none!important}
  .sec-deep *,.sec-ink *,.sec-brown *,.hero *,.hero-sm *,.news *,.calc *,footer *,.darkpanel *,
  .tier *,.door *,.callout *,.btile *,.altend *,.formcard *,.coverwrap *,.cover *{
    color:#000!important;background:transparent!important}

  /* keep the type hierarchy legible in ink */
  h1,h2,h3,h4{color:#000!important;break-after:avoid}
  .lead,.small,.note,.lbl,p,li,td,th{color:#000!important}
  .lbl,.eyebrow{color:#444!important}

  /* cards and rows should not be split across a page break */
  .card,.tier,.prod,.pcard,.ctile,.sell,.catrow,.band,.mult,.cat,
  figure,.faq details,.fee-table tr{break-inside:avoid}
  .fee-table{border-collapse:collapse}
  .fee-table th,.fee-table td{border:1px solid #999!important;padding:4pt 6pt}

  /* accordions are the content on several pages — print them open */
  details{open:true}
  .faq details>div,.faq .a{display:block!important;height:auto!important}

  img{max-width:100%!important;break-inside:avoid}

  /* a printed link is useless without its destination */
  main a[href^="http"]::after{content:" (" attr(href) ")";font-size:9pt;color:#555}
  main a[href^="mailto:"]::after{content:" (" attr(href) ")";font-size:9pt;color:#555}
  main a[href^="#"]::after,main a[href$=".html"]::after{content:""}

  /* Buttons carry real information on paper ("Buy now - $29", "Send a brief"),
     so they print as outlined labels rather than vanishing. Their fills are
     dropped with the rest of the backgrounds, which would otherwise leave
     cream text on white. */
  .btn,.btn-dark,.btn-light,.btn-brown,.btn-line,.btn-lineD,.card.hi .tag,
  button,.formfold summary,.moredetail summary{
    background:#fff!important;color:#000!important;border:1px solid #666!important;
    box-shadow:none!important;padding:3pt 6pt!important}
  .modal-close,.fm-x,.lb-x,.lb-nav{display:none!important}

  /* the button rule above matches every <button>, so a selected pill lost its
     fill and printed identically to the ones beside it. Say it in text, the
     way the forced-colors block already does. */
  .pill.on{font-weight:700!important;border-width:2px!important}
  .pill.on::after{content:" \2713"}

  /* a pseudo-element is not reached by the * rules above, so the on-dark
     placeholder colour printed at 1.67:1 on white */
  ::placeholder{color:#555!important;opacity:1!important}

  .disclaim{border-top:1px solid #999;padding-top:6pt;color:#333!important;font-size:8pt}
}

/* ---- the offer-check verdict --------------------------------------------
   The whole tool exists to deliver one sentence, so the sentence gets the
   display face and the room. The state colour is a left rule, not a fill:
   a red panel would read as an error message rather than a judgement, and
   the answer "you are being underpaid" is information, not a fault. */
.verdict{border-left:3px solid var(--tan);padding-left:var(--s3)}
.calc .pills{margin-top:8px}
.calc-grid > div > label + .pills{margin-top:8px}
.verdict .lbl{color:var(--tan)}
.verdict .vline{font-family:var(--f-disp);font-size:var(--t-h3);line-height:var(--lh-head);
  color:var(--cream);margin:6px 0 var(--s3);text-wrap:balance}
.verdict .note{margin-top:var(--s2);max-width:62ch}
.vband{display:flex;gap:var(--s5);flex-wrap:wrap}
.vband .lbl{margin-bottom:4px}
.vnum{font-family:var(--f-disp);font-size:var(--t-num);line-height:1;color:var(--cream)}

/* state, carried on the rule so the panel stays calm */
.verdict.v-bad{border-left-color:#DC9A80}
.verdict.v-low{border-left-color:#D8AE7B}
.verdict.v-ok{border-left-color:var(--tan)}
.verdict.v-good{border-left-color:#9CC08D}
.verdict.v-none{border-left-color:var(--lineDark)}
.verdict.v-bad .vline,.verdict.v-low .vline{color:var(--badD)}

/* the drafted reply */
.reply{font-family:var(--f-sans);font-size:var(--t-small);line-height:1.62;
  white-space:pre-wrap;color:var(--onDark);background:var(--field);
  padding:var(--s3);border:1px solid var(--lineDark);margin:0;max-width:70ch;
  overflow-wrap:break-word}
.reply:focus-visible{outline:2px solid var(--focus);outline-offset:3px}

@media(max-width:640px){
  .verdict{padding-left:var(--s2)}
  .vband{gap:var(--s3)}
}

/* ---- long unbroken tokens ------------------------------------------------
   No break rule existed anywhere, so one long word in a heading overflowed by
   ~1,500px at 320px. Nothing in the current copy triggers it, but a browser
   auto-translating the page into German will produce one. */
h1,h2,h3,h4,p,li,td,th,dd,figcaption,summary{overflow-wrap:break-word}


/* ================================================================
   THE LEDGER — the structural pieces the homepage and services page
   are built from. Added 25 Aug 2026. These are new patterns, not
   restyles: the scroll-driven brand rail, the pinned section, the
   fee table, the price rows and the month timeline.
   ================================================================ */

/* the fixed reading rule at the very top of the page */
.progress{height:2px;background:var(--brown)}

/* --- scroll-driven brand rail. Moves with the page, not on a timer, so it
       stops when you stop. --- */
.rail{padding-block:clamp(40px,6vw,80px);border-block:1px solid var(--rule2);overflow:hidden}
.rail .track{display:flex;gap:clamp(30px,4vw,64px);white-space:nowrap;will-change:transform}
.rail .track span{font-family:var(--f-disp);font-size:clamp(30px,4.6vw,72px);font-weight:600;
  letter-spacing:-.035em;color:transparent;-webkit-text-stroke:1px var(--lineDark)}
/* These are real brand names, not decoration, so the outline has to be
   readable rather than merely present. */
@supports not ((-webkit-text-stroke:1px #000)){.rail .track span{color:var(--soft)}}
.rail .track span.hot{-webkit-text-stroke:0;color:var(--ink)}

/* With motion off the track never moves, so a single nowrap line would leave
   most of these names sitting behind overflow:hidden, and an outline that
   reads fine sliding past is too faint to be the whole band. Wrap it and
   fill it in. */
@media(prefers-reduced-motion:reduce){
  .rail .track{flex-wrap:wrap;white-space:normal;justify-content:center;
    gap:clamp(12px,2.2vw,30px) clamp(20px,3.2vw,46px);will-change:auto;
    padding:0 clamp(18px,4vw,60px)}
  .rail .track span{-webkit-text-stroke:0;color:var(--soft);
    font-size:clamp(21px,3vw,42px)}
  .rail .track span.hot{color:var(--ink)}
}

/* --- section 02: the line, and the campaigns behind it. -----------------
   This was a 280vh scroll-pinned section that delivered five swapped words
   and nothing else. It was 2,800px, a third of the whole home page, and for
   the entire middle of it the screen held one short sentence in the centre
   of a black field. That is the dead zone you feel on this page.
   Rebuilt 30 August 2026 as one screen: the same line and the same five
   words, now cycling on a timer instead of on scroll, with three real
   campaign photographs beside it. The words still read; the page no longer
   costs 2,000px to say them. --- */
.pin{position:relative;padding-block:clamp(52px,6.6vw,98px)}
.pin-grid{display:grid;grid-template-columns:minmax(0,.86fr) minmax(0,1.14fr);
  gap:clamp(30px,4.4vw,66px);align-items:center}
.pin h2{font-size:clamp(30px,4.2vw,62px);font-weight:700;line-height:1.03}
.pin .swap{position:relative;display:inline-block;min-width:5.2em;text-align:left;height:1.05em;
  vertical-align:bottom}
.pin .swap b{position:absolute;inset:0;font-weight:700;opacity:0;transform:translateY(18px);
  transition:.5s cubic-bezier(.16,1,.3,1);color:var(--ink);white-space:nowrap}
.pin .swap b.on{opacity:1;transform:none}
.pin .under{margin:clamp(18px,2.4vw,34px) 0 0;max-width:44ch}

/* The collage. Every one of these photographs is the same 4:5 portrait crop,
   so stacked in a column they read as a contact sheet rather than a picture.
   Three across with the middle one dropped gives the group a horizon and
   keeps the block roughly the height of the sentence beside it, which is the
   whole reason this section no longer has a void in the middle of it. */
.pin-shots{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(9px,1.1vw,15px);
  align-items:start}
.pin-shots figure{margin:0;overflow:hidden;background:#141210}
.pin-shots figure:nth-child(2){margin-top:clamp(22px,3.6vw,52px)}
.pin-shots img{display:block;width:100%;height:auto;aspect-ratio:4/5;object-fit:cover}

/* --- journal figures ---------------------------------------------------
   Inline SVG, not images: the site fetches nothing extra, the marks stay
   crisp at any width and they read the page's own tokens. Every figure is
   emphasis or a single series, because the brown ramp cannot carry two
   categories that anybody could reliably tell apart. The reasoning, and the
   validator output, are at the top of src/journal/figures.py. --- */
.figsec{padding:0 0 var(--s6)}
.fig{margin:0;padding:var(--s5) 0 0;border-top:1px solid var(--rule)}
.fig svg{display:block;width:100%;height:auto;margin:var(--s3) 0 0;overflow:visible}
.figlbl{font-family:var(--f-mono);font-size:var(--t-label);letter-spacing:.18em;
  text-transform:uppercase;color:var(--brown);margin:0 0 10px}
.fighed{font-family:var(--f-disp);font-size:var(--t-h4);font-weight:700;
  line-height:1.15;letter-spacing:-.015em;margin:0;max-width:34ch}
.fig figcaption{margin-top:var(--s3);font-size:var(--t-fine);line-height:1.6;
  color:var(--soft);max-width:76ch}
@media(max-width:640px){
  /* a figure that would squash below about 560px scrolls in its own box
     rather than compressing the labels into each other */
  .fig>svg{min-width:560px}
  .fig{overflow-x:auto}
}

/* --- the fork: creators one side, brands the other -----------------------
   Was two separate sections, 07 and 08, each a heading with a lead and two
   buttons, one after the other, with the newsletter making a third in the
   same shape. Side by side they stop being a queue of calls to action and
   become the choice the top of the page already offered: I'm a creator,
   I'm a brand. --- */
.fork-grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(26px,3.4vw,52px);
  margin-top:clamp(26px,3.6vw,48px)}
.fk{display:flex;flex-direction:column;gap:14px;
  padding-top:22px;border-top:1px solid var(--rule2)}
.fk h3{font-family:var(--f-disp);font-size:var(--t-h3);font-weight:700;
  line-height:1.1;margin:0;letter-spacing:-.02em}
.fk .lead{margin:0}
.fk-note{margin:0;font-size:var(--t-fine);line-height:1.6;color:var(--soft);
  border-left:2px solid var(--brown);padding-left:14px}
.fk-note b{color:var(--brown)}
.fk .btn-row{margin-top:auto;padding-top:6px}
@media(max-width:760px){
  .fork-grid{grid-template-columns:1fr;gap:clamp(30px,6vw,42px)}
}

/* --- the ledger table: real fees, the centrepiece of the homepage --- */
.ldg{width:100%;border-collapse:collapse;font-variant-numeric:tabular-nums}
.ldg th{text-align:left;font-family:var(--f-mono);font-size:10px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--soft);font-weight:400;padding:0 0 12px;
  border-bottom:1px solid var(--rule2)}
.ldg td{padding:20px 0;border-bottom:1px solid var(--rule);vertical-align:top;
  font-size:var(--t-small);color:var(--muted)}
.ldg th:last-child,.ldg td:last-child{text-align:right}
.ldg .who{font-family:var(--f-disp);font-weight:600;font-size:var(--t-h4);letter-spacing:-.02em;color:var(--ink)}
.ldg .who span{display:block;font-family:var(--f-mono);font-weight:400;font-size:10px;
  letter-spacing:.1em;text-transform:uppercase;color:var(--soft);margin-top:7px}
.ldg .fee{font-family:var(--f-disp);font-weight:600;font-size:var(--t-h3);letter-spacing:-.03em;
  color:var(--ink);white-space:nowrap}
.ldg tbody tr{transition:background .25s}
.ldg tbody tr:hover{background:var(--paper2)}
@media(max-width:700px){.ldg .hide{display:none}}

/* --- price rows: one line per service, opens out on hover --- */
.prows{border-top:1px solid var(--rule2)}
.prow{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:20px;align-items:baseline;
  padding:24px 0;border-bottom:1px solid var(--rule);
  transition:padding .4s cubic-bezier(.16,1,.3,1),background .3s}
.prow:hover{background:var(--paper2);padding-left:16px;padding-right:16px}
.prow .nm{font-family:var(--f-disp);font-size:var(--t-h3);font-weight:600;letter-spacing:-.028em;
  line-height:1.08;color:var(--ink)}
.prow .de{margin-top:8px;max-width:60ch}
.prow .px{font-family:var(--f-disp);font-size:var(--t-h3);font-weight:600;letter-spacing:-.03em;
  white-space:nowrap;font-variant-numeric:tabular-nums;color:var(--ink)}
.prow .px span{display:block;font-family:var(--f-mono);font-size:10px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--soft);font-weight:400;margin-top:6px;text-align:right}

/* --- three months, as a divided band --- */
.months{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--rule2);
  border-block:1px solid var(--rule2)}
.month{background:var(--paper);padding:clamp(24px,3vw,44px)}
.month .n{font-family:var(--f-mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--brown)}
.month h3{margin:14px 0 12px}
@media(max-width:820px){.months{grid-template-columns:1fr}}

/* --- figures band --- */
.figs{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--rule2);
  border-block:1px solid var(--rule2)}
.figs .f{background:var(--paper);padding:clamp(28px,4vw,58px) clamp(18px,4vw,60px)}
.figs .n{font-family:var(--f-disp);font-size:var(--t-big);font-weight:700;letter-spacing:-.045em;
  line-height:.9;font-variant-numeric:tabular-nums;color:var(--ink)}
.figs .t{margin-top:16px;max-width:28ch}
@media(max-width:760px){.figs{grid-template-columns:1fr}}

/* --- the ledger hero --- */
.lhero{min-height:100svh;display:flex;flex-direction:column;justify-content:flex-end;
  padding-block:clamp(110px,14vw,150px) clamp(28px,4vw,40px);position:relative}
.lhero .grid-bg{position:absolute;inset:0;pointer-events:none;opacity:.55;
  background-image:linear-gradient(var(--rule2) 1px,transparent 1px),
                   linear-gradient(90deg,var(--rule2) 1px,transparent 1px);
  background-size:100% 80px,12.5% 100%;
  -webkit-mask-image:radial-gradient(120% 80% at 50% 0%,#000 10%,transparent 72%);
          mask-image:radial-gradient(120% 80% at 50% 0%,#000 10%,transparent 72%)}
.lhero .in{position:relative;will-change:transform,opacity}
.lhero h1{font-size:clamp(42px,10.4vw,164px);font-weight:700;line-height:.92;letter-spacing:-.045em}
.lhero h1 .l{display:block;overflow:hidden}
.lhero h1 .l>span{display:block;transform:translateY(104%);
  transition:transform 1.05s cubic-bezier(.16,1,.3,1)}
.lit .lhero h1 .l>span{transform:none}
.lit .lhero h1 .l:nth-child(2)>span{transition-delay:.07s}
.lit .lhero h1 .l:nth-child(3)>span{transition-delay:.14s}
.lhero .meta{display:grid;grid-template-columns:1fr auto;gap:28px;align-items:end;
  margin-top:clamp(24px,4vw,52px);padding-top:22px;border-top:1px solid var(--rule2)}
@media(max-width:760px){.lhero .meta{grid-template-columns:1fr}}

/* the still row that replaces the swapping word when motion is off */
.pin-still{display:none;justify-content:center;gap:0;flex-wrap:wrap;margin-top:var(--s3);
  color:var(--ink)}
.pin-still span+span::before{content:"\00b7";margin:0 12px;color:var(--soft)}

@media(max-width:900px){
  /* one column: the line, then the campaigns under it */
  .pin-grid{grid-template-columns:1fr;gap:clamp(26px,5vw,42px)}
  .pin .under{max-width:52ch}
}
@media(max-width:760px){
  .pin h2{font-size:clamp(30px,8.4vw,52px)}
  .pin-grid{text-align:center;justify-items:center}
  .pin .swap{min-width:4.6em}
  .pin .under{margin-inline:auto}
}

@media(prefers-reduced-motion:reduce){
  /* Show every word rather than only the first: with motion off the other
     three used to disappear, which loses the point of the section. */
  .pin .swap{min-width:0;height:auto;display:inline}
  .pin .swap b{position:static;opacity:1;transform:none;display:none}
  .pin .swap b:first-child{display:inline}
  .pin-still{display:flex}
  .lhero h1 .l>span{transform:none!important;transition:none}
  .prow,.ldg tbody tr{transition:none}
}

/* --- Ledger page head: the big statement at the top of an inner page --- */
.top-l{padding-block:clamp(96px,12vw,150px) clamp(30px,4vw,54px);border-bottom:1px solid var(--rule2)}
.top-l .eyebrow{margin-bottom:clamp(18px,3vw,34px)}
.top-l h1{font-size:clamp(38px,7.4vw,104px)}
.top-l .lead{margin-top:clamp(18px,2.4vw,30px)}

/* --- price and CTA inside a tier card --- */
.tier-px{font-family:var(--f-disp);font-size:var(--t-num);font-weight:700;letter-spacing:-.045em;
  line-height:1;color:var(--ink)}
.tier-px small{font-family:var(--f-mono);font-size:12px;letter-spacing:.1em;font-weight:400;
  color:var(--soft);text-transform:uppercase}

/* Two services are quoted after a call rather than published. The price slot
   still has to hold something, and that something must not read as a figure:
   set at heading size rather than number size, and in the muted tone, so the eye
   files it as a label. At full --t-num it shouted LET'S TALK louder than the $99
   beside it, which is the opposite of the point. */
.tier-px.ask{font-size:calc(var(--t-num) * .62);color:var(--brown);letter-spacing:-.02em}
.tier-px.ask small{display:block;margin-top:10px;white-space:normal;letter-spacing:.08em}
.prow .px.px-ask{font-size:calc(var(--t-h3) * .68);color:var(--brown);letter-spacing:-.012em}
/* Both halves of a range at one size. .px sets a headline figure with a 10px
   mono line under it, which turns the top of a range into a footnote: the rate
   page chooser read as "$245" with a whisper of "to $490" after it. Smaller
   than a single headline figure, because a range is two numbers and has to fit
   a 390px column beside its label. */
.prow .px.px-range{font-size:calc(var(--t-h3) * .72);letter-spacing:-.015em;white-space:nowrap}
.tier-cta{margin-top:auto;padding-top:var(--s3)}
.tier-cta .btn{width:100%}
.tier.feature{position:relative}
.tier.feature::before{content:"";position:absolute;inset:0 0 auto 0;height:2px;background:var(--brown)}

.tiers{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s3)}
@media(max-width:900px){.tiers{grid-template-columns:1fr}}

/* The static marquee is what shows instead of the scrolling one on small
   screens; it was inheriting the light design's near-black. */
.mqstatic span{color:var(--ink)}
.mqstatic span+span::before{background:var(--rule2)}

/* --- a spec list: label above value, ruled, for book and product metadata --- */
.spec{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:0;
  margin:var(--s4) 0;border-top:1px solid var(--rule2)}
.spec>div{padding:14px 0;border-bottom:1px solid var(--rule)}
.spec dt{margin-bottom:6px;color:var(--soft)}
.spec dd{margin:0;font-family:var(--f-disp);font-size:var(--t-h4);font-weight:600;
  letter-spacing:-.02em;color:var(--ink)}
@media(max-width:600px){.spec{grid-template-columns:1fr 1fr}}

/* ---------------------------------------------------------------------
   Windows High Contrast, and any other forced-colours mode.
   The user has told the operating system to throw our palette away and use
   theirs. That is not a bug to fight, it is an instruction. What it does
   break is anything that carried meaning in colour alone, because every
   background collapses to one of four system colours: the selected pill and
   the unselected one become identical, and the brand rail, which is drawn as
   an outline rather than filled text, disappears completely.
   So: give state a shape as well as a colour, and put a border back on the
   things whose edge was a background change.
   --------------------------------------------------------------------- */
@media (forced-colors: active){
  .btn,.pill,.card,.pcard,.tier,.callout,.box,.calc,.modal-box,.fmbox,
  .figs .f,.spec,.specs,.inside,.forwho .c,.lb img{
    border:1px solid CanvasText}

  /* the four button styles are four background colours and nothing else */
  .btn-light,.btn-dark{background:ButtonFace;color:ButtonText;border:1px solid ButtonText}
  .btn-line,.btn-lineD{background:Canvas;color:LinkText;border:1px solid LinkText}

  /* selected is a fill. A fill is gone here, so say it in text too. */
  /* tripled class: the ground-scoped .pill.on rules are (0,3,0) and come
     later in the sheet, so (0,3,0) here loses to them and the selected pill
     stayed pinned to brand cream inside the user's own theme. */
  .pill.pill.pill.on{background:Highlight;color:HighlightText;border-color:HighlightText;
    forced-color-adjust:none}
  .pill.on::after{content:" \2713";speak:never}

  /* outlined text renders as nothing. These are real brand names. */
  .rail .track span{-webkit-text-stroke:0;color:CanvasText}
  .rail .track span.hot{text-decoration:underline;text-underline-offset:.18em}

  /* status chips are three background colours meaning three different things */
  .status{border:1px solid CanvasText;padding-inline:.5em}

  /* the reveal leaves content at opacity 0 if the observer never fires */
  .rv{opacity:1;transform:none}

  /* our focus ring is a brand colour, which is discarded */
  a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,
  textarea:focus-visible,summary:focus-visible,[tabindex]:focus-visible{
    outline:3px solid Highlight;outline-offset:2px}

  /* a hairline divider drawn as a background stripe */
  .figs{background:CanvasText}
}


/* ---- 15. mobile density -------------------------------------------------
   Measured on a 390px viewport before touching a word of copy: About ran 10.1
   screens, and only about a third of that height was text. The rest was
   furniture around short things. Three figures stacked into 452px to carry 32
   words, at 14px of height per word. The portrait took 432px. So shorter copy
   alone was never going to fix the phone, and this block does the other half.
   Desktop is deliberately untouched: at 1440px the air is the design. */
@media(max-width:760px){

  /* Three short numbers do not need three full-width bands. Across the row
     they read as one proof strip, which is what they are. "1,000s" is the
     longest string and it fits at this size. */
  .figs{grid-template-columns:repeat(3,1fr)}
  .figs .f{padding:20px 11px}
  .figs .n{font-size:clamp(25px,7vw,34px)}
  .figs .t{margin-top:9px;font-size:12px;line-height:1.35;max-width:none}

  /* A 4:5 portrait is half a phone screen for one photograph. Same image and
     the same focal point, cropped to a band. */
  .portrait{aspect-ratio:3/2}

  /* The two end doors were 338px each for about forty words apiece. */
  .doors .door{padding:30px 22px;gap:12px}

  /* The brand marquee carried 411px for a strip of names. */
  .mq{padding:7px 0}

  /* The homepage rail was 367px on a phone to carry twenty brand names. They
     are the proof, so they stay, but they do not need a band this deep around
     them. */
  .rail{padding-block:26px}
  .rail .track span{font-size:clamp(19px,5.6vw,32px)}
}

@media(max-width:760px){

  /* Below 900px the two marquee tracks are already swapped for one wrapped
     list, so hiding a track achieves nothing. It is the list that is 411px. */
  .mqstatic span{font-size:var(--t-body);padding:6px 10px}

  /* Four facts stacked is four rows of two words. Two across reads the same. */
  .kv{grid-template-columns:1fr 1fr;gap:var(--s2) var(--s3)}
}


/* Widening the column found the only two text blocks with no line-length cap
   of their own. At 2560px they ran to about 150 characters a line, which is
   roughly twice a comfortable measure. */
.disclaim p{max-width:76ch}
.inside .bd p{max-width:80ch}


/* ============================================================
   THE PHONE READING PASS — 30 August 2026

   Rocky, looking at the site on his phone: the headings should be
   centred, the text should read better, and the whole thing should
   look cleaner and more pleasant.

   Most people who land here arrive on a phone, from a link in a bio
   or a DM, so this is the layout that matters most and it was the
   one nobody had sat with.

   Three decisions worth writing down, because they will look like
   omissions later:

   1. Headings centre. Body copy does not. Centring a six line
      paragraph gives every line a different left edge, so the eye
      has to hunt for the start of each one. It photographs well and
      reads badly. Headings are one to three lines, so they centre
      without that cost, and a short lead directly under a centred
      heading centres with it.

   2. No text-align:justify. On a 360px column there are only six or
      seven words a line, so justifying has to stretch the spaces
      until white rivers run down the paragraph. Justification needs
      either a wide measure or hyphenation to work, and neither is
      available here.

   3. Every button row goes full width and equal width. Two buttons
      at their natural text widths sit at two different sizes, which
      is what made the home page pair look unaligned.
   ============================================================ */
@media(max-width:760px){

  /* ---- headings ---------------------------------------------------- */
  /* sec-head is already centred. sec-head-l is its left aligned twin and
     is used twice as often, which is why most of the site read as ragged
     on a phone. On a narrow column the distinction earns nothing. */
  .sec-head-l,.sec-head-split{text-align:center}
  .sec-head-l>*,.sec-head-split>*{margin-inline:auto}
  .sec-head-split{justify-content:center}

  /* the eyebrow, the rule under a heading and the heading itself */
  .sec-head-l .lbl,.sec-head-split .lbl{display:block}

  /* a lead is two or three lines, so it centres with its heading and
     gets a tighter measure to keep the shape even */
  .sec-head .lead,.sec-head-l .lead,.sec-head-split .lead{
    max-width:36ch;margin-inline:auto;text-align:center}

  /* the two page tops that were left aligned. lhero is the home page and
     top-l is the services page, which is the only page using it, which is
     why it was the one that stood out in the screenshots. */
  .lhero .in,.top-l{text-align:center}
  .top-l .lead.measure{margin-inline:auto;text-align:center;max-width:36ch}
  .lhero h1 .l>span{display:block}
  .lhero .meta{justify-items:center}
  .lhero .lead.measure{margin-inline:auto;text-align:center;max-width:34ch}

  /* ---- body copy: left aligned, but easier to read ----------------- */
  /* Newsreader 300 on a dark ground needs more leading at small sizes
     than it does on a wide screen, or the lines close up. */
  .lead,p{line-height:1.62}
  .prose p,.bd p,.stack.prose p{max-width:38ch}

  /* ---- buttons ----------------------------------------------------- */
  /* One row, equal columns, so a pair always reads as a pair. Under
     380px two side by side leaves about seven characters each, so they
     stack instead. */
  .btn-row{justify-content:center}
  .btn-row .btn{flex:1 1 0;min-width:0;text-align:center}
  .lhero .btn-row{width:100%;max-width:420px;margin-inline:auto}
}

@media(max-width:380px){
  .btn-row{flex-direction:column;align-items:stretch}
  .btn-row .btn{flex:1 1 auto;width:100%}
}


/* ============================================================
   HOME PAGE, 04 THE WORK and 05 THE FREE GUIDE — 30 August 2026

   Two blocks added because the home page is where most people
   land from a bio link, and it had no proof of the work and no
   prominent way to get the free guide. Everything here reuses
   existing tokens; no new colours, no new type sizes.
   ============================================================ */

/* ---- 04 · the three talents ---- */
.tgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s3)}
.ttile{display:block;text-decoration:none;color:inherit}
.tshot{aspect-ratio:4/5;overflow:hidden;background:var(--panel);
  border:1px solid var(--rule2)}
.tshot img{width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .5s cubic-bezier(.16,1,.3,1)}
.ttile:hover .tshot img,.ttile:focus-visible .tshot img{transform:scale(1.04)}
.ttile .lbl{margin-top:var(--s2);color:var(--brown)}
.ttile h3{margin-top:2px;line-height:1.1}
.ttile:focus-visible{outline:2px solid var(--brown);outline-offset:4px}

/* ---- 05 · the free guide ---- */
.freeg{background:var(--panel);border-block:1px solid var(--rule2)}
.freeg .inner{display:grid;grid-template-columns:minmax(0,280px) minmax(0,1fr);
  gap:clamp(24px,4vw,56px);align-items:center}
.fg-shot img{width:100%;height:auto;display:block;border:1px solid var(--rule2)}
.fg-body .lbl{color:var(--brown)}
.fg-body h2{margin-top:8px}
.fg-body .lead{margin-top:var(--s2);max-width:52ch}
.fg-list{list-style:none;margin:var(--s3) 0 var(--s4);padding:0;display:grid;gap:9px}
.fg-list li{position:relative;padding-left:20px;color:var(--muted)}
.fg-list li::before{content:"";position:absolute;left:0;top:.62em;
  width:7px;height:7px;background:var(--brown)}
.freeg .note{margin-top:var(--s2)}

@media(max-width:760px){
  /* Three portraits side by side on a phone are 110px wide, which is a
     thumbnail, not a photograph. Two across gives them room, and the
     third sits under them rather than being dropped. */
  .tgrid{grid-template-columns:1fr 1fr;gap:var(--s2)}
  .tgrid .ttile:nth-child(3){grid-column:1 / -1}
  .tgrid .ttile:nth-child(3) .tshot{aspect-ratio:16/10}
  .ttile{text-align:center}

  /* the cover above the words, and narrower so it does not eat the fold */
  .freeg .inner{grid-template-columns:1fr;text-align:center}
  .fg-shot{max-width:210px;margin-inline:auto}
  .fg-body .lead{margin-inline:auto;text-align:center;max-width:38ch}
  /* a centred list of ticks with a left bullet reads as broken, so the
     marks come off and the items centre with everything else */
  .fg-list{justify-items:center}
  .fg-list li{padding-left:0;text-align:center}
  .fg-list li::before{display:none}
}


/* ---- two-up product grid, for the bundles -------------------------------
   The bundles moved above the individual grid and became real cards. Two
   cards in a three column grid would sit in a row with a hole in it, so they
   get their own two column grid that collapses at the same width as pgrid3. */
.pgrid2{display:grid;grid-template-columns:repeat(2,1fr);gap:22px;align-items:stretch}
@media(max-width:760px){.pgrid2{grid-template-columns:1fr}}

/* The number a rate page leads with. These pages exist to answer one question
   in one line, so it is set at display size and nothing competes with it. */
.rate-big{font-family:var(--f-disp);font-size:clamp(38px,7vw,68px);font-weight:500;
  line-height:1;letter-spacing:-.02em;color:var(--cream);margin:18px 0 14px;
  font-variant-numeric:tabular-nums}
.rate-big + .lead{max-width:62ch;margin-left:auto;margin-right:auto}

/* The rate pages ship all three platforms and show one. [hidden] is respected
   explicitly because .ratepanel sets display, which would otherwise win. */
.ratepanel[hidden]{display:none}
.ratepanel{display:block}
#ratePlat,#ratePlat2{justify-content:center;margin:6px 0 4px}
#ratePlat2{justify-content:flex-start;margin-bottom:22px}
#ratePlat .pill,#ratePlat2 .pill{cursor:pointer}

/* ============================================================
   ON THE DARK BANDS
   ------------------------------------------------------------
   Warm Stone puts most of the page on cream, so the base rules
   above are written for a light ground. Six surfaces are still
   dark and everything inside them has to be repointed here:

     .sec-deep .hero .hero-sm .news .calc  -> --deep
     .sec-ink .fmbox                       -> --inkBg
     .sec-brown .tier.feature .door-brown  -> --brown
     .door-ink                             -> --inkBg
     footer                                -> --ink2
     .darkpanel                            -> --deep

   Ratios are measured against the ground named, not estimated,
   and the contrast harness re-checks all of them on every page
   at two widths and four open/closed states.
   ============================================================ */

/* ---- forms. 27 of the 40 sit on a dark band ---- */
.sec-deep .field label,.sec-ink .field label,.hero .field label,.hero-sm .field label,
.news .field label,.calc .field label,.darkpanel .field label,.prod.cta .field label{
  color:var(--tan)}                                   /* --tan on --deep 5.04:1 */
.sec-deep .field input,.sec-deep .field textarea,.sec-deep .field select,
.sec-ink .field input,.sec-ink .field textarea,.sec-ink .field select,
.hero .field input,.hero .field textarea,.hero .field select,
.hero-sm .field input,.hero-sm .field textarea,.hero-sm .field select,
.news .field input,.news .field textarea,.news .field select,
.calc .field input,.calc .field textarea,.calc .field select,
.darkpanel .field input,.darkpanel .field textarea,.darkpanel .field select{
  color:var(--cream);border-bottom-color:var(--chartdim)}   /* 3.26:1 on --deep, 5.0:1 on --inkBg */
.sec-deep .field input:focus,.sec-ink .field input:focus,.hero-sm .field input:focus,
.news .field input:focus,.calc .field input:focus,.darkpanel .field input:focus,
.sec-deep .field textarea:focus,.sec-ink .field textarea:focus,.darkpanel .field textarea:focus,
.sec-deep .field select:focus,.sec-ink .field select:focus,.darkpanel .field select:focus{
  border-bottom-color:var(--tan)}
.sec-deep .field ::placeholder,.sec-ink .field ::placeholder,.news .field ::placeholder,
.calc .field ::placeholder,.darkpanel .field ::placeholder,.hero-sm .field ::placeholder{
  color:var(--tan2);opacity:1}                               /* 6.48:1 on --deep */
/* the checkbox rows carry their own colour and were already on-dark */
.sec-deep .field label.ck,.sec-ink .field label.ck,.darkpanel .field label.ck{color:var(--onDark2)}

/* ---- links inside the pop-out box and the brown band ---- */
.fmbox a{color:var(--tan3)}
.fmbox a:hover{color:#fff}
.tier.feature a{color:var(--tan3)}
.prod.cta a{color:var(--tan3)}
.darkpanel a{color:var(--tan3)}
.darkpanel a:hover{color:#fff}

/* ---- the outline buttons. .btn-line is the bone one and belongs on a dark
   band; .btn-lineD is the ink one and belongs on paper. Each needs the other's
   treatment when it lands on the wrong ground, and the a.btn.* block above sets
   these at (0,3,0), so the context has to be stated at least as specifically. */
.sec-brown a.btn.btn-lineD,.sec-brown .btn.btn-lineD,
.tier.feature a.btn.btn-lineD,.tier.feature .btn.btn-lineD,
.prod.cta a.btn.btn-lineD,.prod.cta .btn.btn-lineD,
.darkpanel a.btn.btn-lineD,.darkpanel .btn.btn-lineD,
.fmbox a.btn.btn-lineD,.fmbox .btn.btn-lineD{
  border-color:var(--tan);color:var(--cream)}
.sec-brown a.btn.btn-lineD:hover,.tier.feature a.btn.btn-lineD:hover,
.prod.cta a.btn.btn-lineD:hover,.darkpanel a.btn.btn-lineD:hover,
.fmbox a.btn.btn-lineD:hover{background:var(--cream);color:var(--deep)}

/* ---- the platform pills. The first switch row sits in the dark small hero,
   the second repeats it further down the page on paper, so the pill needs
   both treatments rather than one. ---- */
.hero .pill,.hero-sm .pill,.calc .pill,.sec-deep .pill,.sec-ink .pill{
  color:var(--cream);border-color:var(--lineDark)}
.hero .pill.on,.hero-sm .pill.on,.calc .pill.on,.sec-deep .pill.on,.sec-ink .pill.on{
  background:var(--cream);color:var(--deep);border-color:var(--cream)}
.hero .pill:hover,.hero-sm .pill:hover,.calc .pill:hover{border-color:var(--tan)}

/* ---- a callout is a dark panel wherever it is not itself inside one, so the
   dashed list in it takes the on-dark colour the section rules would give it */
.callout .dash li{color:var(--onDark)}
.callout .dash li strong{color:#fff}
.hero-sm .callout .dash li,.sec-deep .callout .dash li,.sec-ink .callout .dash li{color:var(--muted)}
.hero-sm .callout .dash li strong,.sec-deep .callout .dash li strong,
.sec-ink .callout .dash li strong{color:var(--ink)}

/* ---- a brown door inside a dark section: the section rule gives its eyebrow
   --tan, which is 2.78:1 on brown. The brown band's own eyebrow colour is the
   one that belongs here. */
.door-brown .eyebrow,.door-brown .lbl{color:var(--tan3)}

/* ============================================================
   NON-TEXT CONTRAST (WCAG 1.4.11)
   ------------------------------------------------------------
   A control has to be findable before its label matters, and the
   text harness cannot see this: a field with a --lineDark edge on
   --deep is 1.27:1, so the label reads perfectly and the box it
   belongs to is invisible. Every value below is measured against
   the ground named, and only CONTROLS are touched: a card that
   separates by shadow is not a control and is left alone.
   ============================================================ */
/* the newsletter field keeps its dark fill and gains an edge that can be seen */
.news input,#alerts input{border-color:var(--chartdim)}      /* 3.26:1 on --deep */
.calc select,.calc input[type=number]{border-color:var(--chartdim)}
.lb-nav{border-color:var(--chartdim)}
/* the platform pills, both rows */
.pill{border-color:var(--soft)}                              /* 5.61:1 on --paper */
.hero .pill,.hero-sm .pill,.calc .pill,.sec-deep .pill,.sec-ink .pill{
  border-color:var(--chartdim)}                              /* 3.26:1 on --deep */
/* a form field on paper: --rule2 was 1.49:1 against --paper2 */
.field input,.field textarea,.field select{border-bottom-color:var(--soft)}
.formcard .field input,.formcard .field textarea,.formcard .field select{
  border-bottom-color:var(--soft)}
/* a dark or outlined button dropped on the brown band. --tan is 2.78:1 there,
   which is the one place the outline pair does not carry. */
.sec-brown a.btn.btn-dark,.sec-brown .btn.btn-dark,
.tier.feature a.btn.btn-dark,.tier.feature .btn.btn-dark{
  border-color:var(--tan3)}                                  /* 4.68:1 on --brown */
.sec-brown a.btn.btn-lineD,.sec-brown .btn.btn-lineD,
.tier.feature a.btn.btn-lineD,.tier.feature .btn.btn-lineD,
.prod.cta a.btn.btn-lineD,.prod.cta .btn.btn-lineD,
.darkpanel a.btn.btn-lineD,.darkpanel .btn.btn-lineD,
.fmbox a.btn.btn-lineD,.fmbox .btn.btn-lineD{border-color:var(--tan2)}  /* 3.78:1 */
/* --btn-brown on --deep is 1.81:1, so the contact panel's own send button had
   no edge against the panel it sits in. */
.darkpanel a.btn.btn-brown,.darkpanel .btn.btn-brown,
.darkpanel button.btn-brown{border-color:var(--tan2)}

/* ---- the pale form card on the brown band, continued -------------------
   .moredetail and .small are written on-brown and both appear inside a
   .formcard, which is --panel: 1.07:1 and 1.09:1. */
.formcard .moredetail{border-top-color:var(--rule2)}
.formcard .moredetail summary{color:var(--brown)}
.formcard .moredetail summary:hover{color:var(--ink)}
.formcard .moredetail summary span{color:var(--soft);opacity:1}
.sec-brown .formcard .small,.formcard .small{color:var(--muted)}
.sec-brown .formcard .note,.sec-brown .formcard .lbl{color:var(--soft)}

/* ---- the last outline button on the brown band. --tan is 2.78:1 there, which
   the .btn-dark and .btn-lineD rules above already work around; .btn-line was
   the one left holding it. */
.sec-brown a.btn.btn-line,.sec-brown .btn.btn-line,
.tier.feature a.btn.btn-line,.tier.feature .btn.btn-line{border-color:var(--tan2)}

/* ---- the pop-out's own submit button ----------------------------------
   .fmbox is --inkBg. --ink on it is 1.08:1 and --brown 2.78:1, so on 13 of the
   38 pop-outs the button had a perfectly legible label and no visible edge.
   uicontrast.js cannot see this: the box is display:none until it opens. */
.fmbox a.btn.btn-dark,.fmbox .btn.btn-dark,.fmbox button.btn-dark{
  border-color:var(--tan3)}                                  /* 13.01:1 on --inkBg */
.fmbox a.btn.btn-brown,.fmbox .btn.btn-brown,.fmbox button.btn-brown{
  border-color:var(--tan2)}                                  /*  9.95:1 on --inkBg */

/* ---- placeholders on a light ground -----------------------------------
   There were only on-dark placeholder rules, because on the near-black palette
   every form was on a dark band. On paper the browser default #757575 is
   4.31:1, just under AA, on 38 fields across 7 pages. */
.field ::placeholder,.formcard .field ::placeholder{color:var(--soft);opacity:1}
