:root{
  --paper:#F2ECE0; --paper-2:#E9E1D1; --paper-3:#E3D9C5;
  --ink:#171310; --ink-2:#524A3F; --ink-3:#857B6A;
  --accent:#8E5D26; --accent-deep:#6F4517; --hairline:#CCBE9F; --ember:#B0532A; /* palette: the one bold accent — highlighted phrases / key CTA */
  --brass:#C79A53; --gold:#E6CD96; /* brass accents (nav active tint, quiet refinements) */
  --dark:#171310; --on-dark:#F2ECE0; --on-dark-2:#B9AE99;
  --serif:'Archivo',-apple-system,sans-serif; /* bold display (was Fraunces) */ --sans:'Hanken Grotesk',-apple-system,sans-serif;
  --s1:8px;--s2:16px;--s3:24px;--s4:40px;--s5:64px;--s6:96px;--s7:140px;
  --measure:660px; --wide:1080px; --frame:1240px;
  --rail:clamp(142px,10.5vw,168px);
  /* motion system (home page pass, 2026-07-19): one easing curve + one duration ladder.
     Tokens only — inert until a selector uses them. See motion.css / motion.js (home-only). */
  --ease-gravity:cubic-bezier(.2,.8,.2,1);
  --rev-fast:200ms; --rev-sm:500ms; --rev-line:700ms; --rev-lg:900ms; --rev-stagger:110ms;
}
*,*::before,*::after{box-sizing:border-box;}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;}
body{margin:0;background:var(--paper);color:var(--ink);font-family:var(--sans);
  font-size:21px;line-height:1.72;-webkit-font-smoothing:antialiased;overflow-x:hidden;}
img{max-width:100%;display:block;}
a{color:var(--accent);text-decoration:underline;text-underline-offset:3px;text-decoration-thickness:1px;}
/* keyboard focus ring (only renders on keyboard focus, so the default/screenshot render is unchanged) */
:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:3px;}
.btn:focus-visible,.navtoggle:focus-visible,.hero__scroll:focus-visible{outline-offset:4px;}
@media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important;}}

/* Material grain — subtle paper texture for substance (avatar: serious body of work, not gentle) */
body::after{content:"";position:fixed;inset:0;z-index:9999;pointer-events:none;opacity:.045;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  mix-blend-mode:multiply;}

/* Hero ink-topography canvas (injected by main.js into every hero) */
.hero__fx{position:absolute;inset:0;width:100%;height:100%;z-index:0;pointer-events:none;}

.frame{max-width:var(--frame);margin-inline:auto;padding-inline:var(--s3);}
.measure{max-width:var(--measure);}
.wide{max-width:var(--wide);margin-inline:auto;padding-inline:var(--s3);}
section{padding-block:var(--s6);}
@media(min-width:768px){section{padding-block:var(--s7);}}
.alt{background:var(--paper-2);}
.rule{height:1px;background:var(--hairline);border:0;margin:0;}

.eyebrow{font-family:var(--sans);font-size:12px;font-weight:600;letter-spacing:0.2em;
  text-transform:uppercase;color:var(--accent);margin:0 0 var(--s3);}
h1,h2,h3{font-family:var(--serif);font-weight:700;line-height:1.04;letter-spacing:-0.018em;margin:0;}
h1{font-size:clamp(2.7rem,7.5vw,6rem);}
h2{font-size:clamp(2rem,4.4vw,3.4rem);}
h3{font-size:1.5rem;font-weight:500;}
p{margin:0 0 var(--s3);}
.lead{font-size:clamp(1.2rem,2vw,1.5rem);line-height:1.5;color:var(--ink-2);max-width:50ch;}
.prose p{color:var(--ink-2);max-width:62ch;font-size:1.12rem;}
.prose .em{color:var(--ink);font-size:1.3rem;line-height:1.45;}
.kicker{font-size:13px;letter-spacing:0.18em;text-transform:uppercase;color:var(--ink-3);}
.pq{font-family:var(--serif);font-weight:600;font-size:clamp(2.1rem,5.2vw,3.8rem);line-height:1.14;
  letter-spacing:-0.015em;color:var(--ink);max-width:16ch;}
.pq .it{font-style:italic;color:var(--ember);}

/* nav — slim, SOLID vertical rail down the LEFT side (nothing behind it shows through) */
.railnav{position:fixed;left:0;top:0;bottom:0;z-index:50;width:var(--rail);
  display:flex;flex-direction:column;
  padding:clamp(28px,3.2vh,42px) clamp(18px,1.3vw,26px);
  background:var(--paper);
  border-right:1px solid var(--hairline);
  transition:opacity 1s ease;}
.brand{font-family:var(--serif);font-size:1.12rem;font-weight:800;text-transform:uppercase;color:var(--ink);text-decoration:none;letter-spacing:-0.005em;line-height:1.12;}
.railnav__brand{max-width:8ch;}
.railnav__links{display:flex;flex-direction:column;gap:clamp(13px,1.7vh,20px);align-items:flex-start;
  margin-top:auto;margin-bottom:auto;}
.railnav__links a:not(.btn){font-family:var(--sans);color:var(--ink);text-decoration:none;font-size:15px;font-weight:500;white-space:nowrap;transition:color .2s;}
.railnav__links a:not(.btn):hover{color:var(--accent);}
/* Client Portal — a nav destination that isn't live yet. Rendered as a muted, non-clickable
   item with a small brass "coming soon" pill, so it reads as intentional, not broken. Matches
   the link rhythm (same size/weight) but sits back in ink-3 and shows no pointer cursor. */
.nav__soon{display:inline-flex;align-items:center;flex-wrap:wrap;gap:5px 9px;font-family:var(--sans);
  font-size:15px;font-weight:500;color:var(--ink-3);white-space:nowrap;cursor:default;user-select:none;}
.nav__soon-tag{font-size:9px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;
  color:var(--accent-deep);background:var(--paper-3);border:1px solid var(--hairline);
  border-radius:100px;padding:3px 8px;line-height:1;}
.railnav__foot{display:flex;flex-direction:column;gap:clamp(16px,2.2vh,26px);align-items:flex-start;}
.railnav .btn{padding:10px 18px;font-size:13.5px;white-space:nowrap;}
/* the divider line on the rail's right edge IS the progress: accent fill grows top -> down as you scroll */
.railnav__progress{position:absolute;top:0;right:-1px;width:2px;height:100%;background:var(--accent);
  transform:scaleY(var(--np,0));transform-origin:top center;z-index:1;transition:transform .1s linear;}
