/* ═══════════════════════════════════════════════════════════════════════
   abcsites.ai — marketing site
   Brand (locked 2026-09-02): four colours, white / ink grounds, system
   grotesk, no serif. The name is never plain text — it is the wordmark,
   and the wordmark always arrives. Red check = the "done" mark.
   ═══════════════════════════════════════════════════════════════════════ */

/* Brand tokens first (T62): --ink --blue --red --yellow --green come from
   ~/abcsites/brand/tokens.json via assets/tokens.css (generated; do not edit). */
@import url("tokens.css?v=3");

:root{
  --ink2:var(--abc-neutral-600); --ink3:var(--abc-neutral-500);
  --line:var(--abc-neutral-200); --line2:var(--abc-neutral-100);
  --paper:var(--abc-white); --paper2:var(--abc-neutral-50);
  --grey:var(--abc-neutral-400);
  --font:var(--abc-font-ui);
  --mono:"SF Mono",Menlo,Consolas,monospace;
  --ease-out:cubic-bezier(.22,.61,.36,1);
  --ease-in:cubic-bezier(.55,.06,.68,.19);
  --ease-io:cubic-bezier(.65,0,.35,1);
  --w:1180px;
  --pad:clamp(20px,5vw,64px);
  --nav-h:72px;
}
*{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%}
body{background:var(--paper);color:var(--ink);font:400 17px/1.55 var(--font);
  -webkit-font-smoothing:antialiased;overflow-x:hidden}
img{display:block;max-width:100%;height:auto}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
b{font-weight:700}
::selection{background:color-mix(in srgb,var(--abc-yellow) 40%,var(--abc-white));color:var(--ink)}
:focus-visible{outline:3px solid var(--blue);outline-offset:3px;border-radius:6px}

/* ── the wordmark (from brand/wordmark.py — do not restyle locally) ── */
.abcmark{display:inline-block;font-weight:700;letter-spacing:-.022em;white-space:nowrap;line-height:1}
.abcmark i{font-style:normal;display:inline-block;opacity:0;
  transform:translateY(-1.05em) scaleY(1.08) scaleX(.94);transform-origin:50% 100%;color:var(--abc-neutral-400);
  animation:abcdrop .74s forwards}
.abcmark i.b{--abc:var(--abc-blue)}.abcmark i.r{--abc:var(--abc-grade-red)}.abcmark i.y{--abc:var(--abc-yellow)}
.abcmark i.g{--abc:var(--abc-green)}.abcmark i.n{--abc:var(--abc-neutral-400)}
@keyframes abcdrop{
  0%  {opacity:0;transform:translateY(-1.05em) scaleY(1.08) scaleX(.94);color:var(--abc-neutral-400);animation-timing-function:cubic-bezier(.55,.06,.68,.19)}
  12% {opacity:1;animation-timing-function:cubic-bezier(.55,.06,.68,.19)}
  50% {opacity:1;transform:translateY(0) scaleY(.80) scaleX(1.16);color:var(--abc-neutral-400);animation-timing-function:cubic-bezier(.22,.61,.36,1)}
  66% {transform:translateY(-.24em) scaleY(1.07) scaleX(.96);animation-timing-function:cubic-bezier(.55,.06,.68,.19)}
  80% {transform:translateY(0) scaleY(.91) scaleX(1.06);animation-timing-function:cubic-bezier(.22,.61,.36,1)}
  90% {transform:translateY(-.07em) scaleY(1.03) scaleX(.99)}
  100%{opacity:1;transform:none;color:var(--abc)}
}
.abcmark.abcreplay i{animation:none}
.abcmark.mini{font-size:18px}
.abcmark.final-mark{font-size:clamp(28px,4vw,44px)}
/* the hero mark is driven by JS — it falls from the top of the viewport,
   not from -1.05em, so it opts out of the shared keyframe. */
/* Held until the tab is actually being looked at — a page opened in a
   background tab runs at ~1 frame/s and the drop would crawl. JS adds
   .is-dropped to release it; the animation itself is the house abcdrop
   above, not a bespoke one. */
.drop-stage:not(.is-dropped) .drop-mark i{animation:none;opacity:0}

/* ── primitives ── */
.eyebrow{display:flex;align-items:center;gap:12px;font:600 12px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--ink2)}
.rule4{display:inline-block;width:44px;height:4px;border-radius:2px;flex:none;
  background:linear-gradient(90deg,var(--blue) 0 25%,var(--red) 25% 50%,var(--yellow) 50% 75%,var(--green) 75%)}
.h2{font-size:clamp(34px,5vw,60px);line-height:1.02;letter-spacing:-.035em;font-weight:800;margin:18px 0 20px}
.lede{font-size:clamp(18px,1.6vw,21px);line-height:1.5;color:var(--ink2);max-width:640px}
.sec-head{max-width:var(--w);margin:0 auto;padding:0 var(--pad)}
.dot{display:inline-block;width:10px;height:10px;border-radius:50%;flex:none}
.dot.b{background:var(--blue)}.dot.r{background:var(--red)}.dot.y{background:var(--yellow)}.dot.g{background:var(--green)}

.btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;min-height:48px;padding:0 24px;border-radius:999px;
  font-weight:700;font-size:16px;letter-spacing:-.005em;white-space:nowrap;
  transition:transform .25s var(--ease-out),box-shadow .25s var(--ease-out),background .2s,color .2s;will-change:transform}
.btn:hover{transform:translateY(-2px)}
.btn:active{transform:translateY(0) scale(.98)}
.btn-lg{min-height:60px;padding:0 32px;font-size:18px}
.btn-sm{min-height:44px;padding:0 18px;font-size:15px}
.btn-blue{background:var(--blue);color:var(--abc-white);box-shadow:0 8px 24px -8px rgba(66,133,244,.7)}
.btn-blue:hover{background:color-mix(in srgb,var(--abc-blue) 90%,var(--abc-neutral-900));box-shadow:0 14px 32px -8px rgba(66,133,244,.75)}
.btn-ink{background:var(--ink);color:var(--abc-white)}
.btn-ink:hover{background:var(--abc-neutral-900)}
.btn-white{background:var(--abc-white);color:var(--ink)}
.btn-ghost{background:transparent;color:var(--ink);box-shadow:inset 0 0 0 2px var(--line)}
.btn-ghost:hover{box-shadow:inset 0 0 0 2px var(--ink)}
.btn .arrow{display:inline-block;transition:transform .25s var(--ease-out)}
.btn:hover .arrow{transform:translateX(4px)}

