/* =========================================================
   ALABASTER BOOKKEEPING — site.css
   ========================================================= */

/* ---------- tokens ---------- */
:root{
  /* Stone, not black. Every dark surface is the brown from the Home comp —
     #251E18 is the texture's mid tone, #17120C its shadow. Sampled from
     "New Design Assets/background.png" and "words.png". */
  --ink:        #2A211A;   /* buttons, rules, anything that used to be black */
  --ink-2:      #251E18;
  --ink-soft:   #3A2E24;

  /* Paper is the off-white from the lower half of the logo sheet (#FDFCFB).
     The accent is the light alabaster the live site already used as its
     ground — a near-neutral taupe, deliberately NOT a warm beige: at any real
     saturation it goes orange against the brown and pulls the whole page with
     it. --panel sits a step under the swatch so a panel still reads as a panel
     against --paper. */
  --paper:      #FDFCFB;
  --paper-2:    #FBFAF7;
  --panel:      #F0EEE7;   /* alabaster accent panel */
  --panel-2:    #F8F7F3;

  /* alabaster ↔ brown accent ramp */
  --taupe:      #E7E4DA;
  --taupe-soft: #F1EFE8;
  --taupe-deep: #BEB7A7;
  --brown:      #6B5644;
  --brown-2:    #8B7259;

  --text:       #241C15;
  --text-2:     #55483C;
  --text-3:     #877766;
  --on-dark:    #F5F3EF;
  --on-dark-2:  rgba(245,243,239,.74);
  --on-dark-3:  rgba(233,229,219,.60);   /* alabaster, not beige, on the stone */

  --line:       rgba(59,45,33,.16);
  --line-soft:  rgba(59,45,33,.09);
  --line-dark:  rgba(233,229,219,.20);

  /* type */
  /* the display voice is the wordmark's: Cormorant caps, widely tracked */
  --f-display: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  --f-head:    "Jost", "Archivo", Helvetica, Arial, sans-serif;
  --f-serif:   "Cormorant Garamond", Georgia, "Times New Roman", serif;
  --f-body:    "Archivo", "Helvetica Neue", Arial, sans-serif;

  /* rhythm */
  --gut: clamp(20px, 5vw, 72px);
  --maxw: 1240px;
  --sect-y: clamp(88px, 11vw, 170px);

  /* motion */
  --e-out:  cubic-bezier(.16,.84,.30,1);
  --e-soft: cubic-bezier(.22,.61,.36,1);
  --spring: cubic-bezier(.34,1.32,.44,1);

  /* aurora tint, animated by JS */
  --a1: 252 250 247;
  --a2: 253 252 251;
  --a3: 249 244 236;

  /* One dark treatment shared by hero / band / footer / page header: the stone
     photograph, warmed by a wide radial and closed with a vignette. The
     gradients are what give a 900px hero and a 390px band the same material —
     the texture underneath is identical, only the crop differs. */
  --dark-vignette: radial-gradient(1500px 900px at 50% 42%, transparent 0%, transparent 44%, rgba(12,8,4,.42) 100%);
  --dark-light:    radial-gradient(1600px 1000px at 32% 6%, rgba(74,58,44,.62) 0%, rgba(45,35,27,.42) 34%, rgba(23,18,12,.52) 64%, rgba(19,14,9,.7) 100%);
  --dark-tex:      url("../stone.webp");
  --dark-base:     #17120C;
  --dark-surface:  var(--dark-vignette), var(--dark-light), var(--dark-tex) center/cover no-repeat, var(--dark-base);

  --nav-h: 76px;
}

/* ---------- reset ---------- */
*,*::before,*::after{ box-sizing:border-box; }
html{ -webkit-text-size-adjust:100%; scroll-behavior:smooth; }
body{
  margin:0;
  background:var(--paper);
  color:var(--text);
  font-family:var(--f-body);
  font-size:17.5px; line-height:1.68;
  font-weight:400;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;
  text-rendering:optimizeLegibility;
}
img,svg{ display:block; max-width:100%; }
img{ height:auto; }
a{ color:inherit; }
h1,h2,h3,h4,p,figure,ul,ol{ margin:0; }
ul,ol{ list-style:none; padding:0; }
button{ font:inherit; color:inherit; background:none; border:0; cursor:pointer; }
:focus-visible{ outline:2px solid currentColor; outline-offset:4px; border-radius:2px; }
::selection{ background:var(--ink); color:var(--paper); }

.skip{
  position:fixed; top:8px; left:8px; z-index:999;
  padding:10px 16px; background:var(--ink); color:var(--paper);
  transform:translateY(-160%); transition:transform .2s var(--e-out);
  font-size:13px; letter-spacing:.06em; text-transform:uppercase; text-decoration:none;
}
.skip:focus{ transform:none; }

/* =========================================================
   AMBIENT — continuous flowing background
   ========================================================= */
/* Clipped to the stage's exact bounds — the backdrop can never paint over the
   footer, whatever the stacking context does. overflow:clip does not create a
   scroll container, so the sticky child still tracks the viewport. */
.stage__bg{
  position:absolute; inset:0; z-index:-1;
  overflow:clip; pointer-events:none;
}
.aurora{
  position:sticky; top:0;
  height:100svh;
  overflow:hidden;
  pointer-events:none;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)' opacity='.11'/%3E%3C/svg%3E"),
    linear-gradient(180deg,
      rgb(var(--a2)) 0%,
      rgb(var(--a1)) 45%,
      rgb(var(--a3)) 100%);
  transition:background 1.1s linear;
  will-change:background;
}
.blob{
  position:absolute; display:block; border-radius:50%;
  filter:blur(90px);
  opacity:.5;
  will-change:transform;
}
.b1{ width:62vw; height:62vw; left:-14vw; top:4vh;
     background:radial-gradient(circle at 40% 40%, rgba(255,255,254,1), rgba(255,255,254,0) 68%);
     animation:drift1 46s ease-in-out infinite alternate; }
.b2{ width:52vw; height:52vw; right:-12vw; top:26vh;
     background:radial-gradient(circle at 50% 50%, rgba(240,238,231,.75), rgba(240,238,231,0) 70%);
     animation:drift2 58s ease-in-out infinite alternate; }
.b3{ width:70vw; height:56vw; left:12vw; top:62vh;
     background:radial-gradient(circle at 50% 50%, rgba(255,254,252,.95), rgba(255,254,252,0) 70%);
     animation:drift3 68s ease-in-out infinite alternate; }
.b4{ width:44vw; height:44vw; right:6vw; top:82vh;
     background:radial-gradient(circle at 50% 50%, rgba(231,228,218,.7), rgba(231,228,218,0) 70%);
     animation:drift1 52s ease-in-out infinite alternate-reverse; }

@keyframes drift1{ from{ transform:translate3d(0,0,0) scale(1);}   to{ transform:translate3d(7vw,-6vh,0) scale(1.18);} }
@keyframes drift2{ from{ transform:translate3d(0,0,0) scale(1.1);} to{ transform:translate3d(-8vw,7vh,0) scale(.92);} }
@keyframes drift3{ from{ transform:translate3d(0,0,0) scale(.95);} to{ transform:translate3d(5vw,-9vh,0) scale(1.15);} }

/* Paper grain lives behind content on each surface. It used to be a fixed
   mix-blend-mode layer over every pixel, which forces a whole-page composite
   and dulls the type. */
.grain{ display:none; }

/* thin scroll progress rail */
.scroll-rail{
  position:fixed; top:0; left:0; right:0; height:2px; z-index:60; pointer-events:none;
}
.scroll-rail i{
  display:block; height:100%; width:100%;
  transform:scaleX(var(--sp,0)); transform-origin:0 50%;
  background:linear-gradient(90deg, rgba(107,86,68,.30), rgba(42,33,26,.85));
  transition:transform .08s linear;
}

/* =========================================================
   NAV
   ========================================================= */