/* current-page marker: active nav link clearly highlighted (client couldn't tell which page) */
.railnav__links a[aria-current="page"],.nav__sub a[aria-current="page"]{color:var(--accent-deep);font-weight:700;}
/* "you are here": active nav name (current page on sub-pages, or the section in view on the
   home journey via .is-here) gets accent colour + a soft pulsing highlight around it */
.railnav__links a.is-here{color:var(--accent-deep);font-weight:700;}
.railnav__links a.is-here,.railnav__links a[aria-current="page"]{position:relative;z-index:0;}
.railnav__links a.is-here::before,.railnav__links a[aria-current="page"]::before{
  content:"";position:absolute;inset:-5px -11px;border-radius:9px;background:var(--brass);
  z-index:-1;opacity:.2;animation:navHerePulse 2.4s ease-in-out infinite;}   /* soft brass tint — unmistakable active page */
@keyframes navHerePulse{0%,100%{opacity:.16;transform:scale(.97);}50%{opacity:.28;transform:scale(1);}}
@media(prefers-reduced-motion:reduce){.railnav__links a.is-here::before,.railnav__links a[aria-current="page"]::before{animation:none;opacity:.24;}}
/* on-this-page map (home journey): section list under Home in the rail.
   Highlights the section in view; click jumps straight there (incl. the end). */
.homewrap{display:flex;flex-direction:column;align-items:flex-start;}
.homemap{display:flex;flex-direction:column;gap:9px;margin:0 0 0 7px;padding-left:12px;border-left:1px solid var(--hairline);
  /* collapsed on load — expands (and stays open) once the visitor starts moving through the journey */
  max-height:0;opacity:0;overflow:hidden;pointer-events:none;
  transition:max-height .7s cubic-bezier(.16,1,.3,1),opacity .55s ease,margin .4s ease;}
.homemap.open{max-height:280px;opacity:1;pointer-events:auto;margin:2px 0 4px 7px;}
.homemap a{font-family:var(--sans);font-size:12.5px;font-weight:500;color:var(--ink-2);text-decoration:none;white-space:nowrap;transition:color .2s;}
.homemap a:hover{color:var(--accent-deep);}
.homemap a.on{color:var(--accent-deep);font-weight:700;}
html:not(.js) .homemap{display:none;}   /* the map needs the journey JS */
@media(max-width:680px){.homemap{display:none;}}  /* mobile scrolls natively */

/* current-page breadcrumb — injected by JS into the hero of sub-pages (location,
   without crowding the top bar). Parent is a link (also serves as the back-link). */
.phero__crumb{display:block;margin-bottom:clamp(16px,2.4vh,22px);font-family:var(--sans);
  font-size:12px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--accent-deep);}
.phero__crumb a{color:var(--ink-2);text-decoration:none;transition:color .2s;}
.phero__crumb a:hover{color:var(--accent-deep);}
.phero__crumb .sep{margin:0 8px;color:var(--hairline);}
/* hamburger toggle — hidden on desktop, shown in the mobile top bar */
.navtoggle{display:none;background:none;border:0;cursor:pointer;color:var(--ink);padding:0;-webkit-tap-highlight-color:transparent;}
.navtoggle__bars{position:relative;display:block;width:24px;height:14px;}
.navtoggle__bars i{position:absolute;left:0;right:0;height:2px;border-radius:2px;background:currentColor;
  transition:transform .3s cubic-bezier(.16,1,.3,1),opacity .2s ease;}
.navtoggle__bars i:nth-child(1){top:0;}
.navtoggle__bars i:nth-child(2){top:6px;}
.navtoggle__bars i:nth-child(3){top:12px;}
.railnav.nav-open .navtoggle__bars i:nth-child(1){transform:translateY(6px) rotate(45deg);}
.railnav.nav-open .navtoggle__bars i:nth-child(2){opacity:0;}
.railnav.nav-open .navtoggle__bars i:nth-child(3){transform:translateY(-6px) rotate(-45deg);}
.btn{display:inline-block;font-family:var(--sans);font-weight:600;font-size:15px;padding:13px 26px;
  border-radius:999px;text-decoration:none;cursor:pointer;background:var(--ink);color:var(--paper);
  border:1px solid var(--ink);transition:background .2s,color .2s,transform .15s;}
.btn:hover{background:transparent;color:var(--ink);transform:translateY(-1px);}
.btn--ghost{background:transparent;color:var(--ink);border-color:var(--accent);}  /* deep-brass outline for secondary CTAs */
.btn--ghost:hover{background:var(--ink);color:var(--paper);border-color:var(--ink);}
/* one ember accent per screen — highlighted word(s) inside a split headline */
.w.ember{color:var(--ember);}

/* nav dropdown (Work With Me) — hover + :focus-within, no JS. In the left rail it flies out to the RIGHT. */
.nav__has-sub{position:relative;display:inline-flex;align-items:center;}
/* Work With Me is the one nav item with something to discover behind it (the lens), so it earns a
   look: an ember hairline draws itself under the label, holds, then fades. EMBER, not the brass the
   active-page pill uses, so the two can never be confused. No class needed - Work With Me is the
   only nav item with a submenu. Settles on hover (it has done its job) and on the page itself. */
.railnav__links .nav__has-sub > a:not([aria-current]):not(.is-here){position:relative;}
.railnav__links .nav__has-sub > a:not([aria-current]):not(.is-here)::after{
  content:"";position:absolute;left:0;right:0;bottom:-5px;height:1.5px;border-radius:2px;
  background:var(--ember);transform-origin:left center;pointer-events:none;
  animation:navWwmPulse 3.6s cubic-bezier(.4,0,.6,1) infinite;}
@keyframes navWwmPulse{
  0%{opacity:0;transform:scaleX(0);}
  30%{opacity:.85;transform:scaleX(1);}
  62%{opacity:.85;transform:scaleX(1);}
  100%{opacity:0;transform:scaleX(1);}}
.railnav__links .nav__has-sub:hover > a::after{animation:none;opacity:1;transform:scaleX(1);}
@media(prefers-reduced-motion:reduce){
  .railnav__links .nav__has-sub > a::after{animation:none;opacity:.7;transform:scaleX(1);}}
.railnav .nav__sub{top:-8px;left:100%;margin-top:0;margin-left:16px;transform:translateX(-6px);}
.railnav .nav__has-sub:hover .nav__sub,
.railnav .nav__has-sub:focus-within .nav__sub{transform:translateX(0);}
.railnav .nav__has-sub::after{top:0;left:100%;width:16px;height:100%;}
.nav__sub{position:absolute;top:100%;left:0;margin-top:14px;min-width:230px;
  display:flex;flex-direction:column;background:var(--paper);border:1px solid var(--hairline);
  border-radius:6px;padding:8px 0;box-shadow:0 12px 34px rgba(23,19,16,.12);
  opacity:0;visibility:hidden;transform:translateY(6px);transition:opacity .2s ease,transform .2s ease,visibility .2s;z-index:60;}