/* ── nav ── */
.nav{position:fixed;inset:0 0 auto 0;height:var(--nav-h);z-index:50;display:flex;align-items:center;gap:32px;
  padding:0 var(--pad);background:rgba(255,255,255,0);
  transition:background .3s,box-shadow .3s,backdrop-filter .3s}
.nav.is-solid{background:rgba(255,255,255,.86);backdrop-filter:saturate(180%) blur(14px);-webkit-backdrop-filter:saturate(180%) blur(14px);box-shadow:0 1px 0 var(--line2)}
.nav-logo{display:flex;align-items:center;height:44px}
.nav-mark{font-size:24px;opacity:0;transition:opacity .2s}
.nav.mark-in .nav-mark{opacity:1}
.nav-links{display:flex;gap:28px;margin-left:auto;font-weight:600;font-size:15px;color:var(--ink2)}
.nav-links a{position:relative;padding:6px 0}
.nav-links a::after{content:"";position:absolute;left:0;right:0;bottom:0;height:2px;border-radius:2px;background:var(--ink);transform:scaleX(0);transform-origin:left;transition:transform .3s var(--ease-out)}
.nav-links a:hover{color:var(--ink)}.nav-links a:hover::after{transform:scaleX(1)}
.nav > .btn{opacity:0;transform:translateY(-6px);transition:opacity .4s,transform .4s var(--ease-out)}
.nav.mark-in > .btn{opacity:1;transform:none}

/* ── burger + mobile menu ── */
.burger{display:none;position:relative;width:44px;height:44px;border-radius:12px;flex:none;margin-left:6px;-webkit-tap-highlight-color:transparent}
.burger span{position:absolute;left:11px;width:22px;height:2.5px;border-radius:2px;background:var(--ink);transition:transform .35s var(--ease-out),opacity .2s,top .35s var(--ease-out)}
.burger span:nth-child(1){top:14px}.burger span:nth-child(2){top:21px}.burger span:nth-child(3){top:28px}
.burger[aria-expanded="true"] span:nth-child(1){top:21px;transform:rotate(45deg)}
.burger[aria-expanded="true"] span:nth-child(2){opacity:0;transform:scaleX(.2)}
.burger[aria-expanded="true"] span:nth-child(3){top:21px;transform:rotate(-45deg)}
/* 21 Sep: the panel was inset:0 with no overflow. Seven 30px rows plus the
   footer overrun an iPhone screen, body.menu-open pins the page, and inset:0
   sizes against the LARGE viewport — so the blue button sat behind Safari's
   toolbar and nothing could scroll to it. 100dvh follows the toolbar, the
   panel scrolls on its own, and the footer keeps clear of the bar. */
.menu{position:fixed;inset:0;height:100dvh;z-index:45;background:var(--paper);padding:calc(var(--nav-h) + 12px) var(--pad) calc(28px + env(safe-area-inset-bottom));
  display:flex;flex-direction:column;justify-content:space-between;gap:20px;visibility:hidden;opacity:0;
  overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;
  clip-path:inset(0 0 100% 0);transition:clip-path .55s var(--ease-io),opacity .3s,visibility 0s .55s}
.menu.is-open{visibility:visible;opacity:1;clip-path:inset(0 0 0 0);transition:clip-path .55s var(--ease-io),opacity .2s,visibility 0s}
.menu-links{display:flex;flex-direction:column}
.menu-links a{display:grid;grid-template-columns:14px 1fr;column-gap:14px;align-items:center;padding:16px 0;border-bottom:1px solid var(--line2);
  opacity:0;transform:translateY(18px);transition:opacity .4s var(--ease-out),transform .5s var(--ease-out)}
.menu.is-open .menu-links a{opacity:1;transform:none}
.menu.is-open .menu-links a:nth-child(1){transition-delay:.15s}.menu.is-open .menu-links a:nth-child(2){transition-delay:.21s}
.menu.is-open .menu-links a:nth-child(3){transition-delay:.27s}.menu.is-open .menu-links a:nth-child(4){transition-delay:.33s}
.menu.is-open .menu-links a:nth-child(5){transition-delay:.39s}
.menu-links .dot{grid-row:1/3;width:12px;height:12px}
.menu-links span{font-size:clamp(24px,7vw,30px);font-weight:800;letter-spacing:-.03em;line-height:1.1}
.menu-links em{font-style:normal;font-size:13px;color:var(--ink2);margin-top:3px}
.menu-foot{display:flex;flex-direction:column;gap:14px;align-items:stretch;opacity:0;transform:translateY(14px);transition:opacity .4s var(--ease-out) .45s,transform .5s var(--ease-out) .45s}
.menu.is-open .menu-foot{opacity:1;transform:none}
.menu-foot .btn{width:100%}
.menu-mail{text-align:center;font-weight:600;color:var(--ink2);min-height:44px;display:flex;align-items:center;justify-content:center}
body.menu-open{overflow:hidden}
body.menu-open .nav{background:var(--paper);backdrop-filter:none;box-shadow:none}
body.menu-open .nav-mark{opacity:1}
body.menu-open .sticky-cta{transform:translateY(120%)}
.hide-m{display:inline}

/* ── hero ── */
.hero{position:relative;min-height:100svh;padding:calc(var(--nav-h) + 24px) var(--pad) 0;display:flex;flex-direction:column;align-items:center;overflow:hidden;isolation:isolate}
.hero-bg{position:absolute;inset:0;z-index:-1;pointer-events:none}
.blob{position:absolute;width:56vw;height:56vw;max-width:820px;max-height:820px;border-radius:50%;filter:blur(110px);opacity:.12;will-change:transform;
  animation:drift 26s ease-in-out infinite alternate}