.nav{
  position:fixed; top:0; left:0; right:0; z-index:50;
  height:var(--nav-h);
  transition:background .5s var(--e-soft), backdrop-filter .5s, border-color .5s, transform .45s var(--e-out);
  border-bottom:1px solid transparent;
}
.nav__in{
  max-width:var(--maxw); height:100%; margin:0 auto; padding:0 var(--gut);
  display:flex; align-items:center; gap:clamp(16px,3vw,40px);
}
.nav.is-stuck{
  background:rgba(253,252,251,.86);
  backdrop-filter:saturate(160%) blur(14px);
  -webkit-backdrop-filter:saturate(160%) blur(14px);
  border-bottom-color:var(--line-soft);
}
.nav.is-hidden{ transform:translateY(-101%); }

/* The lockup from the comp: the alabaster vessel beside a two-line wordmark.
   The mark is the cut-out photograph, so it can't take a colour — on the light
   bar it only needs to lose the drop shadow it carries against the stone. */
.brand{
  display:flex; align-items:center; gap:clamp(9px,1vw,13px);
  text-decoration:none; margin-right:auto;
}
.brand__mark{
  width:clamp(20px,1.9vw,25px); flex:none;
  filter:drop-shadow(0 2px 6px rgba(0,0,0,.5));
  transition:filter .5s;
}
.brand__mark img{ width:100%; height:auto; }
.nav.is-stuck .brand__mark{ filter:none; }
.brand__word{
  display:grid; gap:2px;
  font-family:var(--f-serif); font-weight:400;
  color:var(--on-dark); transition:color .5s; white-space:nowrap;
}
.brand__word b{
  font-weight:400; font-size:clamp(15px,1.5vw,18px);
  letter-spacing:.20em; text-transform:uppercase; line-height:1;
}
.brand__word i{
  font-style:normal; font-size:clamp(7.5px,.72vw,8.6px);
  letter-spacing:.42em; text-transform:uppercase; line-height:1;
  padding-left:.16em;   /* optical: the wide tracking pushes the row right */
  opacity:.86;
}
.nav.is-stuck .brand__word{ color:var(--text); }

.nav__links{ display:flex; gap:clamp(14px,2vw,30px); }
.nav__links a{
  position:relative; text-decoration:none;
  font-size:14.5px; letter-spacing:.04em; font-weight:500;
  color:var(--on-dark-2); transition:color .35s;
  padding:6px 0;
}
.nav__links a::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:1px;
  background:currentColor; transform:scaleX(0); transform-origin:100% 50%;
  transition:transform .4s var(--e-out);
}
.nav__links a:hover::after,
.nav__links a.is-active::after{ transform:scaleX(1); transform-origin:0 50%; }
.nav__links a:hover{ color:var(--on-dark); }
.nav.is-stuck .nav__links a{ color:var(--text-2); }
.nav.is-stuck .nav__links a:hover,
.nav.is-stuck .nav__links a.is-active{ color:var(--text); }

.burger{ display:none; width:44px; height:44px; align-items:center; justify-content:center; flex-direction:column; gap:5px; }
.burger span{ display:block; width:22px; height:1.5px; background:var(--on-dark); transition:transform .35s var(--e-out), opacity .25s, background .5s; }
.nav.is-stuck .burger span{ background:var(--text); }
.burger[aria-expanded="true"] span:first-child{ transform:translateY(3.25px) rotate(45deg); }
.burger[aria-expanded="true"] span:last-child{ transform:translateY(-3.25px) rotate(-45deg); }

.mobile-menu{
  position:fixed; inset:var(--nav-h) 0 auto 0; z-index:49;
  background:rgba(253,252,251,.98);
  backdrop-filter:blur(18px); -webkit-backdrop-filter:blur(18px);
  border-bottom:1px solid var(--line-soft);
  padding:22px var(--gut) 30px;
  display:grid; gap:18px;
  animation:menuIn .4s var(--e-out) both;
}
.mobile-menu[hidden]{ display:none; }
.mobile-menu nav{ display:grid; gap:2px; }
/* scoped to the link list — an unscoped .mobile-menu a also beat .btn on
   specificity and painted the CTA's label in the link colour, i.e. near-black
   text on the near-black button */
.mobile-menu nav a{
  text-decoration:none; font-family:var(--f-head); font-weight:300;
  font-size:24px; padding:10px 0; color:var(--text);
  border-bottom:1px solid var(--line-soft);
}
.mobile-menu .btn{ justify-self:start; }
@keyframes menuIn{ from{ opacity:0; transform:translateY(-10px);} to{ opacity:1; transform:none;} }

/* =========================================================
   BUTTONS
   ========================================================= */
.btn{
  --bg:var(--ink); --fg:var(--paper); --bd:var(--ink);
  position:relative; display:inline-flex; align-items:center; justify-content:center;
  min-height:56px; padding:16px 30px;
  font-family:var(--f-body); font-size:13.5px; font-weight:700;
  letter-spacing:.13em; text-transform:uppercase; text-decoration:none; text-align:center;
  color:var(--fg); background:var(--bg);
  border:1px solid var(--bd);
  isolation:isolate; overflow:hidden;
  cursor:pointer;
  transition:color .45s var(--e-soft), border-color .45s, transform .5s var(--spring), box-shadow .5s var(--e-out);
  will-change:transform;
}
.btn > span{ position:relative; z-index:2; }
.btn::before{
  content:""; position:absolute; inset:0; z-index:1;
  background:var(--fg);
  transform:translateY(101%);
  transition:transform .55s var(--e-out);
}
.btn:hover::before,.btn:focus-visible::before{ transform:translateY(0); }
.btn:hover,.btn:focus-visible{ color:var(--bg); box-shadow:0 18px 40px -22px rgba(42,33,26,.55); }
.btn:active{ transform:scale(.975); }

.btn--light{ --bg:var(--paper); --fg:var(--ink); --bd:var(--paper); }
.btn--dark{  --bg:transparent; --fg:var(--ink); --bd:var(--ink); color:var(--ink); }
.btn--dark::before{ background:var(--ink); }
.btn--dark:hover,.btn--dark:focus-visible{ color:var(--paper); }
.btn--sm{ min-height:44px; padding:12px 20px; font-size:11px; letter-spacing:.11em; }
.nav__cta{ --bg:transparent; --fg:var(--on-dark); --bd:var(--on-dark-3); color:var(--on-dark); }
.nav__cta::before{ background:var(--on-dark); }
.nav__cta:hover{ color:var(--ink); }
.nav.is-stuck .nav__cta{ --fg:var(--ink); --bd:var(--line); color:var(--text); }
.nav.is-stuck .nav__cta::before{ background:var(--ink); }
.nav.is-stuck .nav__cta:hover{ color:var(--paper); }

/* =========================================================
   TYPE SCALE
   ========================================================= */
.eyebrow{
  font-size:12.5px; font-weight:600; letter-spacing:.22em; text-transform:uppercase;
  color:var(--brown-2); margin-bottom:20px;
}
.h2{
  font-family:var(--f-head); font-weight:300;
  font-size:clamp(36px,5vw,66px); line-height:1.08; letter-spacing:-.016em;
  color:var(--text); text-wrap:balance;
}
.h2--center{ text-align:center; margin-inline:auto; max-width:20ch; }
.sect--process .h2--center{ max-width:15ch; }
.h2--light{ color:var(--on-dark); }
.sub{ font-size:clamp(16.5px,1.65vw,19.5px); color:var(--text-2); max-width:62ch; }
.sub--center{ text-align:center; margin:20px auto 0; text-wrap:balance; }
.lede{ font-size:clamp(16.5px,1.55vw,19.5px); line-height:1.75; color:var(--text-2); }

/* =========================================================
   LAYOUT / SECTION FLOW
   ========================================================= */
.wrap{ max-width:var(--maxw); margin:0 auto; padding-inline:var(--gut); position:relative; z-index:2; }
.wrap--narrow{ max-width:900px; }

.stage{ position:relative; z-index:2; isolation:isolate; }

