/* ═══════════════════════════════════════════════════════════════════════
   50N Design — stylesheet
   Reverted to the Recro design system (cream/coffee/orange, Epilogue +
   Cormorant + Courier Prime). See CLAUDE.md for intent and constraints.

   Colour note — this is NOT a verbatim copy of Recro's palette. Recro's
   source shipped eight tokens, and measurement (tools/contrast.py) found
   eight WCAG AA failures among them, most of them site-wide. The hues and
   the character are Recro's; the luminances of the failing text colours
   have been pulled down to the nearest passing value. Every change is
   annotated inline with its before/after ratio.
   ═══════════════════════════════════════════════════════════════════════ */

:root {
  /* ── Recro's palette, mostly unchanged ── */
  --bg:      #F8F6EE;   /* page ground */
  --bg2:     #EAE6D4;   /* recessed ground: FAQ, price boxes, about frame */
  /* Was Recro's near-black #0A1E12. Moved to navy at the user's explicit
     instruction — a cooler dark ground than the original brand's coffee
     brown. Every on-coffee pairing below was re-measured against this
     value; see tools/contrast.py for each ratio. */
  --coffee:  #17263F;   /* dark ground: process, footer, mobile menu */
  /* --coffee darkened ~30%, same hue. Coffee buttons used to darken toward
     --ink on hover/press — that worked only because the old coffee brown
     and --ink were nearly the same near-black hue (L* 9.3 -> 7.7). Navy and
     --ink are ~90 degrees apart in hue, so reusing --ink here now reads as
     a colour swap rather than a press; this stays on-hue. */
  --coffee-dark: #101B2C;
  --ink:     #0C1A0E;   /* primary text on light */
  --border:  #D4CCC0;   /* hairlines — non-text, no ratio requirement */
  --white:   #FCF9F2;   /* text on coffee grounds */
  /* Was orange (#E85D04). Replaced with Electric Cyan at the user's
     explicit instruction, confirmed hex #00D9FF, following mockup review.
     --green-ink/--green-bright below are re-derived from this, not the
     old orange — same "re-measure everything downstream" lesson as the
     --coffee swap. */
  --green:   #00D9FF;   /* brand accent: fills, borders, large display type */
  /* Same value as --green, as raw channels — rgba() can't pull channels out
     of a hex custom property, so the two translucent background textures
     and this token are kept in sync manually. If --green changes, this
     must change with it. */
  --green-rgb: 0,217,255;

  /* ── AA corrections ──
     --mid is the body/label colour for the whole light half of the page.
     Recro's #747870 measured 4.16:1 on --bg and 3.60:1 on --bg2, so every
     paragraph, caption, FAQ answer and price line on the site failed AA.
     #656861 is the nearest tone that clears 4.5:1 on BOTH grounds
     (5.24:1 on --bg, 4.52:1 on --bg2). L* moves 49.9 -> 43.6 — visibly
     the same grey-green, just seated properly. */
  --mid:     #656861;

  /* Raw cyan as small text on a light ground measures only 1.57:1 on --bg —
     nowhere close, unlike orange (which needed a much smaller correction:
     3.24:1 -> darken to clear 4.5). Darkened toward black to hold hue
     (tools/contrast.py's fix()) until it clears 4.5:1 on BOTH grounds with
     real margin: 5.61:1 on --bg, 4.85:1 on --bg2. */
  --green-ink:     #006C80;
  /* Raw cyan on --coffee is 8.93:1 — already well clear of 4.5:1 at small
     sizes, unlike orange (4.97:1, not built to survive at label size,
     which is why --green-bright existed as a separate, brighter tone in
     the first place). No darkening or brightening needed this time; kept
     as its own token for structural consistency, not because the number
     requires a different value from --green. */
  --green-bright:  #00D9FF;

  /* Recro set on-coffee text with low-alpha rgba(): .28-.50 of a pale sage
     or white, landing at 2.21-3.55:1. These are solid, measured tones. */
  --on-coffee:     #A8C0AE;   /* body copy on coffee — 8.96:1 */
  --on-coffee-dim: #7E9A86;   /* 9-10px labels on coffee — 5.68:1 */

  --display: 'Epilogue', sans-serif;
  --serif:   'Cormorant Garamond', Georgia, serif;
  --body:    'Courier Prime', 'Courier New', monospace;
  --pad:     clamp(20px, 5.5vw, 80px);
}

*,*::before,*::after{box-sizing:border-box;margin:0;padding:0;}
html{scroll-behavior:smooth;}
body{
  background:var(--bg);
  color:var(--ink);
  font-family:var(--body);
  font-weight:400;
  line-height:1.8;
  overflow-x:hidden;
  background-image:
    radial-gradient(circle at 15% 20%, rgba(var(--green-rgb),0.025) 0%, transparent 45%),
    radial-gradient(circle at 85% 75%, rgba(var(--green-rgb),0.02) 0%, transparent 40%);
}
/* Paper grain. Sits above everything but takes no pointer events. */
body::after{
  content:'';position:fixed;inset:0;z-index:9999;pointer-events:none;opacity:.022;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23n)' opacity='1'/%3E%3C/svg%3E");
}