.blob-b{background:var(--blue);left:-18vw;top:-12vw}
.blob-r{background:var(--red);right:-20vw;top:-6vw;animation-delay:-7s;animation-duration:31s}
.blob-y{background:var(--yellow);left:8vw;bottom:-28vw;animation-delay:-13s;animation-duration:29s}
.blob-g{background:var(--green);right:-6vw;bottom:-30vw;animation-delay:-19s;animation-duration:34s}
@keyframes drift{from{transform:translate(0,0) scale(1)}to{transform:translate(9vw,7vw) scale(1.18)}}
.grid{position:absolute;inset:0;background-image:radial-gradient(var(--line) 1px,transparent 1.2px);background-size:28px 28px;opacity:.5;
  -webkit-mask-image:radial-gradient(ellipse 70% 60% at 50% 40%,var(--abc-neutral-900) 30%,transparent 100%);mask-image:radial-gradient(ellipse 70% 60% at 50% 40%,var(--abc-neutral-900) 30%,transparent 100%)}

.hero-inner{position:relative;width:100%;max-width:980px;text-align:center;display:flex;flex-direction:column;align-items:center}
.hero-eyebrow{justify-content:center;margin-bottom:clamp(10px,2vh,24px)}

.drop-stage{position:relative;display:inline-block;line-height:1;margin:0 auto;padding:0 .35em}
.drop-mark{font-size:clamp(58px,13.5vw,164px);font-weight:700;letter-spacing:-.03em;display:inline-block;will-change:transform}
.drop-mark i{will-change:transform,opacity,color}

.check{width:.62em;height:.52em;font-size:inherit}
.check path{stroke-dasharray:180;stroke-dashoffset:180}
.check.is-drawn path,.check.check-sm.is-in path{animation:draw .62s var(--ease-io) forwards}
@keyframes draw{to{stroke-dashoffset:0}}
#heroCheck{position:absolute;right:-.58em;top:-.26em;font-size:clamp(58px,13.5vw,164px);width:.54em;height:.46em;transform:rotate(-6deg);
  filter:drop-shadow(0 6px 14px rgba(234,67,53,.35))}

.hero-h1{font-size:clamp(36px,6.2vw,80px);line-height:1;letter-spacing:-.04em;font-weight:800;margin:clamp(14px,3vh,34px) 0 18px}
.hero-h1 .line{display:block;overflow:hidden;padding:.04em 0 .16em;margin-bottom:-.12em}
.hero-h1 .line>span{display:block;transform:translateY(110%);will-change:transform}
.hero-sub{font-size:clamp(17px,1.7vw,22px);line-height:1.5;color:var(--ink2);max-width:680px}
.hero-sub b{color:var(--ink)}
.hero-cta{display:flex;gap:14px;flex-wrap:wrap;justify-content:center;margin-top:clamp(20px,3.6vh,36px)}
.hero-claims{list-style:none;display:flex;flex-wrap:wrap;gap:8px 26px;justify-content:center;margin-top:26px;font-weight:600;font-size:15px;color:var(--ink2)}
.hero-claims li{display:flex;align-items:center;gap:9px}
/* The price anchor (19 Sep). "$0" on its own reads as cheap; beside the number
   it replaces it reads as something given. Muted and lighter than the claim it
   qualifies, so it supports the $0 rather than competing with it. Wraps onto
   its own line on a phone, where the claims list is already stacked. */
.anchor-line{font-weight:400;font-size:13.5px;color:var(--ink3,var(--ink2));opacity:.85;white-space:nowrap}
@media (max-width:520px){.anchor-line{white-space:normal}}

.reveal-late{opacity:0;transform:translateY(18px);will-change:transform,opacity}
.hero.is-ready .reveal-late{opacity:1;transform:none;transition:opacity .7s var(--ease-out),transform .8s var(--ease-out)}
.hero.is-ready .hero-eyebrow{transition-delay:.05s}
.hero.is-ready .hero-sub{transition-delay:.22s}
.hero.is-ready .hero-cta{transition-delay:.34s}
.hero.is-ready .hero-claims{transition-delay:.46s}
.hero.is-ready .hero-wall{transition-delay:.55s}

/* ── THE BUILD WALL ─────────────────────────────────────────────────────────
   Full-bleed inside .hero. The hero is already full width with var(--pad) of
   side padding, so the band reaches the viewport edges by cancelling exactly
   that padding — NOT with 100vw, which overshoots by the scrollbar and makes
   the document scroll sideways. .hero is overflow:hidden, so the cards that
   run past the edge are clipped by the section, never by the page.
   Height is the height the old 920px peek occupied (920 * 757/1440 + the
   38px chrome ~ 522px at 1440): the hero does not get taller. */