.sect,.band,.foot{ scroll-margin-top:calc(var(--nav-h) + 8px); }
.sect{
  position:relative;
  padding-block:var(--sect-y);
  background:transparent;
}
/* the "shelf": a long, soft bridge so one section melts into the next */
.seam{
  position:absolute; left:0; right:0; top:-140px; height:400px; pointer-events:none;
  background:linear-gradient(180deg,
    rgba(255,255,255,0) 0%,
    rgba(255,255,255,.34) 34%,
    rgba(255,255,255,.20) 62%,
    rgba(255,255,255,0) 100%);
  z-index:0;
}
/* flat warm panel — the old feathered gradient read as a dirty wash rather than
   a deliberate edge, so the section is a single solid tone */
.sect--about{
  background:var(--panel);
  padding-block:0;
}
.sect--about .seam{ display:none; }
/* Hero → services is a clean hard edge, as in the Canva comp. The stage is an
   opaque plane, so all it needs is the shadow it casts back onto the hero to
   read as a layer sliding over rather than an accidental seam. */
.sect--services .seam{ display:none; }
/* A seam starts 140px above its own section, so after a dark band it washes
   white over the band's lower third — the same haze the hero used to have.
   Dark → light is always a deliberate hard edge. */
.band + .sect .seam,
.foot + .sect .seam,
.sect--process + .sect .seam,
.pagehead + .stage .sect:first-of-type .seam{ display:none; }
.stage{ box-shadow:0 -30px 55px -22px rgba(23,18,12,.45); }

.sect--included{ padding-bottom:clamp(70px,8vw,120px); }

/* =========================================================
   HERO
   ========================================================= */
.hero{
  position:sticky; top:0; z-index:0;
  /* deliberately short of a full viewport: a true 100svh hero read as dead
     space on a laptop before the first section arrived */
  min-height:min(88svh,820px); height:min(88svh,820px);
  display:flex; flex-direction:column; justify-content:center;
  /* reserve the nav (top) and marquee (bottom) so the centred block never
     collides with either */
  padding:calc(var(--nav-h) + clamp(8px,2vh,24px)) 0 clamp(72px,10vh,104px);
  overflow:hidden;
  /* same wide, shallow treatment as the CTA band — dimension, no spotlight */
  background:var(--dark-surface);
  color:var(--on-dark);
  --hp:0; /* scroll progress 0→1, set by JS */
}
.hero__bg{ position:absolute; inset:0; z-index:0; pointer-events:none; }

/* Slow pan light — wide and shallow, matching the CTA band. No linear overlay
   anywhere in the hero; the hero→services transition is handled by the dark
   gradient at the top of the services section instead. */
.hero__glow{
  position:absolute; width:150vmax; height:150vmax; right:-45vmax; top:50%;
  margin-top:-75vmax;
  background:
    radial-gradient(circle at 50% 50%, rgba(255,250,238,.055) 0%, rgba(255,250,238,.02) 40%, rgba(255,250,238,0) 68%);
  animation:heroPan 34s ease-in-out infinite alternate;
  will-change:transform;
}
@keyframes heroPan{
  0%   { transform:translate3d(-3%, -4%, 0) scale(1);    }
  50%  { transform:translate3d( 4%,  3%, 0) scale(1.08); }
  100% { transform:translate3d( 7%, -2%, 0) scale(1.02); }
}

/* The title-card composition from the comp: the wordmark set large and centred
   in the open half of the frame, the alabaster vessel standing at the right.
   Two columns rather than a free-floating absolute jar, so the type recentres
   itself as the vessel shrinks on narrower screens. */
.hero__in{
  position:relative; z-index:2;
  max-width:var(--maxw); width:100%; margin:0 auto; padding:0 var(--gut);
  display:grid; grid-template-columns:minmax(0,1fr) auto;
  align-items:center; gap:clamp(16px,3vw,56px);
  /* scroll takeover: hero recedes as next section rises */
  transform:translate3d(0, calc(var(--hp) * -7vh), 0) scale(calc(1 - var(--hp) * .06));
  opacity:calc(1 - var(--hp) * .95);
  filter:blur(calc(var(--hp) * 5px));
  will-change:transform,opacity,filter;
}
.hero__copy{
  display:flex; flex-direction:column; align-items:center;
  gap:clamp(20px,3.4vh,40px); text-align:center; min-width:0;
}

/* Cormorant, light and widely tracked — the comp's letterform, not the old
   Archivo slab. line-height 1.14 is what keeps two lines this large from
   locking together. */
.hero__title{
  font-family:var(--f-serif); font-weight:300;
  font-size:clamp(31px,7.4vw,93px); line-height:1.14;
  letter-spacing:.075em; text-transform:uppercase;
  color:var(--on-dark);
  margin:0; width:100%;
  /* the tracking hangs off the last letter; pull the block back into centre */
  text-indent:.075em;
}
.hero__title .line{ display:block; overflow:hidden; padding-bottom:.04em; }
.hero__title .line__i{
  display:block;
  transform:translateY(105%);
  opacity:0;
  animation:lineUp 1.2s var(--e-out) forwards;
  animation-delay:var(--d,0s);
  will-change:transform,opacity;
}
@keyframes lineUp{ to{ transform:none; opacity:1; } }
@keyframes heroFade{ to{ opacity:1; } }

/* "practical bookkeeping for small businesses" — Jost, lowercase, with the
   "for" dropped into Cormorant italic exactly as the comp sets it */
.hero__sub{
  font-family:var(--f-head); font-weight:300;
  font-size:clamp(14px,2.55vw,37px); line-height:1.35;
  letter-spacing:.005em; color:var(--on-dark);
  max-width:none; text-wrap:balance;
}
.hero__sub em{
  font-family:var(--f-serif); font-style:italic; font-weight:400;
  font-size:1.02em; letter-spacing:0; padding:0 .06em;
}

.hero__actions{
  display:flex; align-items:center; justify-content:center;
  gap:clamp(16px,2.2vw,28px); flex-wrap:wrap;
}
/* quiet outline button — the comp carries no CTA, so this stays subordinate to
   the wordmark rather than competing with it */
.btn--hero{
  --bg:transparent; --fg:var(--on-dark); --bd:rgba(233,229,219,.42);
  color:var(--on-dark);
}
.btn--hero::before{ background:var(--on-dark); }
.btn--hero:hover,.btn--hero:focus-visible{ color:var(--ink-2); }

.hero__jar{
  margin:0; position:relative; align-self:center;
  width:clamp(92px,14.3vw,198px);
  opacity:0; animation:heroFade 1.4s var(--e-out) .5s forwards;
}
.hero__jar img{ width:100%; height:auto; }

/* ---- credentials ----
   The continuous film-strip loop now runs at EVERY width. It used to switch on
   only below 940, where five items could no longer share a row; above that the
   five sat still and evenly spread. The strip runs edge to edge with both ends
   feathered, so there is no hard cut where an item enters or leaves. */
.hero__creds{
  position:absolute; left:0; right:0; bottom:0; z-index:3;
  padding:clamp(16px,2.2vh,24px) 0 calc(clamp(18px,2.6vh,28px) + env(safe-area-inset-bottom));
  overflow:hidden;
  opacity:calc(1 - var(--hp) * 1.4);
  animation:credIn 1s var(--e-out) .7s both;
  -webkit-mask-image:linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
          mask-image:linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
}
@keyframes credIn{ from{ opacity:0; } to{ opacity:1; } }

.creds__viewport{
  display:flex;
  width:max-content; max-width:none; margin:0 auto;
}
/* all three tracks are identical; the loop translates each by exactly its own
   width, so track 2 lands where track 1 started and the seam never shows */
.creds__track{
  display:flex; align-items:center;
  flex:none; justify-content:flex-start; gap:0;
  animation:credsRoll 42s linear infinite;
  will-change:transform;
}
.creds__track li{
  display:flex; align-items:center; flex:none;
  padding:0 clamp(22px,3vw,46px);
  font-size:clamp(9.5px,.86vw,11.5px); font-weight:600;
  letter-spacing:.16em; text-transform:uppercase;
  color:var(--on-dark-3); white-space:nowrap;
}
/* the dot between items; the negative margin pulls the next item's own padding
   back so the gap either side of the dot stays even */
