/* ============================================================================
   pushpact — landing page
   Ported from the Claude Design source (pushpact.dc.html). Values are copied
   verbatim from that file; where the original used inline styles on every
   element, they are collected here as classes so the markup stays readable.
   ============================================================================ */

/* ---- fonts: self-hosted so nothing silently falls back to Inter ---------- */
@font-face { font-family:'Geist'; src:url("/assets/Geist-Regular-8a3e8476.ttf") format('truetype');
  font-weight:400; font-style:normal; font-display:swap }
@font-face { font-family:'Geist'; src:url("/assets/Geist-Medium-47e964c4.ttf") format('truetype');
  font-weight:500; font-style:normal; font-display:swap }
@font-face { font-family:'Geist'; src:url("/assets/Geist-SemiBold-50cda242.ttf") format('truetype');
  font-weight:600; font-style:normal; font-display:swap }
@font-face { font-family:'Geist'; src:url("/assets/Geist-Bold-294f691e.ttf") format('truetype');
  font-weight:700; font-style:normal; font-display:swap }
@font-face { font-family:'Geist Mono'; src:url("/assets/GeistMono-Regular-ea20bf74.ttf") format('truetype');
  font-weight:400; font-style:normal; font-display:swap }
@font-face { font-family:'Geist Mono'; src:url("/assets/GeistMono-Medium-83dd5059.ttf") format('truetype');
  font-weight:500; font-style:normal; font-display:swap }

/* ---- tokens (Voltage, locked) ------------------------------------------- */
:root{
  --ink-950:#101114; --ink-900:#191B1F; --ink-800:#22252A; --ink-700:#2E323A;
  --ink-600:#33373F; --ink-500:#666C77; --ink-300:#A2A8B3;
  --chalk-050:#F2F3F5; --chalk-100:#E4E6EA; --chalk-200:#D3D6DB; --chalk-300:#C3C7CE;
  /* ink-500 measures 4.23:1 on chalk-100 and 3.57:1 on ink-950 — both under AA for
     small text. These two are the accessible variants for those exact surfaces. */
  --ink-500-on-light:#585E68;   /* 5.23:1 on chalk-100, 5.88:1 on chalk-050 */
  --ink-500-on-dark:#7E8590;    /* 5.07:1 on ink-950,  4.63:1 on ink-900   */
  --volt-700:#4E650A; --volt-400:#C6F24E; --volt-300:#D6FB70;
  --sans:'Geist',-apple-system,BlinkMacSystemFont,'Helvetica Neue',Arial,sans-serif;
  --mono:'Geist Mono','SF Mono',ui-monospace,monospace;
  --pad-x:clamp(20px,4vw,56px);
  --sec-y:clamp(64px,8vw,128px);
  --maxw:1360px;
}

*{box-sizing:border-box}
/* Nothing may exceed its container. body{overflow-x:hidden} hides overflow, which
   means an automated scrollWidth check reports a clean page while text is being
   clipped mid-word — exactly how the mobile subhead shipped cut off. */
img,svg,video,table,pre{max-width:100%}
html{-webkit-text-size-adjust:100%}
body{
  margin:0; background:var(--ink-950); color:var(--chalk-100);
  font-family:var(--sans); -webkit-font-smoothing:antialiased;
  overflow-x:hidden; width:100%;
}
a{color:inherit; text-decoration:none}
a:hover{color:var(--volt-400)}
img{display:block}

@keyframes pp-pulse{0%,100%{opacity:1} 50%{opacity:.25}}
@keyframes pp-rise{from{opacity:0;transform:translateY(16px)} to{opacity:1;transform:none}}
@keyframes pp-cell{from{opacity:0;transform:scaleY(.35)} to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation:none !important; transition:none !important}
}

/* ---- shared -------------------------------------------------------------- */
.wrap{max-width:var(--maxw); margin:0 auto}
.mono-label{font:500 10px/1.3 var(--mono); letter-spacing:.16em; text-transform:uppercase; color:var(--ink-500-on-light)}

