/* ==========================================================================
   BT WEB — shared stylesheet
   Direction: "Workshop After Dark"
   Dark ink workshop sections alternating with warm bone paper sections.
   Signature element: The Reveal (draggable before/after split panel).
   Brand device: the short blue underline from the logo, reused everywhere.
   ========================================================================== */

/* ---------- 1. Tokens ---------- */
:root{
  /* palette */
  --ink:#0B0E13;
  --carbon:#151A22;
  --carbon-2:#1C2330;
  --arc:#0819F0;          /* exact blue sampled from the logo underline */
  --arc-deep:#0713B8;
  --arc-bright:#4356FF;   /* interactive blue on dark backgrounds */
  --glow:#5A6CFF;
  --bone:#F5F0E8;
  --bone-2:#ECE5D8;
  --ink-on-bone:#14171E;
  --muted-on-bone:#5B5648;
  --muted-on-ink:#9AA3B5;
  --ember:#D96A2B;
  --line-dark:rgba(245,240,232,.13);
  --line-light:rgba(20,23,30,.14);

  /* type */
  --font-display:"Bricolage Grotesque",system-ui,sans-serif;
  --font-body:"Instrument Sans",system-ui,sans-serif;
  --font-mono:"IBM Plex Mono",ui-monospace,monospace;

  /* min tuned so "See your website first." holds one line at 320px and 390px */
  --fs-900:clamp(1.5rem,2px + 7.1vw,4.6rem);
  --fs-800:clamp(1.9rem,1.2rem + 3.2vw,3.2rem);
  --fs-700:clamp(1.45rem,1.15rem + 1.5vw,2.05rem);
  --fs-600:clamp(1.2rem,1.1rem + .5vw,1.4rem);
  --fs-500:1.125rem;
  --fs-400:1rem;
  --fs-300:.875rem;
  --fs-200:.78rem;

  /* spacing + shape */
  --space-1:.5rem; --space-2:1rem; --space-3:1.5rem; --space-4:2.5rem;
  --space-5:4rem;  --space-6:6.5rem;
  --radius-s:.55rem; --radius-m:1rem; --radius-l:1.6rem; --radius-xl:2.2rem;
  --container:74rem;

  /* motion */
  --ease-out:cubic-bezier(.16,1,.3,1);
  --ease-in:cubic-bezier(.4,0,.2,1);

  /* layered blue-tinted shadows, never flat grey */
  --shadow-card:0 1px 2px rgba(8,25,240,.06),0 6px 18px rgba(11,14,19,.10),0 24px 48px rgba(11,14,19,.10);
  --shadow-card-dark:0 1px 2px rgba(0,0,0,.4),0 10px 28px rgba(0,0,0,.45),0 30px 70px rgba(8,25,240,.14);
  --shadow-btn:none;
}