/* ── Type scale ── */
.de{font-family:var(--display);font-weight:800;line-height:.92;}
.de-green{color:var(--coffee);}
.de-xl{font-size:clamp(64px,11.5vw,148px);letter-spacing:-.015em;}
.de-lg{font-size:clamp(44px,7vw,100px);letter-spacing:-.012em;line-height:.96;}
.de-md{font-size:clamp(28px,4vw,56px);letter-spacing:-.01em;line-height:1.02;}
.de-sm{font-size:clamp(18px,2.2vw,26px);letter-spacing:-.005em;line-height:1.1;}
.sc{font-family:var(--serif);font-style:italic;font-weight:500;line-height:.88;}
.sc-xl{font-size:clamp(68px,12vw,156px);letter-spacing:-.02em;}
.sc-lg{font-size:clamp(46px,7.5vw,108px);letter-spacing:-.015em;line-height:.9;}
.sc-pull{font-size:clamp(26px,3.8vw,48px);letter-spacing:-.015em;line-height:1.2;}
.cap{font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--mid);font-weight:500;}
p{font-size:clamp(13px,1.2vw,15px);color:var(--mid);line-height:1.85;max-width:540px;}
a{color:inherit;text-decoration:none;}
section{padding:clamp(72px,10vw,130px) 0;}
.wrap{max-width:1360px;margin:0 auto;padding:0 var(--pad);}

/* Visible focus for keyboard users — Recro's source had none at all. */
a:focus-visible,button:focus-visible,input:focus-visible,textarea:focus-visible,
.faq-q:focus-visible{outline:2px solid var(--green-ink);outline-offset:3px;border-radius:2px;}
.mob-menu a:focus-visible,footer a:focus-visible,.ticker-coffee a:focus-visible,
#process a:focus-visible{outline-color:var(--green-bright);}
.skip{position:absolute;left:-9999px;top:0;z-index:300;background:var(--coffee);
  color:var(--white);padding:12px 20px;font-size:11px;letter-spacing:.1em;text-transform:uppercase;}
.skip:focus{left:0;}

/* ── Scroll reveals ── */
.r{opacity:0;transform:translateY(22px);transition:opacity .7s ease,transform .7s ease;}
.r.on{opacity:1;transform:none;}
.r1{transition-delay:.1s;}.r2{transition-delay:.2s;}.r3{transition-delay:.32s;}

/* ── NAV ── */
nav{position:fixed;top:0;left:0;right:0;z-index:200;height:60px;display:flex;
  align-items:center;justify-content:space-between;padding:0 var(--pad);
  transition:background .3s,border-bottom .3s;}
nav.stuck{background:rgba(248,246,238,.95);backdrop-filter:blur(14px);border-bottom:1px solid var(--border);}
/* The coordinate motif's third spot: a callback to what "50N" is short
   for. Stacked under the wordmark rather than beside it so nav-logo's
   own height grows instead of nav's — nav stays a flat 60px and the
   ticker's margin-top:60px spacer (which keeps nav off the hero
   entirely) needs no change. */
.nav-logo{font-family:var(--display);font-size:13px;font-weight:900;text-transform:uppercase;
  letter-spacing:.07em;display:flex;flex-direction:column;align-items:flex-start;gap:2px;}
.nav-logo-coord{font-family:var(--body);font-size:8px;font-weight:400;letter-spacing:.06em;
  text-transform:uppercase;color:var(--mid);font-variant-numeric:tabular-nums;}
.nav-links{display:flex;align-items:center;gap:28px;list-style:none;}
.nav-links a{font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--mid);
  font-weight:500;transition:color .2s;}
.nav-links a:hover,.nav-links a.active{color:var(--ink);}
.nav-cta{display:flex;align-items:center;gap:7px;padding:9px 20px;background:var(--coffee);
  color:var(--white)!important;font-size:10px!important;letter-spacing:.12em;
  font-weight:700!important;transition:background .2s!important;}
.nav-cta::after{content:'■';font-size:6px;opacity:.6;}
.nav-cta:hover{background:var(--coffee-dark)!important;}

/* ── TICKER ──
   The rhythm device between sections. Five slots: dot / number / caption /
   name / dot. The centre slot was a bare ○ in Recro; it now carries the
   per-section coordinate captions that the survey-chart build used, which
   is the one motif kept across the revert. */
.ticker{border-top:1px solid var(--border);border-bottom:1px solid var(--border);
  height:42px;display:flex;align-items:center;justify-content:space-between;padding:0 var(--pad);}
.t-dot{font-size:9px;color:var(--mid);}
.t-mid{font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--mid);font-weight:500;}
.t-coord{font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--green-ink);
  font-weight:700;font-variant-numeric:tabular-nums;}