.creds__track li::after{
  content:""; width:3px; height:3px; border-radius:50%;
  background:currentColor; opacity:.55;
  margin-left:clamp(22px,3vw,46px); margin-right:calc(clamp(22px,3vw,46px) * -1);
}
.hero__creds:hover .creds__track{ animation-play-state:paused; }
@keyframes credsRoll{ from{ transform:translate3d(0,0,0); } to{ transform:translate3d(-100%,0,0); } }

/* =========================================================
   SERVICES
   ========================================================= */
.services{
  display:grid; grid-template-columns:minmax(0,.86fr) minmax(0,1.55fr);
  gap:clamp(32px,5vw,80px); align-items:start;
}
.services__lede{ position:sticky; top:calc(var(--nav-h) + 40px); }
.services__lede .h2{ margin-bottom:34px; }
.services__lede .lede + .lede{ margin-top:0; }

/* hairline divider between the two lede paragraphs (draws in on reveal) */
.lede-div{
  display:block; height:1px; width:clamp(72px,10vw,120px);
  background:var(--line); margin:30px 0 28px;
  transform:scaleX(0); transform-origin:0 50%;
  transition:transform 1.1s var(--e-out) 260ms;
}
.lede-div.in{ transform:scaleX(1); }

.services__cards{ display:grid; gap:clamp(16px,2vw,26px); }

.card{
  position:relative;
  padding:clamp(26px,3vw,42px);
  background:rgba(255,254,252,.82);
  border:1px solid rgba(168,161,143,.34);
  backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);
  transition:transform .6s var(--e-out), box-shadow .6s var(--e-out), background .6s, border-color .6s;
  will-change:transform;
  overflow:hidden;
}
.card::after{
  content:""; position:absolute; inset:0; pointer-events:none;
  background:radial-gradient(340px circle at var(--px,50%) var(--py,0%), rgba(255,254,251,.9), transparent 72%);
  opacity:0; transition:opacity .5s;
}
.card:hover{
  transform:translateY(-6px);
  box-shadow:0 40px 70px -46px rgba(59,45,33,.5);
  background:rgba(255,254,252,.97);
  border-color:rgba(122,113,97,.46);
}
.card:hover::after{ opacity:1; }
.card:first-child{ background:linear-gradient(155deg, rgba(251,250,247,.95), rgba(234,231,222,.86)); }
.card__num{
  display:inline-block; font-family:var(--f-body); font-size:13px; font-weight:600;
  letter-spacing:.14em; color:var(--brown-2);
  padding-bottom:7px; border-bottom:1px solid var(--taupe-deep);
  margin-bottom:18px;
}
.card__title{
  font-family:var(--f-head); font-weight:300;
  font-size:clamp(27px,3.1vw,41px); line-height:1.1; letter-spacing:-.012em;
  margin-bottom:16px;
}
.card p{ color:var(--text-2); font-size:16.5px; line-height:1.75; max-width:64ch; }
.card__tags{
  display:flex; flex-wrap:wrap; gap:10px 0;
  margin-top:26px; padding-top:20px; border-top:1px solid var(--line-soft);
  font-size:15.5px; color:var(--text-2);
}
.card__tags li + li::before{ content:"·"; margin:0 14px; color:var(--text-3); }

.nudge{
  display:flex; align-items:center; justify-content:space-between; gap:clamp(20px,3vw,44px);
  flex-wrap:wrap;
  padding:clamp(24px,3vw,36px) clamp(26px,3vw,42px);
  border-top:1px solid var(--line);
  border-bottom:1px solid var(--line);
  margin-top:clamp(10px,1.5vw,20px);
}
/* the heading carries this block, so it runs close to the .card titles beside
   it rather than sitting a step below them; the looser leading and the wider
   gap under it are what give the pair back the height the shorter lede lost */
.nudge__title{
  font-family:var(--f-head); font-weight:300;
  font-size:clamp(27px,3.1vw,41px); line-height:1.24; letter-spacing:-.008em;
  margin-bottom:clamp(13px,1.5vw,18px);
}
/* The clamp only bites on phones. This sentence measures 2.03x the text column
   at 375px/16.5px, so it broke to a third line by a hair; 3.9vw trims it just
   enough to land on two. It is back to a flat 16.5px from ~424px up, so every
   width above a phone is unchanged. */
.nudge p{
  color:var(--text-2); font-size:clamp(14px,3.9vw,16.5px);
  line-height:1.72; max-width:46ch;
}

/* =========================================================
   ABOUT
   ========================================================= */
/* Contained, not full-bleed: the portrait used to run off the left edge, which
   left it butting against the viewport at any width below full screen. Both
   columns now sit inside the same gutter the rest of the page uses. */
.about{
  display:grid;
  grid-template-columns:minmax(0,.62fr) minmax(0,1fr);
  gap:clamp(26px,4.4vw,70px);
  align-items:center;       /* 4:5 photo, copy drives section height */
  position:relative; z-index:2;
  padding-block:clamp(54px,6.4vw,92px);
  /* gutters come from the enclosing .wrap, so this lines up with the wordmark
     and every other section instead of computing its own (slightly off) box */
}
.about__copy{ align-self:center; }
.about__copy{ max-width:640px; }
/* NB: the wipe lives on the <img>, not on .about__photo — a fully clipped
   element reports zero intersection and would never trigger its own reveal. */
.about__photo{
  position:relative; overflow:hidden;
  aspect-ratio:4 / 5;               /* the asset is pre-cropped 4:5 — show it as-is */
  width:100%; max-width:390px;      /* caps how tall the whole section can get */
  margin-inline:0;                  /* flush to the gutter, like every heading */
}
.about__photo::after{
  content:""; position:absolute; inset:0;
  background:linear-gradient(180deg, transparent 62%, rgba(239,237,229,.32));
  pointer-events:none;
}
.about__photo img{
  object-fit:cover; object-position:50% 50%;
  transform:scale(1.04); transition:transform 1.4s var(--e-soft);
}
.about__photo.in img{ transform:scale(1); }
.about__copy .h2{ margin-bottom:26px; }
.about__copy p{ color:var(--text-2); font-size:clamp(16.5px,1.6vw,20px); line-height:1.78; max-width:56ch; }
.about__copy p + p{ margin-top:20px; }
.sig{
  font-family:var(--f-serif) !important; font-style:italic; font-weight:400;
  font-size:34px !important; color:var(--text) !important; margin-top:28px !important;
}

/* =========================================================
   PROCESS
   ========================================================= */
/* Process is the page's middle dark beat — same treatment as the CTA band, so
   the page reads dark / light / dark / light / dark instead of one long light
   stretch. Text and the flight path invert to the light palette. */
.sect--process{
  position:relative; overflow:hidden;
  background:var(--dark-surface);
  color:var(--on-dark);
  box-shadow:0 -34px 60px -26px rgba(20,17,15,.32);
}
.sect--process .wrap{ position:relative; z-index:2; }
.sect--process .h2{ margin-bottom:clamp(30px,5vw,52px); max-width:18ch; }
.sect--process .step__n{ color:var(--on-dark-3); }
.sect--process .step h3{ color:var(--on-dark); }
.sect--process .step p{ color:var(--on-dark-2); }

.steps{
  --cols:4;
  --step-gap:clamp(14px,2.4vw,34px);
  display:grid; grid-template-columns:repeat(var(--cols),minmax(0,1fr));
  gap:var(--step-gap);
}
.step{ text-align:center; }

/* ---- timeline: a line of dots that fill as you scroll ---- */
.steps--timeline{ position:relative; padding-top:clamp(48px,7vw,88px); }
/* the rail is a child of .steps, so --cols reaches it by inheritance */
.step{ position:relative; }

/* The connecting line spans dot-centre to dot-centre. A column's centre is half
   a column in from the edge, and the gaps come out of the columns — so the
   inset is (100% - (cols-1) * gap) / cols / 2, not a flat 50%/cols. The flat
   version left the rail about 11px short of the first and last dots at desktop
   width. Derived from --cols, so changing the step count needs no new numbers. */