/* ink-500 measures 3.57:1 on ink-950 — under AA for small text. Every dark
   surface therefore promotes the muted neutral rather than patching selectors
   one at a time; a DOM-wide contrast sweep found 14 instances of this after an
   earlier pass fixed only the four I had sampled. */
.sec--dark .mono-label,
.stats .mono-label, .stats .k,
.picker .mono-label,
.join .mono-label,
.site-footer .mono-label,
.figure-block__foot .mono-label{color:var(--ink-500-on-dark)}
.num{font-weight:700; letter-spacing:-.045em; font-variant-numeric:tabular-nums lining-nums; line-height:1}
/* .logo-slot removed 2026-07-31 — the real wordmark replaced both dashed
   placeholders and the rule matched nothing. */

/* ---- header -------------------------------------------------------------- */
.site-header{
  position:absolute; top:0; left:0; right:0; z-index:10;
  display:flex; align-items:center; justify-content:space-between;
  padding:24px var(--pad-x);
  background:linear-gradient(to bottom,rgba(16,17,20,.8) 0%,rgba(16,17,20,.45) 60%,rgba(16,17,20,0) 100%);
}
.site-header a{
  font:400 11px/1 var(--mono); letter-spacing:.14em; text-transform:uppercase;
  color:var(--chalk-050); border-bottom:1px solid rgba(242,243,245,.6);
  /* 44px minimum hit height without moving the underline. 11px line-box + 30 + 3
     lands at 44; the negative margin cancels the layout effect. */
  padding:30px 12px 3px; margin:-30px -12px -3px;
}

/* ---- hero ---------------------------------------------------------------- */
.hero{
  position:relative; width:100%; min-height:min(92vh,860px);
  display:flex; align-items:flex-end; background:var(--ink-950); z-index:2;
}
.hero__img{position:absolute; inset:0; width:100%; height:100%; object-fit:cover; object-position:52% 40%; z-index:-1}
.hero__scrim-v{position:absolute; inset:0; background:linear-gradient(to top,rgba(16,17,20,.94) 0%,rgba(16,17,20,.86) 30%,rgba(16,17,20,.62) 58%,rgba(16,17,20,.3) 80%,rgba(16,17,20,.45) 100%)}
.hero__scrim-h{position:absolute; inset:0; background:linear-gradient(to right,rgba(16,17,20,.55) 0%,rgba(16,17,20,.12) 55%,rgba(16,17,20,0) 100%)}
.hero__grid{
  position:relative; width:100%; padding:112px var(--pad-x) 0;
  display:grid; grid-template-columns:repeat(auto-fit,minmax(330px,1fr));
  gap:clamp(32px,4vw,64px); align-items:end;
}
/* `max-width` is new: the hero used to be two columns and the device on the
   right is what stopped the copy running the width of a desktop. With one
   child, `auto-fit` gives this the whole row, and an 84px h1 measured across
   1600px is a headline nobody finishes. */
.hero__copy{max-width:min(56ch,100%); padding-bottom:clamp(36px,5vw,64px); animation:pp-rise 760ms cubic-bezier(.2,.7,.3,1) both}
.badge{
  display:inline-flex; align-items:center; gap:9px;
  border:1px solid rgba(228,230,234,.25); padding:7px 12px; margin-bottom:24px;
  /* 10px mono sitting straight on the hero photograph measured 2.31:1 against
     the actual pixels. Strengthening the hero scrim enough to carry text this
     small would have flattened the photograph, so the badge carries its own
     plate instead — it already reads as a bordered pill, and the plate is the
     shape the border was implying. */
  background:rgba(16,17,20,.68);
}
.badge i{width:6px; height:6px; background:var(--volt-400); animation:pp-pulse 1.8s ease-in-out infinite; display:inline-block}
.badge span{font:400 10px/1 var(--mono); letter-spacing:.14em; text-transform:uppercase; color:var(--chalk-100)}
.hero h1{
  margin:0; max-width:min(15ch,100%); font-size:clamp(40px,5.6vw,84px); line-height:.98;
  letter-spacing:-.03em; font-weight:500; color:var(--chalk-050); text-wrap:balance;
}
.hero__sub{margin:22px 0 0; max-width:min(46ch,100%); font-size:clamp(15px,1.35vw,19px); line-height:1.5; color:var(--chalk-100); font-weight:300; text-wrap:pretty}
.hero__cta-row{display:flex; flex-wrap:wrap; align-items:center; gap:20px; margin-top:32px}
.btn-volt{
  display:inline-flex; align-items:center; gap:12px; background:var(--volt-400);
  color:var(--ink-950); padding:15px 24px; font-size:15px; font-weight:500;
  letter-spacing:-.01em; border:0; cursor:pointer; font-family:var(--sans);
}
.btn-volt:hover{background:var(--volt-300); color:var(--ink-950)}
.cta-note{font:400 11px/1.4 var(--mono); letter-spacing:.1em; color:var(--ink-300); text-transform:uppercase; min-width:0}