/* bridge the 14px gap so the menu doesn't close while the pointer travels into it */
.nav__has-sub::after{content:"";position:absolute;top:100%;left:0;width:100%;height:16px;}
.nav__has-sub:hover .nav__sub,
.nav__has-sub:focus-within .nav__sub{opacity:1;visibility:visible;transform:translateY(0);}
.nav__sub a{padding:9px 20px;font-family:var(--sans);font-size:14px;font-weight:500;color:var(--ink);
  text-decoration:none;white-space:nowrap;}
.nav__sub a:hover,.nav__sub a:focus{color:var(--accent);background:var(--paper-2);}

/* form confirmation (contact + home CTA) — revealed once the form is wired + submitted */
.form__confirm{margin:var(--s2) 0 0;font-family:var(--sans);font-size:14px;font-weight:600;
  color:var(--accent);letter-spacing:0.01em;}
.form__confirm[hidden]{display:none;}
/* form validation feedback (contact + home CTA): on-brand inline error/highlight, shared
   by every form contact-form.js wires. Was page-local to contact.html; promoted here so
   the home CTA form doesn't need a second copy of the same rules. */
.form__error{margin:0 0 var(--s2);font-family:var(--sans);font-size:14px;font-weight:600;
  color:var(--ember);letter-spacing:0.01em;}
.form__error[hidden]{display:none;}
.field__msg{display:block;margin-top:6px;font-family:var(--sans);font-size:13px;font-weight:600;
  color:var(--ember);letter-spacing:0.01em;}
.field__msg[hidden]{display:none;}
.field--invalid input,.field--invalid textarea{border-color:var(--ember);}

/* hero */
.hero{min-height:96vh;display:flex;align-items:center;padding-top:72px;position:relative;overflow:hidden;}
.hero__aura{position:absolute;inset:-12%;z-index:0;pointer-events:none;opacity:0;
  background:radial-gradient(40% 44% at 78% 26%,rgba(154,107,47,0.14),transparent 70%),
    radial-gradient(46% 40% at 14% 84%,rgba(154,107,47,0.08),transparent 72%);
  animation:auraIn 1.8s ease .2s forwards,auraDrift 28s ease-in-out 2s infinite alternate;}
@keyframes auraIn{to{opacity:1;}}
@keyframes auraDrift{to{transform:translate3d(3%,2%,0) scale(1.08);}}
.hero .frame{position:relative;z-index:1;}
.hero h1{max-width:14ch;}
.hero .lead{margin-top:var(--s4);}
.hero__cta{margin-top:var(--s5);display:flex;gap:16px;flex-wrap:wrap;}
.hero__rule{display:block;width:0;height:2px;background:var(--accent);margin:0 0 var(--s4);}
.js.ready .hero__rule{width:60px;transition:width 1s cubic-bezier(.16,.8,.24,1) .15s;}

/* gap narrative with drop cap */
.dropcap::first-letter{font-family:var(--serif);font-weight:500;font-size:4.6rem;line-height:.8;
  float:left;margin:8px 14px 0 0;color:var(--brass);}  /* brass — ember is reserved for punchlines (client) */
.fixes{font-family:var(--serif);font-size:clamp(1.7rem,3.6vw,2.6rem);line-height:1.4;color:var(--ink);
  margin:var(--s4) 0;font-weight:500;}
.fixes span{display:block;}
.statement{display:flex;align-items:center;min-height:46vh;}

/* distinction */
.contrast{display:grid;gap:var(--s4);margin-top:var(--s5);}
@media(min-width:740px){.contrast{grid-template-columns:1fr 1fr;}}
.contrast>div{padding-top:var(--s3);border-top:2px solid var(--ink);}
.contrast .gold{border-top-color:var(--accent);}
.contrast .tag{font-size:12px;letter-spacing:0.18em;text-transform:uppercase;color:var(--ink-2);margin-bottom:var(--s2);}
.contrast .big{font-family:var(--serif);font-size:1.65rem;line-height:1.3;color:var(--ink);}
.contrast .gold .big{color:var(--accent);}

/* bio */
.split{display:grid;gap:var(--s5);align-items:center;}
@media(min-width:880px){.split{grid-template-columns:1.3fr .9fr;}}
.portrait{aspect-ratio:4/5;background:var(--paper-3);border:1px solid var(--hairline);
  display:flex;align-items:center;justify-content:center;color:var(--ink-3);font-size:12px;
  letter-spacing:0.18em;text-transform:uppercase;}
.stats{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s3);margin-top:var(--s5);
  border-top:1px solid var(--hairline);padding-top:var(--s4);}
.stat .n{font-family:var(--serif);font-weight:500;font-size:clamp(2.2rem,5vw,3rem);color:var(--ink);line-height:1;}
.stat .l{font-size:12px;letter-spacing:0.12em;text-transform:uppercase;color:var(--ink-2);margin-top:10px;}

