/* hireianflaherty.com — single stylesheet, no build step.
   CACHE RULE: served immutable for a year as /css/site.css?v=N. Any edit here
   MUST bump the ?v= in index.html, 404.html, and both Link: lines in _headers.
   Grep "site.css?v=" — four hits, all must match.

   THE COMPOSITION — one black scroll, one axis. The page is not sections; it
   is a single canvas where hierarchy is type scale, sideways shifts of the
   axis, and gaps of deliberately uneven height.

   THE LAWS:
   · the diagonal is the SIGNATURE, not the wallpaper: it appears only on
     the green commitments — the hero field, the \$2,400 bar, the email
     bar, the button, and the page-end horizon blade. Green is never a
     flood: it is elements, not grounds (the hero field is the one
     exception and it earns it). Every neutral element (chips, the sheet,
     tabs, bars, threads) is square or hairline; the window dots are the
     one circle family (window dots, the ask badges). Variety comes from
     the supporting shapes; identity comes from the diagonal staying
     scarce. Each list wears the form its content asks for: includes are
     pills, the estimates run on dot leaders, the ask counts on circles.
     The cuts share one slope (~0.30) — featured bar, email bar, button,
     each with per-breakpoint cut sizes so the slope survives shrinking.
     The hero field holds 0.30 only at its capped desktop geometry; on
     phones its edge steepens toward vertical by geometric necessity
     (a 0.30 slope cannot fit a 27%-wide, full-height field) — that is
     accepted, not drift. Two other angles are their own registers: the
     mark's channel (0.667, logo identity) and the page-end horizon
     blade (a near-flat ground plane). Don't "fix" any of them to match.
   · between those moments the page is quiet: no horizontal rules, no
     surfaces, no uppercase, no tracking. The quiet is what makes the
     three moments land.
   · mono is for machine output and dollar figures, nothing else.
     text-shadow and box-shadow are BANNED.
   · MOTION: one loop on the whole page (the wireframe building itself —
     restarted on first view by js/wire.js, the site's only script),
     hover responses on interactive elements only, smooth anchor glide.
     No scroll-triggered reveals — a reveal repeated per movement is the
     repetition trap. Everything transform/opacity, everything behind
     prefers-reduced-motion, nothing that moves layout.
   · five type levels. ONE left edge: every movement starts on the same
     axis, on desktop and phone alike. An indent large enough to notice
     reads as floating, not as rhythm — difference comes from type scale,
     gap size and the green moments, never from drifting the text right.
     The rhythm rule: within any ~900px of scroll there is a scale
     change, an artifact, or one of the green moments.
   · BREAKPOINTS are canonical and width-only, so every orientation of
     every device gets the same treatment at the same width: 480 (small
     phone), 640 (mobile), 900 (single column), 1150 (wide step), plus
     the surgical 901-960 band for the address. Do not invent new ones.
     Hover effects live behind (hover:hover) — touch gets none.

   Measured on #000: bone 18.3:1 · mute 6.5:1 · neon 15.8:1. */

:root {
  --ground: #000000;
  --panel:  #0c0e0d;
  --bone:   #f2efec;
  --mute:   #8b908c;
  --line:   #232825;
  --ghost:  #1c211e;
  --neon:   #00ff9d;
  --mono:   ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
}

/* ── base ─────────────────────────────────────────────────────────── */

* { box-sizing: border-box; }

html {
  color-scheme: dark;
  background: var(--ground);
  -webkit-text-size-adjust: 100%;
  scrollbar-color: var(--line) var(--ground);
}
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--bone);
  font: 400 16.5px/1.65 -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
}
/* NO overflow-x:hidden on body — it breaks position:sticky. */

img { max-width: 100%; display: block; }
a { color: inherit; }
::selection { background: var(--neon); color: var(--ground); }
:focus-visible { outline: 2px solid var(--neon); outline-offset: 3px; }

.wrap { max-width: 1080px; margin-inline: auto; padding-inline: 24px; }

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }
.measure { max-width: 54ch; }
.lede { font-size: 21px; line-height: 1.5; }
.sm { font-size: 14.5px; color: var(--mute); }

.skip {
  position: absolute; left: 24px; top: -48px; z-index: 30;
  background: var(--neon); color: var(--ground);
  padding: 10px 16px; font-weight: 700; font-size: 14px; text-decoration: none;
}
.skip:focus { top: 8px; }