/* ---- hero device — DELETED 2026-08-10 ------------------------------------
   Thirty lines drew a phone containing a screen the app does not render: a
   scrimmed photograph with "day 03 / 14", a pulsing counting dot, an animated
   rep counter, a progress bar and "on device · nothing uploaded" set in the
   app's own mono. It was a mockup, and it was the largest claim on the page.
   The comment that used to sit here measured its contrast ratios, which is how
   carefully a thing that was never real got maintained.

   `.hero__grid` is `auto-fit`, so one child fills the row — `.hero__copy` now
   carries its own measure instead of getting one from a neighbour. When the
   real captures land (`web/script/capture-app-screens.sh`) they go in as
   images with their own rules; none of the above returns. */

/* ---- stat strip ---------------------------------------------------------- */
.stats{background:var(--ink-950); border-top:1px solid var(--ink-800);
  padding:clamp(28px,3vw,40px) var(--pad-x) clamp(28px,3vw,44px); position:relative; z-index:1}
/* Was a wrapping flex row of natural-width items with a single large `gap`.
   Two problems, and they compound: the items size to their labels, so a longer
   label pushes the fourth one onto its own line; and a single `gap` value sets
   the ROW gap as well, so that stranded fourth item landed ~88px below three
   items sitting alone on the line above. A grid fixes both — four equal columns
   that never depend on label length, a tight row gap, and a deliberate 2x2 at
   narrow widths instead of an accidental 3+1. */
.stats__inner{display:grid; grid-template-columns:repeat(4,minmax(0,1fr));
  column-gap:clamp(16px,2vw,40px); row-gap:32px; max-width:var(--maxw);
  margin:0 auto; padding-right:clamp(0px,30vw - 60px,280px)}
@media (max-width:900px){
  .stats__inner{grid-template-columns:repeat(2,minmax(0,1fr)); padding-right:0}
}
.stats .num{font-size:clamp(30px,3.4vw,46px); color:var(--chalk-050)}
.stats .k{margin-top:8px; font:400 10px/1.3 var(--mono); letter-spacing:.14em; text-transform:uppercase; color:var(--ink-500-on-dark)}

/* ---- sections ------------------------------------------------------------ */
.sec{padding:var(--sec-y) var(--pad-x)}
.sec--light{background:var(--chalk-050); color:var(--ink-900)}
.sec--mid{background:var(--chalk-100); color:var(--ink-900)}
.sec--dark{background:var(--ink-950); color:var(--chalk-100)}
.sec h2{margin:20px 0 0; line-height:1.02; letter-spacing:-.03em; font-weight:500; text-wrap:balance}
.sec__lede{margin:20px 0 0; line-height:1.55; font-weight:300; text-wrap:pretty}

.split{display:grid; grid-template-columns:repeat(auto-fit,minmax(320px,1fr)); gap:clamp(36px,5vw,80px)}
.split--center{align-items:center}
.split--start{align-items:start}

/* ---- step cards ---------------------------------------------------------- */
.steps{display:grid; grid-template-columns:repeat(auto-fit,minmax(240px,1fr)); gap:1px;
  background:var(--chalk-200); margin-top:clamp(40px,5vw,72px);
  border-top:1px solid var(--chalk-200); border-bottom:1px solid var(--chalk-200)}