.ticker-coffee{background:var(--coffee);border-color:rgba(255,255,255,.1);}
.ticker-coffee .t-dot,.ticker-coffee .t-mid{color:var(--on-coffee-dim);}
.ticker-coffee .t-coord{color:var(--green-bright);}
/* Below 620px the five slots cannot fit; keep the number and the caption. */
@media(max-width:620px){
  .ticker{justify-content:space-between;}
  .ticker .t-dot,.ticker .t-mid.t-name{display:none;}
}

/* ── HERO ──
   Full-bleed: the photo is #hero's own background across the entire
   section at every breakpoint, no separate photo column or phone-only
   band. The nav does not overlap the hero — the ticker above it carries
   margin-top:60px and clears the fixed bar — so nav text sits on plain
   --bg and needs no scrim.

   Text stays dark (--ink/--coffee): pixel-sampling the actual photo found
   the label/headline zone clears AA against the raw image with near-zero
   correction (7.35:1 / 6.40:1 against that zone's average luminance),
   while pale text would need to roughly double its effective contrast
   across that same zone. Only the bottom band (subcopy/CTAs), where the
   photo's own foreground runs dark, needs real scrim weight. See
   .hero-content below for the scrim itself. */
#hero{
  position:relative;
  min-height:clamp(560px,86vh,820px);
  padding:0;
  display:flex;
  align-items:center;
  background-color:var(--bg2);       /* graceful ground if the photo 404s */
  background-image:url('../images/hero-coast.jpg');
  background-size:cover;
  background-position:56% 40%;
}
#hero>.wrap{width:100%;}   /* #hero is a flex row; without this the wrap shrinks to content */
/* Scoped to the text column's own box, not the whole section — the
   opposite shape of the old edge-to-edge wash. A vertical gradient so
   the label/headline sit much lighter (just enough to guard the odd dark
   pixel, e.g. the headland's edge, which measured as low as 1.3:1 on its
   own) and the subcopy/CTA band gets real weight, where the photo's
   foreground runs dark. The right edge sits flush with the page's normal
   right padding, matching every other right-aligned edge above and below
   the hero — no left-edge fade: an earlier attempt at one used a corner
   mask, which dampened the whole left-aligned text column (all of it
   sits near the box's left edge) rather than just the bare margin outside
   it, and undid most of the vertical ramp's effect. Stops verified
   against the rendered page's own worst pixel per element at every
   breakpoint, not the source image or an average — tools/regress.py hero. */
.hero-content{
  position:relative;z-index:1;
  max-width:640px;margin-left:auto;
  display:flex;flex-direction:column;justify-content:space-between;
  min-height:clamp(380px,54vh,480px);
  padding:clamp(28px,4vw,44px) 0 clamp(28px,4vw,44px) clamp(32px,5vw,64px);
  background:linear-gradient(to bottom,
    rgba(248,246,238,.20) 0%,
    rgba(248,246,238,.26) 22%,
    rgba(248,246,238,.44) 40%,
    rgba(248,246,238,.90) 55%,
    rgba(248,246,238,.97) 65%,
    rgba(248,246,238,.97) 85%,
    rgba(248,246,238,.92) 100%);
}
#hero .cap{color:var(--coffee);}   /* --mid (the usual label grey) measured 2.3:1 on this photo */
/* The coordinate motif's second spot — moved here from the top ticker.
   --green-ink is the sitewide coordinate colour, but it only measured
   ~3.2-3.45:1 against this scrim (tuned for flat --bg/--bg2, not a photo) —
   caught by tools/regress.py hero, not eyeballed. Uses --coffee instead,
   the same override .cap needed for the same reason. */
.hero-coord{font-size:10px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--coffee);font-weight:700;font-variant-numeric:tabular-nums;}
.hero-top{display:flex;align-items:baseline;gap:16px;flex-wrap:wrap;}
.hero-hl{flex:1;display:flex;align-items:center;margin:20px 0;}
.hero-hl h1{line-height:.92;}
.hl-sans{display:block;font-family:var(--display);font-size:clamp(38px,6vw,78px);
  font-weight:800;letter-spacing:-.015em;color:var(--coffee);}
.hl-serif{display:block;font-family:var(--serif);font-style:italic;font-weight:500;
  font-size:clamp(42px,6.5vw,86px);letter-spacing:-.02em;color:var(--coffee);}
.hero-btm{border-top:1px solid var(--border);padding-top:20px;margin-top:20px;}
.hero-btm p{font-size:13px;max-width:300px;line-height:1.6;margin-bottom:20px;}
.hero-ctas{display:flex;flex-wrap:wrap;gap:12px;align-items:center;}

/* ── Buttons ── */
.btn{display:inline-flex;align-items:center;gap:8px;padding:10px 24px;font-family:var(--body);
  font-size:10px;font-weight:400;letter-spacing:.1em;text-transform:uppercase;
  transition:background .2s,color .2s,transform .18s;border-radius:4px;}
.btn-coffee{background:var(--coffee);color:var(--white);}
.btn-coffee:hover{background:var(--coffee-dark);transform:translateY(-1px);}
.btn-ghost{background:transparent;border:1px solid var(--ink);color:var(--ink);}
.btn-ghost:hover{background:var(--ink);color:var(--bg);}