/* how */
/* HOW IT WORKS: two columns — text/headline left (vertically centred), video right */
.how__in{width:100%;display:grid;grid-template-columns:1fr 1fr;gap:clamp(48px,6vw,110px);align-items:center;}
.how__text{align-self:center;}
.how__text .prose{max-width:46ch;}
.how__in .video{margin-top:0;width:100%;}
@media(max-width:900px){.how__in{grid-template-columns:1fr;gap:var(--s4);}}
.video{margin-top:var(--s4);aspect-ratio:16/9;border:1px solid var(--hairline);background:var(--paper-2);
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;text-decoration:none;color:var(--ink-3);transition:border-color .3s,color .3s;}
.video:hover{border-color:var(--accent);color:var(--accent);}
.video .play{width:60px;height:60px;border-radius:50%;border:1px solid currentColor;display:flex;align-items:center;justify-content:center;}
.video .play::after{content:"";border-top:9px solid transparent;border-bottom:9px solid transparent;border-left:15px solid currentColor;margin-left:5px;}
.video .vl{font-size:12px;letter-spacing:0.16em;text-transform:uppercase;}
/* click-to-play home video: poster + big play button; native controls appear once playing */
.video--play{position:relative;padding:0;border:0;background:#0b0a09;overflow:hidden;border-radius:8px;box-shadow:0 22px 54px rgba(23,19,16,.18);}
.video--play .video__el{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;background:#0b0a09;}
.video--play .video__btn{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  background:linear-gradient(180deg,rgba(11,10,9,.10),rgba(11,10,9,.34));border:0;cursor:pointer;
  -webkit-tap-highlight-color:transparent;transition:background .35s ease,opacity .4s ease;}
.video--play .video__btn:hover{background:linear-gradient(180deg,rgba(11,10,9,.06),rgba(11,10,9,.28));}
.video--play .video__btn .play{width:76px;height:76px;border-radius:50%;border:1.5px solid rgba(255,255,255,.9);
  color:#fff;background:rgba(11,10,9,.28);display:flex;align-items:center;justify-content:center;transition:transform .3s ease,background .3s ease;}
.video--play .video__btn:hover .play{transform:scale(1.06);background:rgba(11,10,9,.42);}
.video--play .video__btn .play::after{content:"";border-top:12px solid transparent;border-bottom:12px solid transparent;border-left:19px solid #fff;margin-left:6px;}
.video--play.is-playing .video__btn{opacity:0;pointer-events:none;}

/* CTA dark — last panel: invitation (stage 0) swaps to a form (stage 1); footer pinned at the bottom */
.cta{background:var(--dark);color:var(--on-dark);}
.cta .eyebrow{color:#C79A5E;}
.cta h2{max-width:20ch;}
.cta .lead{color:var(--on-dark-2);}
.cta .btn{background:var(--paper);color:var(--ink);border-color:var(--paper);}
.cta .btn:hover{background:transparent;color:var(--paper);}
/* home CTA form sits on the dark ground: confirm stays quiet on-dark cream; ember lifts a
   step so the error/highlight state still burns (same treatment as wwm-dark.css's
   punch-on-dark rule) rather than reading as muddy ember-on-near-black. */
.cta .form__confirm{color:var(--on-dark);}
.cta .form__error,.cta .field__msg{color:#D2643A;}
.cta .field--invalid input,.cta .field--invalid textarea{border-color:#D2643A;}
/* the cta panel is a vertical stack: content grows + centres, footer sits at the bottom */
.htrack > section.cta{flex-direction:column;align-items:stretch;justify-content:center;}
.cta__inner{flex:1 1 auto;display:flex;align-items:center;width:100%;}
/* two columns: invitation text stays on the LEFT, the form appears on the RIGHT (stage 1) */
.cta__grid{width:100%;display:grid;grid-template-columns:1fr 1fr;gap:clamp(48px,6vw,110px);align-items:center;}
.cta__intro{align-self:center;}
.cta__form{align-self:center;opacity:0;transform:translateX(40px);pointer-events:none;
  transition:opacity .7s ease,transform .8s cubic-bezier(.16,1,.3,1);}
.cta[data-stage="1"] .cta__form{opacity:1;transform:none;pointer-events:auto;}
@media(max-width:900px){.cta__grid{grid-template-columns:1fr;gap:var(--s4);}}
/* form fields on the dark panel */
.cta__fields{display:grid;grid-template-columns:1fr 1fr;gap:clamp(14px,2.2vh,22px);margin-top:clamp(18px,2.6vh,30px);}
.field{display:flex;flex-direction:column;gap:7px;}
.field--full{grid-column:1 / -1;}
.field span{font-family:var(--sans);font-size:13px;letter-spacing:.04em;color:var(--on-dark-2);}
.field input,.field textarea{font-family:var(--sans);font-size:16px;color:var(--on-dark);background:transparent;
  border:0;border-bottom:1px solid rgba(242,236,224,.22);padding:9px 0;outline:none;transition:border-color .25s;}
.field input:focus,.field textarea:focus{border-bottom-color:var(--paper);}
.field textarea{resize:none;}

/* footer (now lives at the bottom of the get-in-touch panel, not its own page) */
.cta__footer{flex:0 0 auto;background:transparent;padding:0;margin-top:clamp(24px,4vh,52px);}
.foot{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:var(--s4);}
.foot .brand{color:var(--on-dark);}
.foot__links{display:flex;gap:26px;flex-wrap:wrap;}
.foot__links a{color:var(--on-dark-2);text-decoration:none;font-size:14px;}
.foot__links a:hover{color:var(--on-dark);}
.foot__base{margin-top:var(--s4);padding-top:var(--s3);border-top:1px solid rgba(242,236,224,.14);
  display:flex;justify-content:space-between;flex-wrap:wrap;gap:10px;font-size:12px;color:var(--on-dark-2);}
.foot__base a{color:var(--on-dark-2);display:inline-block;padding:12px 0;margin:-12px 0;}

/* motion */
.js [data-anim]{opacity:0;transform:translateY(20px);transition:opacity .95s ease,transform .95s cubic-bezier(.16,.8,.24,1);transition-delay:var(--d,0s);}
.js.ready [data-anim]{opacity:1;transform:none;}
/* hide the whole split headline until JS has split it into .w spans AND .ready fires.
   Without this the raw text paints at full opacity (the end-of-body script runs after
   first paint), then snaps to the hidden word-spans = the headline flash on page load. */
.js [data-split]{opacity:0;}
.js.ready [data-split]{opacity:1;}
.js [data-split] .w{display:inline-block;opacity:0;transform:translateY(.5em);filter:blur(8px);
  transition:opacity .8s ease,transform .9s cubic-bezier(.16,.8,.24,1),filter .8s ease;transition-delay:calc(.25s + var(--i)*.06s);}
.js.ready [data-split] .w{opacity:1;transform:none;filter:none;}
.reveal{opacity:0;transform:translateY(24px);transition:opacity .9s ease,transform .9s cubic-bezier(.16,.8,.24,1);}
.reveal.in{opacity:1;transform:none;}

/* cards (hub pathway grid) */
.cards{display:grid;gap:var(--s3);margin-top:var(--s5);}
@media(min-width:740px){.cards{grid-template-columns:1fr 1fr;}}
.card{display:flex;flex-direction:column;padding:var(--s4);background:var(--paper);border:1px solid var(--hairline);
  text-decoration:none;color:var(--ink);transition:border-color .3s,transform .2s;}
.card:hover{border-color:var(--accent);transform:translateY(-2px);}
.card h3{font-family:var(--serif);font-size:1.5rem;font-weight:500;color:var(--ink);margin:0 0 var(--s2);}
.card p{color:var(--ink-2);font-size:1rem;line-height:1.6;margin:0 0 var(--s3);max-width:none;}
.card .go{margin-top:auto;font-family:var(--sans);font-size:14px;font-weight:600;color:var(--accent);
  letter-spacing:0.02em;text-decoration:none;}
.alt .card{background:var(--paper-2);}

/* complaint voices (organisations) */
.voices{margin:var(--s4) 0;display:flex;flex-direction:column;gap:var(--s3);}
.voices .voice{font-family:var(--serif);font-style:italic;font-size:clamp(1.15rem,1.8vw,1.35rem);
  line-height:1.4;color:var(--ink);max-width:40ch;}  /* a step above body, well under title size (client: they pulled too much attention) */

/* writing / blog */
.toc{list-style:none;margin:var(--s3) 0 0;padding:0;}
.toc li{padding:var(--s2) 0;border-bottom:1px solid var(--hairline);font-family:var(--serif);
  font-size:1.25rem;color:var(--ink);}
.cat{margin-top:var(--s5);padding-top:var(--s4);border-top:1px solid var(--hairline);}
.cat .desc{color:var(--ink-2);max-width:62ch;margin-top:var(--s2);}
.cat ul{list-style:none;margin:var(--s3) 0 0;padding:0;}
.cat ul li{padding:10px 0;border-bottom:1px solid var(--hairline);color:var(--ink-2);font-size:1.05rem;}
.coming{font-family:var(--serif);font-style:italic;color:var(--ink-3);font-size:1.05rem;margin-top:var(--s2);}

/* contact form placeholder */
.formslot{margin-top:var(--s4);padding:var(--s4);border:1px dashed var(--hairline);background:var(--paper-2);}
.formslot .field{display:block;width:100%;padding:14px 16px;margin-bottom:var(--s2);border:1px solid var(--hairline);
  background:var(--paper);font-family:var(--sans);font-size:16px;color:var(--ink);border-radius:4px;}
.formslot textarea.field{min-height:120px;resize:vertical;}
.formslot .note{font-size:13px;color:var(--ink-3);margin:0 0 var(--s3);letter-spacing:0.04em;}
/* Booking — holds the live GHL "Let's Chat" (20 min) widget. GHL's form_embed.js
   measures the iframe content and sets its height, so no fixed aspect-ratio here;
   min-height just stops a collapsed box before the resizer runs. */
.calendar-slot{margin-top:var(--s4);padding:16px;border:1px solid var(--hairline);border-top:3px solid var(--brass);border-radius:5px;
  overflow:hidden;background:var(--paper-3);}
.calendar-slot iframe{display:block;width:100%;border:0;min-height:640px;}
/* Newsletter subscribe (Writing page): email + button on one line, stacking on mobile.
   Reuses .cform field styling so it matches the contact form. */
.nform{margin-top:var(--s4);display:flex;flex-wrap:wrap;gap:12px;align-items:center;max-width:640px;}
.nform__field{flex:1 1 260px;gap:0;}
.nform .form__confirm,.nform .form__error{flex:1 1 100%;margin:0;}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0;}
@media(max-width:600px){
  .nform{flex-direction:column;align-items:stretch;}
  .nform .btn{width:100%;min-height:48px;}
}

/* Honeypot — off-screen, never shown to a human; bots that fill it get a fake success. */
.cform__hp{position:absolute;left:-9999px;top:auto;width:1px;height:1px;overflow:hidden;}

/* back link */
.backlink{display:inline-block;margin-bottom:var(--s3);font-family:var(--sans);font-size:14px;
  font-weight:600;color:var(--accent);text-decoration:none;letter-spacing:0.02em;}
.backlink:hover{text-decoration:underline;}
.list{margin-top:var(--s4);}
.list .item{padding-top:var(--s3);padding-bottom:var(--s3);border-top:1px solid var(--hairline);}
.list .item h3{font-family:var(--serif);font-size:1.35rem;font-weight:500;color:var(--ink);margin:0 0 var(--s2);}
.list .item p{color:var(--ink-2);max-width:62ch;margin:0;}

/* ===================================================================
   DRAFT: BOLD HERO + LEFT-TO-RIGHT HORIZONTAL SCROLL (wonjyou-inspired)
   Local experiment. Copy verbatim; this only changes layout + motion.
   =================================================================== */

/* ---- page becomes a horizontal scroller (nav stays fixed on top) ---- */
body.hx{overflow:hidden;height:100vh;height:100svh;overscroll-behavior:none;}
.htrack{
  position:relative;
  height:100vh;height:100svh;
  /* 2D path: an L-shape. Top row = hero + gap. Then the journey DROPS DOWN into
     merge and continues left->right along the bottom row. (desktop; mobile stacks below) */
  display:grid;
  grid-template-columns:repeat(4,100vw);
  grid-template-rows:repeat(4,100vh);
  /* native scroll ONLY on x (touch); y is JS-driven only — overflow-y:hidden stops
     the wheel's downward delta leaking a few px of native vertical scroll before a
     horizontal step. programmatic scrollTop still works under overflow-y:hidden. */
  overflow-x:auto;overflow-y:hidden;
  /* trackpad: stop horizontal overscroll from chaining to the browser's swipe-to-go-back
     gesture and from rubber-band bouncing at the first/last panel (both read as jitter) */
  overscroll-behavior:none;
  scrollbar-width:none;-ms-overflow-style:none;
  will-change:scroll-position;
  scroll-snap-type:x mandatory;
}
.htrack::-webkit-scrollbar{display:none;}

/* place each section on a STAIRCASE path: right, down, right, down, right, down */
.htrack > .hero--bold{grid-column:1;grid-row:1;}
.htrack > .feature--gap{grid-column:2;grid-row:1;}
.htrack > .merge{grid-column:2;grid-row:2;}   /* drop 1 — below the gap */
.htrack > .bio{grid-column:3;grid-row:2;}
.htrack > .whofor{grid-column:3;grid-row:3;}   /* drop 2 — below the bio */
.htrack > .alt{grid-column:4;grid-row:3;}
.htrack > .cta{grid-column:4;grid-row:4;}      /* drop 3 — below How it works */

/* each section FILLS the page — one section at a time, no bleed */
.htrack > section,
.htrack > footer{
  width:100vw;min-width:0;height:100vh;height:100svh;
  display:flex;align-items:center;
  padding:clamp(56px,7vh,96px) clamp(48px,6vw,110px) clamp(56px,7vh,96px) calc(var(--rail) + clamp(28px,3.5vw,64px));
  background:var(--paper);
  scroll-snap-align:start;scroll-snap-stop:always;
}
.htrack > section.alt{background:var(--paper-2);}
.htrack > section.cta,.htrack > footer{background:var(--dark);border-right:0;}
.htrack .frame{margin:0;max-width:none;width:auto;padding:0;}
.htrack .measure{max-width:clamp(420px,42vw,560px);}
.htrack .wide{max-width:clamp(560px,62vw,860px);}
.htrack section{padding-block:0;} /* override the base vertical section padding */
.htrack .statement{align-items:center;}
.htrack .statement .pq{max-width:18ch;}
.htrack .split{grid-template-columns:1.2fr .8fr;gap:var(--s5);}
.htrack .stats{margin-top:var(--s4);}

/* horizontal-scroll chrome */
/* (top progress bar retired — progress now lives in the left rail as .vprogress) */
/* floating scroll cue: JS adds .is-on per panel + sets data-dir to the next move */
.hcue{position:fixed;right:clamp(20px,2.2vw,34px);bottom:clamp(18px,2.6vh,32px);z-index:40;
  font-family:var(--sans);font-size:11px;font-weight:600;letter-spacing:.2em;text-transform:uppercase;
  color:var(--accent);display:inline-flex;align-items:center;gap:10px;   /* brass — client: the cue is a "quiet refinement" mark */
  pointer-events:none;opacity:0;transition:opacity .5s ease;}
.hcue.is-on{opacity:.72;}
.hcue__arrow{width:24px;height:24px;flex:none;border:1px solid currentColor;border-radius:50%;
  display:inline-flex;align-items:center;justify-content:center;position:relative;}
.hcue__arrow::after{content:"";width:6px;height:6px;
  border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;
  transform:rotate(-45deg);position:relative;left:-1px;}          /* chevron points RIGHT */
.hcue[data-dir="down"] .hcue__arrow::after{transform:rotate(45deg);left:0;top:-1px;}   /* points DOWN */
.hcue[data-dir="right"] .hcue__arrow{animation:hcueNudgeX 1.7s ease-in-out infinite;}
.hcue[data-dir="down"] .hcue__arrow{animation:hcueNudgeY 1.7s ease-in-out infinite;}
@keyframes hcueNudgeX{0%,100%{transform:translateX(0);}50%{transform:translateX(4px);}}
@keyframes hcueNudgeY{0%,100%{transform:translateY(0);}50%{transform:translateY(4px);}}
@media(prefers-reduced-motion:reduce){.hcue__arrow{animation:none!important;}}

/* ---- BOLD STATEMENT HERO — both headlines appear together on load ---- */
.hero--bold{width:100vw;min-width:100vw;padding:clamp(56px,7vh,96px) clamp(40px,6vw,110px) clamp(56px,7vh,96px) calc(var(--rail) + clamp(28px,3.5vw,64px));position:relative;overflow:hidden;
  display:flex;flex-direction:column;justify-content:flex-end;}  /* copy sits low so it clears the portrait's face */
.hero--bold .frame{position:relative;z-index:1;width:100%;padding-bottom:clamp(8px,3vh,34px);}
.hero__photo{display:none;}  /* desktop: no hero photo (mobile only) */

/* Filimon head + shoulders behind the hero copy — the colour "reveal" the gold
   preloader outline resolves into once the curtain lifts. Head + face at FULL
   opacity; from the shoulders down the mask fades him out. Shoulders span ~75%
   of the page. Sits above the emergence canvas, below the text. */
.hero__portrait{position:absolute;left:50%;top:4vh;z-index:0;transform:translateX(-50%);
  height:92vh;width:auto;aspect-ratio:3089/2703;pointer-events:none;
  /* NO background-color here. The portrait sits OVER the giant hero name — any opaque
     backdrop paints out the name (regression 2026-07-22: hid the name on mobile, showed as
     a plate on desktop). The cutout must stay transparent. Video-alpha failure is handled at
     runtime by the alpha probe in main.js, not by a CSS plate. Real-alpha PNG fallback via
     image-set() alongside the webp for browsers with unreliable webp alpha. */
  background-image:url("filimon-head.png?v=1");
  background-image:image-set(url("filimon-head.webp?v=2") type("image/webp"), url("filimon-head.png?v=1") type("image/png"));
  background-repeat:no-repeat;background-position:center top;background-size:contain;
  -webkit-mask-image:linear-gradient(to bottom,#000 0%,#000 60%,rgba(0,0,0,0) 97%);
  mask-image:linear-gradient(to bottom,#000 0%,#000 60%,rgba(0,0,0,0) 97%);
  opacity:0;transition:opacity 1.5s ease .2s;}
.intro-done .hero__portrait,.pre-done .hero__portrait{opacity:1;}
/* living portrait video: sits exactly over the static photo (same crop), inherits the
   container's shoulder-fade mask. Desktop only; static remains the poster/fallback. */
.hero__live{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;object-position:center top;}
/* the glance clip: hidden over the idle loop; crossfades in when the journey's first scroll fires */
.hero__live--look{opacity:0;transition:opacity .55s cubic-bezier(.33,0,.2,1);}
.hero__portrait.is-looking .hero__live--look{opacity:1;}
@media(max-width:680px),(prefers-reduced-motion:reduce){.hero__live{display:none;}}
/* line-art silhouette overlay: the SAME box + contain sizing as the photo, so when the
   load screen hands the outline off here it matches the portrait exactly at any viewport.
   Shown for a beat by the preloader's zoom-through, then faded out — never static. */
.hero__sketch{position:absolute;inset:0;z-index:3;pointer-events:none;opacity:0;
  background:url("fil-line.webp?v=6") center top/contain no-repeat;}
/* while the load screen runs, the portrait holds back so the silhouette lands on an EMPTY
   hero; the living video then fades in to REPLACE the line as it dissolves (pre-reveal is
   added at the handoff; pre-done covers every fallback path so the photo can never stay hidden) */
html.pre-on:not(.pre-reveal):not(.pre-done) .hero__portrait{opacity:0;}
/* legibility over the full-opacity face: soft paper halo behind the copy text only */
.hero--bold .hero__h2,.hero--bold .lead,.hero--bold .hero__above{text-shadow:0 1px 16px rgba(242,236,224,.85),0 1px 3px rgba(242,236,224,.9);}
@media(max-width:680px){
  /* mobile: head + shoulders large at the top, copy stacks below; fits viewport.
     styles2 forces .hero--bold > * to position:relative, so the portrait is an
     in-flow flex item here — centre it with align-self, not left/translate. */
  .hero__portrait{left:auto;top:0;transform:none;align-self:center;
    width:min(112vw,520px);height:auto;aspect-ratio:3089/2703;
    -webkit-mask-image:linear-gradient(to bottom,#000 0%,#000 54%,rgba(0,0,0,0) 92%);
    mask-image:linear-gradient(to bottom,#000 0%,#000 54%,rgba(0,0,0,0) 92%);}
  .intro-done .hero__portrait,.pre-done .hero__portrait{opacity:1;transform:none;}
}

.hero__heads{display:grid;grid-template-columns:1fr 1fr;gap:clamp(32px,5vw,80px);align-items:center;}
/* desktop: the name is GIANT and stacked BEHIND the portrait — top of the screen down
   to his shoulders (Archivo 900, the site display face). The portrait sits over it,
   the copy over both. Client-approved from the name-behind draft. */
@media(min-width:901px){
  .hero--bold .hero__name{position:absolute;left:calc(50% + var(--rail)/2);top:1vh;transform:translateX(-50%);z-index:1;
    display:flex;flex-direction:column;align-items:center;pointer-events:none;white-space:nowrap;
    /* centred in the CONTENT area (right of the rail); sized off the available width so
       FILIPPOU always keeps an even margin both sides (4.71em wide at Archivo 900) */
    font-size:min(calc((100vw - var(--rail))/5.35),33vh);line-height:.84;letter-spacing:-0.015em;}
  .hero--bold .hero__name span{display:block;}
  .hero--bold .hero__portrait{z-index:2;}
  .hero--bold .frame{z-index:3;}
  /* THE STATEMENT — a bold bottom band, part of the poster system: the line set
     huge in Archivo 900 uppercase (echoing the giant name), lead + CTA composed
     as a right-hand column, everything anchored across the bottom of the hero. */
  .hero--bold .hero__heads{display:grid;grid-template-areas:"h2 more";
    grid-template-columns:1.55fr 1fr;column-gap:clamp(36px,4.5vw,84px);align-items:end;}
  .hero--bold .hero__col1{display:none;}
  .hero--bold .hero__col2{display:contents;}
  .hero--bold .hero__h2{grid-area:h2;}
  .hero--bold .hero__more{grid-area:more;}
  /* eyebrow anchored to the NAME: sits just under the giant letters on clear paper,
     right-aligned to the hero's padding — independent of the bottom band's height */
  .hero--bold > .hero__above{position:absolute;z-index:3;right:clamp(40px,6vw,110px);margin:0;
    top:calc(1vh + 1.68*min(calc((100vw - var(--rail))/5.35),33vh) + 3vh);}
  .hero--bold .hero__h2{font-weight:900;text-transform:uppercase;
    font-size:clamp(2.3rem,3.8vw,3.9rem);line-height:.95;letter-spacing:-0.015em;max-width:15ch;margin:0;}
  .hero--bold .hero__more{align-self:end;}
  .hero--bold .lead{font-size:clamp(1rem,1.25vw,1.18rem);margin-top:0;}
}
@media(max-width:900px){.hero__heads{grid-template-columns:1fr;gap:var(--s4);align-items:start;}}

/* LEFT: the practice descriptor (smaller, brass) above the name (big, ink) */
.hero__above{font-family:var(--sans);font-weight:600;font-size:12px;line-height:1.4;text-transform:uppercase;
  letter-spacing:0.2em;color:var(--accent);margin:0 0 clamp(12px,1.6vh,20px);max-width:none;}
.hero__name{font-family:var(--serif);font-weight:900;text-transform:uppercase;font-size:clamp(2.6rem,5.6vw,5.6rem);line-height:.98;
  letter-spacing:-0.01em;color:var(--ink);margin:0;}

/* RIGHT: the hook (ink) + the lead/CTA under it */
.hero__h2{font-family:var(--serif);font-weight:800;font-size:clamp(2rem,4.4vw,4.3rem);line-height:1.02;
  letter-spacing:-0.02em;color:var(--ink);margin:0;max-width:15ch;}

/* lead + CTA appear shortly after the headlines (both headlines reveal together via [data-split] on load) */
.hero__more{margin-top:clamp(32px,6vh,80px);opacity:0;transform:translateY(20px);
  transition:opacity .95s ease,transform .95s cubic-bezier(.16,1,.3,1);}
.js.ready .hero__more{opacity:1;transform:none;transition-delay:1s;}
.hero__more .lead{font-size:clamp(1.15rem,1.7vw,1.5rem);max-width:46ch;margin:0;}
.hero__more .hero__cta{margin-top:clamp(24px,3vw,40px);display:flex;align-items:center;gap:clamp(16px,2vw,28px);flex-wrap:wrap;}
/* scroll-path hint next to the CTA — shows the journey shape: right, then down.
   A dot travels the L-path (across, pause at the turn, then down) so the reader sees
   the navigation goes left->right then drops down, without the word "swipe". */
.pathhint{display:inline-flex;align-items:center;gap:11px;color:var(--ink-2);
  font-family:var(--sans);font-size:12px;font-weight:600;letter-spacing:.18em;text-transform:uppercase;}
.hero__scroll{display:none;}  /* mobile-only scroll cue (shown in @media max-width:680px); hidden on desktop so the locked desktop render is unchanged */
.pathhint__svg{width:48px;height:26px;flex:none;overflow:visible;color:var(--accent);}  /* brass scroll arrow/dot */
.pathhint__line{opacity:.30;}
.pathhint__arrow{opacity:.55;}
.pathhint__dot{fill:var(--accent);offset-path:path("M4 6 H34 V17");offset-distance:0%;
  animation:pathTravel 2.6s cubic-bezier(.55,0,.45,1) infinite;}
@keyframes pathTravel{
  0%{offset-distance:0%;opacity:0;}
  10%{opacity:1;}
  46%{offset-distance:71%;}   /* along the top, reaching the turn */
  56%{offset-distance:71%;}   /* brief pause at the corner (direction change reads) */
  90%{opacity:1;}
  100%{offset-distance:100%;opacity:0;}
}
@media(prefers-reduced-motion: reduce){.pathhint__dot{animation:none;offset-distance:100%;opacity:.7;}}

/* no-JS fallback */
html:not(.js) .hero__more{opacity:1;transform:none;}

/* ---- HERO INTRO: giant centred name on load -> shrinks to its spot, the rest fades in ---- */
/* during intro the name is JS-positioned (giant, centred); the descriptor + right column wait */
.js .hero__name{opacity:0;will-change:transform;backface-visibility:hidden;}
.js .hero--bold .hero__above,
.js .hero--bold .hero__col2{opacity:0;transform:translateY(42px);}
.hero--bold.hero--settled .hero__above{opacity:1;transform:none;
  transition:opacity .9s cubic-bezier(.16,1,.3,1) .35s,transform .9s cubic-bezier(.16,1,.3,1) .35s;}
.hero--bold.hero--settled .hero__col2{opacity:1;transform:none;
  transition:opacity 1s cubic-bezier(.16,1,.3,1) .55s,transform 1s cubic-bezier(.16,1,.3,1) .55s;}
/* if JS never runs / reduced motion handled in JS, show everything */
html:not(.js) .hero__name,
html:not(.js) .hero__above,
html:not(.js) .hero__col2{opacity:1;}

/* left rail waits out the giant-name intro, then fades in with the rest */
.js .railnav{opacity:0;}
.js.intro-done .railnav{opacity:1;}
html:not(.js) .railnav{opacity:1;}

/* mobile: horizontal scroll is awkward; the experiment is desktop-first. Native touch swipe still works.
   The left rail collapses to a slim top bar so it doesn't eat the narrow screen. */

/* ---- FEATURED PANEL (wonjyou composition): statement headline + copy placed around it ---- */
.feature{width:100vw;min-width:100vw;height:100%;display:flex;align-items:stretch;
  padding:clamp(56px,7vh,96px) clamp(48px,6vw,110px) clamp(56px,7vh,96px) calc(var(--rail) + clamp(28px,3.5vw,64px));background:var(--paper-2);}
.feature__in{width:100%;display:grid;column-gap:clamp(48px,6vw,120px);
  grid-template-columns:1fr 1fr;align-items:center;grid-template-areas:"kicker body";}
/* the gap STATEMENT is the big LEFT headline (leads the section, per the document) */
.feature__kicker{grid-area:kicker;align-self:center;margin:0;font-family:var(--serif);font-weight:700;
  font-size:clamp(1.7rem,3.4vw,3.3rem);line-height:1.1;letter-spacing:-0.02em;text-transform:none;
  color:var(--ink);max-width:17ch;}
/* "You've tried the logical fixes." + copy + points sit on the right half */
.feature__body{grid-area:body;align-self:center;max-width:660px;}
.feature__headline{margin:0;font-family:var(--serif);font-weight:700;font-size:clamp(1.8rem,3.2vw,3.1rem);
  line-height:1.06;letter-spacing:-0.02em;color:var(--accent-deep);max-width:20ch;}
/* copy is the 3rd reveal: collapsed until the 3rd scroll (stage 2) */
.feature__copy{margin-top:0;max-height:0;overflow:hidden;opacity:0;display:grid;gap:var(--s3);max-width:48ch;
  transition:max-height .85s cubic-bezier(.16,1,.3,1),opacity .6s ease,margin-top .6s ease;}
.feature--gap[data-stage="2"] .feature__copy,
.feature--gap[data-stage="3"] .feature__copy{max-height:60vh;opacity:1;margin-top:clamp(18px,2.6vh,34px);}
html:not(.js) .feature__copy{max-height:none;opacity:1;margin-top:clamp(18px,2.6vh,34px);}
.feature__copy p{margin:0;color:var(--ink-2);font-size:clamp(1.08rem,1.2vw,1.22rem);line-height:1.64;}
/* closing pull-quote: reveals with the copy on stage 2, sits under it */
.feature__pq{margin:0;max-height:0;overflow:hidden;opacity:0;max-width:22ch;color:var(--ink);
  font-size:clamp(1.35rem,2.1vw,2rem);line-height:1.22;
  transition:max-height .85s cubic-bezier(.16,1,.3,1),opacity .6s ease,margin-top .6s ease;}
.feature--gap[data-stage="2"] .feature__pq{max-height:30vh;opacity:1;margin-top:clamp(20px,3vh,38px);}
html:not(.js) .feature__pq{max-height:none;opacity:1;margin-top:clamp(20px,3vh,38px);}
/* points are the 2nd reveal: collapsed until the 2nd scroll, then open + flip down (stay open at stage 2) */
.feature__points{margin-top:0;max-height:0;overflow:hidden;perspective:1000px;list-style:none;padding:0;
  transition:max-height .85s cubic-bezier(.16,1,.3,1),margin-top .6s ease,margin-bottom .6s ease;margin-bottom:0;}
.feature--gap[data-stage="1"] .feature__points,
.feature--gap[data-stage="2"] .feature__points,
.feature--gap[data-stage="3"] .feature__points{max-height:46vh;margin-top:clamp(18px,2.6vh,34px);margin-bottom:clamp(20px,2.8vh,36px);}
html:not(.js) .feature__points{max-height:none;margin-top:clamp(18px,2.6vh,34px);margin-bottom:clamp(20px,2.8vh,36px);}
.feature__points .fold{display:flex;align-items:baseline;gap:.5em;font-family:var(--serif);font-weight:600;line-height:1.18;
  font-size:clamp(1.4rem,2.2vw,2.1rem);color:var(--ink);transform-origin:top center;
  transform:rotateX(-92deg);opacity:0;
  transition:transform .85s cubic-bezier(.2,.72,.2,1),opacity .5s ease;
  transition-delay:calc(.05s + var(--i,0)*.22s);}
.feature__points .fold::before{content:"";flex:none;width:.32em;height:.32em;border-radius:50%;
  background:var(--accent);transform:translateY(-.18em);}
/* flip down from the SECOND scroll on (stays flipped through stage 3) */
.feature--gap[data-stage="1"] .feature__points .fold,
.feature--gap[data-stage="2"] .feature__points .fold,
.feature--gap[data-stage="3"] .feature__points .fold{transform:rotateX(0);opacity:1;}

/* feature entrance: the left statement (kicker) settles in on reveal */
.feature__in.reveal .feature__kicker{opacity:0;transform:translateY(22px);
  transition:opacity .9s ease,transform .9s cubic-bezier(.16,1,.3,1);}
.feature__in.reveal.in .feature__kicker{opacity:1;transform:none;transition-delay:.05s;}

/* feature headline: same word-by-word appear as the hero (fade + rise + unblur), triggered when the panel enters view */
.feature__headline .w{display:inline-block;opacity:0;transform:translateY(.5em);filter:blur(8px);
  transition:opacity .8s ease,transform .9s cubic-bezier(.16,.8,.24,1),filter .8s ease;
  transition-delay:calc(.12s + var(--i,0)*.05s);}
.feature__in.in .feature__headline .w{opacity:1;transform:none;filter:none;}

html:not(.js) .feature__points .fold{transform:none;opacity:1;}
@media(max-width:740px){
  .feature__in{grid-template-columns:1fr;grid-template-areas:"kicker" "body";row-gap:var(--s4);align-items:start;}
  .feature__points{justify-self:start;text-align:left;}
}