.timeline__line{
  position:absolute; top:0;
  left:calc((100% - (var(--cols) - 1) * var(--step-gap)) / var(--cols) / 2);
  right:calc((100% - (var(--cols) - 1) * var(--step-gap)) / var(--cols) / 2);
  height:2px;
  background:rgba(244,241,235,.18);   /* muted track on the dark section */
  overflow:hidden; pointer-events:none;
}
.timeline__fill{
  display:block; height:100%; width:100%;
  background:var(--on-dark);
  transform:scaleX(var(--p,0)); transform-origin:0 50%;
  transition:transform .18s linear;
}
/* dot sits on the line, centred over each step */
.tdot{
  position:absolute; top:0; left:50%;
  width:14px; height:14px; margin:-6px 0 0 -7px; border-radius:50%;
  border:2px solid var(--on-dark);
  background:transparent;
  transition:background-color .45s var(--e-out), transform .45s var(--spring);
  z-index:2;
}
.tdot.is-on{ background:var(--on-dark); transform:scale(1.12); }
.steps--timeline .step__n{ margin-top:6px; }
.step__n{
  display:block; font-size:12px; font-weight:600; letter-spacing:.2em;
  color:var(--text-3); margin-bottom:12px;
}
.step h3{
  font-family:var(--f-body); font-weight:700;
  font-size:clamp(15.5px,1.55vw,19px); line-height:1.32; letter-spacing:-.006em;
  margin-bottom:12px; text-wrap:balance;
}
.step p{ font-size:15.5px; line-height:1.68; color:var(--text-2); }

/* =========================================================
   INCLUDED
   ========================================================= */
.incl{
  margin-top:clamp(40px,6vw,70px);
  display:grid; grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(14px,1.8vw,24px);
}
.incl__item{
  position:relative;
  padding:clamp(22px,2.4vw,32px);
  background:linear-gradient(135deg, rgba(253,252,250,.94), rgba(239,237,229,.78));
  border:1px solid transparent;
  transition:transform .55s var(--e-out), box-shadow .55s var(--e-out), border-color .55s;
  overflow:hidden;
}
.incl__item::before{
  content:""; position:absolute; left:0; top:0; bottom:0; width:2px;
  background:var(--taupe-deep); transform:scaleY(0); transform-origin:0 0;
  transition:transform .6s var(--e-out);
}
.incl__item:hover{ transform:translateY(-4px); box-shadow:0 30px 56px -40px rgba(59,45,33,.45); border-color:rgba(168,161,143,.45); }
.incl__item:hover::before{ transform:scaleY(1); }
.incl__item h3{
  font-family:var(--f-body); font-size:14px; font-weight:600;
  letter-spacing:.14em; text-transform:uppercase; margin-bottom:13px;
}
.incl__item p{ font-size:16px; line-height:1.72; color:var(--text-2); }

/* =========================================================
   DARK BAND + FOOTER
   ========================================================= */
.band,.foot{
  position:relative; overflow:hidden;
  background:var(--dark-surface);
  color:var(--on-dark);
}
.band{ padding-block:clamp(56px,7vw,92px); }
.band__glow,.foot__glow{
  position:absolute; inset:-40% -20%;
  background:radial-gradient(70% 90% at 45% 40%, rgba(255,248,232,.055), transparent 76%);
  animation:heroPan 40s ease-in-out infinite alternate;
  pointer-events:none;
}
.band::after,.foot::after{
  content:""; position:absolute; left:0; right:0; top:0; height:1px;
  background:linear-gradient(90deg, transparent, rgba(255,255,255,.22), transparent);
}
/* the dark plane casts a shadow onto the section it slides over */
.band,.foot{ box-shadow:0 -34px 60px -26px rgba(20,17,15,.32); }
.band__in{
  display:grid; grid-template-columns:minmax(0,1.35fr) minmax(0,auto);
  gap:clamp(24px,4vw,60px); align-items:center;
}
.band__in .h2{ font-size:clamp(29px,3.8vw,50px); margin-bottom:16px; }
.band__in p{ color:var(--on-dark-2); font-size:16.5px; line-height:1.7; max-width:56ch; }
.band__cta{ display:flex; align-items:center; }

.foot{ padding-top:clamp(56px,7vw,92px); position:relative; z-index:3; }
.foot__cta{
  display:grid; grid-template-columns:minmax(0,1fr) minmax(0,auto);
  gap:clamp(24px,4vw,60px); align-items:center;
  padding-bottom:clamp(48px,6vw,76px);
}
.foot__cta .h2{ font-size:clamp(33px,4.4vw,58px); margin-bottom:14px; }
.foot__cta p{ color:var(--on-dark-2); font-size:17px; }
.foot__base{
  display:flex; flex-wrap:wrap; gap:10px clamp(18px,3vw,44px); align-items:center;
  padding-block:26px calc(30px + env(safe-area-inset-bottom));
  border-top:1px solid var(--line-dark);
  position:relative; z-index:2;
}
.foot__brand{
  font-family:var(--f-serif); letter-spacing:.2em; text-transform:uppercase;
  font-size:14px; color:var(--on-dark); margin-right:auto;
}
.foot__meta{ font-size:13px; letter-spacing:.05em; color:var(--on-dark-3); }

/* =========================================================
   INNER PAGE HEADER (FAQ)
   ========================================================= */
.pagehead{
  position:relative; overflow:hidden;
  padding:calc(var(--nav-h) + clamp(58px,8vw,110px)) 0 clamp(58px,8vw,104px);
  background:var(--dark-surface);
  color:var(--on-dark);
  box-shadow:0 -34px 60px -26px rgba(20,17,15,.32);
}
.pagehead__glow{
  position:absolute; inset:-40% -20%;
  background:radial-gradient(70% 90% at 45% 40%, rgba(255,248,232,.055), transparent 76%);
  animation:heroPan 40s ease-in-out infinite alternate;
  pointer-events:none;
}
/* --maxw (not a narrower cap) so page titles start on the same left edge as the
   wordmark and the hero headline; the measure is limited on the text instead */
.pagehead__in{ position:relative; z-index:2; max-width:var(--maxw); }
/* 14ch used to live here and it sheared the Y off FREQUENTLY at every desktop
   width: the word measures 14.4ch, so it overran the box by 10px at 960 and
   15px at 1600, and the overflow:hidden on .line cut it. The title column is
   679px at its widest, so 16ch is still a measure, not the column. */
.pagehead__title{ max-width:16ch; }
.eyebrow--light{ color:var(--on-dark-3); }

/* FAQ header carries the monthly-update mockup, so the page opens on something
   concrete instead of a bare title */
.pagehead__in--split{
  max-width:var(--maxw);
  display:grid; grid-template-columns:minmax(0,1fr) minmax(0,.52fr);
  gap:clamp(24px,4.4vw,64px); align-items:center;
}
.pagehead__copy{ min-width:0; }
.pagehead__art{
  margin:0; position:relative; min-width:0;
  display:flex; flex-direction:column; align-items:center;
}
/* a soft pool of light behind the phone so it sits in the dark rather than on it */
.pagehead__art::before{
  content:""; position:absolute; inset:-18% -12% -10%;
  background:radial-gradient(58% 58% at 52% 46%, rgba(255,248,232,.10), transparent 72%);
  pointer-events:none;
}
/* constrained by HEIGHT, not width — these are tall portrait assets, so a width
   cap alone let the header grow past a full viewport */
.pagehead__art img{
  position:relative; display:block;
  width:auto; max-width:100%;
  height:auto; max-height:clamp(330px,36vw,460px);
  filter:drop-shadow(0 40px 60px rgba(0,0,0,.5));
}
.pagehead__art figcaption{
  position:relative; margin-top:clamp(12px,1.6vw,18px);
  font-size:13px; letter-spacing:.09em; text-transform:uppercase;
  color:var(--on-dark-3); text-align:center;
}

/* line art, not a photograph: it's already beige-on-transparent, so it needs no
   drop shadow (which would only smear the strokes) and can run larger */
.pagehead__art--line img{
  max-height:clamp(300px,33vw,420px); filter:none; opacity:.92;
}
.pagehead__art--line::before{
  background:radial-gradient(58% 58% at 52% 50%, rgba(255,248,232,.07), transparent 74%);
}

/* the page header speaks in the hero's voice — the same widely-tracked
   Cormorant caps — so the FAQ page reads as a sibling of the home page rather
   than a separate plain document */