/* ── STATEMENT ── */
#statement{border-bottom:1px solid var(--border);}
.stmt-grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(48px,7vw,100px);align-items:end;}
.stmt-quote{font-family:var(--serif);font-style:italic;font-size:clamp(26px,3.5vw,46px);
  font-weight:400;line-height:1.22;letter-spacing:-.015em;color:var(--ink);}
.stmt-quote em{font-style:normal;color:var(--coffee);}
.stmt-body p{max-width:100%;font-size:15px;margin-bottom:16px;}

/* ── PROCESS (coffee ground) ── */
#process{background:var(--coffee);position:relative;}
#process::before{content:'';position:absolute;inset:0;pointer-events:none;
  background-image:radial-gradient(circle at 25% 65%, rgba(var(--green-rgb),0.06), transparent 65%);}
#process .wrap{position:relative;z-index:1;}
.proc-hd{margin-bottom:32px;}
/* --on-coffee, not --on-coffee-dim. Same trap the callout label below hit
   and for the same reason: --on-coffee-dim computes 4.95:1 on flat
   --coffee, but #process::before washes the ground with 6% cyan, and the
   real pixel-sampled reading was 4.41:1 at 2560px (4.51-4.55:1 at
   1440/1600) — under the 4.5 floor for a 10px label. check_aa never saw it
   because it reads the computed background colour, which the ::before
   overlay is not part of; tools/regress.py process samples the rendered
   pixels instead. Pre-existing, found while relocating the callout. */
.proc-hd .cap{color:var(--on-coffee);}
.proc-hl-sans{font-family:var(--display);font-weight:800;font-size:clamp(40px,6.5vw,96px);
  letter-spacing:-.012em;line-height:.96;color:var(--white);}
/* --green on coffee is 8.93:1 (was 4.97:1 with orange — fine at
   display-scale, but not built to survive at label size). Cyan clears
   both thresholds comfortably. */
.proc-hl-serif{font-family:var(--serif);font-style:italic;font-weight:400;
  font-size:clamp(44px,7vw,104px);letter-spacing:-.02em;line-height:.9;color:var(--green);}
/* FIX: no stroke-dasharray/offset in CSS — set via JS setAttribute only.
   Carried over from Recro deliberately; a CSS declaration here wins the
   specificity fight against the JS and the line never draws. */
.process-divider{width:100%;max-width:400px;margin:0 auto 48px auto;}
.process-divider svg{width:100%;height:2px;display:block;overflow:visible;}
.process-divider line{stroke:var(--green);stroke-width:3;}
/* Connected timeline (mockup review), replacing the old boxed proc-grid/
   proc-card treatment. .proc-timeline's rail is a static muted line behind
   the three dots — distinct from .process-divider above, which keeps its
   own scroll-triggered draw-in animation and green accent colour. */
.proc-timeline{position:relative;display:grid;grid-template-columns:repeat(3,1fr);
  gap:clamp(24px,3vw,40px);}
.proc-timeline::before{content:'';position:absolute;top:6px;left:0;right:0;height:1px;
  background:rgba(255,255,255,.18);z-index:0;}
.proc-item{position:relative;z-index:1;padding-top:36px;}
.proc-dot{position:absolute;top:0;left:0;width:12px;height:12px;border-radius:50%;
  background:var(--green);display:flex;align-items:center;justify-content:center;
  transform-origin:center;transition:transform .25s ease;}
.proc-num{font-family:var(--body);font-size:9px;font-weight:700;line-height:1;
  color:var(--coffee);opacity:0;transition:opacity .2s ease;}
/* Growth/number-reveal is gated to pointer devices via the hover-capability
   query itself, not a screen-width breakpoint — a touch laptop or
   mouse-equipped tablet gets whichever behaviour matches its actual input.
   On hover:none this block never matches at all, so dots stay at rest size
   with no tap equivalent and the numbers are never shown. */
@media(hover:hover){
  .proc-item:hover .proc-dot{transform:scale(2.2);}
  .proc-item:hover .proc-num{opacity:1;}
}
.proc-item h3{font-family:var(--display);font-size:clamp(18px,2.2vw,26px);font-weight:900;
  text-transform:uppercase;color:var(--white);letter-spacing:-.01em;margin-bottom:14px;}
.proc-item p{font-size:13px;color:var(--on-coffee);max-width:100%;}

/* ── WORK ── */
#work{border-bottom:1px solid var(--border);scroll-margin-top:70px;}
.work-hd{display:flex;justify-content:space-between;align-items:flex-end;gap:24px;margin-bottom:40px;}
/* Three cards in a two-column grid leaves a visible hole on the second row
   (Recro's source had exactly that). Three columns wide, and the odd card
   spanning the full width at tablet, keeps the row closed at every size. */
.work-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;}
/* Scoped to the two-column band only. Left open-ended it also fired below
   768px, where the grid is already one column — the last card then became a
   squat full-width strip while the other two stayed 4:3. */