.step{background:var(--chalk-050); padding:28px 24px 32px}
.step__n{font:400 10px/1 var(--mono); letter-spacing:.16em; color:var(--volt-700)}
.step h3{margin:18px 0 0; font-size:21px; line-height:1.25; font-weight:500; letter-spacing:-.02em}
.step p{margin:10px 0 0; font-size:15px; line-height:1.5; color:var(--ink-500-on-light); font-weight:300}

/* ---- full-bleed image band ----------------------------------------------- */
.band{position:relative; width:100%; height:min(70vh,620px); background:var(--ink-950)}
.band img{position:absolute; inset:0; width:100%; height:100%; object-fit:cover; object-position:30% 50%}

/* ---- counting section ---------------------------------------------------- */
.pullquote{margin:22px 0 0; max-width:min(46ch,100%); font-size:16px; line-height:1.6;
  color:var(--chalk-100); border-left:2px solid var(--volt-400); padding-left:18px; font-weight:300}
.figure-block{display:flex; flex-direction:column; gap:16px}
.figure-block__img{position:relative; width:100%; aspect-ratio:3/2; overflow:hidden; background:var(--ink-900)}
.figure-block__img img{width:100%; height:100%; object-fit:cover}
/* `.figure-block__foot` — the "Counting — 18 / 25" strip under the section 02
   photograph — went with the hero device on 2026-08-10. Same objection: a rep
   total the page invented, set in the type the app uses for real ones. The
   rules stay defined because the element is a plain caption bar and the next
   thing under a photograph will want one; nothing renders it today. */
.figure-block__foot{display:flex; align-items:baseline; justify-content:space-between;
  border-top:1px solid var(--ink-800); padding-top:16px}
.figure-block__foot .num{font-size:40px; color:var(--volt-400)}

/* ---- day grid ------------------------------------------------------------ */
.grid-head{display:flex; flex-wrap:wrap; gap:24px; align-items:flex-end; justify-content:space-between; margin-top:20px}
.grid-head h2{margin:0; max-width:min(16ch,100%); font-size:clamp(28px,3.6vw,52px); text-wrap:balance}
.grid-stats{display:flex; gap:28px}
.grid-stats .num{font-size:clamp(26px,2.6vw,36px)}
.grid-stats .k{margin-top:6px; font:400 10px/1 var(--mono); letter-spacing:.14em; text-transform:uppercase; color:var(--ink-500-on-light)}
.daygrid{margin-top:clamp(32px,4vw,56px); overflow:hidden}
.daygrid__row{display:grid; grid-template-columns:clamp(76px,9vw,124px) 1fr; gap:clamp(8px,1.2vw,18px); align-items:center}
.daygrid__row + .daygrid__row{margin-top:clamp(3px,.5vw,7px)}
.daygrid__cells{display:grid; grid-template-columns:repeat(14,minmax(0,1fr)); gap:clamp(3px,.5vw,7px)}
.daygrid__daynum{font:400 10px/1 var(--mono); letter-spacing:.04em; color:var(--ink-500-on-light); text-align:center}
/* A row used to be labelled 001..014, which read as a spreadsheet export. The
   monogram is generated from the name, so there is no avatar asset to ship and
   nothing that looks like a photograph of a person who does not exist. The
   tiles are deliberately all one colour: volt already means "day missed" in
   the cells to their right, and a second meaning for the same colour in the
   same graphic is worse than no highlight. */
.daygrid__who{display:flex; align-items:center; gap:9px; min-width:0}
.daygrid__av{flex:none; width:22px; height:22px; border-radius:50%;
  background:var(--ink-700); color:var(--chalk-050);
  font:500 10px/22px var(--mono); text-align:center; text-transform:uppercase}