/* The cap is set by the widest word the headings use — "FREQUENTLY" runs about
   8.4x the font size at this tracking — against the copy column, which stops
   growing at 679px once .wrap hits --maxw. Anything larger and the
   overflow:hidden on .line shears its last letter off on wide screens. */
.pagehead__title{
  font-family:var(--f-serif); font-weight:300;
  font-size:clamp(34px,5.2vw,78px); line-height:1.1;
  letter-spacing:.07em; text-transform:uppercase; text-indent:.07em;
  color:var(--on-dark); margin:0 0 clamp(20px,2.6vw,32px);
}
/* overflow:hidden is the mask the line-rise animation slides out of, so it has
   to stay — but it clips horizontally too. The padding/negative-margin pair
   moves the clip edge a little to the right of the text box without moving the
   text, so a wide final glyph can never be sheared again. */
.pagehead__title .line{
  display:block; overflow:hidden; padding-bottom:.04em;
  padding-right:.16em; margin-right:-.16em;
}
.pagehead__title .line__i{
  display:block; transform:translateY(108%); opacity:0;
  animation:lineUp 1.15s var(--e-out) forwards; animation-delay:var(--d,0s);
  will-change:transform,opacity;
}
.pagehead__title .line--serif{ overflow:visible; }
.pagehead__title .line--serif .line__i{
  font-family:var(--f-serif); font-style:italic; font-weight:300;
  text-transform:lowercase; letter-spacing:0; font-size:.88em; line-height:1.12;
  text-indent:0; color:var(--on-dark-2);
  transform:none; opacity:0;
  animation:heroFade 1.1s var(--e-out) var(--d,0s) forwards;
}
.pagehead__sub{
  font-size:clamp(16.5px,1.7vw,20px); line-height:1.7;
  color:var(--on-dark-2); max-width:52ch;
}

/* the FAQ list sits closer to its own page header */
.sect--faqpage{ padding-top:clamp(56px,7vw,96px); }
.sect--faqpage .faq{ margin-top:0; }

/* the Included grid on its own page: header lives in the pagehead, so the grid
   sits straight under it with no extra top gap */
.sect--inclpage{ padding-top:clamp(56px,7vw,96px); }
.sect--inclpage .incl{ margin-top:0; }

/* ---- still wondering ---- */
.askmore{ position:relative; text-align:center; }
.askmore__plane{
  width:76px; margin:0 auto clamp(22px,3vw,34px); opacity:.8;
}
.askmore__cta{
  display:flex; flex-wrap:wrap; gap:14px; justify-content:center;
  margin-top:clamp(28px,4vw,42px);
}
.btn--ghost{ --bg:transparent; --fg:var(--text-3); --bd:var(--line); color:var(--text-2); }
.btn--ghost::before{ background:var(--text); }
.btn--ghost:hover,.btn--ghost:focus-visible{ color:var(--paper); border-color:var(--text); }

/* quiet direct-contact line — for the few who want it, not shouted */
.askmore__contact{
  margin-top:clamp(26px,3.4vw,38px);
  font-size:15px; line-height:1.6; color:var(--text-3);
}
.askmore__contact a{
  color:var(--text-2); text-decoration:underline;
  text-underline-offset:3px; text-decoration-thickness:1px;
  white-space:nowrap; transition:color .3s;
}
.askmore__contact a:hover{ color:var(--text); }

/* =========================================================
   FAQ
   ========================================================= */
.faq{ margin-top:clamp(34px,5vw,58px); border-top:1px solid var(--line-soft); }
.faq__item{ border-bottom:1px solid var(--line-soft); }
.faq__item summary{
  list-style:none; cursor:pointer;
  display:flex; align-items:center; justify-content:space-between; gap:24px;
  padding:clamp(20px,2.4vw,28px) 0;
  font-family:var(--f-head); font-weight:400;
  font-size:clamp(20px,2.3vw,29px); line-height:1.28; letter-spacing:-.007em;
  transition:color .35s;
}
.faq__item summary::-webkit-details-marker{ display:none; }
.faq__item summary:hover{ color:var(--brown); }
.faq__icon{ flex:none; width:34px; color:var(--taupe-deep); transition:transform .6s var(--e-out), color .4s; }
.faq__icon svg{ width:100%; height:auto; }
.faq__item[open] .faq__icon{ transform:translateX(10px) rotate(-14deg); color:var(--brown); }
.faq__body{ overflow:hidden; }
.faq__body p{
  padding-bottom:clamp(22px,2.6vw,30px);
  max-width:62ch; font-size:17px; line-height:1.78; color:var(--text-2);
}
.faq__item[open] .faq__body{ animation:faqOpen .5s var(--e-out); }
@keyframes faqOpen{ from{ opacity:0; transform:translateY(-8px);} to{ opacity:1; transform:none;} }

/* =========================================================
   VALUES + OFFER
   ========================================================= */
/* top row: display title on the left, the three statements on the right */
.values-top{
  display:grid; grid-template-columns:minmax(0,.92fr) minmax(0,1.05fr);
  gap:clamp(36px,5vw,80px); align-items:start;
  margin-bottom:clamp(56px,8vw,120px);
}
.values-title{ position:sticky; top:calc(var(--nav-h) + 48px); }
.vtitle{
  font-family:var(--f-serif); font-weight:300;
  font-size:clamp(30px,3.8vw,54px); line-height:1.12;  /* must fit "BOOKKEEPING" */
  letter-spacing:.07em; text-transform:uppercase; text-indent:.07em;
  color:var(--text);
  margin:0;
}
.vtitle .line{ display:block; overflow:hidden; padding-bottom:.05em; }
.vtitle .line__i{
  display:block; transform:translateY(110%); opacity:0;
  animation:lineUp 1.15s var(--e-out) forwards; animation-delay:var(--d,0s);
}
.vtitle .line--serif{ overflow:visible; }
.vtitle .line--serif .line__i{
  font-family:var(--f-serif); font-style:italic; font-weight:400;
  text-transform:lowercase; letter-spacing:0; font-size:.92em; line-height:1.1;
  text-indent:0; color:var(--brown-2);
  transform:none; animation:heroFade 1.1s var(--e-out) var(--d,0s) forwards;
}

.values__list{ display:grid; gap:clamp(30px,4vw,54px); }
.value h3{
  font-family:var(--f-head); font-weight:400;
  font-size:clamp(20px,2.15vw,28px); letter-spacing:.008em; text-transform:uppercase;
  margin-bottom:14px; text-wrap:balance;
}
.value p{ color:var(--text-2); font-size:17px; line-height:1.78; max-width:60ch; }

/* bottom row: the desk photo as a plain full-bleed band. It used to carry a
   floated copy panel; that read as a card stuck onto a photograph, so the image
   now closes the section on its own and the footer takes the ask. */
.values-cta{
  position:relative; z-index:2;
  min-height:clamp(300px,34vw,440px);
  overflow:hidden;
}
.values-cta__bg{ position:absolute; inset:0; z-index:0; }
.values-cta__bg img{
  width:100%; height:100%; object-fit:cover; object-position:60% 50%;
  /* the source frame is a cool grey — a light warming is enough to keep it in
     the family; any more and it goes orange against the alabaster */
  filter:sepia(.12) saturate(1.02) brightness(1.02);
}
/* the band fades up into the page rather than starting on a hard horizon */
.values-cta__bg::after{
  content:""; position:absolute; inset:0;
  background:linear-gradient(180deg, rgba(253,252,251,.55) 0%, rgba(253,252,251,0) 26%);
}

/* =========================================================
   REVEAL + FLOAT UTILITIES
   ========================================================= */
/* ---- word-level heading reveal (JS wraps each word) ---- */
.split .wr{
  display:inline-block; overflow:hidden; vertical-align:bottom;
  padding-bottom:.14em; margin-bottom:-.14em;   /* room for descenders */
}
.split .wi{
  display:inline-block;
  transform:translate3d(0,110%,0);
  transition:transform 1.05s var(--e-out);
  transition-delay:calc(var(--i) * 42ms + var(--rd,0) * 1ms);
  will-change:transform;
}
.split.in .wi,
.in .split .wi{ transform:none; }
/* headings that are themselves inside a revealed parent shouldn't double-fade */
.split.reveal{ opacity:1; transform:none; }