@media(min-width:769px) and (max-width:1023px){
  .work-grid{grid-template-columns:1fr 1fr;}
  .work-grid .work-card:last-child{grid-column:1 / -1;}
  .work-grid .work-card:last-child::before{padding-top:42%;}
}
.work-card{position:relative;overflow:hidden;display:block;border:1px solid var(--border);
  border-radius:6px;transition:transform .25s ease,box-shadow .3s ease,border-color .3s ease;}
.work-card::before{content:'';display:block;padding-top:75%;}
.work-card:hover{transform:translateY(-4px);box-shadow:0 18px 40px rgba(10,30,18,.14);border-color:var(--ink);}
.work-img{position:absolute;top:0;left:0;width:100%;height:100%;object-fit:cover;
  display:block;transition:transform .5s ease;}
.work-card:hover .work-img{transform:scale(1.04);}
/* The overlay is hover-only on pointer devices. On touch there is no hover,
   so it is painted in permanently below — the tag and title are the only
   thing naming each project. */
/* The scrim has to stay strong for the full height of the text block, not
   just at the very bottom edge. Recro's gradient was already fading by 38%,
   which put the tag over near-bare photo — measured as low as 1.00:1 against
   a bright image. The stops are in px, not %, because the text block is a
   fixed height: on a short card a percentage stop starts fading partway up
   the tag (3.15:1 on the wide card at 390px). 104px covers the 28px padding
   plus both lines on every card shape, holding the worst pixel under any
   glyph at 5.3:1 or better even where the photo underneath is pure white. */
.work-over{position:absolute;inset:0;z-index:2;opacity:0;transition:opacity .32s;
  background:linear-gradient(to top,
    rgba(10,30,18,.94) 0,
    rgba(10,30,18,.93) 104px,
    rgba(10,30,18,.55) 152px,
    transparent 214px);
  display:flex;flex-direction:column;justify-content:flex-end;padding:28px;}
.work-card:hover .work-over,.work-card:focus-visible .work-over{opacity:1;}
.work-tag{font-size:9px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--green-bright);margin-bottom:5px;}
.work-title{font-family:var(--display);font-size:clamp(15px,1.8vw,21px);font-weight:900;
  text-transform:uppercase;color:var(--white);}
@media(hover:none){
  .work-over{opacity:1;}
  .work-card:hover{transform:none;}
}

/* ── CARNSTONE CONCEPT CALLOUT ──
   A concept piece, not a client project, so it must not sit inside
   .work-grid pretending to be one of the three. It keeps the work-card
   vocabulary — same border, radius, hover lift, same tag/title block — but
   runs full width and carries an honest empty frame rather than a
   screenshot. Carnstone currently ships placeholder photography of its own,
   so a capture taken today would be a placeholder inside a placeholder
   presented as a preview. One honest empty frame beats two stacked pretend
   ones. See README.md and tools/shoot-carnstone.py. */
.cnc{display:block;margin-top:14px;border:1px solid var(--border);border-radius:6px;
  overflow:hidden;transition:transform .25s ease,box-shadow .3s ease,border-color .3s ease;}
.cnc:hover{transform:translateY(-4px);box-shadow:0 18px 40px rgba(10,30,18,.14);border-color:var(--ink);}
/* The frame's base is --bg, not --bg2. The hatch darkens whatever it sits on
   by ~4.5%, and on --bg2 that dragged the tag and the note to 4.13:1 and
   4.15:1 — under AA. On --bg the same hatch leaves them at 4.76:1 / 4.78:1.
   The border and the hatch carry the "not a real card" read on their own. */
.cnc-f{position:relative;background-color:var(--bg);border-bottom:1px solid var(--border);
  display:flex;align-items:center;justify-content:center;min-height:clamp(120px,15vw,190px);
  background-image:repeating-linear-gradient(-45deg,
    transparent 0 9px, rgba(10,30,18,.045) 9px 10px);}
.cnc-tag{position:absolute;top:14px;left:14px;font-size:9px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--green-ink);font-weight:700;}
.cnc-note{font-family:var(--serif);font-size:17px;font-style:italic;color:var(--mid);}
.cnc-m{display:flex;align-items:baseline;justify-content:space-between;gap:20px;
  padding:18px 22px;background:var(--bg);}
.cnc-n{font-family:var(--display);font-size:clamp(15px,1.8vw,21px);font-weight:900;
  text-transform:uppercase;color:var(--ink);}
.cnc-c{font-size:11px;color:var(--mid);text-align:right;}
.cnc:hover .cnc-n{text-decoration:underline;text-underline-offset:3px;}
@media(max-width:768px){
  .cnc-m{display:block;}
  .cnc-c{text-align:left;margin-top:5px;}
}

/* ── TESTIMONIAL (section currently DISABLED in index.html) ──
   Kept deliberately. The section is commented out of the markup until a
   real client quote exists, and this rule is what lets it come back
   styled by uncommenting alone — no CSS archaeology at that point. It
   matches nothing today and costs nothing. */