/* ── header — its bottom border is the last rule until the footer ─── */

.top {
  position: sticky; top: 0; z-index: 10;
  background: var(--ground);
  border-bottom: 1px solid var(--line);
}
.top .wrap { display: flex; align-items: center; gap: 22px; min-height: 60px; }

.lock { display: flex; align-items: center; gap: 11px; text-decoration: none; }
.lock img { width: 32px; height: 32px; }
.lock span { font-size: 16.5px; font-weight: 800; letter-spacing: -.035em; white-space: nowrap; }

.top nav { display: flex; gap: 6px; margin-left: auto; }
.top nav a {
  font-size: 14px; font-weight: 700;
  color: var(--mute); text-decoration: none;
  padding: 12px 8px; white-space: nowrap;
  transition: color .2s;
}
@media (hover: hover) { .top nav a:hover { color: var(--bone); } }

@media (max-width: 640px) {
  /* the name stays visible on phones — a person, not just a glyph;
     14px next to the 32px mark fits beside three nav links at 320 */
  .lock span { font-size: 14px; }
  .lock { gap: 8px; }
  .top .wrap { gap: 10px; }
  .top nav { gap: 0; }
}

/* short screens — the hero gives up ornament before it gives up the ask */
@media (max-height: 660px) {
  .mv-hero .sub { font-size: 15px; line-height: 1.45; }
  .statchips { gap: 6px; }
  .statchips li { padding: 6px 12px; }
  .statchips b { font-size: 16px; }
  .statchips span { font-size: 11.5px; }
}

/* ── the flow: movements, not sections ────────────────────────────── */

section { border: 0; padding: 0; margin: 0; }
[id] { scroll-margin-top: 84px; }

/* gaps between movements — deliberately uneven. Kin ideas sit close
   (refusals→AI, 90px); subject changes breathe (into price and into the
   close, 220px). Mobile scales ×0.55. */
.mv-hero  { margin: 0 0 140px; padding-top: 72px; }   /* padding, not margin:
    the field is absolutely positioned to the movement's box, so this keeps
    its top edge meeting the header instead of floating below it. Every
    hero measure below also answers to viewport HEIGHT, so the whole first
    screen — headline, price, button, chips — lands without scrolling. */
@supports (height: 1svh) { .mv-hero { padding-top: clamp(28px, 6svh, 72px); } }
.mv-work  { margin: 0 0 220px; }
.mv-price { margin: 0 0 120px; }
.mv-own   { margin: 0 0 140px; }
.mv-fast  { margin: 0 0 100px; }
.mv-nos   { margin: 0 0 90px; }
.mv-ai    { margin: 0 0 220px; }
/* .mv-close's gap (150px / 90px mobile, down to the horizon blade) is
   set in the close's own block below */
@media (max-width: 640px) {
  .mv-hero  { margin: 0 0 78px; padding-top: 56px; padding-top: clamp(24px, 5svh, 56px); }
  .mv-work  { margin: 0 0 120px; }
  .mv-price { margin: 0 0 66px; }
  .mv-own   { margin: 0 0 66px; }
  .mv-fast  { margin: 0 0 56px; }
  .mv-nos   { margin: 0 0 50px; }
  .mv-ai    { margin: 0 0 120px; }
}

/* ── type: five levels ────────────────────────────────────────────── */

h1 {
  font-size: clamp(38px, 8.4vw, 104px);
  font-weight: 800; letter-spacing: -.045em; line-height: .92;
  margin: 0 0 26px;
}
@supports (height: 1svh) {
  h1 { font-size: clamp(34px, min(8.4vw, 11.5svh), 104px); margin-bottom: clamp(16px, 3svh, 26px); }
}
.dB {
  font-size: clamp(38px, 6vw, 84px);
  font-weight: 800; letter-spacing: -.04em; line-height: .98;
  margin: 0 0 26px;
}
h2:not(.dB) {
  font-size: 32px;
  font-weight: 800; letter-spacing: -.035em; line-height: 1.05;
  margin: 0 0 24px;
}
@media (max-width: 640px) { h2:not(.dB) { font-size: 26px; } }
h3 { font-size: 17px; font-weight: 700; letter-spacing: -.02em; margin: 0 0 6px; }