/* section arrival — the incoming panel lifts and settles as it takes over */
.takeover{
  --t:0; /* 0 = incoming, 1 = settled (set by JS) */
  /* Vertical lift only. This used to also scale .99→1, which pulled the panel
     ~5px in from each side and left About/Process visibly out of line with the
     wordmark and every other section whenever --t hadn't settled. */
  transform:translate3d(0, calc((1 - var(--t)) * 26px), 0);
  will-change:transform;
}

/* ---- scroll-driven life for the lower half of the page ---- */

/* portrait drifts against the copy as you pass it */
@property --sc{ syntax:'<number>'; inherits:false; initial-value:1; }
.about__photo img{
  --sc:1.08;
  width:100%; height:100%; min-height:100%;
  transform:scale(var(--sc));
  translate:0 calc(var(--par,0) * 1.1px);
  clip-path:inset(0 0 100% 0);
  transition:--sc 1.8s var(--e-soft), clip-path 1.3s var(--e-out);
}
.about__photo.in img{ --sc:1.03; clip-path:inset(0 0 0 0); }

/* the light on each "included" tile tracks scroll position */
.incl__item{ --sh:0; }
.incl__item::after{
  content:""; position:absolute; inset:0; z-index:0; pointer-events:none;
  background:linear-gradient(105deg, transparent 40%, rgba(255,254,250,.9) 50%, transparent 60%);
  background-size:300% 100%;
  background-position:calc((1 - var(--sh)) * 200% - 50%) 0;
}
.incl__item h3,.incl__item p{ position:relative; z-index:1; }

/* the askmore plane (FAQ page) still drifts on scroll */
.askmore__plane{
  translate:calc(var(--par,0) * .45px) calc(var(--par,0) * -1px);
}

/* FAQ rows lift slightly under the pointer */
.faq__icon{ translate:0 calc(var(--par,0) * .5px); }

/* values: a hairline draws itself in beside each statement */
.value{ position:relative; padding-left:clamp(18px,2.2vw,30px); }
.value::before{
  content:""; position:absolute; left:0; top:.35em; bottom:.2em; width:1px;
  background:var(--brown-2); transform:scaleY(0); transform-origin:50% 0;
  transition:transform 1.1s var(--e-out) calc(var(--rd,0) * 1ms + 120ms);
  opacity:.6;
}
.value.in::before{ transform:scaleY(1); }

.reveal{
  opacity:0; transform:translate3d(0,26px,0);
  transition:opacity .9s var(--e-out), transform 1s var(--e-out);
  transition-delay:calc(var(--rd,0) * 1ms);
  will-change:opacity,transform;
}
.reveal.in{ opacity:1; transform:none; }

.float-soft{ animation:floatSoft 7s ease-in-out infinite alternate; }
@keyframes floatSoft{
  from{ transform:translateY(-5px); rotate:-2deg; }
  to  { transform:translateY(5px);  rotate:2.5deg; }
}

/* =========================================================
   RESPONSIVE
   ========================================================= */
@media (max-width:1080px){
  .services{ grid-template-columns:1fr; }
  .services__lede{ position:static; }
  .services__lede .h2{ max-width:18ch; }
  /* off desktop the lede stacks above the cards — trim it to the essentials
     (heading + one line) so it doesn't read as a wall of text */
  .lede-div{ display:none; }
  .services__lede .lede:last-of-type{ display:none; }

  .values-top{ grid-template-columns:1fr; gap:clamp(28px,6vw,44px); }
  .values-title{ position:static; }
  .values-cta{ min-height:clamp(240px,38vw,380px); }
}