#testimonial{padding:clamp(60px,8vw,90px) 0;border-bottom:1px solid var(--border);}

/* ── PRICING ── */
#pricing{border-bottom:1px solid var(--border);scroll-margin-top:70px;}
.price-hd{display:grid;grid-template-columns:1fr 1fr;gap:80px;align-items:end;margin-bottom:52px;}
.price-hd p{max-width:100%;}
.price-row{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;}
.price-box{background:var(--bg2);padding:clamp(28px,4vw,48px) clamp(20px,3vw,36px);
  border:1px solid var(--border);border-top:3px solid var(--border);
  transition:border-color .3s,transform .2s,box-shadow .3s;position:relative;}
.price-box:hover{transform:translateY(-3px);border-top-color:var(--green);
  box-shadow:0 12px 28px rgba(10,30,18,.08);}
.price-box.hot{border-top-color:var(--green);}
.price-tag{font-size:9px;letter-spacing:.12em;text-transform:uppercase;color:var(--mid);
  display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:18px;}
.price-flag{color:var(--green-ink);font-weight:700;}
.price-box h3{font-family:var(--display);font-size:clamp(16px,2vw,24px);font-weight:900;
  text-transform:uppercase;letter-spacing:-.01em;margin-bottom:16px;}
.price-amt{font-family:var(--serif);font-size:clamp(48px,7vw,88px);font-weight:500;
  letter-spacing:-.03em;line-height:.88;margin-bottom:18px;color:var(--ink);}
.price-amt sup{font-size:.4em;vertical-align:top;margin-top:.2em;display:inline-block;
  font-family:var(--body);font-weight:400;}
.price-d{font-size:12px;color:var(--mid);margin-bottom:22px;max-width:100%;line-height:1.6;}
.price-ul{list-style:none;display:flex;flex-direction:column;gap:8px;}
.price-ul li{font-size:12px;color:var(--mid);display:flex;gap:9px;}
.price-ul li::before{content:'—';color:var(--coffee);font-weight:700;flex-shrink:0;}
.price-note{margin-top:28px;font-family:var(--serif);font-size:15px;font-style:italic;
  color:var(--mid);text-align:center;max-width:100%;}

/* ── ABOUT ── */
#about{border-bottom:1px solid var(--border);scroll-margin-top:70px;}
.about-grid{display:grid;grid-template-columns:1fr 1.4fr;gap:clamp(48px,7vw,100px);align-items:center;}
.about-img{aspect-ratio:3/4;background:var(--bg2);border:1px solid var(--border);
  display:flex;align-items:center;justify-content:center;overflow:hidden;}
.about-img img{width:100%;height:100%;object-fit:cover;object-position:50% 30%;display:block;}
.about-text .de-md{margin-bottom:24px;text-transform:uppercase;}
.about-text p{max-width:100%;margin-bottom:14px;}
.facts{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-top:36px;
  padding-top:36px;border-top:1px solid var(--border);}
.fk{font-size:9px;letter-spacing:.14em;text-transform:uppercase;color:var(--mid);margin-bottom:4px;}
/* All four facts take this one treatment. The coordinate variant that used
   to sit here went with the Position fact — see the note in index.html. */
.fv{font-family:var(--display);font-size:13px;font-weight:900;text-transform:uppercase;letter-spacing:.03em;}

/* ── FAQ ── */
#faq{background:var(--bg2);border-bottom:1px solid var(--border);scroll-margin-top:70px;}
.faq-grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(48px,7vw,100px);align-items:start;}
.faq-list{border-top:1px solid var(--border);}
.faq-item{border-bottom:1px solid var(--border);}
.faq-q{display:flex;justify-content:space-between;align-items:center;gap:16px;padding:17px 0;
  cursor:pointer;font-family:var(--display);font-size:clamp(11px,1.3vw,14px);font-weight:900;
  text-transform:uppercase;letter-spacing:.02em;transition:color .2s;color:var(--ink);
  background:none;border:none;width:100%;text-align:left;font-family:var(--display);}
.faq-q:hover{color:var(--mid);}
.faq-icon{font-size:18px;font-weight:300;flex-shrink:0;color:var(--mid);line-height:1;transition:transform .3s;}
.faq-a{font-size:13px;color:var(--mid);line-height:1.72;max-height:0;overflow:hidden;
  transition:max-height .4s ease,padding .3s;max-width:100%;}
.faq-item.open .faq-a{max-height:280px;padding-bottom:18px;}
.faq-item.open .faq-icon{transform:rotate(45deg);}

/* ── CONTACT FORM ── */
#contact-form{border-bottom:1px solid var(--border);scroll-margin-top:70px;}
.cf-grid{display:grid;grid-template-columns:1fr 1.5fr;gap:clamp(48px,7vw,100px);align-items:start;}
.cf-detail{margin-bottom:32px;}
.cf-detail-label{font-size:9px;letter-spacing:.14em;text-transform:uppercase;color:var(--mid);margin-bottom:5px;}
.cf-detail-val{font-family:var(--display);font-size:14px;font-weight:900;text-transform:uppercase;letter-spacing:.02em;}
.cf-detail-val.coord{font-family:var(--body);font-weight:700;text-transform:none;
  letter-spacing:.06em;font-variant-numeric:tabular-nums;}