.accent { color: var(--neon); }   /* flat. */
h1 .accent { display: inline-block; }   /* the green phrase wraps as a unit */

/* ── hero: the first committed moment — a neon field cut at the mark's
      angle, with the mark itself set into it in black ─────────────── */

.mv-hero { position: relative; overflow: hidden; }
.mv-hero .wrap { position: relative; z-index: 1; }
.herofield {
  position: absolute; top: 0; right: 0; bottom: 0;
  width: 42%; max-width: 605px;   /* capped at its 1440 size: the clip's
     inset is a percentage, so an uncapped field steepens its slope on
     wide monitors and leaves the 0.30 family */
  background: var(--neon);
  /* left edge leans at the logo channel's slope: top further right,
     bottom further left */
  /* inset% = 0.30 slope × field height ÷ field width. The hero now sizes
     itself to the viewport's HEIGHT, so this lands on ~0.30 at a typical
     screen and drifts a little either side of it — near enough to read as
     the same cut as the button and the featured bar. */
  clip-path: polygon(41% 0, 100% 0, 100% 100%, 0 100%);
}
.herofield svg {
  position: absolute; right: 9%; bottom: 12%;
  width: 300px; height: 300px;
}
@media (max-width: 1150px) { .herofield { width: 34%; } .herofield svg { width: 220px; height: 220px; } }
@media (max-width: 900px)  { .herofield { width: 30%; } .herofield svg { width: 100px; height: 100px; right: 5%; bottom: 5%; } }
@media (max-width: 480px)  { .herofield { width: 27%; } .herofield svg { width: 80px; height: 80px; right: 4%; } }

/* ── hero ─────────────────────────────────────────────────────────── */

.sub { max-width: 46ch; margin-bottom: 26px; }
@supports (height: 1svh) {
  .mv-hero .sub { margin-bottom: clamp(14px, 3svh, 26px); font-size: clamp(16px, 2.3svh, 21px); }
}
.mv-hero h1 { max-width: 56%; }
@media (max-width: 900px) {
  .mv-hero h1 { max-width: 74%; }
  .mv-hero .sub, .mv-hero .priceline { max-width: 72%; }
}

.priceline {
  width: fit-content;
  font-size: 21px; font-weight: 700; letter-spacing: -.01em;
  font-variant-numeric: tabular-nums;
  margin-bottom: 30px;
}
@supports (height: 1svh) {
  .priceline { font-size: clamp(17px, 2.4svh, 21px); margin-bottom: clamp(16px, 3.2svh, 30px); }
}

.btn {
  display: inline-block; text-decoration: none;
  font-size: 15px; font-weight: 700; letter-spacing: -.01em;
  padding: 15px 26px; border: 1px solid;
  transition: background-color .2s, color .2s, border-color .2s, translate .2s;
}
/* hover travels the mark's own slope (2:3); press settles back.
   hover:hover keeps every hover effect off touch screens, where a tap
   would otherwise leave the button stuck in its hovered state */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .btn-primary:hover { translate: 2px -3px; }
  .btn-primary:active { translate: 0 0; }
}
.btn-primary {
  background: var(--neon); border-color: var(--neon); color: var(--ground);
  clip-path: polygon(0 0, 100% 0, calc(100% - 17px) 100%, 0 100%);
  padding-right: 34px;   /* 17px cut over the 57px button = the 0.30 slope */
}
@media (hover: hover) {
  .btn-primary:hover { background: var(--bone); border-color: var(--bone); }
}