@media (max-width:940px){
  :root{ --nav-h:66px; }
  .nav__links{ display:none; }
  .nav__cta{ display:none; }
  .burger{ display:flex; margin-left:auto; }
  .brand{ margin-right:0; }

  /* Deliberately short of the viewport, as on desktop, so the next section
     shows a little and the hero doesn't read as a dead full screen.
     justify-content:center split the leftover height above AND below the copy,
     which is what left a dead band under the marquee — flex-start plus an auto
     top margin sends all of it above the headline instead, so the marquee sits
     flush at the bottom and the gap under the subline is exactly what's set. */
  .hero{
    height:auto; min-height:min(78svh,860px); position:relative;
    justify-content:flex-start;
    padding:calc(var(--nav-h) + 20px) 0 0;
  }
  /* padding-bottom is the gap from the subline down to the credential marquee */
  .hero__in{
    transform:none; opacity:1; filter:none;
    margin-top:auto; padding-bottom:44px; gap:clamp(34px,5.8vh,52px);
  }
  /* A phone has no room for the vessel beside the type, and putting it under
     the type left the hero reading as two stacked objects. It goes behind the
     wordmark instead, centred and knocked well back — large enough to be the
     thing you notice second, faint enough that the type never fights it. */
  .hero__in{ grid-template-columns:1fr; justify-items:center; gap:0; }
  .hero__copy{ position:relative; z-index:2; grid-area:1 / 1; justify-self:stretch; width:100%; }
  /* Two things fixed here against the first pass. It is smaller: the vessel is
     only 185px wide in the source, and at 58vw it was being blown up past
     twice its real detail, which is what read as low quality. And <picture>
     has swapped in the shadowless crop (assets/mark.webp), so centring the box
     now centres the vessel — the wide file's box includes the cast shadow off
     to one side, which pulled the vessel left of the wordmark. */
  .hero__jar{
    grid-area:1 / 1; z-index:0; align-self:center; justify-self:center;
    width:clamp(112px,36vw,180px);
    /* Lifted off centre so the vessel's foot lands just inside the top of the
       CTA rather than hanging below it — centred, it left a dead band between
       the nav and the vessel's finial. A percentage resolves against the
       vessel's own height, so the lift tracks the clamp instead of drifting. */
    transform:translateY(-26%);
    opacity:0; animation:jarGhost 1.6s var(--e-out) .45s forwards;
    /* a touch of blur keeps the marble's carving from competing with the
       letterforms sitting on top of it */
    filter:blur(.5px);
    pointer-events:none;
  }
  .hero__jar picture{ display:block; }
  .hero__jar img{ width:100%; height:auto; }
  @keyframes jarGhost{ to{ opacity:.24; } }
  /* "BOOKKEEPING" runs ~7.5x the font size at this tracking, so 10.4vw is what
     keeps it on one line inside a 320px gutter — the tracking, not the glyphs,
     is the constraint here */
  .hero__title{ font-size:clamp(26px,10.4vw,64px); line-height:1.16; letter-spacing:.06em; text-indent:.06em; }
  .hero__sub{ font-size:clamp(13px,4.6vw,26px); line-height:1.4; }
  .hero__actions .btn{
    min-height:41px; padding:10px 19px;
    font-size:10.5px; letter-spacing:.1em;
  }
  .hero__scroll{ display:none; }
  /* the marquee itself is now in the base rules; below 940 the strip leaves the
     hero's bottom edge and becomes a band of its own under it */
  .hero__creds{
    position:relative; opacity:1;
    border-top:1px solid var(--line-dark);
  }

  /* stays side-by-side on tablet — the photo shrinks rather than the copy
     dropping below it (it only stacks on phones, at 620px) */
  .about{ gap:clamp(20px,3.4vw,34px); }
  .about__photo{ aspect-ratio:4/5; max-width:300px; }
  .about__photo img{ object-position:50% 50%; }
  .about__copy p{ font-size:16.5px; }

  /* Off desktop these three points used to wrap mid-list, orphaning a leading
     "·" onto its own row. Down to ~600px they fit on one row once tightened;
     below that they stack (see the 620px block) — card 2 is too long to fit a
     single line at any readable size. */
  .card__tags{
    flex-wrap:nowrap; align-items:baseline; gap:0;
    font-size:clamp(11px,2.35vw,13.5px); letter-spacing:-.005em;
  }
  .card__tags li{ white-space:nowrap; }
  /* separator trails its item, so a wrap can never strand a "·" at line start */
  .card__tags li + li::before{ content:none; }
  .card__tags li:not(:last-child)::after{
    content:"·"; margin:0 .6em; color:var(--text-3);
  }

  /* "Bookkeeping made simple" — 17px body is a wall of text on a narrow column */
  .value p{ font-size:15.5px; line-height:1.72; }

  /* Off desktop the five steps stack, and the dot-line stands up with them:
     same rail, same scroll-driven fill, rotated a quarter turn. The rail's
     extent is set in JS from the first and last dot centres, because the steps
     are not equal heights and a CSS top/bottom pair can't know where the last
     dot actually lands. */
  .steps{ grid-template-columns:1fr; gap:0; text-align:left; }
  .steps--timeline{
    --rail-x:8px;                       /* rail centre, from the list's edge */
    --rail-gap:clamp(34px,8vw,52px);    /* where the copy starts */
    padding-top:0; padding-left:var(--rail-gap);
  }
  .step{
    text-align:left;
    /* the rail carries the sequence now, so the row hairlines the two-column
       layout needed are gone; this padding is what the dots space against */
    padding-block:clamp(14px,2.6vw,20px);
  }
  .timeline__line{
    display:block;
    left:calc(var(--rail-x) - 1px); right:auto;
    top:0; width:2px; height:0;         /* both set by JS from the dot centres */
  }
  .timeline__fill{
    transform:scaleY(var(--p,0)); transform-origin:50% 0;
  }
  .tdot{
    display:block;
    /* centred on the step number's line box: step padding, the number's own
       6px top margin, then half its ~20px line */
    top:calc(clamp(14px,2.6vw,20px) + .92em);
    left:calc(var(--rail-x) - var(--rail-gap));
    margin:-7px 0 0 -7px;
  }

  .incl{ grid-template-columns:1fr; }
  .band__in,.foot__cta{ grid-template-columns:1fr; }
  .band__cta{ justify-content:flex-start; }

  /* art drops below the title and shrinks rather than squeezing the headline */
  .pagehead__in--split{ grid-template-columns:1fr; gap:clamp(26px,5vw,40px); }
  .pagehead__art img,
  .pagehead__art--line img{ max-height:min(300px,44vh); }

  /* The title had been pinned to the desktop clamp's 40px floor at every width
     below 940, which read as small. It scales with the viewport instead now.
     "FREQUENTLY" is the limiting word — about 6.8x the font size at this
     tracking — so 12vw is what keeps it inside the gutters on a 320px SE while
     still reaching 76px on a tablet. A fixed floor can't do both: anything tall
     enough to look right at 375 shears the word at 320. */
  /* "FREQUENTLY" is the limiting word — about 8.4x the font size at this
     tracking — so 9.4vw is what keeps it inside the gutters on a 320px SE while
     still reaching a proper size on a tablet */
  .pagehead__title{
    font-size:clamp(28px,9.4vw,62px); letter-spacing:.055em; text-indent:.055em;
    max-width:none;
  }

  /* Included keeps its two columns below the desktop breakpoint — title beside
     the phone, lede full-width underneath both. display:contents dissolves the
     .pagehead__copy box so the title and lede become grid items in their own
     right and can be placed on separate rows. */
  .pagehead__in--cols{
    grid-template-columns:minmax(0,1fr) minmax(0,.44fr);
    grid-template-areas:
      "title art"
      "sub   sub";
    column-gap:clamp(12px,3vw,26px);
    row-gap:clamp(20px,4vw,32px);
    align-items:center;
  }
  .pagehead__in--cols .pagehead__copy{ display:contents; }
  .pagehead__in--cols .pagehead__art{ grid-area:art; }
  /* the lede steps back so the enlarged title carries the row — 16.5px next to
     a 62px headline read as two competing sizes rather than a title and a note */
  .pagehead__in--cols .pagehead__sub{
    grid-area:sub; max-width:60ch;
    font-size:clamp(14.5px,1.7vw,16px); line-height:1.62;
  }
  /* "INCLUDED" measures 5.32x the font size at this tracking, and the title
     column is (content - column-gap) / 1.44 wide — so the shear point runs at
     about 11.3vw. 9.6vw keeps ~15% of clear room at every width from 320 up,
     and the 62px cap is the same ceiling the FAQ header uses, so the two page
     titles land on one size on a tablet. */
  .pagehead__in--cols .pagehead__title{
    grid-area:title; margin-bottom:0;
    font-size:clamp(30px,9.6vw,62px);
  }
  /* the caption is dropped below the desktop breakpoint: in a column this narrow
     it wrapped to three lines and read as a second heading beside the title.
     The img alt still describes the mockup for screen readers. */
  .pagehead__in--cols .pagehead__art figcaption{ display:none; }
}

/* The Included lede is 1.97x its column at 375px/14.5px, so it cleared two
   lines on measure but lost to a word break and fell to three. A hair smaller
   on the narrowest phones is all it needs. Scoped this tight because 390px and
   up already sit on two lines at the full 14.5px. */
@media (max-width:389px){
  .pagehead__in--cols .pagehead__sub{ font-size:13.6px; line-height:1.6; }
}

/* phones only: this is the first width where the portrait can no longer sit
   beside the copy without squeezing it */
@media (max-width:620px){
  /* one point per line: the longest set ("Past months cleaned up · Accounts
     reviewed · Organized starting point") needs a ~9px font to fit one row at
     phone widths, so a clean stack is the consistent, legible answer */
  .card__tags{ flex-direction:column; gap:8px; font-size:14px; letter-spacing:0; }
  .card__tags li:not(:last-child)::after{ content:none; }

  .value p{ font-size:14.5px; line-height:1.68; }
  .value h3{ font-size:18px; }

  .about{ grid-template-columns:1fr; gap:clamp(24px,6vw,36px); }
  /* fills the column so both edges land on the gutter, flush with the copy —
     a fixed cap left a lopsided 20px/30px gap */
  .about__photo{ max-width:100%; }
}

@media (max-width:560px){
  .btn{ width:100%; }
  /* the hero CTA stays a centred pill — stretched to the gutter it outweighs
     the wordmark it is meant to sit under */
  .hero__actions .btn{ width:auto; }
  .nudge{ align-items:flex-start; }
  .foot__base{ flex-direction:column; align-items:flex-start; }
  .foot__brand{ margin-right:0; }
  .band__cta .btn,.foot__cta .btn,.nudge .btn{ width:100%; }
  .values-cta{ min-height:clamp(200px,52vw,300px); }
}

/* =========================================================
   ACCESSIBILITY — reduced motion
   ========================================================= */
@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior:auto; }
  *,*::before,*::after{
    animation-duration:.001ms !important; animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
  }
  .reveal{ opacity:1 !important; transform:none !important; }
  .hero__title .line__i,
  .pagehead__title .line__i,
  .vtitle .line__i{ opacity:1; transform:none; }
  .hero__in{ transform:none; opacity:1; filter:none; }
  .hero{ position:relative; }
  /* timeline reads as complete without the scroll fill */
  .timeline__fill{ transform:scaleX(1) !important; }
  .tdot{ background:var(--on-dark) !important; }
  .takeover{ transform:none !important; }
  .about__photo img{ clip-path:none !important; }
  .split .wi{ transform:none !important; }
  .value::before{ transform:scaleY(1) !important; }
  /* no motion means no loop, so the strip goes back to five items standing
     still and evenly spread, with the duplicate tracks hidden. The edge feather
     and the edge-to-edge padding both exist to serve the scroll, and on a
     static row they would only dim the first and last item, so both go. */
  .hero__creds{
    padding-inline:var(--gut);
    -webkit-mask-image:none !important; mask-image:none !important;
  }
  .creds__track{
    animation:none !important;
    flex:1 1 auto; justify-content:space-between; gap:clamp(10px,2vw,28px);
  }
  .creds__viewport{ width:auto; max-width:var(--maxw); }
  .creds__track:not(:first-child){ display:none; }
  .creds__track li{ padding:0; }
  .creds__track li::after{ display:none; }
  .incl__item::after{ display:none; }
  .creds__track span{ opacity:1; }
}