.cf-form{display:flex;flex-direction:column;gap:20px;}
.cf-row{display:grid;grid-template-columns:1fr 1fr;gap:16px;}
.cf-field{display:flex;flex-direction:column;gap:6px;}
.cf-label{font-size:9px;letter-spacing:.14em;text-transform:uppercase;color:var(--mid);}
.cf-input,.cf-textarea{background:transparent;border:none;border-bottom:1px solid var(--border);
  padding:10px 0;font-family:var(--body);font-size:13px;color:var(--ink);
  transition:border-color .2s;width:100%;outline:none;border-radius:0;}
.cf-input:focus,.cf-textarea:focus{border-bottom-color:var(--ink);}
.cf-input::placeholder,.cf-textarea::placeholder{color:var(--mid);opacity:1;}
.cf-textarea{min-height:90px;resize:vertical;}
.cf-submit{align-self:flex-start;margin-top:8px;border:none;cursor:pointer;}
.cf-success{display:none;font-size:13px;color:var(--ink);padding:12px 0;border-top:1px solid var(--border);}

/* ── CTA BAND (cyan ground) ──
   Both --ink and --coffee clear AA on --green now that it's cyan rather
   than orange: --ink 10.57:1, --coffee 8.93:1 — both comfortably past the
   4.5:1 small-text floor. Under orange only --ink cleared at small sizes
   (5.13:1); --coffee cleared only the 3.0 large-text floor there (4.97:1,
   then 4.33:1 once --coffee became navy), which is why the small labels
   below use --ink and the headline's second line (.cta-hl .sc-lg) uses
   --coffee. That split is no longer contrast-forced under cyan, just kept
   as-is. Recro set the supporting note at rgba(10,30,18,.4) = 2.00:1; it
   is solid --ink here. */
#cta{padding:0;}
.cta-band{background:var(--green);padding:clamp(80px,12vw,160px) var(--pad);
  display:grid;grid-template-columns:1fr auto;gap:60px;align-items:center;
  position:relative;overflow:hidden;}
.cta-band::after{content:'';position:absolute;inset:0;pointer-events:none;
  background-image:linear-gradient(rgba(10,30,18,.05) 1px, transparent 1px),
                   linear-gradient(90deg, rgba(10,30,18,.05) 1px, transparent 1px);
  background-size:48px 48px;}
.cta-band>*{position:relative;z-index:1;}
.cta-hl .de-lg{color:var(--ink);}
.cta-hl .sc-lg{color:var(--coffee);}
.cta-r{flex-shrink:0;display:flex;flex-direction:column;gap:12px;align-items:flex-start;}
.cta-note{font-size:10px;color:var(--ink);letter-spacing:.08em;text-transform:uppercase;}
/* Quick email capture — the second YOURFORMID (CLAUDE.md 10). */
.cta-or{display:flex;align-items:center;gap:10px;margin:4px 0;width:100%;}
.cta-or span{font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink);}
.cta-or::before,.cta-or::after{content:'';flex:1;height:1px;background:rgba(10,30,18,.28);}
.cta-email-form{display:flex;gap:0;width:100%;}
.cta-email-form input[type="email"]{flex:1;min-width:0;height:40px;padding:0 14px;
  background:rgba(255,255,255,.45);border:1px solid rgba(10,30,18,.35);border-right:none;
  font-family:var(--body);font-size:10px;color:var(--ink);letter-spacing:.04em;
  border-radius:4px 0 0 4px;}
/* Recro's placeholder was rgba(10,30,18,.45) = 2.3:1 on the orange band. */
.cta-email-form input[type="email"]::placeholder{color:#3A2A1C;opacity:1;}
.cta-email-form input[type="email"]:focus{outline:none;background:rgba(255,255,255,.62);}
.cta-email-form button{height:40px;padding:0 18px;background:var(--coffee);color:var(--white);
  border:none;font-family:var(--body);font-size:10px;letter-spacing:.1em;text-transform:uppercase;
  cursor:pointer;white-space:nowrap;border-radius:0 4px 4px 0;transition:background .2s;}
.cta-email-form button:hover{background:var(--coffee-dark);}
.visually-hidden{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;}

/* ── FOOTER ── */
footer{background:var(--coffee);}
.foot-top{padding:clamp(60px,9vw,110px) var(--pad) clamp(40px,6vw,72px);
  border-bottom:1px solid rgba(255,255,255,.09);}
.foot-hl .de-lg{color:var(--white);}
.foot-hl .sc-lg{color:var(--green);}
.foot-btm{padding:28px var(--pad);display:flex;justify-content:space-between;
  align-items:center;flex-wrap:wrap;gap:16px;}
.foot-logo{font-family:var(--display);font-size:12px;font-weight:900;text-transform:uppercase;
  letter-spacing:.07em;color:var(--white);display:flex;align-items:center;gap:8px;}
.foot-copy{font-size:10px;color:var(--on-coffee-dim);letter-spacing:.08em;text-transform:uppercase;}
.foot-links{display:flex;gap:24px;list-style:none;}
.foot-links a{font-size:10px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--on-coffee-dim);transition:color .2s;}
.foot-links a:hover{color:var(--white);}