.hero-wall{position:relative;width:calc(100% + var(--pad)*2);margin:clamp(30px,5.2vh,58px) calc(var(--pad)*-1) 0;
  height:clamp(212px,33vw,470px);perspective:1500px;perspective-origin:50% 42%;
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 8%,#000 92%,transparent 100%);
          mask-image:linear-gradient(90deg,transparent 0,#000 8%,#000 92%,transparent 100%)}
.wall-track{display:flex;width:max-content;height:100%;align-items:center;gap:0;
  transform-style:preserve-3d;animation:wallRoll 84s linear infinite;will-change:transform}
.wall-set{display:flex;align-items:center;gap:clamp(14px,2.2vw,34px);padding-right:clamp(14px,2.2vw,34px)}
.wall-card{margin:0;flex:0 0 auto;width:clamp(230px,30vw,430px);transform:rotateY(-17deg) rotateX(5deg);
  transform-origin:50% 50%;backface-visibility:hidden}
.wall-card .browser{border-radius:13px;box-shadow:0 1px 0 var(--line),0 34px 64px -26px rgba(32,33,36,.42),0 0 0 1px var(--line2)}
.wall-card .browser-bar{height:30px;padding:0 11px;gap:5px}
.wall-card .browser-bar i{width:8px;height:8px}
.wall-card .browser-bar span{margin-left:9px;font-size:10.5px;padding:4px 9px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.wall-shot,.wall-film{display:block;width:100%;height:auto;aspect-ratio:880/496;object-fit:cover;background:var(--abc-neutral-900)}
.wall-cap{margin-top:10px;text-align:center;font:500 11.5px/1.4 var(--mono);letter-spacing:.01em;color:var(--ink3);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* Counter-clockwise: the front face of a turning drum travels right to left.
   -50% lands on the duplicate set, which is identical, so the wrap is invisible. */
@keyframes wallRoll{from{transform:translate3d(0,0,0)}to{transform:translate3d(-50%,0,0)}}
/* Grab it and move it. JS takes the roll over (.is-live) and then the CSS
   animation must be OFF, or the two fight over the same transform and the
   wall stutters. Without JS the keyframes above still run, so the band turns
   on a dead script. touch-action:pan-y keeps the PAGE scrolling vertically
   while we take the horizontal drag. */
.hero-wall{touch-action:pan-y;cursor:grab;-webkit-user-select:none;user-select:none}
.hero-wall.is-live .wall-track{animation:none}
.hero-wall.is-drag{cursor:grabbing}
.hero-wall.is-drag .wall-card,.hero-wall.is-drag .wall-shot{pointer-events:none}
.hero-wall .wall-shot,.hero-wall .wall-film{-webkit-user-drag:none;user-select:none}
.hero-wall:not(.is-live):hover .wall-track{animation-play-state:paused}
.browser{position:relative;background:var(--abc-white);border-radius:16px;overflow:hidden;box-shadow:0 1px 0 var(--line),0 40px 80px -30px rgba(32,33,36,.35),0 0 0 1px var(--line2)}
.browser-bar{display:flex;align-items:center;gap:7px;height:38px;padding:0 14px;background:var(--paper2);border-bottom:1px solid var(--line2)}
.browser-bar i{width:11px;height:11px;border-radius:50%;background:var(--line)}
.browser-bar span{margin-left:12px;font:500 12px/1 var(--mono);color:var(--ink3);background:var(--abc-white);border:1px solid var(--line2);border-radius:6px;padding:6px 12px;flex:1;text-align:center}
.device.browser img.nw{aspect-ratio:1440/757}

.scroll-hint{position:absolute;left:50%;bottom:18px;transform:translateX(-50%);width:26px;height:42px;border:2px solid var(--line);border-radius:14px;opacity:0;transition:opacity .6s 1.2s}
.hero.is-ready .scroll-hint{opacity:1}
.scroll-hint span{position:absolute;left:50%;top:7px;width:4px;height:8px;margin-left:-2px;border-radius:2px;background:var(--ink2);animation:hint 1.8s var(--ease-io) infinite}
@keyframes hint{0%{transform:translateY(0);opacity:1}70%{transform:translateY(16px);opacity:0}100%{opacity:0}}

/* ── marquee ── */
.marquee{overflow:hidden;border-top:1px solid var(--line2);border-bottom:1px solid var(--line2);background:var(--paper);padding:16px 0;
  -webkit-mask-image:linear-gradient(90deg,transparent,var(--abc-neutral-900) 8%,var(--abc-neutral-900) 92%,transparent);mask-image:linear-gradient(90deg,transparent,var(--abc-neutral-900) 8%,var(--abc-neutral-900) 92%,transparent)}
.marquee-track{display:flex;gap:44px;width:max-content;animation:marquee 42s linear infinite;font-weight:600;font-size:15px;color:var(--ink2)}
.marquee-track span{display:flex;align-items:center;gap:10px;white-space:nowrap}
.marquee:hover .marquee-track{animation-play-state:paused}
@keyframes marquee{to{transform:translateX(-50%)}}

/* ── how it works ── */
.how{padding:clamp(80px,12vh,140px) 0 0}
.how-head{max-width:var(--w);margin:0 auto;padding:0 var(--pad) clamp(40px,6vh,72px)}
.how-stage{max-width:var(--w);margin:0 auto;padding:0 var(--pad);display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.1fr);gap:clamp(32px,6vw,96px);align-items:center;min-height:100svh}
.how-copy{position:relative;min-height:380px}
.chapter{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;opacity:0;transform:translateY(24px);pointer-events:none;
  transition:opacity .5s var(--ease-out),transform .6s var(--ease-out)}
.chapter.is-active{opacity:1;transform:none;pointer-events:auto}
.chapter-n{font:700 13px/1 var(--mono);letter-spacing:.12em;margin-bottom:18px}
.chapter-n.b{color:var(--blue)}.chapter-n.r{color:var(--red)}.chapter-n.y{color:var(--yellow)}.chapter-n.g{color:var(--green)}
.chapter h3{font-size:clamp(28px,3.4vw,44px);line-height:1.05;letter-spacing:-.03em;font-weight:800;margin-bottom:16px}
.chapter p{font-size:clamp(16px,1.35vw,19px);color:var(--ink2);max-width:520px}
.ticks{list-style:none;display:flex;flex-wrap:wrap;gap:8px;margin-top:22px}
.ticks li{font:600 13px/1 var(--font);color:var(--ink);background:var(--paper2);border:1px solid var(--line2);border-radius:999px;padding:9px 13px 9px 10px;display:flex;align-items:center;gap:7px}
.ticks li::before{content:"";width:14px;height:14px;border-radius:50%;background:var(--green) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 6.5l2.3 2.3L9.5 3.8' fill='none' stroke='%23fff' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/9px no-repeat}
/* 19 Sep: .btn-ring / .ring-ico (the "Hear it ring" button) and .kit-paused
   (the $249 bundle's paused note) were removed with the copy they belonged to. */
.pricing-timeline{max-width:min(920px,100%);margin:26px auto 0;text-align:center;font:600 14.5px/1.7 var(--font);color:var(--ink2)}
.peek-note{max-width:min(760px,100%);margin:14px auto 0;text-align:center;font:500 13px/1.6 var(--mono);letter-spacing:.01em;color:var(--ink3)}
.peek-note b{color:var(--ink2);font-weight:600}
.m-shot{display:none}
.how-progress{position:absolute;left:0;bottom:-46px;display:flex;gap:8px}
.how-progress i{flex:1 1 0;min-width:22px;max-width:36px;height:4px;border-radius:2px;background:var(--line2);position:relative;overflow:hidden}
.how-progress i::after{content:"";position:absolute;inset:0;transform:scaleX(0);transform-origin:left;transition:transform .5s var(--ease-out)}
.how-progress i.b::after{background:var(--blue)}.how-progress i.r::after{background:var(--red)}.how-progress i.y::after{background:var(--yellow)}.how-progress i.g::after{background:var(--green)}
.how-progress i.is-on::after{transform:scaleX(1)}

.how-visual{position:relative;height:min(78vh,720px);display:grid;place-items:center}
.device{position:absolute;opacity:0;transform:translateY(40px) scale(.94);transition:opacity .55s var(--ease-out),transform .7s var(--ease-out);will-change:transform,opacity}
.device.is-on{opacity:1;transform:none}
.device.phone{width:min(300px,68vw);border-radius:38px;background:var(--abc-neutral-900);padding:10px;box-shadow:0 50px 90px -40px rgba(0,0,0,.55),0 0 0 1px var(--abc-neutral-900),inset 0 0 0 2px var(--abc-neutral-800)}
.device.phone img{border-radius:30px;aspect-ratio:800/1732;object-fit:cover;object-position:top}
.device.browser{width:min(660px,100%)}
.device.browser img{aspect-ratio:1400/875;object-fit:cover;object-position:top}
.device.browser img[src*="northwood"]{aspect-ratio:1440/757}
.m-shot img[src*="northwood-desk"]{aspect-ratio:1440/757}
.build-bar{position:absolute;left:0;right:0;bottom:0;height:6px;background:var(--line2)}
.build-bar i{display:block;height:100%;width:0;background:linear-gradient(90deg,var(--blue),var(--green));transition:width 2.4s var(--ease-io)}
.device.is-on .build-bar i{width:92%}
.check-over{position:absolute;right:6%;bottom:8%;width:min(160px,26%);height:auto;filter:drop-shadow(0 10px 22px rgba(234,67,53,.4))}
/* The site going live — what step 05 promises — where the incoming call used
   to sit. Same shape and position so the phone frame is unchanged. */
.live-flag{position:absolute;left:22px;right:22px;top:80px;background:rgba(20,20,20,.86);backdrop-filter:blur(10px);color:var(--abc-white);border-radius:18px;padding:14px 16px 14px 56px;
  opacity:0;transform:translateY(-16px);transition:opacity .4s,transform .5s var(--ease-out)}
.live-flag::before{content:"";position:absolute;left:14px;top:50%;width:30px;height:30px;margin-top:-15px;border-radius:50%;background:var(--green) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 6.5l2.3 2.3L9.5 3.8' fill='none' stroke='%23fff' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/14px no-repeat}
.live-flag b{display:block;font-size:15px}.live-flag span{font-size:12px;opacity:.75}
.live-flag.is-on{opacity:1;transform:none}

/* ── the kid ── */
.kid{background:var(--ink);color:var(--abc-white);padding:clamp(80px,12vh,150px) 0;margin-top:clamp(60px,10vh,120px);overflow:hidden}
.kid-inner{max-width:var(--w);margin:0 auto;padding:0 var(--pad);display:grid;grid-template-columns:minmax(0,.8fr) minmax(0,1fr);gap:clamp(32px,6vw,90px);align-items:center}
.kid-fig{position:relative;border-radius:22px;overflow:hidden;background:var(--abc-neutral-800);max-width:440px}
.kid-fig img{aspect-ratio:9/16;object-fit:cover;filter:saturate(.92)}
.kid-fig figcaption{position:absolute;left:14px;bottom:14px;font:600 12px/1 var(--mono);letter-spacing:.06em;color:var(--abc-white);background:rgba(0,0,0,.55);backdrop-filter:blur(6px);padding:9px 12px;border-radius:8px}
.kid .h2{color:var(--abc-white)}
.kid .big{font-size:clamp(22px,2.4vw,30px);line-height:1.3;color:var(--abc-neutral-100);margin-bottom:18px}
.kid .big b{color:var(--abc-white)}
.kid p{color:var(--abc-neutral-300);max-width:560px;margin-bottom:18px}
.kid .btn{margin-top:14px;background:var(--abc-white);color:var(--ink)}
.kid .btn:hover{background:var(--abc-neutral-100)}

/* split headline (word by word) */
.split .w{display:inline-block;overflow:hidden;vertical-align:top;padding:.04em 0;margin:-.04em 0}
.split .w>span{display:inline-block;transform:translateY(110%);will-change:transform}
.split.is-in .w>span{transform:none;transition:transform .8s var(--ease-out)}

/* reveal */
.reveal{opacity:0;transform:translateY(28px);will-change:transform,opacity}
.reveal.is-in{opacity:1;transform:none;transition:opacity .45s var(--ease-out),transform .55s var(--ease-out)}

/* ── fears ── */
.fears{padding:clamp(80px,12vh,150px) 0 0}
.fear-grid{list-style:none;max-width:var(--w);margin:clamp(36px,5vh,60px) auto 0;padding:0 var(--pad);display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px}
.fear-grid li{background:var(--paper2);border:1px solid var(--line2);border-radius:18px;padding:24px 22px 24px 62px;position:relative;min-height:150px;
  transition:transform .35s var(--ease-out),box-shadow .35s var(--ease-out),background .3s}
.fear-grid li:hover{transform:translateY(-4px);background:var(--abc-white);box-shadow:0 30px 60px -30px rgba(32,33,36,.28)}
.fear-grid li b{display:block;font-size:17px;letter-spacing:-.015em;margin-bottom:8px;line-height:1.3}
.fear-grid li span{display:block;color:var(--ink2);font-size:15px;line-height:1.5}
.tick{position:absolute;left:20px;top:24px;width:28px;height:28px;border-radius:50%;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7.5' fill='none' stroke='%23fff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");background-size:16px;background-position:center;background-repeat:no-repeat;
  transform:scale(.4);opacity:0;transition:transform .5s cubic-bezier(.34,1.56,.64,1),opacity .3s}
.reveal.is-in .tick{transform:none;opacity:1;transition-delay:.25s}
.tick.b{background-color:var(--blue)}.tick.r{background-color:var(--red)}.tick.y{background-color:var(--yellow)}.tick.g{background-color:var(--green)}
.fear-cta{padding:24px 22px!important;display:flex;flex-direction:column;justify-content:center;gap:12px;background:var(--ink)!important;color:var(--abc-white);border-color:var(--ink)!important}
.fear-cta b{color:var(--abc-white);font-size:20px!important}
.fear-cta .btn{align-self:flex-start}

/* ── pricing ── */
.pricing{padding:clamp(80px,12vh,150px) 0 0}
.tiers{max-width:var(--w);margin:clamp(36px,5vh,60px) auto 0;padding:0 var(--pad);display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px;align-items:stretch}
.tier{position:relative;display:flex;flex-direction:column;background:var(--abc-white);border:1px solid var(--line);border-radius:24px;padding:30px 28px;transition:transform .35s var(--ease-out),box-shadow .35s var(--ease-out)}
.tier:hover{transform:translateY(-6px);box-shadow:0 40px 70px -36px rgba(32,33,36,.35)}
.tier-rec{border-color:var(--ink);box-shadow:0 30px 70px -30px rgba(32,33,36,.35)}
.rec-badge{position:absolute;top:-14px;left:28px;background:var(--ink);color:var(--abc-white);font:700 12px/1 var(--font);letter-spacing:.02em;padding:9px 12px;border-radius:999px}
.tier header{display:flex;flex-direction:column;gap:6px;margin-bottom:22px}
.tier-name{font-size:14px;font-weight:800;letter-spacing:.12em;text-transform:uppercase}
.tier-name.b{color:var(--blue)}.tier-name.r{color:var(--red)}.tier-name.g{color:var(--green)}
.tier-for{font-size:14px;color:var(--ink2)}
.price{font-size:64px;line-height:1;letter-spacing:-.045em;font-weight:800}
.price sup{font-size:26px;vertical-align:top;margin-top:8px;display:inline-block;letter-spacing:0}
.price small{font-size:18px;font-weight:600;letter-spacing:0;color:var(--ink2);margin-left:2px}
.build-fee{margin:10px 0 22px;font-size:15px;color:var(--ink2)}
.build-fee s{margin-right:6px}
.build-fee b{color:var(--green);background:color-mix(in srgb,var(--abc-green) 12%,var(--abc-white));padding:4px 9px;border-radius:6px}
.tier ul{list-style:none;display:flex;flex-direction:column;gap:12px;margin-bottom:28px;flex:1}
.tier li{position:relative;padding-left:26px;font-size:15px;line-height:1.45;color:var(--ink)}
.tier li::before{content:"";position:absolute;left:0;top:3px;width:16px;height:16px;border-radius:50%;background:var(--ink) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 6.5l2.3 2.3L9.5 3.8' fill='none' stroke='%23fff' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/9px no-repeat}
.tier li:nth-child(4n+1)::before{background-color:var(--blue)}.tier li:nth-child(4n+2)::before{background-color:var(--red)}
.tier li:nth-child(4n+3)::before{background-color:var(--yellow)}.tier li:nth-child(4n+4)::before{background-color:var(--green)}
.tier .btn{width:100%}

.guarantees{max-width:var(--w);margin:24px auto 0;padding:0 var(--pad);display:grid;grid-template-columns:minmax(0,1.6fr) minmax(0,1fr);gap:18px;align-items:stretch}
.annual-line{max-width:var(--w);margin:26px auto 0;padding:0 var(--pad);text-align:center;font-size:17px;line-height:1.45;font-weight:700;letter-spacing:-.01em;color:var(--ink)}
.guarantee-main{background:var(--abc-white);border-color:var(--ink)}
.guarantee-main h3{font-size:clamp(22px,2.4vw,28px);line-height:1.2}
.guarantee p.guarantee-terms{margin-top:14px;font-size:14px;line-height:1.5}
.guarantee-terms a{color:var(--ink);font-weight:700;text-decoration:underline;text-underline-offset:3px}
.guarantee-side h3{font-size:20px}
.guarantee-side p{font-size:15px}
.guarantee{background:var(--paper2);border:1px solid var(--line2);border-radius:24px;padding:30px 28px 30px 96px;position:relative}
.guarantee .check-sm{position:absolute;left:28px;top:30px;width:48px;height:40px}
.guarantee h3{font-size:24px;letter-spacing:-.025em;font-weight:800;margin-bottom:8px}
.guarantee p{color:var(--ink2);font-size:16px}

/* ── who ── */
.who{padding:clamp(80px,12vh,150px) 0 0}
.who .h2{max-width:860px}
.trades{overflow:hidden;margin-top:clamp(28px,4vh,48px);padding:6px 0;
  -webkit-mask-image:linear-gradient(90deg,transparent,var(--abc-neutral-900) 6%,var(--abc-neutral-900) 94%,transparent);mask-image:linear-gradient(90deg,transparent,var(--abc-neutral-900) 6%,var(--abc-neutral-900) 94%,transparent)}
.trades-track{display:flex;gap:12px;width:max-content;animation:marquee 60s linear infinite}
.trades-track span{font-size:clamp(20px,2.6vw,34px);font-weight:800;letter-spacing:-.03em;padding:14px 24px;border:1px solid var(--line);border-radius:999px;white-space:nowrap;color:var(--ink)}
.trades-track span:nth-child(4n+1){border-color:var(--blue);color:var(--blue)}
.trades-track span:nth-child(4n+2){border-color:var(--red);color:var(--red)}
.trades-track span:nth-child(4n+3){border-color:var(--yellow);color:color-mix(in srgb,var(--abc-yellow) 55%,var(--abc-neutral-900))}
.trades-track span:nth-child(4n+4){border-color:var(--green);color:var(--green)}
.who-not{max-width:var(--w);margin:clamp(28px,4vh,44px) auto 0;padding:0 var(--pad);font-size:clamp(17px,1.5vw,20px);color:var(--ink2);max-width:calc(var(--w))}
.who-not{padding-right:var(--pad)}

/* ── faq ── */
.faq{padding:clamp(80px,12vh,150px) 0 0}
.faq-list{max-width:var(--w);margin:clamp(28px,4vh,44px) auto 0;padding:0 var(--pad)}
.faq details{max-width:820px}
.faq details{border-top:1px solid var(--line2)}
.faq details:last-child{border-bottom:1px solid var(--line2)}
.faq summary{list-style:none;cursor:pointer;display:flex;align-items:center;justify-content:space-between;gap:20px;padding:22px 0;font-size:clamp(17px,1.5vw,20px);font-weight:700;letter-spacing:-.015em}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"";flex:none;width:28px;height:28px;border-radius:50%;border:2px solid var(--line);
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 6v12M6 12h12' stroke='%23202124' stroke-width='2.4' stroke-linecap='round'/%3E%3C/svg%3E") center/14px no-repeat;transition:transform .35s var(--ease-out),background-color .2s}
.faq details[open] summary::after{transform:rotate(45deg);border-color:var(--ink)}
.faq details p{padding:0 44px 24px 0;color:var(--ink2);font-size:16px;line-height:1.6;max-width:720px}

/* ── final ── */
.final{margin-top:clamp(80px,12vh,150px);background:var(--ink);color:var(--abc-white);padding:clamp(90px,14vh,170px) var(--pad);text-align:center;position:relative;overflow:hidden}
.final::before{content:"";position:absolute;inset:-40% -20%;background:
  radial-gradient(40% 40% at 20% 30%,rgba(66,133,244,.28),transparent 60%),
  radial-gradient(35% 35% at 80% 25%,rgba(234,67,53,.22),transparent 60%),
  radial-gradient(35% 35% at 30% 85%,rgba(249,171,0,.18),transparent 60%),
  radial-gradient(40% 40% at 80% 80%,rgba(52,168,83,.22),transparent 60%);
  filter:blur(40px);animation:drift 30s ease-in-out infinite alternate;pointer-events:none}
.final-inner{position:relative;max-width:820px;margin:0 auto;display:flex;flex-direction:column;align-items:center;gap:22px}
.final h2{font-size:clamp(36px,6vw,76px);line-height:1;letter-spacing:-.04em;font-weight:800}
.final p{font-size:clamp(17px,1.6vw,21px);color:var(--abc-neutral-300);max-width:560px}
.final .btn-white{box-shadow:0 20px 50px -20px rgba(255,255,255,.5)}
.final-fine{font-size:14px!important;color:var(--abc-neutral-400)!important}

/* ── footer ── */
.foot{background:var(--abc-neutral-900);color:var(--abc-neutral-400);padding:34px var(--pad);font-size:14px}
.foot-inner{max-width:var(--w);margin:0 auto;display:flex;align-items:center;gap:24px;flex-wrap:wrap}
.foot nav{display:flex;gap:6px;margin-left:auto}
.foot nav a{display:inline-flex;align-items:center;min-height:44px;padding:0 8px}
.foot nav a:hover{color:var(--abc-white)}
.foot-copy{width:100%;color:var(--abc-neutral-500)}
@media(min-width:760px){.foot-copy{width:auto}}

/* ── sticky mobile cta ── */
.sticky-cta{position:fixed;left:12px;right:12px;bottom:calc(12px + env(safe-area-inset-bottom));z-index:40;display:none;align-items:center;gap:12px;
  background:rgba(255,255,255,.94);backdrop-filter:blur(12px);border:1px solid var(--line2);border-radius:18px;padding:10px 10px 10px 16px;box-shadow:0 20px 50px -20px rgba(0,0,0,.4);
  transform:translateY(120%);transition:transform .45s var(--ease-out)}
.sticky-cta span{font-size:14px;color:var(--ink2);flex:1;min-width:0;line-height:1.3}
.sticky-cta.is-on{transform:none}

/* ═══════════════ responsive ═══════════════ */
@media(max-width:1000px){
  .fear-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .tiers{grid-template-columns:minmax(0,1fr);max-width:560px}
  .tier-rec{order:-1}
  .guarantees{grid-template-columns:minmax(0,1fr);max-width:560px}
}
@media(max-width:900px){
  .nav-links{display:none}
  .burger{display:block;margin-left:6px}
  .nav-cta{margin-left:auto}
  .how-stage{display:block;min-height:0}
  .how-copy{min-height:0}
  .chapter{position:relative;inset:auto;opacity:1;transform:none;pointer-events:auto;padding:28px 0}
  .how-progress{display:none}
  .how-visual{display:none}
  /* on a phone each chapter carries its own screen, stacked */
  .chapter::after{content:"";display:block}
  .m-shot{display:block;margin:22px 0 0;border-radius:16px;overflow:hidden;border:1px solid var(--line2);box-shadow:0 30px 60px -30px rgba(32,33,36,.35)}
  .m-shot img{aspect-ratio:16/10;object-fit:cover;object-position:top}
  .m-shot.phone img{aspect-ratio:9/12}
  .kid-inner{grid-template-columns:minmax(0,1fr)}
  .kid-fig{max-width:100%;max-height:70vh}
  /* keep the 9/16 ratio: `aspect-ratio:auto` discards the width/height attributes and the
     figure is 0px tall until the lazy image lands, shifting everything below it */
  .kid-fig img{aspect-ratio:9/16;max-height:70vh;object-fit:cover;object-position:top;width:100%}
  .sticky-cta{display:flex}
}
@media(max-width:640px){
  :root{--nav-h:64px}
  .nav{gap:14px}
  .nav-cta{display:none}
  .nav .burger{margin-left:auto}
  .hide-m{display:none}
  .hero{padding-top:calc(var(--nav-h) + 10px)}
  .hero-eyebrow{margin-bottom:8px}
  .hero-sub{font-size:16px}
  .hero-h1{margin:14px 0 14px}
  .hero-cta{flex-direction:column;width:100%;align-items:stretch}
  .hero-cta .btn{width:100%}
  .hero-claims{display:grid;grid-template-columns:1fr 1fr;gap:10px 12px;font-size:14px;text-align:left;width:100%;max-width:360px;margin-top:20px}
  .hero-wall{height:clamp(196px,54vw,300px);margin-top:26px}
  .wall-card{width:clamp(210px,62vw,300px);transform:rotateY(-13deg) rotateX(4deg)}
  .wall-cap{font-size:10.5px}
  .fear-grid{grid-template-columns:minmax(0,1fr)}
  .fear-grid li{min-height:0}
  .guarantee{padding:26px 22px 26px 78px}
  .guarantee .check-sm{left:22px;width:38px;height:32px}
  .price{font-size:56px}
  .foot nav{margin-left:0;width:100%;flex-wrap:wrap;gap:14px 18px}
  #heroCheck{right:-.42em;top:-.18em}
}

/* ═══════════════ reduced motion: same page, no entrance ═══════════════ */
@media(prefers-reduced-motion:reduce){
  .abcmark i,.drop-mark i{animation:none;opacity:1;transform:none;color:var(--abc)}
  .hero-h1 .line>span,.split .w>span{transform:none}
  .reveal,.reveal-late,.scroll-hint,.nav-mark,.nav > .btn{opacity:1;transform:none;transition:none}
  .check path{stroke-dashoffset:0;animation:none}
  .blob,.marquee-track,.trades-track,.final::before,.scroll-hint span{animation:none}
  .marquee-track,.trades-track{flex-wrap:wrap;width:auto;justify-content:center;padding:0 var(--pad)}
  .tick{transform:none;opacity:1}
  .device{transition:none}
  /* The wall stops, it does not disappear: the duplicate run is dropped and
     the single run is centred, so a reduced-motion visitor gets a composed
     row of cards rather than an empty band. */
  .wall-track{animation:none;width:100%;justify-content:center}
  .wall-set[aria-hidden="true"]{display:none}
  .wall-set{flex-wrap:wrap;justify-content:center;padding-right:0}
  .hero-wall{height:auto;-webkit-mask-image:none;mask-image:none}
  .wall-card{transform:none}
  /* 7 Oct 2026: the wall holds eight sites. A reduced-motion visitor gets one row (three
     cards, two on a phone), not eight stacked. */
  .wall-set .wall-card:nth-child(n+4){display:none}
}
@media(prefers-reduced-motion:reduce) and (max-width:640px){
  .wall-set .wall-card:nth-child(n+3){display:none}
}

/* ── ADDITIVE REVEALS — the page must never be blank ────────────────────────
   Every reveal on this site hides its content first and animates it in: fine
   while the script runs, catastrophic when it does not. First paint would be a
   blank pastel gradient, and the buyer opening this is on a phone, on a weak
   connection, in a truck. A blank screen reads as broken, and we sell
   competence at building websites.

   So the hidden states apply ONLY under html.js, which the inline script in the
   head sets before first paint. With no script at all the flag never lands and
   the page renders complete. If the script runs but the hero never comes up,
   the head's watchdog reveals the hero through the site's own classes — it does
   NOT remove this flag, because removing it was what broke the live site on
   2026-09-05: a page opened in a background tab legitimately holds its intro,
   the watchdog read that as a stall, and stripping .js killed the wordmark
   animation it existed to protect.

   WHAT IS DELIBERATELY NOT IN THIS LIST. `.chapter`, `.device` and `.menu-foot`
   are not reveals, they are STACKED STATE — four chapters at position:absolute;
   inset:0 of which exactly one carries .is-active, and a menu meant to be shut.
   Forcing opacity:1 on all of them painted every chapter on top of the next in
   a heap of overlapping type. They already degrade correctly unaided: chapter
   01 ships with .is-active in the markup, and a media query below unstacks them
   on a phone. Reveals get a floor; state does not. */
html:not(.js) .reveal,
html:not(.js) .reveal-late,
html:not(.js) .scroll-hint,
html:not(.js) .nav > .btn{opacity:1 !important;transform:none !important;transition:none !important}
html:not(.js) .hero-h1 .line>span,
html:not(.js) .split .w>span{transform:none !important}
html:not(.js) .abcmark i,
html:not(.js) .drop-mark i{animation:none !important;opacity:1 !important;transform:none !important;color:var(--abc) !important}
html:not(.js) .check path{stroke-dashoffset:0 !important;animation:none !important}

/* ═══════════════ phones: the same page, without the GPU bill ═══════════════
   Measured 2026-09-12 on a 375px viewport: the four 56vw blobs at blur(110px)
   animating forever, the blur(40px) drift under the closer, and backdrop-filter
   on the nav and sticky bar are the whole reason the hero stutters on an iPhone.
   None of them is the design — the colour is. Keep the colour, drop the filters. */
@media(max-width:900px),(pointer:coarse){
  .blob{animation:none;filter:none;opacity:.10;width:70vw;height:70vw;
    background:radial-gradient(circle at 50% 50%,var(--c,transparent) 0%,transparent 70%)}
  .blob-b{--c:var(--blue)}.blob-r{--c:var(--red)}.blob-y{--c:var(--yellow)}.blob-g{--c:var(--green)}
  .final::before{filter:none;animation:none;opacity:.9}
  .nav.is-solid{backdrop-filter:none;-webkit-backdrop-filter:none;background:rgba(255,255,255,.97)}
  .sticky-cta{backdrop-filter:none;background:rgba(255,255,255,.98)}
  .drop-mark i{will-change:auto}
  /* the headline and button do not wait for the letters to land */
  .hero .reveal-late{transition-delay:0s!important}
}