/* ---------- 2. Reset + base ---------- */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
/* when Lenis drives the scroll, native smooth scrolling must switch off or they fight */
html.lenis{height:auto;scroll-behavior:auto!important}
body{
  font-family:var(--font-body);
  font-size:var(--fs-400);
  line-height:1.7;
  color:var(--bone);
  background:var(--ink);
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
button{font:inherit;border:0;background:none;cursor:pointer;color:inherit}
h1,h2,h3,h4{font-family:var(--font-display);line-height:1.08;letter-spacing:-.03em;font-weight:700}
:focus-visible{outline:3px solid var(--arc-bright);outline-offset:3px;border-radius:2px}
::selection{background:var(--arc);color:#fff}

/* ---------- 3. Utilities ---------- */
.container{width:min(100% - 2.5rem,var(--container));margin-inline:auto}
@media(max-width:480px){.container{width:min(100% - 2rem,var(--container))}}

.section{padding-block:clamp(4rem,9vw,7rem);position:relative}
.section--bone{background:var(--bone);color:var(--ink-on-bone)}
.section--carbon{background:var(--carbon)}

/* faint blueprint grid + grain on dark sections */
.section--ink{background:var(--ink)}
.texture::before{
  content:"";position:absolute;inset:0;pointer-events:none;
  background-image:
    linear-gradient(var(--line-dark) 1px,transparent 1px),
    linear-gradient(90deg,var(--line-dark) 1px,transparent 1px);
  background-size:72px 72px;
  opacity:.14;
  -webkit-mask-image:radial-gradient(ellipse 90% 70% at 50% 0%,#000 30%,transparent 75%);
          mask-image:radial-gradient(ellipse 90% 70% at 50% 0%,#000 30%,transparent 75%);
}
.grain::after{
  content:"";position:absolute;inset:0;pointer-events:none;opacity:.05;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.6'/%3E%3C/svg%3E");
}

/* mono kicker labels, the technical voice */
.kicker{
  font-family:var(--font-mono);font-size:var(--fs-200);font-weight:500;
  text-transform:uppercase;letter-spacing:.22em;
  color:var(--ember);display:flex;align-items:center;gap:.9rem;
  margin-bottom:var(--space-3);
}
.kicker::before{content:"";width:2.2rem;height:2px;background:var(--ember);flex:none}

/* the logo underline, reused as the site-wide emphasis device */
.u-mark{position:relative;display:inline-block;white-space:nowrap}
.u-mark::after{
  content:"";position:absolute;left:.02em;right:.02em;bottom:-.15em;
  height:.12em;background:var(--arc);border-radius:1px;
}
.section--ink .u-mark::after,.section--carbon .u-mark::after{background:var(--arc-bright)}

/* Headings run at 1.08 leading, which is tight enough that an underlined word
   on any line but the last drops its rule onto the caps of the line below.
   Only headings that actually carry a mark are loosened, and the rule is
   pulled a touch closer to the word at the same time, so the fix is invisible
   on a heading that fits one line and impossible to hit on one that wraps.
   The step-form questions are left alone: they set their own pair already. */
h1:has(.u-mark):not(.sf-q),
h2:has(.u-mark):not(.sf-q),
h3:has(.u-mark):not(.sf-q){line-height:1.2}
h1:has(.u-mark):not(.sf-q) .u-mark::after,
h2:has(.u-mark):not(.sf-q) .u-mark::after,
h3:has(.u-mark):not(.sf-q) .u-mark::after{bottom:-.08em}

.nb{white-space:nowrap}

/* quiet secondary link, the lower-commitment path next to a main CTA */
.soft-link{font-size:.92rem;color:var(--muted-on-ink);margin-bottom:var(--space-4)}
.soft-link a{color:var(--bone);text-decoration:underline;text-underline-offset:3px;text-decoration-color:var(--arc-bright);transition:color .25s var(--ease-in)}
.soft-link a:hover{color:var(--arc-bright)}
.section--bone .soft-link{color:var(--muted-on-bone)}
.section--bone .soft-link a{color:var(--ink-on-bone);text-decoration-color:var(--arc)}

.section-head{max-width:46rem}
.section-head h2{font-size:var(--fs-800);margin-bottom:var(--space-2)}
.section-head p{font-size:var(--fs-500);color:var(--muted-on-ink)}
.section--bone .section-head p{color:var(--muted-on-bone)}

/* ---------- 4. Buttons ---------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:.6rem;
  font-family:var(--font-display);font-weight:600;font-size:1.02rem;
  letter-spacing:-.01em;padding:.95rem 1.7rem;border-radius:6px;
  min-height:48px;position:relative;overflow:hidden;
  transition:transform .35s var(--ease-out),box-shadow .35s var(--ease-out);
  will-change:transform;
}
.btn:active{transform:scale(.965)}
.btn--primary{
  background:linear-gradient(135deg,var(--arc) 0%,#2334FF 100%);
  color:#fff;box-shadow:var(--shadow-btn);
}
.btn--primary:hover{transform:translateY(-2px)}
.btn--primary::after{ /* shine sweep */
  content:"";position:absolute;top:0;bottom:0;left:-70%;width:45%;
  background:linear-gradient(105deg,transparent,rgba(255,255,255,.35),transparent);
  transform:skewX(-20deg);transition:transform .6s var(--ease-out);
}
.btn--primary:hover::after{transform:skewX(-20deg) translateX(340%)}
.btn--ghost{border:1.5px solid var(--line-dark);color:var(--bone)}
.btn--ghost:hover{transform:translateY(-2px);border-color:var(--muted-on-ink)}
.section--bone .btn--ghost{border-color:var(--line-light);color:var(--ink-on-bone)}
.btn--bone{background:var(--bone);color:var(--arc-deep);box-shadow:none}
.btn--bone:hover{transform:translateY(-2px)}

.link-arrow{
  display:inline-flex;align-items:center;gap:.45rem;font-weight:600;
  font-family:var(--font-display);color:var(--arc-bright);
}
.section--bone .link-arrow{color:var(--arc)}
.link-arrow svg{transition:transform .3s var(--ease-out)}
.link-arrow:hover svg{transform:translateX(4px)}

/* ---------- 5. Header ---------- */
.site-header{
  position:fixed;inset-inline:0;top:0;z-index:50;
  transition:transform .4s var(--ease-out);
}
.site-header .bar{
  display:flex;align-items:center;justify-content:space-between;
  padding-block:1rem;gap:1.5rem;
}
.site-header::before{
  content:"";position:absolute;inset:0;background:rgba(11,14,19,.93);
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  border-bottom:1px solid transparent;opacity:0;transition:opacity .4s var(--ease-in);
}
.site-header.scrolled::before{opacity:1;border-bottom-color:var(--line-dark)}
.site-header>*{position:relative}

/* wordmark rebuilt in code from the logo */
.wordmark{display:inline-flex;align-items:baseline;font-family:var(--font-display);line-height:1}
.wordmark .wm-bt{
  font-weight:800;font-size:1.62rem;letter-spacing:-.03em;color:#fff;
  position:relative;padding-bottom:.14em;
}
.wordmark .wm-bt::after{
  content:"";position:absolute;left:0;right:.04em;bottom:0;height:.115em;
  background:var(--arc);border-radius:1px;
}
.wordmark .wm-web{font-weight:500;font-size:1.62rem;letter-spacing:-.015em;color:#fff;margin-left:.16em}

.main-nav{display:flex;align-items:center;gap:.35rem}
.main-nav>a,.nav-drop>button{
  font-weight:500;font-size:.98rem;padding:.55rem .85rem;border-radius:.6rem;
  color:var(--muted-on-ink);position:relative;
  transition:color .25s var(--ease-in);display:inline-flex;align-items:center;gap:.35rem;
}
.main-nav>a:hover,.nav-drop>button:hover{color:#fff}
.main-nav>a.active{color:#fff}
.main-nav>a.active::after{
  content:"";position:absolute;left:.85rem;right:.85rem;bottom:.25rem;
  height:2px;background:var(--arc-bright);border-radius:1px;
}

.nav-drop{position:relative}
.nav-drop svg{transition:transform .3s var(--ease-out)}
.nav-drop.open svg,.nav-drop:hover svg{transform:rotate(180deg)}
.drop-panel{
  position:absolute;top:calc(100% + .6rem);left:50%;transform:translateX(-50%) translateY(8px);
  min-width:17rem;background:var(--carbon-2);border:1px solid var(--line-dark);
  border-radius:var(--radius-m);padding:.5rem;box-shadow:var(--shadow-card-dark);
  opacity:0;pointer-events:none;
  transition:opacity .3s var(--ease-out),transform .3s var(--ease-out);
}
.nav-drop.open .drop-panel,.nav-drop:hover .drop-panel,.nav-drop:focus-within .drop-panel{
  opacity:1;pointer-events:auto;transform:translateX(-50%) translateY(0);
}
.drop-panel a{display:block;padding:.7rem .85rem;border-radius:.6rem;transition:background .25s var(--ease-in)}
.drop-panel a:hover{background:rgba(255,255,255,.06)}
.drop-panel a strong{display:block;font-family:var(--font-display);font-weight:600;color:#fff;font-size:.98rem}
.drop-panel a span{font-size:.85rem;color:var(--muted-on-ink)}

.header-cta{display:flex;align-items:center;gap:.6rem}
.header-cta .btn{padding:.7rem 1.3rem;min-height:44px;font-size:.95rem}

/* hamburger */
.menu-btn{
  display:none;width:46px;height:46px;border-radius:50%;
  place-items:center;transition:background .25s var(--ease-in);
}
.menu-btn:hover{background:rgba(255,255,255,.08)}

@media(max-width:1020px){
  .main-nav,.header-cta .btn{display:none}
  .menu-btn{display:grid}
}

/* mobile drawer */
.drawer{position:fixed;inset:0;z-index:60;pointer-events:none}
.drawer-backdrop{
  position:absolute;inset:0;background:rgba(0,0,0,.55);
  opacity:0;transition:opacity .35s var(--ease-in);
}
.drawer-panel{
  position:absolute;top:0;right:0;height:100%;width:min(84%,22rem);
  background:var(--carbon);border-left:1px solid var(--line-dark);
  transform:translateX(100%);transition:transform .4s var(--ease-out);
  display:flex;flex-direction:column;overflow-y:auto;
}
.drawer.open{pointer-events:auto}
.drawer.open .drawer-backdrop{opacity:1}
.drawer.open .drawer-panel{transform:translateX(0)}
.drawer-top{display:flex;align-items:center;justify-content:space-between;padding:1.15rem 1.4rem;border-bottom:1px solid var(--line-dark)}
.drawer-nav{display:flex;flex-direction:column;padding:1rem .8rem;font-size:1.12rem}
.drawer-nav a{padding:.85rem 1rem;border-radius:.8rem;font-weight:500;min-height:48px;display:flex;align-items:center;transition:background .25s var(--ease-in)}
.drawer-nav a:hover{background:rgba(255,255,255,.06)}
.drawer-nav .drawer-sub{padding-left:1.9rem;font-size:1rem;color:var(--muted-on-ink)}
.drawer-foot{margin-top:auto;padding:1.4rem;border-top:1px solid var(--line-dark);display:grid;gap:.8rem}
.drawer-foot .btn{width:100%}
.drawer-foot p{font-size:.85rem;color:var(--muted-on-ink);text-align:center}

/* ---------- 6. Hero ---------- */
.hero{
  padding-top:clamp(7rem,14vh,9.5rem);
  padding-bottom:clamp(3rem,7vw,5.5rem);
  position:relative;overflow:hidden;
}
.hero-glow{
  position:absolute;width:60rem;height:60rem;border-radius:50%;
  background:radial-gradient(circle,rgba(8,25,240,.32) 0%,rgba(8,25,240,.10) 40%,transparent 68%);
  top:-22rem;right:-18rem;pointer-events:none;
  animation:breathe 7s var(--ease-in) infinite alternate;
  will-change:transform,opacity;
}
@keyframes breathe{from{transform:scale(1);opacity:.75}to{transform:scale(1.14);opacity:1}}

.hero-grid{
  display:grid;grid-template-columns:minmax(0,5fr) minmax(0,6fr);
  gap:clamp(2rem,5vw,4.5rem);align-items:center;
}
.hero h1{font-size:var(--fs-900);font-weight:800;color:#fff;margin-bottom:var(--space-3)}
.hero .lede{font-size:var(--fs-500);color:var(--muted-on-ink);max-width:33rem;margin-bottom:var(--space-4)}
.hero-ctas{display:flex;gap:.9rem;flex-wrap:wrap;margin-bottom:var(--space-4)}
.hero-facts{
  display:flex;gap:1.6rem;flex-wrap:wrap;
  font-family:var(--font-mono);font-size:var(--fs-200);letter-spacing:.06em;
  color:var(--muted-on-ink);
}
.hero-facts span{display:flex;align-items:center;gap:.5rem}
.hero-facts span::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--ember)}

@media(max-width:900px){
  .hero{padding-top:6rem}
  /* On a phone the proof should sit between the promise and the buttons,
     so the Reveal is visible without scrolling past the call to action. */
  .hero-grid{display:flex;flex-direction:column;gap:0;align-items:stretch}
  .hero-copy{display:contents}
  .hero .kicker{order:1;margin-bottom:1rem}
  .hero h1{order:2;margin-bottom:1rem}
  .hero .lede{order:3;margin-bottom:1.6rem;font-size:1.04rem}
  .hero-visual{order:4;margin-bottom:1.8rem}
  .hero-ctas{order:5;margin-bottom:1rem;gap:.7rem}
  .hero .soft-link{order:6;margin-bottom:1.4rem;font-size:.86rem}
  .hero-facts{order:7;gap:.5rem 1.2rem;font-size:.72rem}
  .hero-ctas .btn{width:100%}
}
@media(min-width:901px){.hero-ctas .btn{width:auto}}

/* ---------- 7. The Reveal ---------- */
.reveal-frame{
  background:var(--carbon-2);border:1px solid var(--line-dark);
  border-radius:var(--radius-l);box-shadow:var(--shadow-card-dark);
  overflow:hidden;position:relative;
}
.reveal-chrome{
  display:flex;align-items:center;gap:.9rem;
  padding:.8rem 1.1rem;border-bottom:1px solid var(--line-dark);
}
.reveal-chrome .dots{display:flex;gap:.4rem}
.reveal-chrome .dots i{width:.72rem;height:.72rem;border-radius:50%;background:rgba(255,255,255,.16)}
.reveal-chrome .addr{
  /* min-width:0 or the nowrap text sets a min-content floor and quietly
     widens whatever grid track the frame sits in */
  flex:1;min-width:0;text-align:center;font-family:var(--font-mono);font-size:.78rem;
  color:var(--muted-on-ink);background:rgba(255,255,255,.05);
  border-radius:999px;padding:.32rem 1rem;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.reveal-stage{position:relative;aspect-ratio:16/10;overflow:hidden;touch-action:pan-y;cursor:ew-resize;background:#dedcd2}
.reveal-after{position:absolute;inset:0}
.reveal-after img{width:100%;height:100%;object-fit:cover;object-position:top}
.reveal-before{position:absolute;inset:0;z-index:2;overflow:hidden}
.reveal-before-inner{position:absolute;inset:0}
.reveal-divider{
  position:absolute;top:0;bottom:0;z-index:3;width:0;
  border-left:3px solid var(--bone);
  box-shadow:0 0 0 1px rgba(0,0,0,.2),0 0 24px rgba(8,25,240,.55);
}
.reveal-handle{
  position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  width:52px;height:52px;border-radius:50%;
  background:var(--bone);color:var(--ink);
  display:grid;place-items:center;box-shadow:0 4px 16px rgba(0,0,0,.45);
  cursor:ew-resize;
}
.reveal-label{
  position:absolute;bottom:.85rem;z-index:4;
  font-family:var(--font-mono);font-size:.7rem;font-weight:500;
  letter-spacing:.14em;text-transform:uppercase;
  padding:.34rem .8rem;border-radius:999px;
  transition:opacity .3s var(--ease-in);pointer-events:none;
}
.reveal-label--before{left:.85rem;background:rgba(20,23,30,.72);color:var(--bone)}
.reveal-label--after{right:.85rem;background:var(--arc);color:#fff}
@media(max-width:600px){
  .reveal-label{font-size:.58rem;letter-spacing:.1em;bottom:.6rem}
  .reveal-label--before{left:.6rem}
  .reveal-label--after{right:.6rem}
}
.reveal-caption{
  font-size:.83rem;color:var(--muted-on-ink);
  padding:.8rem 1.1rem;border-top:1px solid var(--line-dark);
}

/* the "before" mock: a deliberately dated fake site, clearly a mock-up */
.oldsite{
  position:absolute;inset:0;background:#EFEDE4;color:#3a3a34;
  font-family:Georgia,"Times New Roman",serif;font-size:clamp(.5rem,1.4vw,.8rem);
  line-height:1.45;filter:saturate(.75);display:flex;flex-direction:column;
}
.oldsite-top{background:#2e3548;color:#fff;padding:4% 5% 3%;}
.oldsite-top h3{font-family:inherit;font-size:2.1em;letter-spacing:0;font-weight:700}
.oldsite-top p{font-style:italic;font-size:.95em;color:#c9cdd8}
.oldsite-nav{display:flex;gap:1.2em;background:#d9d5c6;padding:1.2% 5%;font-family:Verdana,sans-serif;font-size:.82em}
.oldsite-nav span{color:#1a3f8f;text-decoration:underline}
.oldsite-body{padding:3.5% 5%;display:grid;grid-template-columns:1.6fr 1fr;gap:5%;flex:1;min-height:0}
.oldsite-body h4{font-family:inherit;font-size:1.35em;font-weight:700;letter-spacing:0;margin-bottom:.5em}
.oldsite-line{height:.55em;background:#cfccbd;border-radius:2px;margin-bottom:.55em}
.oldsite-line.short{width:62%}
.oldsite-photo{
  background:repeating-conic-gradient(#d8d4c6 0% 25%,#cbc7b8 0% 50%);
  border:2px inset #b5b1a2;display:grid;place-items:center;
  color:#8a8677;font-family:Verdana,sans-serif;font-size:.75em;
  min-height:52%;text-align:center;padding:.5em;
}
.oldsite-btn{
  display:inline-block;margin-top:.9em;background:linear-gradient(#f8e277,#d4a017);
  border:2px outset #e8c04a;color:#4a3606;font-family:Verdana,sans-serif;
  font-size:.8em;font-weight:700;padding:.45em 1.1em;
}
.oldsite-foot{background:#d9d5c6;font-family:Verdana,sans-serif;font-size:.68em;color:#7c786a;padding:1.2% 5%;display:flex;justify-content:space-between;gap:1em}

@media(max-width:600px){
  .reveal-handle{width:44px;height:44px}
  /* stage keeps the 16/10 browser-window shape so the screenshot is never cropped */
}
@media(max-width:420px){
  /* small phones: the mock stays messy on purpose, but text must never
     genuinely overflow or get chopped mid-word */
  .oldsite{font-size:.44rem;line-height:1.35}
  .oldsite-top h3{font-size:1.8em;overflow-wrap:break-word}
  .oldsite-top p{font-size:.9em}
  .oldsite-nav{gap:.8em;flex-wrap:wrap;row-gap:.2em}
  .oldsite-foot span:last-child{white-space:nowrap}
}

/* ---------- 8. Ticker ---------- */
.ticker{
  border-block:1px solid var(--line-dark);overflow:hidden;
  padding-block:.85rem;background:var(--ink);position:relative;
}
.ticker-track{
  display:flex;gap:3rem;width:max-content;
  animation:ticker 30s linear infinite;will-change:transform;
}
.ticker span{
  font-family:var(--font-mono);font-size:var(--fs-300);letter-spacing:.16em;
  text-transform:uppercase;color:var(--muted-on-ink);
  display:flex;align-items:center;gap:3rem;white-space:nowrap;
}
.ticker span::after{content:"";width:7px;height:7px;border-radius:50%;background:var(--arc-bright);flex:none}
@keyframes ticker{to{transform:translateX(-50%)}}

/* ---------- 9. Cards (problem / included) ---------- */
.card-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1.4rem;margin-top:var(--space-5)}
@media(max-width:900px){.card-grid{grid-template-columns:1fr}}
.p-card{
  background:var(--bone-2);border:1px solid var(--line-light);
  border-radius:var(--radius-m);padding:1.8rem;
  box-shadow:var(--shadow-card);
  transition:transform .4s var(--ease-out),box-shadow .4s var(--ease-out);
  will-change:transform;
}
.p-card:hover{transform:translateY(-5px);box-shadow:0 2px 4px rgba(8,25,240,.08),0 14px 34px rgba(20,23,30,.14),0 34px 70px rgba(20,23,30,.12)}
.p-card h3{font-size:var(--fs-600);margin-bottom:.6rem}
.p-card p{color:var(--muted-on-bone);font-size:.98rem}
.p-card .tag{
  font-family:var(--font-mono);font-size:.7rem;letter-spacing:.16em;
  text-transform:uppercase;color:var(--ember);display:block;margin-bottom:1rem;
}

/* ---------- 10. Steps ---------- */
.steps{display:grid;grid-template-columns:repeat(4,1fr);gap:1.4rem;margin-top:var(--space-5)}
@media(max-width:1000px){.steps{grid-template-columns:repeat(2,1fr)}}
@media(max-width:640px){.steps{grid-template-columns:1fr}}
.step{
  background:var(--carbon-2);border:1px solid var(--line-dark);
  border-radius:var(--radius-m);padding:1.7rem;position:relative;
  transition:transform .4s var(--ease-out),box-shadow .4s var(--ease-out);
  will-change:transform;
}
.step:hover{transform:translateY(-5px);box-shadow:var(--shadow-card-dark)}
.step .num{
  font-family:var(--font-mono);font-size:var(--fs-200);color:var(--arc-bright);
  letter-spacing:.16em;display:block;margin-bottom:1.1rem;
}
.step h3{font-size:1.18rem;color:#fff;margin-bottom:.55rem}
.step p{color:var(--muted-on-ink);font-size:.95rem}

/* ---------- 11. Work cards ---------- */
.work-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1.6rem;margin-top:var(--space-5)}
@media(max-width:960px){.work-grid{grid-template-columns:1fr}}
.work-card{display:block;border-radius:var(--radius-m);overflow:hidden;background:var(--carbon-2);border:1px solid var(--line-dark);transition:transform .45s var(--ease-out),box-shadow .45s var(--ease-out);will-change:transform}
.work-card:hover{transform:translateY(-6px);box-shadow:var(--shadow-card-dark)}
.work-shot{position:relative;aspect-ratio:16/10;overflow:hidden}
.work-shot img{width:100%;height:100%;object-fit:cover;object-position:top;transition:transform .6s var(--ease-out);will-change:transform}
.work-card:hover .work-shot img{transform:scale(1.04)}
.work-shot::after{ /* colour treatment layer */
  content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,transparent 55%,rgba(11,14,19,.55));
}
.work-meta{padding:1.3rem 1.4rem 1.5rem}
.work-meta .type{font-family:var(--font-mono);font-size:.72rem;letter-spacing:.16em;text-transform:uppercase;color:var(--ember);display:block;margin-bottom:.5rem}
.work-meta h3{color:#fff;font-size:1.22rem;margin-bottom:.3rem}
.work-meta p{color:var(--muted-on-ink);font-size:.92rem}
.work-badge{
  position:absolute;top:1rem;left:1rem;z-index:2;
  font-family:var(--font-mono);font-size:.68rem;letter-spacing:.13em;
  text-transform:uppercase;background:var(--arc);color:#fff;
  padding:.35rem .75rem;border-radius:999px;
}
.work-note{margin-top:var(--space-4);font-size:.95rem;color:var(--muted-on-ink);max-width:44rem}
.industries-line{
  margin-top:1.4rem;font-size:1rem;color:var(--muted-on-ink);
  display:flex;align-items:center;gap:.65rem;flex-wrap:wrap;
}
.industries-line .link-arrow{
  text-decoration:underline;text-underline-offset:4px;
  text-decoration-thickness:2px;text-decoration-color:var(--arc-bright);
}
.industries-line .link-arrow:hover{text-decoration-color:var(--glow)}

/* ---------- 12. Included list ---------- */
.included-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1.2rem;margin-top:var(--space-5)}
@media(max-width:900px){.included-grid{grid-template-columns:1fr 1fr}}
@media(max-width:600px){.included-grid{grid-template-columns:1fr}}
.inc{
  display:flex;gap:1rem;align-items:flex-start;
  background:var(--bone-2);border:1px solid var(--line-light);
  border-radius:var(--radius-m);padding:1.35rem 1.45rem;
}
.inc svg{flex:none;margin-top:.2rem;color:var(--arc)}
.inc strong{font-family:var(--font-display);font-weight:600;display:block;font-size:1.04rem}
.inc span{color:var(--muted-on-bone);font-size:.92rem}

/* ---------- 13. Pricing teaser ---------- */
.price-teaser{text-align:center;max-width:52rem;margin-inline:auto}
.price-teaser .big{
  font-family:var(--font-display);font-weight:800;font-size:var(--fs-800);
  color:#fff;letter-spacing:-.03em;line-height:1.15;margin-block:var(--space-3);
}
.price-teaser .big .n{color:var(--arc-bright)}
.price-teaser p.note{color:var(--muted-on-ink);margin-bottom:var(--space-3)}
.why-cheap{
  max-width:38rem;margin:0 auto var(--space-4);
  font-size:.95rem;color:var(--muted-on-ink);
  border-left:2px solid var(--ember);padding-left:1.1rem;text-align:left;
}

/* ---------- 14. CTA panel ---------- */
.cta-panel{
  background:linear-gradient(135deg,var(--arc-deep) 0%,var(--arc) 55%,#2334FF 100%);
  border-radius:var(--radius-xl);padding:clamp(2.5rem,6vw,4.5rem);
  text-align:center;color:#fff;position:relative;overflow:hidden;
  box-shadow:0 20px 60px rgba(8,25,240,.35);
}
.cta-panel::before{
  content:"";position:absolute;inset:0;
  background:radial-gradient(ellipse 70% 90% at 80% 10%,rgba(255,255,255,.16),transparent 60%);
  pointer-events:none;
}
.cta-panel h2{font-size:var(--fs-800);margin-bottom:var(--space-2);position:relative}
.cta-panel p{position:relative;max-width:36rem;margin:0 auto var(--space-4);color:rgba(255,255,255,.85);font-size:var(--fs-500)}
.cta-panel .row{display:flex;gap:1rem;justify-content:center;flex-wrap:wrap;position:relative}
/* two equal ways in, so neither one reads as the afterthought. On a phone
   they stack, and matching widths stop the pair looking ragged. */
@media(max-width:600px){
  .cta-panel .row--two{flex-direction:column;align-items:stretch}
  .cta-panel .row--two .btn{width:100%}
}
.cta-panel .alt{margin-top:1.2rem;font-size:.95rem;color:rgba(255,255,255,.75);position:relative}
.cta-panel .alt + .alt{margin-top:.5rem}
.cta-panel .alt a{font-weight:600;color:#fff;text-decoration:underline;text-underline-offset:3px}

/* ---------- 15. Footer ---------- */
.site-footer{background:var(--ink);border-top:1px solid var(--line-dark);padding-block:var(--space-5) var(--space-4)}
.footer-grid{display:grid;grid-template-columns:2fr 1fr 1fr 1.4fr;gap:2.5rem}
@media(max-width:900px){.footer-grid{grid-template-columns:1fr 1fr}}
@media(max-width:560px){.footer-grid{grid-template-columns:1fr}}
.site-footer .pitch{color:var(--muted-on-ink);font-size:.95rem;max-width:18rem;margin-top:1rem}
.site-footer h4{font-family:var(--font-mono);font-size:.72rem;font-weight:500;letter-spacing:.18em;text-transform:uppercase;color:var(--ember);margin-bottom:1rem}
.site-footer ul{list-style:none;display:grid;gap:.55rem}
.site-footer ul a{color:var(--muted-on-ink);font-size:.95rem;transition:color .25s var(--ease-in)}
.site-footer ul a:hover{color:#fff}
.footer-bottom{
  margin-top:var(--space-5);padding-top:var(--space-3);
  border-top:1px solid var(--line-dark);
  display:flex;justify-content:space-between;gap:1rem;flex-wrap:wrap;
  font-size:.82rem;color:var(--muted-on-ink);
}

/* ---------- 16. Scroll reveals + failsafe ---------- */
.reveal-el{opacity:1;transform:none}
.js .reveal-el{
  opacity:0;transform:translateY(26px);
  transition:opacity .8s var(--ease-out),transform .8s var(--ease-out);
  transition-delay:var(--d,0s);
  will-change:transform,opacity;
}
.js .reveal-el.in{opacity:1;transform:translateY(0)}

/* ---------- 17. Reduced motion ---------- */
@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.001s!important;animation-iteration-count:1!important;transition-duration:.001s!important}
  .ticker-track{animation:none}
  .hero-glow{animation:none}
  .js .reveal-el{opacity:1;transform:none}
}

/* ==========================================================================
   18. Motion layer
   One idea, used consistently: the blue underline from the logo draws itself.
   Everything else here is either ambient light on the dark sections or a
   small hover response. Nothing new competes with The Reveal in the hero.
   ========================================================================== */

/* --- the wordmark draws its own underline on load, and redraws on hover --- */
.js .wordmark .wm-bt::after{
  transform-origin:left center;
  animation:draw-line .9s var(--ease-out) .2s both;
}
.js .wordmark:hover .wm-bt::after{animation:redraw-line .75s var(--ease-out)}
@keyframes draw-line{from{transform:scaleX(0)}to{transform:scaleX(1)}}
@keyframes redraw-line{from{transform:scaleX(0)}to{transform:scaleX(1)}}

/* --- every emphasis underline in the copy draws in as its section arrives --- */
.js .reveal-el .u-mark::after,
.js .reveal-el.u-mark::after{
  transform:scaleX(0);transform-origin:left center;
  transition:transform .85s var(--ease-out) .3s;
}
.js .reveal-el.in .u-mark::after,
.js .reveal-el.in.u-mark::after{transform:scaleX(1)}

/* --- the little mono label dash draws in the same way --- */
.js .reveal-el .kicker::before,
.js .reveal-el.kicker::before{
  transform:scaleX(0);transform-origin:left center;
  transition:transform .7s var(--ease-out) .1s;
}
.js .reveal-el.in .kicker::before,
.js .reveal-el.in.kicker::before{transform:scaleX(1)}

/* --- thin blue line across the top showing how far down the page you are --- */
.scroll-progress{
  position:fixed;top:0;left:0;right:0;height:2px;z-index:70;
  background:linear-gradient(90deg,var(--arc),var(--glow));
  transform:scaleX(0);transform-origin:left center;
  pointer-events:none;will-change:transform;
}

/* --- ambient light drifting behind the dark sections --- */
/* both dark tones must clip, or a drift orb widens the whole document and
   the page scrolls sideways on a phone */
.section--ink,.section--carbon{overflow:hidden}
.drift{
  position:absolute;width:44rem;height:44rem;border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,rgba(8,25,240,.22) 0%,rgba(8,25,240,.07) 45%,transparent 70%);
  top:-14rem;right:-12rem;
  animation:drift-a 22s var(--ease-in) infinite alternate;
  will-change:transform;
}
.drift--left{top:auto;bottom:-16rem;right:auto;left:-14rem;animation-name:drift-b;animation-duration:26s}
@keyframes drift-a{from{transform:translate3d(0,0,0) scale(1)}to{transform:translate3d(-6rem,4rem,0) scale(1.12)}}
@keyframes drift-b{from{transform:translate3d(0,0,0) scale(1.08)}to{transform:translate3d(5rem,-3rem,0) scale(1)}}

/* --- the drag handle quietly pings until someone touches it --- */
.js .reveal-handle::before{
  content:"";position:absolute;inset:-7px;border-radius:50%;
  border:2px solid var(--arc-bright);pointer-events:none;
  animation:handle-ping 2.8s var(--ease-out) 1.8s infinite;
}
.js .reveal-stage.touched .reveal-handle::before{animation:none;opacity:0}
@keyframes handle-ping{
  0%{transform:scale(.9);opacity:.85}
  60%,100%{transform:scale(1.55);opacity:0}
}

/* --- a slow shine across the main call to action so the eye finds it --- */
.js .btn--beacon::before{
  content:"";position:absolute;top:0;bottom:0;left:-55%;width:38%;
  background:linear-gradient(105deg,transparent,rgba(255,255,255,.32),transparent);
  transform:skewX(-20deg) translateX(0);
  animation:beacon 7s var(--ease-in) 2.4s infinite;
}
@keyframes beacon{
  0%{transform:skewX(-20deg) translateX(0)}
  22%,100%{transform:skewX(-20deg) translateX(430%)}
}

/* --- the hero fact dots breathe, slightly out of step with each other --- */
.hero-facts span::before{animation:dot-pulse 3.6s var(--ease-in) infinite}
.hero-facts span:nth-child(2)::before{animation-delay:.6s}
.hero-facts span:nth-child(3)::before{animation-delay:1.2s}
@keyframes dot-pulse{
  0%,100%{opacity:.45;transform:scale(.78)}
  50%{opacity:1;transform:scale(1.18)}
}

/* --- each tick draws itself as the "what you get" grid scrolls in --- */
.js .inc svg path{
  stroke-dasharray:1;stroke-dashoffset:1;
  transition:stroke-dashoffset .8s var(--ease-out) .3s;
}
.js .inc.in svg path{stroke-dashoffset:0}
.inc{transition:transform .35s var(--ease-out),border-color .35s var(--ease-in)}
.inc:hover{transform:translateY(-3px);border-color:rgba(8,25,240,.3)}
.inc svg{transition:transform .35s var(--ease-out)}
.inc:hover svg{transform:scale(1.14)}

/* --- nav links get the same underline, sliding in on hover --- */
.main-nav>a::before{
  content:"";position:absolute;left:.85rem;right:.85rem;bottom:.25rem;
  height:2px;background:var(--arc-bright);border-radius:1px;
  transform:scaleX(0);transform-origin:left center;
  transition:transform .3s var(--ease-out);
}
.main-nav>a:hover::before{transform:scaleX(1)}
.main-nav>a.active::before{content:none}

/* --- footer links nudge across on hover --- */
.site-footer ul a{display:inline-block;transition:color .25s var(--ease-in),transform .25s var(--ease-out)}
.site-footer ul a:hover{transform:translateX(3px)}

/* --- light turning slowly inside the closing panel --- */
.cta-panel::after{
  content:"";position:absolute;inset:-45%;pointer-events:none;
  background:radial-gradient(circle at 32% 68%,rgba(120,136,255,.4),transparent 52%);
  animation:panel-turn 20s linear infinite;
  will-change:transform;
}
@keyframes panel-turn{to{transform:rotate(360deg)}}

/* --- the effort line under the four steps --- */
.effort-line{
  margin-top:var(--space-4);max-width:40rem;
  font-size:var(--fs-500);color:var(--bone-2);
  border-left:2px solid var(--arc-bright);padding-left:1.1rem;
}
/* the same aside on warm paper: the bone tint would all but vanish there */
.section--bone .effort-line{color:var(--muted-on-bone);border-left-color:var(--arc)}

/* --- everything above switches off for anyone who asks for less motion --- */
@media(prefers-reduced-motion:reduce){
  .drift,.cta-panel::after{animation:none}
  .js .reveal-handle::before,.js .btn--beacon::before{display:none}
  .hero-facts span::before{animation:none}
  .js .wordmark .wm-bt::after{animation:none;transform:none}
  .js .reveal-el .u-mark::after,.js .reveal-el.u-mark::after,
  .js .reveal-el .kicker::before,.js .reveal-el.kicker::before{transform:none}
  .js .inc svg path{stroke-dasharray:none;stroke-dashoffset:0}
  .scroll-progress{display:none}
}

/* ==========================================================================
   19. About page
   ========================================================================== */

.about-grid{
  display:grid;grid-template-columns:minmax(0,6fr) minmax(0,5fr);
  gap:clamp(2.5rem,6vw,5rem);align-items:center;
}

/* the portrait: framed like a print. No brand underline here on purpose:
   that device belongs under key words in headings, not under images. */
.portrait{position:relative;max-width:24rem;margin-inline:auto;width:100%}
.portrait img{
  width:100%;height:auto;display:block;border-radius:var(--radius-m);
  box-shadow:0 2px 8px rgba(0,0,0,.4),0 24px 60px rgba(0,0,0,.45);
}
.portrait-tag{
  position:absolute;bottom:1rem;left:1rem;
  font-family:var(--font-mono);font-size:.7rem;font-weight:500;
  letter-spacing:.14em;text-transform:uppercase;
  padding:.34rem .8rem;border-radius:999px;
  background:rgba(11,14,19,.72);color:var(--bone);
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
}

/* long-form copy blocks */
.prose{max-width:44rem}
.prose p{font-size:var(--fs-500);margin-bottom:1.25em}
.prose p:last-child{margin-bottom:0}
.section--bone .prose p{color:var(--ink-on-bone)}
.section--bone .prose p strong{font-weight:650}
.section--ink .prose p,.section--carbon .prose p{color:var(--muted-on-ink)}

/* the standout line inside a light section, cousin of .why-cheap */
.pull-line{
  max-width:40rem;margin-top:var(--space-4);
  font-family:var(--font-display);font-weight:600;font-size:var(--fs-600);
  color:var(--ink-on-bone);
  position:relative;padding-left:1.2rem;
}
.pull-line::before{ /* the blue bar draws itself in, same idea as every underline */
  content:"";position:absolute;left:0;top:.15em;bottom:.15em;width:3px;
  background:var(--arc);border-radius:2px;
}
.js .pull-line::before{transform:scaleY(0);transform-origin:top center;transition:transform .8s var(--ease-out) .35s}
.js .pull-line.in::before{transform:scaleY(1)}

/* the portrait answers the cursor, same family as the work cards */
.portrait img{transition:transform .45s var(--ease-out),box-shadow .45s var(--ease-out)}
.portrait:hover img{
  transform:translateY(-5px);
  box-shadow:0 4px 12px rgba(0,0,0,.45),0 30px 70px rgba(0,0,0,.5),0 30px 70px rgba(8,25,240,.14);
}

/* scroll drift: JS feeds --par so the portrait floats a touch slower than the page */
.portrait{transform:translateY(var(--par,0));will-change:transform}

/* a soft light sweeps across the photo on hover, clipped inside the frame */
.portrait::before{
  content:"";position:absolute;inset:0;border-radius:var(--radius-m);z-index:1;
  background:linear-gradient(105deg,transparent 40%,rgba(255,255,255,.16) 50%,transparent 60%) no-repeat;
  background-size:300% 100%;background-position:220% 0;
  transition:background-position .9s var(--ease-out);
  pointer-events:none;
}
.portrait:hover::before{background-position:-120% 0}

@media(max-width:900px){
  /* phones: editorial hero. The photo runs full width and its base dissolves
     into the dark section, and the headline tucks up into the fade, so image
     and words read as one composed piece instead of a card above text */
  .about-grid{display:flex;flex-direction:column;align-items:stretch;gap:0}
  .about-copy{display:contents}
  .about-photo{order:1;margin-bottom:0}
  .portrait{max-width:none;margin-inline:0}
  .portrait img{
    aspect-ratio:4/4.6;object-fit:cover;object-position:50% 10%;
    border-radius:var(--radius-m) var(--radius-m) 0 0;
    box-shadow:none;
    -webkit-mask-image:linear-gradient(180deg,#000 58%,transparent 99%);
            mask-image:linear-gradient(180deg,#000 58%,transparent 99%);
  }
  .portrait-tag{top:.9rem;left:.9rem;bottom:auto}
  .about-grid h1{margin-top:-3.2rem;position:relative;z-index:2}
}
@media(max-width:360px){
  .about-grid h1{margin-top:-2.4rem}
  .portrait-tag{font-size:.6rem;letter-spacing:.1em;padding:.3rem .65rem}
}
@media(prefers-reduced-motion:reduce){
  .portrait{transform:none}
  .portrait::before{display:none}
}

/* ==========================================================================
   20. Work page
   Each build is a self-contained "case" block: browser-framed desktop shot
   with a phone shot hanging off the corner, copy beside it. To add a fifth
   build, copy one whole CASE section in work.html and flip the section
   background and .case--flip class to keep the light/dark rhythm going.
   ========================================================================== */

.case{
  display:grid;grid-template-columns:minmax(0,6fr) minmax(0,5fr);
  gap:clamp(2.5rem,6vw,5rem);align-items:center;
}
.case--flip .case-media{order:2}

/* the media composition: browser frame + overlapping phone */
.case-media{position:relative}
.case-browser{
  background:var(--carbon-2);border:1px solid var(--line-dark);
  border-radius:var(--radius-l);box-shadow:var(--shadow-card-dark);
  overflow:hidden;
}
.case-browser img{width:100%;height:auto;display:block}

/* The phone hangs off whichever side of that build's screenshot carries the
   least information, so it never sits on top of the headline behind it.
   Set the side per case in the markup, not from the flip. */
.case-phone{
  position:absolute;bottom:-2.4rem;
  width:min(34%,11.5rem);
  border-radius:1.3rem;overflow:hidden;
  border:5px solid #232B3A;background:#232B3A;
  box-shadow:0 10px 30px rgba(0,0,0,.5),0 30px 60px rgba(8,25,240,.18);
  transform:translateY(var(--par,0));will-change:transform;
}
.case-phone img{width:100%;height:auto;display:block;border-radius:.9rem}
.case-phone--right{right:-.9rem;left:auto}
.case-phone--left{left:-.9rem;right:auto}

/* honesty badges: who paid and who didn't is never blurred */
.case-badge{
  display:inline-flex;align-items:center;gap:.45rem;
  font-family:var(--font-mono);font-size:.68rem;font-weight:500;
  letter-spacing:.13em;text-transform:uppercase;
  padding:.38rem .8rem;border-radius:999px;margin-bottom:var(--space-3);
}
.case-badge--paid{background:var(--arc);color:#fff}
.case-badge--demo{border:1px solid var(--line-dark);color:var(--muted-on-ink)}
.section--bone .case-badge--demo{border-color:var(--line-light);color:var(--muted-on-bone)}

.case-copy h2{font-size:var(--fs-700);margin-bottom:.6rem}

/* where the business actually is. Kept out of the kicker so that label
   stays one short line instead of wrapping onto an orphan word. */
.case-loc{
  font-family:var(--font-mono);font-size:var(--fs-200);letter-spacing:.1em;
  color:var(--muted-on-ink);margin-bottom:var(--space-3);
  display:flex;align-items:center;gap:.5rem;
}
.case-loc::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--ember);flex:none}
.section--bone .case-loc{color:var(--muted-on-bone)}
.case-body{font-size:var(--fs-500);margin-bottom:var(--space-3)}
.section--ink .case-body,.section--carbon .case-body{color:var(--muted-on-ink)}
.section--bone .case-body{color:var(--ink-on-bone)}

/* "The goal" pull line, same family as .why-cheap and .effort-line */
.case-goal{
  border-left:2px solid var(--arc-bright);padding-left:1.1rem;
  font-size:1rem;color:var(--bone-2);margin-bottom:var(--space-3);
}
.section--bone .case-goal{border-color:var(--arc);color:var(--muted-on-bone)}
.case-goal strong{font-family:var(--font-display);font-weight:600}
.section--ink .case-goal strong,.section--carbon .case-goal strong{color:#fff}
.section--bone .case-goal strong{color:var(--ink-on-bone)}

/* mono chips naming what the build pushed hardest */
.case-tags{display:flex;flex-wrap:wrap;gap:.5rem}
.case-tags span{
  font-family:var(--font-mono);font-size:.68rem;letter-spacing:.1em;
  text-transform:uppercase;padding:.42rem .85rem;border-radius:999px;
  border:1px solid var(--line-dark);color:var(--muted-on-ink);
  transition:border-color .3s var(--ease-in),transform .3s var(--ease-out);
}
.case-tags span:hover{border-color:var(--arc-bright);transform:translateY(-2px)}
.section--bone .case-tags span{border-color:var(--line-light);color:var(--muted-on-bone)}
.section--bone .case-tags span:hover{border-color:var(--arc)}

/* the index in the hero: jump straight to a build */
.case-index{
  display:flex;flex-wrap:wrap;gap:.7rem 1.8rem;margin-top:var(--space-4);
  font-family:var(--font-mono);font-size:var(--fs-300);
}
.case-index a{
  display:inline-flex;align-items:baseline;gap:.55rem;
  color:var(--muted-on-ink);transition:color .25s var(--ease-in);
}
.case-index a span{color:var(--arc-bright)}
.case-index a:hover{color:#fff}

@media(max-width:900px){
  .case,.case--flip{grid-template-columns:minmax(0,1fr);gap:0}
  /* Stacked, it reads: who this is, then the picture, then why it was built
     that way. A screenshot says nothing until you know whose it is, and the
     reasoning only means something once you have seen the thing.
     The copy block dissolves into the grid so its parts can sit either side
     of the picture. Nothing moves in the markup, so a screen reader still
     gets name, location, body, goal and tags in one uninterrupted run. */
  .case-copy{display:contents}
  .case-badge{order:1}
  .case-copy .kicker{order:2}
  .case-copy h2{order:3}
  .case-loc{order:4}
  .case-media,.case--flip .case-media{order:5}
  .case-body{order:6}
  .case-goal{order:7}
  .case-tags{order:8}
  /* grid items stretch by default, which would pull the pill the full width */
  .case-badge{justify-self:start}
  /* the phone still hangs below the browser frame, so the bottom margin stays;
     the top one is the gap between the location line and the picture */
  .case-media{margin-top:1.9rem;margin-bottom:3.4rem}
  .case-loc{margin-bottom:0}
  .case-phone{bottom:-2rem;width:min(38%,10rem)}
  .case-phone--right{right:-.4rem}
  .case-phone--left{left:-.4rem}
  .case-index{gap:.6rem 1.3rem;font-size:.78rem}
}
@media(max-width:600px){
  /* one build per line, so the index reads like a contents page instead of
     wrapping into uneven pairs, and each link is an easy thumb target */
  /* align-items:flex-start or each link stretches the full width of the column
     and the whole row becomes tappable, so a thumb landing in the empty space
     to the right of a short name still fires the jump. Shrink-wrapped to the
     text, then padded back up to a 44px touch target. */
  .case-index{flex-direction:column;align-items:flex-start;gap:.15rem}
  .case-index a{padding-block:.55rem;min-height:44px;align-items:center}

  /* Two columns for the long homepage index: five stacked lines push the
     hero too tall on a phone. Grid rather than wrap, so every cell is the
     same width and each link fills its own cell. Free wrapping would give
     ragged, uneven tap zones, which is the exact thing the stacked layout
     was built to avoid. */
  .case-index--two{
    display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    align-items:stretch;gap:.25rem .9rem;
  }
  .case-index--two a{display:flex;padding-right:.4rem}

  /* The short indexes (Work has 4, Google Ads has 3) sit alone in a
     full-height hero, so they get more air and a touch more weight instead
     of huddling at the top with dead space underneath. */
  .case-index:not(.case-index--two){gap:.75rem;font-size:.85rem}
  .case-index:not(.case-index--two) a{padding-block:.95rem;min-height:58px}
}

/* ==========================================================================
   21. Services page
   Three anchored service blocks, the full process timeline, the industries
   grid. No new motion ideas: the process line draws itself in exactly the
   same way every underline on the site does.
   ========================================================================== */

/* anchored sections must clear the fixed header when jumped to */
section[id]{scroll-margin-top:5.5rem}

/* the Services dropdown gets the same current-page marker the links have */
.nav-drop>button.active{color:#fff}
.nav-drop>button.active::after{
  content:"";position:absolute;left:.85rem;right:1.75rem;bottom:.25rem;
  height:2px;background:var(--arc-bright);border-radius:1px;
}

/* --- service block: copy on the left, a summary panel beside it --- */
.svc{
  display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);
  gap:clamp(2rem,5vw,4rem);align-items:start;
}
@media(max-width:900px){.svc{grid-template-columns:minmax(0,1fr)}}

.svc-panel{
  border-radius:var(--radius-l);padding:1.8rem;
  background:var(--bone-2);border:1px solid var(--line-light);
  box-shadow:var(--shadow-card);
}
.section--ink .svc-panel,.section--carbon .svc-panel{
  background:var(--carbon-2);border-color:var(--line-dark);
  box-shadow:var(--shadow-card-dark);
}
.svc-panel h3{font-size:1.12rem;margin-bottom:1.1rem}
.section--ink .svc-panel h3{color:#fff}
.svc-price{
  font-family:var(--font-mono);font-size:var(--fs-200);letter-spacing:.14em;
  text-transform:uppercase;color:var(--ember);display:block;margin-bottom:.9rem;
}
.svc-list{list-style:none;display:grid;gap:.85rem;margin-bottom:1.6rem}
.svc-list li{display:flex;gap:.75rem;align-items:flex-start;font-size:.96rem}
.svc-list svg{flex:none;margin-top:.28rem;color:var(--arc)}
.section--ink .svc-list svg,.section--carbon .svc-list svg{color:var(--arc-bright)}
.section--bone .svc-list li{color:var(--muted-on-bone)}
.section--ink .svc-list li,.section--carbon .svc-list li{color:var(--muted-on-ink)}
.svc-panel .btn{width:100%}
.svc-panel .fine{
  margin-top:.9rem;font-size:.82rem;text-align:center;color:var(--muted-on-bone);
}
.section--ink .svc-panel .fine,.section--carbon .svc-panel .fine{color:var(--muted-on-ink)}

/* On a phone the Contact hero's "call or text" panel just pushes the form
   further down, and the same number, email and Instagram already appear
   under both forms and again in the footer. So it only shows on desktop. */
@media(max-width:900px){
  #contact-page .hero .svc-panel{display:none}
}

/* --- the process timeline --- */
.timeline{position:relative;margin-top:var(--space-5);max-width:46rem}
.tl-line{
  position:absolute;left:1.15rem;top:1.2rem;bottom:1.4rem;width:2px;border-radius:2px;
  background:linear-gradient(180deg,var(--arc-bright) 0%,rgba(67,86,255,.16) 100%);
}
/* same idea as every underline on the site: the line draws itself in */
.js .timeline .tl-line.reveal-el{
  opacity:1;transform:scaleY(0);transform-origin:top center;
  transition:transform 1.8s var(--ease-out);
}
.js .timeline .tl-line.reveal-el.in{transform:scaleY(1)}

.tl{position:relative;padding-left:3.7rem;padding-bottom:2.1rem}
.tl:last-child{padding-bottom:0}
.tl-num{
  position:absolute;left:0;top:0;width:2.4rem;height:2.4rem;border-radius:50%;
  display:grid;place-items:center;background:var(--carbon-2);
  border:1px solid var(--line-dark);z-index:1;
  font-family:var(--font-mono);font-size:.72rem;color:var(--arc-bright);
  transition:border-color .35s var(--ease-in),transform .35s var(--ease-out);
}
.tl:hover .tl-num{border-color:var(--arc-bright);transform:translateY(-2px)}
.tl h3{font-size:1.14rem;color:#fff;margin-bottom:.45rem;padding-top:.5rem}
.tl p{color:var(--muted-on-ink);font-size:.98rem}
.tl-when{
  font-family:var(--font-mono);font-size:.68rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ember);display:block;margin-top:.55rem;
}
@media(max-width:480px){
  .tl{padding-left:3.1rem;padding-bottom:1.9rem}
  .tl-num{width:2.1rem;height:2.1rem;font-size:.66rem}
  .tl-line{left:1rem}
  .tl h3{padding-top:.35rem}
}

/* --- the industries grid --- */
.ind-grid{
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:1.2rem;margin-top:var(--space-5);
}
@media(max-width:900px){.ind-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:560px){.ind-grid{grid-template-columns:minmax(0,1fr)}}
.ind{
  background:var(--bone-2);border:1px solid var(--line-light);
  border-radius:var(--radius-m);padding:1.5rem 1.55rem;
  transition:transform .4s var(--ease-out),border-color .3s var(--ease-in);
  will-change:transform;
}
.ind:hover{transform:translateY(-4px);border-color:rgba(8,25,240,.3)}
.ind h3{font-size:1.05rem;margin-bottom:.85rem}
.ind ul{list-style:none;display:flex;flex-wrap:wrap;gap:.4rem}
.ind li{
  font-family:var(--font-mono);font-size:.67rem;letter-spacing:.07em;
  text-transform:uppercase;color:var(--muted-on-bone);
  border:1px solid var(--line-light);border-radius:999px;padding:.32rem .68rem;
}

/* --- the hero's "on this page" panel, doubling as a quick price list --- */
.svc-hero{
  display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);
  gap:clamp(2rem,5vw,4rem);align-items:center;
}
@media(max-width:900px){
  .svc-hero{grid-template-columns:minmax(0,1fr);gap:2.2rem}
}
.svc-menu{list-style:none;display:grid}
.svc-menu li + li{border-top:1px solid var(--line-dark)}
.svc-menu a{
  display:flex;align-items:baseline;gap:.7rem;padding:.85rem .2rem;min-height:48px;
  transition:transform .3s var(--ease-out);
}
.svc-menu a:hover{transform:translateX(4px)}
.svc-menu .n{font-family:var(--font-mono);font-size:.7rem;color:var(--arc-bright);flex:none}
/* min-width:0 or the title sets a min-content floor and widens the panel */
.svc-menu .t{font-family:var(--font-display);font-weight:600;font-size:1.02rem;color:#fff;flex:1;min-width:0}
.svc-menu .v{
  font-family:var(--font-mono);font-size:.66rem;letter-spacing:.09em;
  text-transform:uppercase;color:var(--muted-on-ink);flex:none;
  transition:color .25s var(--ease-in);
}
.svc-menu a:hover .v{color:var(--ember)}

/* --- a hero that holds the screen on its own --------------------------------
   The Work hero is short (a heading, a line of copy and the jump index), so the
   bone section underneath used to show through at the bottom before anyone had
   scrolled: about 350px of it on a laptop. That broke the feeling that the hero
   owns the first screen.

   Use lvh, the TALLEST the viewport ever gets, meaning the phone with its
   address bar hidden. Erring taller is the whole point: the hero is then at
   least a full screen no matter what the browser bars are doing, so the bone
   section can never peek in.

   Do not switch this to svh. svh is the screen WITH the bars showing, so it
   measures correctly the instant the page loads and then leaves a light strip
   the moment the bar collapses on scroll. That was the original bug, and a
   headless browser has no address bar so it cannot catch it.

   The plain vh line is the fallback for older phones, and both iOS and Android
   already treat 100vh as the large viewport, so the fallback behaves the same.
   Content is centred so the extra height reads as deliberate space, not a gap. */
.hero--full{
  min-height:100vh;
  min-height:100lvh;
  display:flex;
  flex-direction:column;
  justify-content:center;
}

/* ==========================================================================
   22. Google Ads page
   Proof-led. The dashboard screenshots reuse the Work page browser frame so
   a real screenshot always reads as a real screenshot anywhere on the site.
   ========================================================================== */

/* the honesty note: one campaign, not a track record. Cousin of .why-cheap */
.ga-honest{
  max-width:42rem;margin-top:var(--space-4);
  font-size:.98rem;color:var(--muted-on-ink);
  border-left:2px solid var(--ember);padding-left:1.1rem;
}
.section--bone .ga-honest{color:var(--muted-on-bone)}

/* The headline numbers as a tight stat row: a rule down the left, the number,
   a plain-English label. Same shape as the stat row in the Electronic Garage
   build, translated into this palette. No cards, so it stays quiet next to
   the screenshot underneath it. */
.ga-stats{
  display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:1.8rem 1.4rem;margin-top:var(--space-5);
}
@media(max-width:760px){.ga-stats{grid-template-columns:repeat(2,minmax(0,1fr))}}
.ga-stat{border-left:2px solid var(--arc-bright);padding-left:1.1rem}
.ga-stat .n{
  display:block;font-family:var(--font-display);font-weight:800;
  font-size:clamp(1.75rem,1rem + 2.2vw,2.5rem);
  letter-spacing:-.03em;line-height:1.05;color:#fff;
}
.ga-stat .n small{font-size:.55em;font-weight:700;color:var(--arc-bright)}
.ga-stat .l{
  display:block;margin-top:.6rem;
  font-family:var(--font-mono);font-size:.66rem;letter-spacing:.13em;
  line-height:1.5;text-transform:uppercase;color:var(--muted-on-ink);
}

/* a dashboard screenshot in the same frame the Work page uses */
.ga-shot{margin-top:var(--space-5)}
.ga-shot .case-browser{background:#fff}
.ga-shot .reveal-chrome{background:var(--carbon-2)}
.ga-shot img{width:100%;height:auto;display:block}
.ga-cap{
  margin-top:1rem;font-size:.86rem;color:var(--muted-on-ink);
  display:flex;align-items:flex-start;gap:.6rem;max-width:46rem;
}
.ga-cap::before{content:"";flex:none;margin-top:.55rem;width:1.6rem;height:2px;background:var(--ember)}
.section--bone .ga-cap{color:var(--muted-on-bone)}

/* the split test, side by side */
.ga-vs{
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:1.2rem;margin-top:var(--space-5);
}
@media(max-width:640px){.ga-vs{grid-template-columns:minmax(0,1fr)}}
.ga-side{
  border-radius:var(--radius-m);padding:1.6rem;
  border:1px solid var(--line-light);background:var(--bone-2);
  transition:transform .4s var(--ease-out),border-color .3s var(--ease-in);
}
.ga-side:hover{transform:translateY(-4px)}
.ga-side--win{border-color:rgba(8,25,240,.4);box-shadow:var(--shadow-card)}
.ga-tag{
  display:inline-block;margin-bottom:.9rem;
  font-family:var(--font-mono);font-size:.66rem;letter-spacing:.13em;
  text-transform:uppercase;padding:.34rem .75rem;border-radius:999px;
}
.ga-tag--win{background:var(--arc);color:#fff}
.ga-tag--old{border:1px solid var(--line-light);color:var(--muted-on-bone)}
.ga-side h3{font-size:var(--fs-600);margin-bottom:.9rem}
.ga-row{
  display:flex;justify-content:space-between;align-items:baseline;gap:1rem;
  padding:.6rem 0;border-top:1px solid var(--line-light);
  font-size:.95rem;color:var(--muted-on-bone);
}
.ga-row b{font-family:var(--font-display);font-weight:700;font-size:1.15rem;color:var(--ink-on-bone)}
.ga-side--win .ga-row b{color:var(--arc-deep)}

/* the search terms that actually sold */
.ga-terms{display:flex;flex-wrap:wrap;gap:.6rem;margin-top:var(--space-4)}
.ga-terms span{
  font-family:var(--font-mono);font-size:.8rem;
  padding:.6rem 1.05rem;border-radius:999px;
  border:1px solid var(--line-dark);color:var(--bone);
  background:rgba(67,86,255,.08);
}
.ga-terms span::before{content:"“";opacity:.5}
.ga-terms span::after{content:"”";opacity:.5}

/* the three-part "how it works" money explainer */
.ga-deal{display:grid;gap:1.2rem;margin-top:var(--space-5);max-width:52rem}
.ga-deal article{
  border-left:3px solid var(--arc);padding-left:1.4rem;
}
.ga-deal h3{font-size:var(--fs-600);margin-bottom:.5rem}
.ga-deal p{color:var(--muted-on-bone);font-size:1rem}
.ga-deal p + p{margin-top:.75rem}
.section--ink .ga-deal p,.section--carbon .ga-deal p{color:var(--muted-on-ink)}

/* Wide dashboard tables cannot be made readable squeezed onto a phone, so the
   frame opens the raw image in a new tab where it can be pinch-zoomed. Better
   than a cramped scroller that is still too small to read. */
.ga-frame{display:block;cursor:zoom-in}
.ga-frame .case-browser{transition:transform .4s var(--ease-out),box-shadow .4s var(--ease-out)}
.ga-frame:hover .case-browser{transform:translateY(-4px);box-shadow:var(--shadow-card-dark)}
.ga-zoom{
  display:inline-flex;align-items:center;gap:.45rem;margin-top:.9rem;
  font-family:var(--font-mono);font-size:.68rem;letter-spacing:.13em;
  text-transform:uppercase;color:var(--arc-bright);
}
.section--bone .ga-zoom{color:var(--arc)}
.ga-zoom svg{transition:transform .3s var(--ease-out)}
.ga-frame:hover .ga-zoom svg{transform:translate(2px,-2px)}

/* --- full-height hero: top-aligned on phones -------------------------------
   Centring the content looks deliberate on a laptop, but on a phone it pushed
   the heading down the screen so Work and Google Ads started lower than Home,
   About and Services. Below the phone breakpoint the content sits at the same
   6rem top padding every other hero uses, and the min-height still stops the
   next section bleeding in. */
@media(max-width:900px){
  .hero--full{justify-content:flex-start}
  /* the homepage jump index is a flex child of the hero grid on phones, so it
     needs an order or it jumps ahead of the heading */
  .hero .case-index{order:8;margin-top:1.4rem}
  .hero .case-index:not(.case-index--two){margin-top:2rem}
}

/* --- full-screen viewer for the proof screenshots --------------------------
   Tapping through to the raw image file dumped a wide dashboard onto a blank
   browser page, tiny and off-centre. This shows it on-brand instead, big
   enough to read, and pannable. The markup is still a plain link to the image,
   so if the script never runs the tap just opens the file as before. */
.lightbox{
  position:fixed;inset:0;z-index:80;
  background:rgba(11,14,19,.96);
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  opacity:0;pointer-events:none;
  transition:opacity .3s var(--ease-in);
}
.lightbox.open{opacity:1;pointer-events:auto}
.lb-scroll{
  position:absolute;inset:0;overflow:auto;-webkit-overflow-scrolling:touch;
  display:flex;padding:4.75rem 1rem 3.75rem;
}
/* margin:auto rather than centring on the container: an oversized image stays
   reachable at both edges when it overflows */
.lb-scroll img{
  margin:auto;display:block;border-radius:.6rem;
  box-shadow:0 30px 80px rgba(0,0,0,.6);
  max-width:min(1400px,94vw);height:auto;
}
@media(max-width:820px){
  /* hold a readable width and let the panel be swiped across */
  .lb-scroll img{max-width:none;width:820px}
}
.lb-close{
  position:absolute;top:1rem;right:1rem;z-index:2;
  width:46px;height:46px;border-radius:50%;display:grid;place-items:center;
  background:rgba(245,240,232,.12);color:var(--bone);
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  transition:background .25s var(--ease-in),transform .3s var(--ease-out);
}
.lb-close:hover{background:rgba(245,240,232,.24)}
.lb-close:active{transform:scale(.94)}
.lb-hint{
  position:absolute;left:0;right:0;bottom:1.15rem;text-align:center;
  font-family:var(--font-mono);font-size:.65rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted-on-ink);pointer-events:none;
}
@media(min-width:821px){.lb-hint{display:none}}

/* ==========================================================================
   23. Contact page — the one-question-at-a-time request form
   Same workshop-after-dark treatment as the rest of the site: the question
   is a display-face headline with the blue underline on the key word, the
   labels and the counter are mono, and the only bright thing on the screen
   is the Arc blue Continue button. Progress is the site's own scroll bar at
   the top of the page, handed over to the form on this page only.
   ========================================================================== */
[hidden]{display:none !important}

/* the card keeps its narrow width, which is what makes each question feel
   quick, and is centred rather than left with a dead half-page beside it.
   The heading centres with it, or the two would sit out of line. */
.sform-wrap{margin:var(--space-5) auto 0;max-width:44rem}
#demo-form .section-head{margin-inline:auto;text-align:center}
#demo-form .section-head p{margin-inline:auto}
#demo-form .kicker{justify-content:center}

.sform{
  background:var(--carbon-2);border:1px solid var(--line-dark);
  border-radius:var(--radius-l);padding:2.4rem;
  box-shadow:var(--shadow-card-dark);
}
@media(max-width:600px){.sform{padding:1.5rem;border-radius:var(--radius-m)}}

/* the honeypot: a real field bots fill in and people never see */
.sf-hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

/* --- counter row: same mono numbering used on Work and Services ---------- */
.sf-bar{
  display:flex;align-items:center;justify-content:space-between;gap:1rem;
  padding-bottom:1.1rem;margin-bottom:1.8rem;
  border-bottom:1px solid var(--line-dark);
  font-family:var(--font-mono);font-size:var(--fs-200);letter-spacing:.14em;
  text-transform:uppercase;
}
.sf-count{color:#fff}
.sf-count i{color:var(--muted-on-ink);font-style:normal;padding:0 .15rem}
.sf-phase{color:var(--ember)}

/* --- one question on screen ---------------------------------------------
   min-height stops the panel jumping in size between a short question and a
   long one, which is what makes a stepper feel cheap on a phone. */
.sf-stage{display:grid}
.js .sf-stage{min-height:19rem}
/* on a phone the floor comes down: holding 17rem padded the short questions
   out until Continue fell below the fold, which is the whole ballgame here */
@media(max-width:600px){.js .sf-stage{min-height:11rem}}

.sf-step{display:grid;align-content:start;gap:.5rem}
/* every step is visible with JS off, so the form still works as one page */
.js .sf-step{display:none}
.js .sf-step.on{display:grid;animation:sfIn .45s var(--ease-out) both}
@keyframes sfIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
@media(prefers-reduced-motion:reduce){.js .sf-step.on{animation:none}}

.sf-kicker{
  font-family:var(--font-mono);font-size:var(--fs-200);letter-spacing:.16em;
  text-transform:uppercase;color:var(--muted-on-ink);
}
.sf-q{
  font-family:var(--font-display);font-weight:800;
  font-size:clamp(1.5rem,1.1rem + 1.8vw,2.1rem);
  letter-spacing:-.03em;color:#fff;margin:.35rem 0 .2rem;
  /* looser than the site's 1.08 headings on purpose: when a question wraps
     and the underlined word lands on the first line, a tight leading drops
     that underline onto the caps of the line below and it reads as though it
     belongs to the wrong words */
  line-height:1.3;
}
.sf-q .u-mark::after{bottom:-.09em}
.sf-help{font-size:.98rem;line-height:1.6;color:var(--muted-on-ink);max-width:34rem}
.sf-label{
  font-family:var(--font-mono);font-size:.66rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted-on-ink);margin-top:1rem;
}

/* 16px minimum, or iOS zooms the whole page in the moment a field is tapped */
.sform input[type=text],.sform input[type=tel],.sform input[type=email],.sform textarea{
  width:100%;font-family:var(--font-body);font-size:1rem;color:#fff;
  background:rgba(11,14,19,.55);border:1.5px solid var(--line-dark);
  border-radius:var(--radius-s);padding:.9rem 1.05rem;min-height:54px;
  transition:border-color .25s var(--ease-in),box-shadow .25s var(--ease-in);
}
.sform textarea{min-height:6.5rem;resize:vertical;line-height:1.6}
.sform ::placeholder{color:rgba(154,163,181,.6)}
.sform input:focus-visible,.sform textarea:focus-visible{
  outline:none;border-color:var(--arc-bright);
  box-shadow:0 0 0 3px rgba(67,86,255,.25);
}
.sform input.bad,.sform textarea.bad{border-color:var(--ember)}

/* --- pick-one answers ---------------------------------------------------- */
.sf-choices{display:flex;flex-wrap:wrap;gap:.7rem;margin-top:.9rem}
.sf-choices--stack{flex-direction:column;align-items:stretch}
.sf-choice{
  display:flex;align-items:center;gap:.7rem;cursor:pointer;
  font-family:var(--font-body);font-size:1rem;color:var(--bone);
  padding:.85rem 1.15rem;min-height:54px;
  background:rgba(11,14,19,.55);border:1.5px solid var(--line-dark);
  border-radius:999px;
  transition:border-color .25s var(--ease-in),background .25s var(--ease-in);
}
.sf-choice input{accent-color:var(--arc-bright);width:18px;height:18px;flex:none}
.sf-choice:has(input:checked){border-color:var(--arc-bright);background:rgba(67,86,255,.12);color:#fff}
.sf-choice:focus-within{box-shadow:0 0 0 3px rgba(67,86,255,.25)}

/* --- upload slots -------------------------------------------------------- */
.sf-files{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:.8rem;margin-top:1rem}
@media(max-width:600px){
  .sf-files{grid-template-columns:minmax(0,1fr);gap:.55rem}
  /* three stacked slots at full height pushed Continue off the screen, so on
     a phone the button and its status sit on one row under the caption */
  .sf-file{grid-template-columns:auto minmax(0,1fr);align-items:center;gap:.4rem .8rem;padding:.75rem .85rem}
  .sf-file-cap{grid-column:1/-1}
}
.sf-file{
  display:grid;gap:.55rem;padding:1rem;align-content:start;justify-items:start;
  background:rgba(11,14,19,.55);border:1.5px dashed var(--line-dark);
  border-radius:var(--radius-s);
  transition:border-color .25s var(--ease-in),background .25s var(--ease-in);
}
.sf-file:hover{border-color:var(--arc-bright)}
.sf-file.has-file{border-style:solid;border-color:var(--arc-bright);background:rgba(67,86,255,.1)}
.sf-file-cap{
  font-family:var(--font-mono);font-size:.62rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted-on-ink);
}

/* The native control paints a few pixels of unstyleable grey system text that
   truncates to "...sen" at this width. The input itself is kept in the page,
   visually hidden but still focusable, and the label is the button. */
.js .sf-file-input{
  position:absolute;width:1px;height:1px;padding:0;margin:0;
  overflow:hidden;clip-path:inset(50%);white-space:nowrap;
}
.sf-file-btn{
  display:inline-flex;align-items:center;justify-content:center;
  font-family:var(--font-display);font-weight:600;font-size:.9rem;
  color:#fff;background:rgba(67,86,255,.2);
  border:1px solid rgba(67,86,255,.45);border-radius:999px;
  padding:.6rem 1.15rem;min-height:44px;cursor:pointer;
  transition:background .25s var(--ease-in),border-color .25s var(--ease-in);
}
.sf-file-btn:hover{background:rgba(67,86,255,.34);border-color:var(--arc-bright)}
.sf-file-btn:active{transform:scale(.97)}
/* the hidden input still takes keyboard focus, so the ring has to show on
   the label standing in for it */
.sf-file-input:focus-visible + .sf-file-btn{outline:3px solid var(--arc-bright);outline-offset:3px}
/* no JS, no custom control: show the browser's own so the field still works */
.sf-file-btn{display:none}
.js .sf-file-btn{display:inline-flex}
.js .sf-file-input::file-selector-button{display:none}

.sf-file-name{
  font-size:.85rem;color:var(--muted-on-ink);font-weight:500;
  overflow-wrap:anywhere;line-height:1.45;
}
.sf-file.has-file .sf-file-name{color:#fff;font-weight:600}
.sf-file-name{display:none}
.js .sf-file-name{display:block}

/* --- controls ------------------------------------------------------------ */
.sf-nav{
  display:flex;align-items:center;gap:1.2rem;flex-wrap:wrap;
  margin-top:1.9rem;padding-top:1.6rem;border-top:1px solid var(--line-dark);
}
.sf-nav .btn{min-width:11rem}
@media(max-width:600px){
  /* the primary action goes full width and sits first under the thumb */
  .sf-nav{gap:.85rem}
  .sf-nav .btn{width:100%;min-width:0}
}
.sf-back{
  display:inline-flex;align-items:center;gap:.45rem;min-height:44px;
  font-family:var(--font-mono);font-size:var(--fs-200);letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted-on-ink);
  transition:color .25s var(--ease-in);
}
.sf-back:hover{color:#fff}
.sf-fine{margin-top:1.2rem;font-size:.9rem;color:var(--muted-on-ink)}
.sf-alert{
  margin-top:1.4rem;font-size:.95rem;color:#FFD9C6;
  background:rgba(217,106,43,.16);border:1px solid rgba(217,106,43,.45);
  border-radius:var(--radius-s);padding:.9rem 1.1rem;
}
.sf-alert a{color:#fff;text-decoration:underline;text-underline-offset:3px}

/* --- the confirmation, swapped in where the form was --------------------- */
.sform-done{
  display:grid;justify-items:start;gap:.9rem;
  background:var(--carbon-2);border:1px solid var(--line-dark);
  border-radius:var(--radius-l);padding:2.4rem;
  box-shadow:var(--shadow-card-dark);
}
@media(max-width:600px){.sform-done{padding:1.5rem;border-radius:var(--radius-m)}}
.sf-tick{
  display:grid;place-items:center;width:64px;height:64px;border-radius:50%;
  background:rgba(67,86,255,.16);color:var(--arc-bright);
}
.sform-done h3{font-size:var(--fs-700);color:#fff}
.sform-done p{color:var(--muted-on-ink);font-size:var(--fs-500);max-width:34rem}
.sf-done-alt{font-size:.98rem}
.sform-done a{color:var(--arc-bright);font-weight:600}

.sf-escape{
  margin-top:1.6rem;font-size:.95rem;color:var(--muted-on-ink);
}
.sf-escape a{color:#fff;text-decoration:underline;text-underline-offset:3px}
.sf-escape a:hover{color:var(--arc-bright)}

/* --- the form's own progress bar ----------------------------------------
   Deliberately not the one pinned to the top of the window: that one still
   reports page scroll on every page including this one. This one lives
   inside the card, directly under the 03 / 12 counter it belongs to, so at a
   glance it is obvious which bar is measuring what. */
.sf-track{
  position:relative;height:3px;border-radius:2px;overflow:hidden;
  background:rgba(245,240,232,.1);margin:-.6rem 0 1.6rem;
}
.sf-fill{
  position:absolute;inset:0;transform-origin:left center;transform:scaleX(0);
  background:linear-gradient(90deg,var(--arc),var(--glow));
  transition:transform .55s var(--ease-out);
}
@media(prefers-reduced-motion:reduce){.sf-fill{transition:none}}
/* with JS off there are no steps, so a progress bar would be a lie */
.sf-track{display:none}
.js .sf-track{display:block}

/* the direct-call block in the hero panel */
.ct-phone{
  display:inline-flex;align-items:center;gap:.7rem;
  font-family:var(--font-display);font-weight:700;font-size:1.35rem;
  letter-spacing:-.01em;color:#fff;min-height:48px;
  transition:color .25s var(--ease-in);
}
.ct-phone svg{color:var(--arc-bright);flex:none}
.ct-phone:hover{color:var(--arc-bright)}
.ct-note{margin:.5rem 0 1.4rem;font-size:.92rem;color:var(--muted-on-ink)}
.section--ink .svc-panel .svc-list a{color:#fff;text-decoration:underline;text-underline-offset:3px}
.section--ink .svc-panel .svc-list a:hover{color:var(--arc-bright)}

/* ==========================================================================
   24. Pricing page
   One price block per thing I sell, each paired with a short note explaining
   why it is priced that way. No tier table, because there are no tiers.
   ========================================================================== */
.price-wrap{
  display:grid;grid-template-columns:minmax(0,1.35fr) minmax(0,1fr);
  gap:1.6rem;margin-top:var(--space-5);align-items:start;
}
@media(max-width:900px){.price-wrap{grid-template-columns:minmax(0,1fr)}}

/* The monthly section stacks in one column at every width: card, then the
   "you run your business" line, then the PayPal box. The other two pricing
   sections keep their normal side-by-side layout. */
.price-wrap--stack{grid-template-columns:minmax(0,1fr)}

.price-card{
  background:var(--bone-2);border:1px solid var(--line-light);
  border-radius:var(--radius-l);padding:2.2rem;
  box-shadow:var(--shadow-card);
}
.price-card--dark{
  background:var(--carbon-2);border-color:var(--line-dark);
  box-shadow:var(--shadow-card-dark);
}
@media(max-width:600px){.price-card{padding:1.5rem;border-radius:var(--radius-m)}}

.price-tag{
  font-family:var(--font-mono);font-size:var(--fs-200);letter-spacing:.14em;
  text-transform:uppercase;color:var(--ember);display:block;margin-bottom:1rem;
}
/* the number carries the section on its own, so it is set at display size
   and the unit sits on the baseline beside it rather than under it */
.price-figure{display:flex;align-items:baseline;gap:.7rem;flex-wrap:wrap}
.price-num{
  font-family:var(--font-display);font-weight:800;
  font-size:clamp(3rem,2rem + 5vw,4.6rem);
  letter-spacing:-.045em;line-height:.95;color:var(--ink-on-bone);
}
.price-card--dark .price-num{color:#fff}
.price-unit{
  font-family:var(--font-mono);font-size:var(--fs-300);letter-spacing:.12em;
  text-transform:uppercase;color:var(--muted-on-bone);
}
.price-card--dark .price-unit{color:var(--arc-bright)}
.price-sub{
  margin-top:1rem;font-size:var(--fs-500);color:var(--muted-on-bone);
  max-width:32rem;
}
.price-card--dark .price-sub{color:var(--muted-on-ink)}

.price-list{list-style:none;display:grid;gap:.9rem;margin:1.8rem 0}
.price-list li{display:flex;gap:.75rem;align-items:flex-start;font-size:.98rem;color:var(--muted-on-bone)}
.price-card--dark .price-list li{color:var(--muted-on-ink)}
.price-list svg{flex:none;margin-top:.2rem;color:var(--arc)}
.price-card--dark .price-list svg{color:var(--arc-bright)}
.price-fine{margin-top:1rem;font-size:.88rem;color:var(--muted-on-bone)}
.price-card--dark .price-fine,.price-note--dark .price-fine{color:var(--muted-on-ink)}

/* the short note beside each price: why it is priced this way */
.price-note{
  border-left:3px solid var(--arc);padding:.2rem 0 .2rem 1.5rem;
}
.price-note--dark{border-left-color:var(--arc-bright)}
.price-note h3{font-size:var(--fs-600);margin-bottom:.7rem}
.price-note--dark h3{color:#fff}
.price-note p{color:var(--muted-on-bone);font-size:1rem}
.price-note--dark p{color:var(--muted-on-ink)}
.price-note p + p{margin-top:.75rem}
.price-note .link-arrow{margin-top:1.2rem}

/* --- the subscribe block -------------------------------------------------
   Framed as the last step rather than the first: nobody should be able to
   read this page and think the $50 is what you pay to get started. */
.pay-warn{
  margin-top:.2rem;padding:.9rem 1.1rem;border-radius:var(--radius-s);
  background:rgba(217,106,43,.14);border:1px solid rgba(217,106,43,.4);
  font-size:.92rem;line-height:1.6;
}
.price-note--dark .pay-warn{color:#FFD9C6}
.pay-box{margin-top:1.3rem}
/* PayPal renders its button into an iframe of its own; this just keeps it
   from butting up against the text above it. Keyed off the iframe rather
   than :not(:empty), because the slot now always holds PayPal's (initially
   empty) container div, and an empty slot must not reserve any space. */
.pp-slot:has(iframe){margin-bottom:.9rem}
.pp-standin .btn{width:100%}
@media(min-width:601px){.pp-standin .btn{width:auto}}

/* --- Web Design page: the Google Ads hand-off ---------------------------
   Deliberately a single band rather than a numbered section. Ads are the
   second service and the page should not read as though they are half the
   offer, but anyone who wants them needs an obvious door out. */
.ads-teaser{
  display:grid;grid-template-columns:minmax(0,1fr) auto;
  gap:1.6rem 2.5rem;align-items:center;
}
@media(max-width:820px){
  .ads-teaser{grid-template-columns:minmax(0,1fr)}
  .ads-teaser .btn{width:100%}
}
.ads-teaser h2{font-size:var(--fs-700);margin:.5rem 0 .6rem}
.ads-teaser p{color:var(--muted-on-ink);font-size:var(--fs-500);max-width:34rem}

/* ==========================================================================
   25. Free audit page
   The tool is the same card as the request form on Contact, so the whole
   thing already looks like the site. Everything below is only the parts a
   step form does not have: the branch, the waiting state, and the result.
   ========================================================================== */

/* the hero side panel: a list of what gets checked, not links */
.aud-checklist{list-style:none;display:grid}
.aud-checklist li{
  display:flex;align-items:baseline;gap:.7rem;padding:.7rem .2rem;
}
.aud-checklist li + li{border-top:1px solid var(--line-dark)}
.aud-checklist .n{font-family:var(--font-mono);font-size:.7rem;color:var(--arc-bright);flex:none}
.aud-checklist .t{font-family:var(--font-display);font-weight:600;font-size:1.02rem;color:#fff;flex:1;min-width:0}
.aud-checklist .v{
  font-family:var(--font-mono);font-size:.66rem;letter-spacing:.09em;
  text-transform:uppercase;color:var(--muted-on-ink);flex:none;
}
.aud-panel-fine{margin-top:1.1rem;font-size:.86rem;line-height:1.6;color:var(--muted-on-ink)}

/* the card needs JS to talk to Google at all, so it is hidden without it and
   the noscript block takes its place */
.aud-card{display:none}
.js .aud-card{display:block}

/* same floor as the request form, so the card does not resize between a
   short panel and a long one */
.aud-stage{display:grid;min-height:19rem}
@media(max-width:600px){.aud-stage{min-height:13rem}}
.aud-panel{display:grid;align-content:start;gap:.5rem;animation:sfIn .45s var(--ease-out) both}
@media(prefers-reduced-motion:reduce){.aud-panel{animation:none}}

/* the two ways in. Equal weight would be a lie, most people have a site */
.aud-branch-row{display:flex;flex-wrap:wrap;gap:.9rem;margin-top:1.6rem}
.aud-branch-row .btn{min-width:12rem;flex:1}
@media(max-width:600px){
  .aud-branch-row{flex-direction:column}
  .aud-branch-row .btn{width:100%}
}

/* waiting on Google. A sweep, not a progress bar: there is no progress to
   report, the request is either open or it is not, and inventing steps to
   fill the silence would be the kind of thing this page exists to call out */
.aud-sweep{
  position:relative;height:3px;border-radius:2px;overflow:hidden;
  background:rgba(245,240,232,.1);margin:1.6rem 0 .9rem;
}
.aud-sweep span{
  position:absolute;top:0;bottom:0;width:38%;border-radius:2px;
  background:linear-gradient(90deg,transparent,var(--arc-bright),var(--glow),transparent);
  animation:audSweep 1.5s var(--ease-in) infinite;
}
@keyframes audSweep{from{left:-40%}to{left:102%}}
@media(prefers-reduced-motion:reduce){
  .aud-sweep span{animation:none;left:0;width:100%;opacity:.5}
}
.aud-elapsed{
  font-family:var(--font-mono);font-size:var(--fs-200);letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted-on-ink);
  /* long domains would otherwise push the card sideways on a phone */
  overflow-wrap:anywhere;
}

/* the score itself */
.aud-score{display:flex;align-items:baseline;gap:.6rem;margin:.4rem 0 .2rem}
.aud-score-num{
  font-family:var(--font-display);font-weight:800;
  font-size:clamp(3.4rem,2rem + 7vw,5.6rem);letter-spacing:-.045em;line-height:.9;
  color:#fff;
}
.aud-score[data-band="0"] .aud-score-num{color:var(--arc-bright)}
.aud-score[data-band="2"] .aud-score-num{color:var(--ember)}
.aud-score-unit{
  font-family:var(--font-mono);font-size:var(--fs-300);letter-spacing:.12em;
  text-transform:uppercase;color:var(--muted-on-ink);
}

/* one row per category: name, number, a meter, and a line of plain English */
.aud-cats{display:grid;gap:1.1rem;margin:1.8rem 0 .4rem}
.aud-cat{display:grid;gap:.45rem}
.aud-cat-head{display:flex;align-items:baseline;justify-content:space-between;gap:1rem}
.aud-cat-name{font-family:var(--font-display);font-weight:700;font-size:1.05rem;color:#fff}
.aud-cat-val{font-family:var(--font-mono);font-size:.8rem;color:var(--muted-on-ink);flex:none}
.aud-meter{position:relative;height:6px;border-radius:3px;overflow:hidden;background:rgba(245,240,232,.1)}
.aud-meter span{
  position:absolute;left:0;top:0;bottom:0;border-radius:3px;
  background:linear-gradient(90deg,var(--arc),var(--glow));
  transition:width .7s var(--ease-out);
}
.aud-meter[data-band="2"] span{background:linear-gradient(90deg,#B4531F,var(--ember))}
.aud-cat-line{font-size:.95rem;line-height:1.55;color:var(--muted-on-ink)}

/* the one thing worth doing first, pulled out of the list on purpose */
.aud-weak{
  margin-top:1.8rem;padding:1.2rem 1.3rem;border-radius:var(--radius-m);
  background:rgba(217,106,43,.12);border:1px solid rgba(217,106,43,.38);
}
.aud-weak-cap{
  font-family:var(--font-mono);font-size:var(--fs-200);letter-spacing:.14em;
  text-transform:uppercase;color:var(--ember);margin-bottom:.4rem;
}
.aud-weak-name{font-family:var(--font-display);font-weight:800;font-size:1.35rem;color:#fff;margin-bottom:.35rem}
.aud-weak-line{font-size:.98rem;line-height:1.6;color:var(--muted-on-ink)}

.aud-after{
  margin-top:2rem;padding-top:1.8rem;border-top:1px solid var(--line-dark);
  display:grid;gap:.7rem;justify-items:start;
}
.aud-after h4{font-family:var(--font-display);font-weight:800;font-size:var(--fs-600);color:#fff}
.aud-after p{color:var(--muted-on-ink);font-size:var(--fs-400);line-height:1.6}
.aud-after .btn{margin-top:.4rem}
@media(max-width:600px){.aud-after .btn{width:100%;justify-content:center}}

.aud-escape{margin-top:1rem;font-size:.92rem;color:var(--muted-on-ink)}
.aud-escape a{color:#fff;text-decoration:underline;text-underline-offset:3px}
/* a button that has to read as a link, since it changes the panel rather
   than going anywhere */
.aud-link{
  background:none;border:0;padding:0;cursor:pointer;font:inherit;
  color:#fff;text-decoration:underline;text-underline-offset:3px;
}
.aud-link:hover{color:var(--arc-bright)}

/* the quiz sits inside the card's own stage, which already holds the floor,
   so the inner one would double it up */
.js #aud-quiz .sf-stage{min-height:0}