.daygrid__name{font:400 12px/1 var(--sans); color:var(--ink-500-on-light);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
@media (max-width:560px){ .daygrid__name{display:none} }
.cell{height:clamp(16px,2vw,28px)}
.cell--hit{background:var(--ink-900)}
.cell--miss{background:var(--volt-400)}
/* .cell--dead — the greyed-out "you are out" state — removed 2026-08-03 with
   elimination. The grid has two states now: hit and missed. */
.legend{display:flex; flex-wrap:wrap; gap:clamp(14px,2vw,28px); margin-top:28px; align-items:center}
.legend > span{display:flex; align-items:center; gap:8px}
.legend i{width:14px; height:14px; display:inline-block}
.legend em{font:400 10px/1 var(--mono); letter-spacing:.12em; text-transform:uppercase; color:var(--ink-500-on-light); font-style:normal}
.legend .disclaimer{font:400 10px/1 var(--mono); letter-spacing:.12em; text-transform:uppercase; color:var(--ink-500-on-light); margin-left:auto}

/* ---- picker -------------------------------------------------------------- */
.picker{margin-top:36px; border:1px solid var(--ink-800); background:var(--ink-900)}
.picker__top{display:flex; align-items:center; justify-content:space-between; padding:20px 24px; border-bottom:1px solid var(--ink-800)}
.picker__ctrls{display:flex; align-items:center; gap:18px}
.picker__btn{width:44px; height:44px; background:transparent; border:1px solid var(--ink-700);
  color:var(--chalk-100); font-size:18px; cursor:pointer; line-height:1; font-family:var(--sans)}
.picker__btn:hover{border-color:var(--volt-400); color:var(--volt-400)}
.picker__n{min-width:2.6ch; text-align:center; font-size:clamp(40px,4.4vw,60px); color:var(--volt-400)}
.picker__presets{display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:8px; padding:20px 24px; border-bottom:1px solid var(--ink-800)}
.preset{width:100%; min-height:44px; padding:11px 0; background:transparent; border:1px solid var(--ink-700);
  color:var(--ink-300); font:400 12px/1 var(--mono); cursor:pointer; font-variant-numeric:tabular-nums}
.preset:hover{border-color:#4a5058; color:var(--chalk-100)}
.preset[aria-pressed="true"]{border-color:var(--volt-400); color:var(--volt-400)}
.picker__total{display:flex; align-items:baseline; justify-content:space-between; padding:22px 24px}
.picker__total .num{font-size:clamp(28px,3vw,40px); color:var(--chalk-050)}
.picker__img{position:relative; width:100%; aspect-ratio:4/5; overflow:hidden; background:var(--ink-900)}
.picker__img img{width:100%; height:100%; object-fit:cover}

/* ---- stakes -------------------------------------------------------------- */
.stakes{margin-top:clamp(40px,5vw,72px); border-top:1px solid var(--chalk-200)}
.stakes__cells{display:grid; grid-template-columns:repeat(auto-fit,minmax(210px,1fr)); gap:1px; background:var(--chalk-200)}
.stakes__cell{background:var(--chalk-050); padding:32px 24px 36px}
.stakes__cell .num{margin-top:14px; font-size:clamp(38px,4.4vw,64px)}
.stakes__cell--accent .mono-label, .stakes__cell--accent .num{color:var(--volt-700)}
.stakes__foot{border-top:1px solid var(--chalk-200); padding-top:14px;
  font:400 10px/1.4 var(--mono); letter-spacing:.12em; text-transform:uppercase; color:var(--ink-500-on-light)}

/* ---- quote band ---------------------------------------------------------- */
.quoteband{position:relative; width:100%; min-height:min(80vh,720px); display:flex; align-items:center; background:var(--ink-950)}
.quoteband img{position:absolute; inset:0; width:100%; height:100%; object-fit:cover; object-position:60% 50%}
.quoteband__scrim{position:absolute; inset:0; background:linear-gradient(to right,rgba(16,17,20,.9) 0%,rgba(16,17,20,.55) 45%,rgba(16,17,20,.1) 100%)}
.quoteband__inner{position:relative; padding:clamp(48px,6vw,88px) var(--pad-x); max-width:var(--maxw); margin:0 auto; width:100%}
.quoteband h2{margin:0; max-width:min(17ch,100%); font-size:clamp(28px,3.8vw,54px); line-height:1.03; letter-spacing:-.03em; font-weight:500; color:var(--chalk-050); text-wrap:balance}

/* ---- faq ----------------------------------------------------------------- */
.faq__item{border-top:1px solid var(--chalk-200); padding:22px 0}
.faq__item h3{margin:0; font-size:17px; font-weight:500; letter-spacing:-.015em}
.faq__item p{margin:8px 0 0; max-width:min(56ch,100%); font-size:15px; line-height:1.55; color:var(--ink-500-on-light); font-weight:300}
.reserved{border:1px dashed var(--chalk-300); padding:26px 24px}
.reserved p{margin:10px 0 0; font-size:15px; line-height:1.5; color:var(--ink-500-on-light); font-weight:300}

/* ---- join ---------------------------------------------------------------- */
.join{position:relative; width:100%; background:var(--ink-950); display:flex; align-items:flex-end; min-height:min(88vh,780px)}
.join > img{position:absolute; inset:0; width:100%; height:100%; object-fit:cover; object-position:35% 55%}
.join__scrim{position:absolute; inset:0; background:linear-gradient(to top,rgba(16,17,20,.95) 6%,rgba(16,17,20,.45) 48%,rgba(16,17,20,.15) 100%)}
.join__inner{position:relative; width:100%; padding:0 var(--pad-x) clamp(48px,6vw,88px)}
.join h2{margin:0; max-width:min(14ch,100%); font-size:clamp(34px,5.2vw,76px); line-height:.99; letter-spacing:-.03em; font-weight:500; color:var(--chalk-050); text-wrap:balance}
.join__form{display:flex; flex-wrap:wrap; gap:12px; align-items:center; margin-top:32px}
.join__form input[type=email]{
  flex:1 1 280px; max-width:400px; background:rgba(16,17,20,.72); border:1px solid var(--ink-600);
  color:var(--chalk-050); font:400 16px/1 var(--sans); padding:16px 18px;
}
.join__form input[type=email]::placeholder{color:var(--ink-500-on-dark)}
.join__form input[type=email]:focus{outline:none; border-color:var(--volt-400)}
.join__note{font:400 11px/1.5 var(--mono); letter-spacing:.1em; text-transform:uppercase; color:var(--ink-300); margin-top:16px}
.flash{margin-top:18px; padding:16px 20px; border-left:3px solid var(--volt-400);
  background:rgba(198,242,78,.10); font-size:16px; line-height:1.45;
  color:var(--chalk-050); max-width:min(52ch,100%); scroll-margin-top:80px}
.flash--error{border-left-color:#E0665C; background:rgba(224,102,92,.08)}

/* ---- footer -------------------------------------------------------------- */
.site-footer{background:var(--ink-950); color:var(--ink-300); border-top:1px solid var(--ink-800);
  padding:clamp(40px,5vw,64px) var(--pad-x)}
.site-footer__top{max-width:var(--maxw); margin:0 auto; display:flex; flex-wrap:wrap; gap:32px;
  justify-content:space-between; align-items:flex-start}
.site-footer__brand{display:flex; flex-direction:column; gap:16px}
.site-footer__cols{display:flex; gap:clamp(28px,4vw,72px); flex-wrap:wrap}
.site-footer__col{display:flex; flex-direction:column; gap:2px}
.site-footer__col > span{font:400 10px/1 var(--mono); letter-spacing:.14em; text-transform:uppercase; color:var(--ink-500-on-dark)}
.site-footer__col a{font-size:14px; font-weight:300; padding:13px 0; margin:-13px 0}
.site-footer__legal{max-width:var(--maxw); margin:40px auto 0; border-top:1px solid var(--ink-800);
  padding-top:18px; font:400 10px/1.5 var(--mono); letter-spacing:.1em; text-transform:uppercase; color:var(--ink-500-on-dark)}

/* ---- accessibility ------------------------------------------------------- */
.visually-hidden{position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0}
:focus-visible{outline:2px solid var(--volt-400); outline-offset:2px}

/* ---------------------------------------------------------------------------
   Narrow viewports — the scrims, re-aimed.

   The hero and quote-band scrims are HORIZONTAL gradients. That is correct on
   a wide screen, where the copy occupies the left column and the gradient is
   dense exactly where the words are, leaving the right side of the photograph
   open. It stops being correct the moment the layout stacks: the copy goes
   full-bleed and runs straight off the transparent end of its own scrim.

   Measured at a true 390px against the rendered pixels rather than the
   computed background:

     hero h1                                              2.11:1  (needs 3)
     quote band h2                                        1.94:1  (needs 3)
     hero subhead                                         2.62:1  (needs 4.5)
     "iPhone app · TestFlight beta"                       1.75:1  (needs 4.5)

   Measured 2026-08-02, against the copy that was in those elements then. The
   words changed on 2026-08-03; the type sizes and the scrims did not, so the
   ratios still hold.

   One of those is the headline and the other is the first sentence anyone
   reads. Both were failing on the only device this product runs on.

   The DOM-computed sweep reported zero failures here and was not wrong about
   what it measured — the photograph is an <img> painted over an opaque section
   background, so reading `background-color` up the ancestor chain returns
   #101114 for text that is actually sitting on a lit shoulder. Text over
   photography has to be measured in pixels.

   These raise the floor at the transparent end rather than flattening the
   gradient, so the photograph still reads as a photograph. -------------------- */
@media (max-width:700px){
  /* Weighted toward the middle, where the 15px/300 subhead sits — that line is
     the binding constraint here, not the headline. The h1 clears its 3:1 with
     room to spare, so the top of the ramp is deliberately lighter and the
     photograph survives above the copy. */
  .hero__scrim-v{background:linear-gradient(to top,rgba(16,17,20,.94) 0%,rgba(16,17,20,.88) 30%,rgba(16,17,20,.74) 58%,rgba(16,17,20,.56) 80%,rgba(16,17,20,.54) 100%)}
  .hero__scrim-h{background:linear-gradient(to right,rgba(16,17,20,.55) 0%,rgba(16,17,20,.34) 55%,rgba(16,17,20,.26) 100%)}
  .quoteband__scrim{background:linear-gradient(to right,rgba(16,17,20,.9) 0%,rgba(16,17,20,.84) 45%,rgba(16,17,20,.78) 100%)}
}

/* ---- wordmark -------------------------------------------------------------
   The dashed logo-slot placeholders are gone; this is the real thing. Drawn as
   a stroked skeleton and inlined, so it inherits currentColor and one file
   serves both the header (on a photograph) and the footer (on near-black).

   The viewBox is 1200x320, but only 120 of those 320 units are x-height — the
   rest is ascender and descender room. So a 30px-tall box renders 11px of
   actual letter. Sizes below are set from the width, which is what the eye
   reads, and were checked at the real header size in both polarities rather
   than picked to look right in a comp.

   The favicon placeholder that sat in the footer is gone too, along with its
   rules. It was telling visitors about an unfinished internal task. The mark
   itself is still unbuilt — the candidate lifted from this wordmark read as a
   capital P, straight into the Product Hunt / Pinterest / Patreon / Peloton /
   Pushscroll collision the brief bans — but that is a note for the brand repo,
   not for the page. Evidence:
   brand/concepts-wordmark/x-mark-p-FAILED-reads-as-cap-P.svg. ----------------- */
.wordmark{display:block; height:auto}
.wordmark--header{width:112px; color:var(--chalk-050)}
.wordmark--footer{width:128px; color:var(--chalk-050)}
/* Written as `.site-header a.site-header__home` on purpose. The existing
   `.site-header a` rule gives every header link an underline and 30px of top
   padding — correct for the "Join" nav link, wrong under a wordmark. A plain
   `.site-header__home` selector loses to it on specificity and the underline
   returns. 44px minimum hit target, without moving the mark. */
.site-header a.site-header__home{
  display:inline-flex; align-items:center; border-bottom:0;
  padding:8px 10px; margin:-8px -10px;
}
.site-header a.site-header__home:hover .wordmark{color:var(--volt-400)}
/* Complete legal copy is rendered verbatim so the web agreement stays byte-aligned with the app. */
.legal-document {
  max-width: 78ch;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  font: inherit;
  line-height: 1.6;
}