/* ── MOBILE NAV ── */
.nav-burger{display:none;flex-direction:column;gap:5px;cursor:pointer;padding:6px;
  background:none;border:none;z-index:201;}
.nav-burger span{display:block;width:22px;height:1.5px;background:var(--ink);
  transition:transform .3s,opacity .3s;}
.nav-burger.open span:nth-child(1){transform:translateY(6.5px) rotate(45deg);}
.nav-burger.open span:nth-child(2){opacity:0;}
.nav-burger.open span:nth-child(3){transform:translateY(-6.5px) rotate(-45deg);}
.mob-menu{position:fixed;inset:0;background:var(--coffee);z-index:200;display:flex;
  flex-direction:column;justify-content:center;align-items:flex-start;padding:0 var(--pad);
  opacity:0;pointer-events:none;transition:opacity .35s ease;}
.mob-menu.open{opacity:1;pointer-events:all;}
.mob-nav{display:flex;flex-direction:column;gap:4px;width:100%;}
.mob-link{font-family:var(--display);font-size:clamp(18px,4.5vw,26px);font-weight:700;
  text-transform:uppercase;letter-spacing:.06em;color:rgba(248,246,238,.85);padding:10px 0;
  opacity:0;transform:translateY(16px);
  transition:opacity .4s ease,transform .4s ease,color .2s;}
.mob-menu.open .mob-link{opacity:1;transform:none;}
.mob-menu.open .mob-link:nth-child(1){transition-delay:.06s;}
.mob-menu.open .mob-link:nth-child(2){transition-delay:.12s;}
.mob-menu.open .mob-link:nth-child(3){transition-delay:.18s;}
.mob-menu.open .mob-link:nth-child(4){transition-delay:.24s;}
.mob-menu.open .mob-link:nth-child(5){transition-delay:.30s;}
.mob-menu.open .mob-link:nth-child(6){transition-delay:.36s;}
.mob-link:hover{color:var(--white);}
.mob-cta{color:var(--green-bright)!important;margin-top:16px;}
.mob-close{position:absolute;top:22px;right:var(--pad);font-size:13px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--on-coffee);background:none;border:none;cursor:pointer;
  font-family:var(--body);}
.mob-footer{position:absolute;bottom:32px;left:var(--pad);font-size:11px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--on-coffee-dim);}

/* ── BREAKPOINTS ──
   900px: nav collapses to the burger (CLAUDE.md 11).
   768px: multi-column grids fold to one column. */
@media(max-width:900px){
  .nav-burger{display:flex;}
  .nav-links{display:none;}
}
@media(max-width:768px){
  .hero-btm p{max-width:100%;}
  .stmt-grid,.price-hd,.about-grid,.faq-grid,.cf-grid,.cf-row{grid-template-columns:1fr;gap:32px;}
  .price-row{grid-template-columns:1fr;}
  .work-grid{grid-template-columns:1fr;}
  /* Timeline folds from horizontal (dots on a shared top rail) to vertical
     (dots on a left rail, one per item) — a horizontal three-across line
     doesn't have room to breathe under 768px. */
  .proc-timeline{grid-template-columns:1fr;gap:0;}
  .proc-timeline::before{display:none;}
  .proc-item{padding-top:0;padding-left:32px;padding-bottom:40px;}
  .proc-item:last-child{padding-bottom:0;}
  .proc-item::before{content:'';position:absolute;top:6px;left:6px;bottom:-46px;width:1px;
    background:rgba(255,255,255,.18);z-index:0;}
  .proc-item:last-child::before{display:none;}
  .proc-dot{top:0;left:0;}
  .cta-band{grid-template-columns:1fr;gap:36px;}
  .work-hd{flex-direction:column;align-items:flex-start;gap:20px;}
  .hero-ctas{flex-direction:column;align-items:stretch;}
  .hero-ctas .btn{justify-content:center;}
  footer .foot-btm{flex-direction:column;text-align:center;}
  .foot-links{flex-wrap:wrap;justify-content:center;}
}

/* ── REDUCED MOTION ──
   Recro's source had no reduced-motion handling at all. Everything below
   lands on the finished end-state, not a half-played one: reveals are
   visible, and JS reads this same query to paint the counters and the
   process line at their final values. The headline used to open from a
   clip-path wipe and needed an explicit override here; it has no entrance
   animation of its own any more, so there is nothing left to override. */
@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto;}
  *,*::before,*::after{
    animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important;transition-delay:0ms!important;}
  .r{opacity:1;transform:none;}
  .mob-menu .mob-link{opacity:1;transform:none;}
}