/* stat chips: the hero's facts as objects, not a caption */
.statchips {
  list-style: none; margin: 40px 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 10px;
  max-width: 56%;   /* stays clear of the field's slanted edge at every width */
}
.statchips li {
  background: var(--panel); border: 1px solid var(--line);
  padding: 10px 16px;
}
@supports (height: 1svh) {
  .statchips { margin-top: clamp(16px, 3.2svh, 34px); }
  .statchips li { padding: clamp(7px, 1.4svh, 12px) 16px; }
}
.statchips b { display: block; font-size: 18px; font-weight: 800; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.statchips span { display: block; font-size: 12.5px; color: var(--mute); }
@media (max-width: 900px) {
  /* a real 2×2 grid, not flex-wrap: both rows share their edges */
  .statchips { display: grid; grid-template-columns: 1fr 1fr; grid-auto-rows: 1fr; max-width: 66%; gap: 8px;
    margin-top: 40px; margin-top: clamp(16px, 3.2svh, 34px); }
  .statchips li { padding: 10px 14px; }
}
@media (max-width: 480px) {
  /* small phones: sized so "1 person" and "you own it" hold one line */
  .statchips li { padding: 10px 12px; }
  .statchips b { font-size: 17px; }
}

/* ── two-column flow: text on the axis, artifact right ────────────── */

.flow2 {
  display: grid; grid-template-columns: minmax(0, 58ch) 440px;
  justify-content: space-between; gap: 32px 64px; align-items: start;
}
/* the artifact CENTRES in its column. A top offset used to push it down
   so it hung into the next gap, but that left a tall empty rectangle
   beside the heading — on a page selling design, a void reads as broken.
   Centred, the leftover space splits evenly and reads as breathing room. */
.straddle { align-self: center; margin: 0; }
@media (max-width: 900px) {
  .flow2 { grid-template-columns: 1fr; }
  .straddle { align-self: start; }
  .flow2 > .win, .flow2 > .relay { max-width: 460px; }
}

/* ── steps: run-in lines, no rules, no gutter ─────────────────────── */

.steps {
  list-style: none; margin: 40px 0 0; padding: 0; max-width: 58ch;
  position: relative;
}
.steps::before {   /* the thread that strings the sequence */
  content: ""; position: absolute; left: 25px; top: 10px; bottom: 14px;
  width: 1px; background: var(--line);
}
.steps li {
  position: relative;
  display: grid; grid-template-columns: 52px 1fr; gap: 18px;
  align-items: start; margin-bottom: 24px;
}
.steps .sno {   /* panel tab, bone numeral: with the wireframe's green CTA
  in the same screenful, even neon numerals blew the four-green budget */
  background: var(--panel); border: 1px solid var(--line); color: var(--bone);
  font-size: 15px; font-weight: 800; font-variant-numeric: tabular-nums;
  padding: 5px 0; text-align: center; margin-top: 1px;
}

/* ── window chrome: the page's only bordered objects ──────────────── */

.win { border: 1px solid var(--line); background: var(--panel); }
.winbar {
  display: flex; align-items: center; gap: 6px;
  padding: 10px 14px; border-bottom: 1px solid var(--line);
}
.winbar i { width: 9px; height: 9px; border-radius: 50%; background: var(--line); }
.winbar .wintitle { margin-left: 10px; font: 400 12px/1 var(--mono); color: var(--mute); }
.winbody { padding: 22px; }

.wire .bar { background: var(--ghost); }
.wire .w-nav { display: flex; align-items: center; gap: 10px; margin-bottom: 26px; }
.wire .w-dot { width: 14px; height: 14px; background: var(--ghost); }
.wire .w-nav .bar { height: 8px; width: 42px; }
.wire .w-nav .bar:last-child { margin-left: auto; width: 58px; }
.wire .w-h1 { height: 22px; width: 72%; margin-bottom: 10px; background: var(--line); }
.wire .w-h2 { height: 22px; width: 46%; margin-bottom: 22px; background: var(--line); }
.wire .w-p { height: 8px; margin-bottom: 9px; }
.wire .w-p1 { width: 88%; } .wire .w-p2 { width: 76%; } .wire .w-p3 { width: 58%; }
.wire .w-cta { height: 30px; width: 128px; background: var(--neon); margin-top: 20px; }
.wire .w-cols { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 12px; margin-top: 26px; }
.wire .w-cols .bar { height: 54px; }

/* THE one loop: the wireframe draws itself in, holds, clears, redraws.
   The site's claim acted out — "I build the site." scaleX/opacity only,
   so it stays composited; containers never animate, only the bars. */
@media (prefers-reduced-motion: no-preference) {
  .wire .w-h1, .wire .w-h2, .wire .w-p, .wire .w-cta,
  .wire .w-nav > *, .wire .w-cols > * {
    animation: wirebuild 10s infinite both;
    transform-origin: left center;
  }
  .wire .w-nav > :nth-child(1) { animation-delay: .1s; }
  .wire .w-nav > :nth-child(2) { animation-delay: .2s; }
  .wire .w-nav > :nth-child(3) { animation-delay: .3s; }
  .wire .w-nav > :nth-child(4) { animation-delay: .4s; }
  .wire .w-h1 { animation-delay: .6s; }
  .wire .w-h2 { animation-delay: .75s; }
  .wire .w-p1 { animation-delay: .95s; }
  .wire .w-p2 { animation-delay: 1.05s; }
  .wire .w-p3 { animation-delay: 1.15s; }
  .wire .w-cta { animation-delay: 1.4s; }
  .wire .w-cols > :nth-child(1) { animation-delay: 1.65s; }
  .wire .w-cols > :nth-child(2) { animation-delay: 1.75s; }
  .wire .w-cols > :nth-child(3) { animation-delay: 1.85s; }
  /* js/wire.js adds .seen when the window first scrolls into view;
     the twin animation name restarts the build from frame zero right
     then, so the viewer always arrives at the start of the show */
  .wire.seen .w-h1, .wire.seen .w-h2, .wire.seen .w-p, .wire.seen .w-cta,
  .wire.seen .w-nav > *, .wire.seen .w-cols > * { animation-name: wirebuild2; }
}
/* the relay: who talks to whom, drawn instead of argued. Its thread is
   the steps' thread; the neon edge sits on the node where judgment lives */
/* the relay fills the 440px flow2 column: its right edge holds the
   wrap's line, same as the wireframe and the sheet */
.rl-node { border: 1px solid var(--line); background: var(--panel); padding: 14px 18px; }
.rl-node b { display: block; font-size: 17px; letter-spacing: -.02em; }
.rl-node span { display: block; font-size: 13.5px; line-height: 1.5; color: var(--mute); margin-top: 2px; }
.rl-me { border-left: 6px solid var(--neon); padding-left: 13px; }
/* 13px = 18 - (6 - 1): the three nodes' text sits on one left edge */
.rl-link { width: 1px; height: 28px; background: var(--line); margin-left: 25px; }

@keyframes wirebuild {
  0%        { transform: scaleX(0); opacity: 0; }
  4%, 86%   { transform: scaleX(1); opacity: 1; }
  90%, 100% { transform: scaleX(0); opacity: 0; }
}
/* identical twin of wirebuild — exists only so swapping the name
   restarts the animation the moment .seen lands (see js/wire.js) */
@keyframes wirebuild2 {
  0%        { transform: scaleX(0); opacity: 0; }
  4%, 86%   { transform: scaleX(1); opacity: 1; }
  90%, 100% { transform: scaleX(0); opacity: 0; }
}


/* ── the price: pure typography, no box ───────────────────────────── */

/* the estimate sheet: the whole price block as one document object.
   Square by law — the diagonal belongs to the green commitments only */
.sheet {
  background: var(--panel); border: 1px solid var(--line);
  padding: 40px 44px 44px;
  margin-top: 44px;
}
@media (max-width: 640px) { .sheet { padding: 24px 20px 28px; } }

.pricegrid {
  display: grid; grid-template-columns: minmax(0, 440px) minmax(0, 40ch);
  justify-content: space-between; gap: 32px 72px; align-items: start;
}
.terms { margin-top: 48px; }
.terms h3 { margin-top: 24px; }
.terms h3:first-child { margin-top: 0; }
/* pills: what's included, as objects you can count at a glance */
.pills { list-style: none; margin: 4px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.pills li {
  background: var(--ground); border: 1px solid var(--line);
  padding: 7px 12px; font-size: 13.5px;
}
/* margin notes start lower than the ladder — notes on an estimate,
   not a two-column template */
.pricenotes { margin-top: 64px; max-width: 44ch; }
.pricenotes h3 { margin-top: 28px; }
.pricenotes h3:first-child { margin-top: 0; }
@media (max-width: 900px) {
  .pricegrid { grid-template-columns: 1fr; }
  .pricenotes { margin-top: 8px; }
}

.ladder { list-style: none; margin: 0; padding: 0; max-width: 460px; }
.ladder li {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 16px; margin-bottom: 18px;
}
.ladder .amt { font: 600 24px/1.2 var(--mono); }
/* the second moment: the most common price as a green diagonal bar */
.ladder .feat {
  background: var(--neon); color: var(--ground);
  margin-inline: -16px; padding: 12px 16px;   /* equal padding: the amount
     right-aligns with the rest of the money column; the cut only insets
     ~4px at cap height, so no glyph is clipped */
  clip-path: polygon(0 0, 100% 0, calc(100% - 18px) 100%, 0 100%);
}
.ladder .feat .cnt { font-size: 19px; font-weight: 700; }
.ladder .feat .amt { font-size: 32px; color: var(--ground); font-weight: 700; }
.ladder .feat .tag { color: #084d33; }
.ladder .tag { font-size: 13px; font-weight: 400; color: var(--mute); margin-left: 10px; }
@media (max-width: 480px) {
  /* stack the tag deliberately instead of letting it wrap raggedly;
     the shorter bar takes a shorter cut so the slope stays ~0.30 */
  .ladder .feat .amt { font-size: 26px; }
  .ladder .feat { clip-path: polygon(0 0, 100% 0, calc(100% - 23px) 100%, 0 100%); }
  .ladder .tag { display: block; margin: 2px 0 0; }
}
.pastfive { font-size: 14.5px; color: var(--mute); margin: 4px 0 0; }

/* dot leaders: the estimates read like a good menu */
.lands { list-style: none; margin: 8px 0 0; padding: 0; }
.lands li { margin-bottom: 14px; }
.lands .lrow { display: flex; align-items: baseline; gap: 10px; }
.lands .who { font-weight: 700; white-space: nowrap; }
.lands .lead { flex: 1; border-bottom: 2px dotted #39413c; transform: translateY(-4px); min-width: 24px; }
.lands .sum { font: 600 15px/1.4 var(--mono); white-space: nowrap; }
.lands .pages { display: block; color: var(--mute); font-size: 13.5px; margin-top: 3px; }
/* on phones the sheet is the longest quiet run on the page — the dollar
   rows step up a size so the scroll keeps a beat inside it */
@media (max-width: 640px) {
  .lands .who { font-size: 17px; }
  .lands .sum { font-size: 18px; }
}

/* the one pulled quote. It sits ON the page's single left edge like
   everything else — an indent big enough to notice reads as floating,
   not as rhythm. Difference comes from scale and gap, not from drift. */
.jab { margin: 72px 0 0; max-width: 46ch; }

/* ── ownership: the sideways shift announces the thought ──────────── */

.ownblock {
  /* on the page's left edge; the bar is the only thing that sits in the
     margin, and its 36px is why this text alone starts slightly inside */
  margin-left: 0; max-width: 52ch;
  position: relative; padding-left: 36px;
}
.ownblock::before {   /* the mark's channel, six units wide — straight,
  like every neutral edge; the slant stays with the green commitments */
  content: ""; position: absolute; left: 0; top: 12px; bottom: 8px;
  width: 6px; background: var(--neon);
}
.ownblock p { max-width: 46ch; }


/* the pull line: the page's one spoken-aloud sentence. It lives in the
   AI movement's 58ch column, so the cap is what keeps "I'm the one on
   the hook for it." to one line */
.pull {
  margin: 44px 0 0;
  font-size: clamp(25px, 2.2vw, 30px); font-weight: 800;
  letter-spacing: -.035em; line-height: 1.12;
}
.pull::after {
  content: ""; display: block; width: 190px; height: 8px; margin-top: 20px;
  background: var(--neon);
}

/* the manifesto: refusals as stacked declarations */
.nosk { margin-bottom: 34px; }
.nolist { list-style: none; margin: 0; padding: 0; }
.nolist li {
  font-size: clamp(27px, 3.4vw, 46px); font-weight: 800;
  letter-spacing: -.035em; line-height: 1.28;
  color: var(--mute);
}
.nolist li:nth-child(odd) { color: var(--bone); }
.noskicker { margin-top: 26px; }

/* the number: speed as a single monumental stat */
.bigstat { margin-bottom: 30px; }
.bignum {
  display: block;
  font-size: clamp(96px, 14vw, 200px); font-weight: 800;
  letter-spacing: -.05em; line-height: .9;
  font-variant-numeric: tabular-nums;
}
.bignum em { font-style: normal; color: var(--neon); }
.biglabel {
  display: block; margin-top: 14px;
  font-size: 15px; color: var(--mute); max-width: 60ch;
}
/* the speed movement sits on the same left edge as everything else */


.race { margin: 34px 0 30px; max-width: 620px; }
.rrow { display: flex; align-items: center; gap: 14px; margin-bottom: 12px; }
.rbar { display: block; height: 22px; }
/* the bars keep the real ratio: 0.9s / 4s = 22.5% of the grey track.
   Sized so both labels hold one line inside the indented track. */
.r-me   { width: 12.6%; background: var(--neon); }
.r-them { width: 56%; background: var(--ghost); border: 1px solid var(--line); }
.rval { font: 500 12.5px/1.4 var(--mono); color: var(--mute); white-space: nowrap; }
@media (max-width: 640px) { .rval { white-space: normal; } }

/* ── the close: black like everything else — the green retreats to the
      one element that earns it, the address you're being asked to use ── */

.mv-close { margin: 0 0 150px; }
@media (max-width: 640px) { .mv-close { margin: 0 0 90px; } }

/* the fourth green commitment: the ask itself, cut on the shared slope */
.reach {
  width: fit-content; max-width: 100%;
  background: var(--neon); color: var(--ground);
  margin: 36px 0 40px; padding: 13px 42px 13px 18px;
  clip-path: polygon(0 0, 100% 0, calc(100% - 16px) 100%, 0 100%);
}
/* width:fit-content is safe here because the address never wraps; the
   cap is measured against the real 29-char address holding one line in
   the flow2 column, with ~3px spare at every width 320-1440 */
.reach .line {
  display: block; white-space: nowrap;
  font-size: clamp(14px, 4vw, 26px); font-weight: 800;
  letter-spacing: -.03em; line-height: 1.3;
}
.reach ::selection { background: var(--ground); color: var(--neon); }
/* the address is a real mailto link — tappable on the device most of these
   readers are holding — but keeps its plain look; the visible text is still
   the address, so a desktop with no mail client can read and copy it */
.reach .line { text-decoration: none; }
footer .meta a { text-decoration: none; }
@media (hover: hover) { footer .meta a:hover { color: var(--bone); } }
/* every green surface inverts its selection, not just this one */
.ladder .feat ::selection, .btn-primary::selection { background: var(--ground); color: var(--neon); }
/* small phones: the shorter bar takes a shorter cut, holding ~0.30 */
@media (max-width: 480px) {
  .reach { clip-path: polygon(0 0, 100% 0, calc(100% - 13px) 100%, 0 100%); }
}
/* 901-960: the two-column layout is back but its left column is at its
   narrowest — the 22px address clips into the cut. Measured clean at 18px */
@media (min-width: 901px) and (max-width: 960px) { .reach .line { font-size: 18px; } }

/* the horizon: one neon blade ends the page where the flood used to be */
.ground { height: 56px; background: var(--neon); clip-path: polygon(100% 0, 100% 100%, 0 100%); }
@media (max-width: 640px) { .ground { height: 32px; } }
/* circle badges: the three asks, counted like the window dots */
.asklist { list-style: none; margin: 14px 0 0; padding: 0; max-width: 52ch; counter-reset: ask; }
.asklist li {
  counter-increment: ask;
  position: relative; padding-left: 40px; margin-bottom: 12px; min-height: 26px;
}
.asklist li::before {
  content: counter(ask);
  position: absolute; left: 0; top: -1px;
  width: 26px; height: 26px; border: 1.5px solid var(--bone); border-radius: 50%;
  display: grid; place-items: center;
  font-size: 13px; font-weight: 700;
}

.aboutcol { margin-top: 150px; }
.aboutcol p { font-size: 14.5px; color: var(--mute); }
.aboutcol a { color: var(--bone); font-weight: 700; }
@media (max-width: 900px) { .aboutcol { margin-top: 40px; } }

/* ── footer ───────────────────────────────────────────────────────── */

footer { padding: 64px 0 72px; }
footer .wrap { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
footer img { width: 40px; height: 40px; }
.totop { display: block; transition: translate .2s; }
@media (hover: hover) and (prefers-reduced-motion: no-preference) { .totop:hover { translate: 0 -3px; } }
footer .meta { display: flex; flex-wrap: wrap; gap: 6px 26px; font-size: 13px; color: var(--mute); }

/* ── 404 ──────────────────────────────────────────────────────────── */

.lost { padding-block: 120px; }

/* 404's button row */
.cta { display: flex; flex-wrap: wrap; gap: 14px; }
