/* =========================================================
   ALABASTER BOOKKEEPING — editorial prototype
   A separate exploration. Nothing here ships to build/.

   Three rules from the brief drive everything below:
     1. one continuous cream base, no alternating dark bands
     2. two typefaces: a display serif, a clean sans
     3. exactly ONE animated moment (the vein), everything else static
   ========================================================= */

/* ---------- tokens ---------- */
:root{
  /* The cream base. Near-neutral by rule: warm beige reads orange next to the
     cocoa and drags the whole page with it. Every tone here keeps its
     red-to-blue spread inside ~12 points. */
  --cream:      #F6F4ED;   /* the page ground, everywhere */
  --cream-2:    #EFEDE5;   /* a half-step down, for inset panels */
  --alabaster:  #F0EEE7;   /* the accent panel, carried over unchanged */

  /* The browns are the ones already signed off. Not touched. */
  --cocoa:      #2A211A;
  --cocoa-2:    #17120C;
  --cocoa-soft: #3A2E24;
  --brown:      #6B5644;

  --text:       #241C15;
  --text-2:     #55483C;
  --text-3:     #746657;   /* 4.5:1 on the cream. Do not lighten. */
  --on-dark:    #F5F3EF;
  --on-dark-2:  rgba(245,243,239,.74);
  --on-dark-3:  rgba(233,229,219,.58);

  --line:       rgba(59,45,33,.14);
  --line-soft:  rgba(59,45,33,.08);
  --line-dark:  rgba(233,229,219,.18);

  /* Two faces. The old build carried three (Cormorant, Jost, Archivo); Jost is
     gone. Cormorant is the wordmark's own voice, so the headlines now speak in
     the logo's face rather than beside it. */
  --f-display: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  --f-body:    "Archivo", "Helvetica Neue", Arial, sans-serif;

  /* rhythm. Editorial layouts want more air than the old build had. */
  --gut:   clamp(22px, 5vw, 80px);
  --maxw:  1280px;
  --sect:  clamp(96px, 12vw, 190px);

  /* motion. Only the vein uses these; nothing else on the page moves. */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);

  --nav-h: 78px;
}

/* ---------- reset ---------- */
*,*::before,*::after{ box-sizing:border-box; }
html{ -webkit-text-size-adjust:100%; scroll-behavior:smooth; }
@media (prefers-reduced-motion: reduce){ html{ scroll-behavior:auto; } }

body{
  margin:0;
  background:var(--cream);
  color:var(--text);
  font-family:var(--f-body);
  font-size:17px;
  line-height:1.7;
  font-weight:400;
  letter-spacing:.004em;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;
}
/* height:auto is load-bearing. Every img here carries width/height attributes
   (they reserve layout space and stop the page shifting as images arrive), and
   those map to a presentational height. Constraining only max-width leaves the
   height at its natural pixel value, which stretched the portrait to 372x1250
   instead of 372x465. */
img{ max-width:100%; height:auto; display:block; }
a{ color:inherit; }
h1,h2,h3{ margin:0; font-weight:400; }
p{ margin:0 0 1.1em; }
/* ol as well as ul: the process list is an <ol>, and its default 40px
   padding-inline-start left the steps inset from their own container, exposing
   the container's hairline background as a grey band down the left. */
ul,ol{ margin:0; padding:0; list-style:none; }
/* figure carries a UA margin of 1em 40px. Every image on this page sits in one,
   so that 80px was quietly shrinking each texture block and the portrait
   inside its own column. */
figure{ margin:0; }

.vh{
  position:absolute; width:1px; height:1px; overflow:hidden;
  clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap;
}
.skip{
  position:absolute; left:-9999px; top:0; z-index:100;
  background:var(--cocoa); color:var(--on-dark);
  padding:14px 20px; font-size:14px;
}
.skip:focus{ left:12px; top:12px; }

:focus-visible{
  outline:2px solid var(--brown);
  outline-offset:3px;
  border-radius:2px;
}

.wrap{
  width:100%; max-width:var(--maxw);
  margin-inline:auto;
  padding-inline:var(--gut);
}

/* ---------- paper grain ----------
   Fixed and pointer-events:none, so it never sits on a scrolling container.
   A grain layer attached to scrolling content forces a repaint of the whole
   surface on every frame. */
.grain{
  position:fixed; inset:0; z-index:3;
  pointer-events:none;
  background:url("../img/grain.png") repeat;
  background-size:180px 180px;
  opacity:.045;
  mix-blend-mode:multiply;
}

/* =========================================================
   NAV
   Not a full-bleed bar glued to the top edge. It sits inset on the cream and
   only grows a hairline once you have left the hero.
   ========================================================= */
.nav{
  position:sticky; top:0; z-index:20;
  background:color-mix(in srgb, var(--cream) 86%, transparent);
  backdrop-filter:blur(14px);
  -webkit-backdrop-filter:blur(14px);
  border-bottom:1px solid transparent;
  transition:border-color .5s var(--ease-out), background-color .5s var(--ease-out);
}
.nav[data-stuck="true"]{
  border-bottom-color:var(--line-soft);
  background:color-mix(in srgb, var(--cream) 94%, transparent);
}
.nav__in{
  max-width:var(--maxw); margin-inline:auto;
  padding-inline:var(--gut);
  min-height:var(--nav-h);
  display:flex; align-items:center; gap:32px;
}
.brand{
  display:flex; align-items:center; gap:12px;
  text-decoration:none; margin-right:auto;
}
.brand__mark{ width:15px; flex:none; opacity:.9; }
.brand__mark img{ width:100%; height:auto; }
.brand__word{ display:flex; flex-direction:column; line-height:1; }
.brand__word b{
  font-family:var(--f-display); font-weight:400;
  font-size:20px; letter-spacing:.20em; text-transform:uppercase;
}
.brand__word i{
  font-style:normal; font-size:8.5px; letter-spacing:.34em;
  text-transform:uppercase; color:var(--text-3); margin-top:5px;
}
.nav__links{ display:flex; gap:30px; }
.nav__links a{
  text-decoration:none; font-size:13.5px; color:var(--text-2);
  letter-spacing:.02em;
  padding-block:6px;
  border-bottom:1px solid transparent;
  transition:color .3s var(--ease-out), border-color .3s var(--ease-out);
}
@media (hover:hover) and (pointer:fine){
  .nav__links a:hover{ color:var(--text); border-bottom-color:var(--line); }
}
.nav__links a[aria-current="page"]{ color:var(--text); border-bottom-color:var(--brown); }

/* ---------- buttons ---------- */
.btn{
  display:inline-flex; align-items:center; gap:14px;
  padding:15px 22px 15px 26px;
  background:var(--cocoa); color:var(--on-dark);
  text-decoration:none;
  font-size:13.5px; letter-spacing:.055em; text-transform:uppercase;
  border:none; border-radius:0;   /* editorial: square, not pill */
  transition:background-color .4s var(--ease-out), transform .18s var(--ease-out);
}
.btn__ico{
  width:26px; height:26px; flex:none;
  display:grid; place-items:center;
  border:1px solid rgba(245,243,239,.28);
  border-radius:50%;
  transition:transform .45s var(--ease-out), border-color .45s var(--ease-out);
}
.btn__ico svg{ width:11px; height:11px; }
@media (hover:hover) and (pointer:fine){
  .btn:hover{ background:var(--cocoa-soft); }
  .btn:hover .btn__ico{ transform:translate(2px,-2px); border-color:rgba(245,243,239,.5); }
}
.btn:active{ background:var(--cocoa-2); }

.btn--ghost{
  background:transparent; color:var(--text);
  border:1px solid var(--line);
  padding:13px 20px 13px 24px;
}
.btn--ghost .btn__ico{ border-color:var(--line); }
@media (hover:hover) and (pointer:fine){
  .btn--ghost:hover{ background:var(--alabaster); border-color:var(--line); }
  .btn--ghost:hover .btn__ico{ border-color:var(--brown); }
}
.btn--light{ background:var(--cream); color:var(--cocoa); }
.btn--light .btn__ico{ border-color:rgba(42,33,26,.25); }
@media (hover:hover) and (pointer:fine){
  .btn--light:hover{ background:#fff; }
}
.btn--sm{ padding:11px 16px 11px 20px; font-size:12px; }
.btn--sm .btn__ico{ width:22px; height:22px; }

.nav__cta{ display:inline-flex; }

/* ---------- press feedback (2.9) ----------
   Every control answers the moment a finger or button goes down, not on
   release. The pressed state switches in instantly (transition-duration 0 on
   :active) and eases back out on release with each rule's own timing. The
   press is a colour step plus a slight give (scale .97); under Reduce Motion
   the colour step stays and the give is dropped. The grey tap flash is turned
   off only on controls that now draw their own pressed state. proto.js adds
   an empty touchstart listener, without which iOS Safari never shows :active. */
.btn,.burger,.nav__links a,.mobile-menu nav a,.testi__btn,.testi__play,.faq__item summary{
  -webkit-tap-highlight-color:transparent;
}
.btn:active{ transform:scale(.97); transition-duration:0s, .08s; }
.btn--ghost:active{ background:var(--cream-2); border-color:var(--brown); }
.btn--light:active{ background:var(--cream-2); }
.nav__links a:active{ color:var(--text); transition-duration:0s; }
.mobile-menu nav a{ transition:color .3s var(--ease-out); }
.mobile-menu nav a:active{ color:var(--brown); transition-duration:0s; }
.burger:active span{ background:var(--brown); }
@media (prefers-reduced-motion: reduce){
  .btn:active{ transform:none; }
}

/* ---------- burger ---------- */
.burger{
  display:none;
  width:44px; height:44px; margin-right:-10px;
  background:none; border:0; padding:0; cursor:pointer;
  position:relative;
}
.burger span{
  position:absolute; left:11px; width:22px; height:1px;
  background:var(--text);
  transition:transform .45s var(--ease-out), opacity .25s var(--ease-out);
}
.burger span:nth-child(1){ top:19px; }
.burger span:nth-child(2){ top:25px; }
.burger[aria-expanded="true"] span:nth-child(1){ transform:translateY(3px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2){ transform:translateY(-3px) rotate(-45deg); }

.mobile-menu{
  position:fixed; inset:var(--nav-h) 0 0; z-index:19;
  background:var(--cream);
  padding:40px var(--gut);
  display:flex; flex-direction:column; gap:8px;
}
/* display on a class outranks the bare [hidden] attribute, so the menu would
   sit open on page load without this */
.mobile-menu[hidden]{ display:none; }
.mobile-menu nav a[aria-current="page"]{ font-style:italic; color:var(--brown); }
/* 2.8 fix: these rules used to target every `.mobile-menu a`, which (1) left
   the links flowing inline, three to a row, because the <nav> around them
   was a plain block, and (2) also hit the call-to-action button, blowing it
   up to 30px serif with a hairline under it. Now the list is its own column
   and only the list links get the big serif. */
.mobile-menu{ overflow-y:auto; overscroll-behavior:contain; padding-bottom:max(40px, env(safe-area-inset-bottom)); }
/* 2.9: the menu arrives from under the nav and leaves back up the same way,
   in step with the burger turning into a cross, instead of cutting in and
   out. proto.js removes [hidden], then adds .is-open a frame later; closing
   takes .is-open off and only hides the menu once it has faded. Reopening
   mid-close just reverses from wherever it is. Reduce Motion: fade only. */
.mobile-menu{
  opacity:0; transform:translateY(-10px);
  transition:opacity .2s var(--ease-out), transform .2s var(--ease-out);
}
.mobile-menu.is-open{
  opacity:1; transform:none;
  transition-duration:.34s;
}
@media (prefers-reduced-motion: reduce){
  .mobile-menu{ transform:none; }
}
.mobile-menu nav{ display:flex; flex-direction:column; }
.mobile-menu nav a{
  text-decoration:none; font-family:var(--f-display);
  font-size:30px; line-height:1.2; padding:12px 0;
  border-bottom:1px solid var(--line-soft);
}
.mobile-menu .btn{ margin-top:32px; align-self:flex-start; }

/* =========================================================
   THE VEIN: one hairline crack, the page's one moving thing

   2.1: the approved "Hairline Crack" (prototype A, vein-a-motion.html). It
   replaces 2.0's seven per-section segments, which ran nearly straight down a
   narrow gutter strip and jumped sideways at every section break.

   What is drawn: ONE crack, generated by proto.js at the page's real pixel
   size (nothing stretched), from the hairline that closes the hero to the
   hairline under the footer's call to action. The hero above the first line
   and the Contact / Site / Legal columns below the last stay clear. It swings across the full width in diagonal legs with sharp broken
   elbows, a core that thickens and pinches, and short splinters branching
   off. The shapes are filled, tapering paths, not strokes.

   It is painted twice from the same path data: a grey-taupe copy in <main>
   (running on through the gap above the footer) and a pale copy in the dark
   footer whose viewBox picks up exactly where the first leaves off. Both sit
   at z-index:-1, so the crack passes BEHIND text and behind anything with its
   own background (texture slabs, photographs, the process rows).

   Motion is a clip-path wipe tied to scroll position: it grows as you scroll
   down with its tip level with the middle of the screen, and retracts as you
   scroll back up. In the footer it runs just fast enough to finish as the page
   ends. proto.js picks one of three engines:
     .crack-css     Chrome/Edge: CSS scroll-driven animation, off the main thread
     .crack-js      Safari/Firefox: a rAF-throttled scroll listener, same math
     .crack-static  Reduce Motion on: fully drawn, not moving
   Shown at every width, phones included, softened at 820px and below.
   ========================================================= */

/* <main> is the context the crack sits at z-index:-1 in. Each section and the
   footer stay contexts of their own, so their own negative-z layers (the about
   slab, the testimonial watermark, the footer's copy of the crack) stay put. */
main,.hero,.phead,.sect,.foot{ position:relative; z-index:0; }

.vl{
  position:absolute; top:0; left:0;
  width:100%; height:100%;          /* proto.js sets each copy's real px top/height */
  z-index:-1; pointer-events:none;
  display:block; overflow:hidden;
  clip-path:inset(0 0 100% 0);      /* hidden until an engine takes over */
}

/* Each svg is its own view() subject. From "cover 50vh" (its top at
   mid-screen) to "cover calc(100% - 50vh)" (its bottom at mid-screen) is
   exactly its own height of scrolling, which keeps the tip at mid-screen. */
.crack-css .vl{
  /* Longhands only. The `animation` shorthand resets animation-duration to
     0s, and a scroll-driven animation with a 0s duration never moves. */
  animation-name:crack-grow;
  animation-duration:auto;
  animation-timing-function:linear; /* any easing would detach the tip from mid-screen */
  animation-fill-mode:both;
  animation-timeline:view();
  animation-range-start:cover 50vh;
  animation-range-end:cover calc(100% - 50vh);
}
/* The footer copy ends at the hairline under the call to action, which sits
   near the page bottom, so the page may run out before that end reaches
   mid-screen. proto.js sets --crack-tail (the footer left below the line).
   The range ends with the crack's end at mid-screen when the page can scroll
   that far, and otherwise exactly as the page runs out. */
.crack-css .vl--foot{ animation-range-end:cover calc(100% - max(50vh, 100vh - var(--crack-tail, 0px))); }
@keyframes crack-grow{
  from{ clip-path:inset(0 0 100% 0); }
  to  { clip-path:inset(0 0 0 0); }
}
.crack-static .vl{ animation:none; clip-path:inset(0); }

/* Phones and small tablets: the same crack, softened. On a narrow screen it
   crosses the text more often and read a little harsh at full strength. */
@media (max-width:820px){ .vl{ opacity:.6; } }
/* 2.6: the legal pages are long runs of small text, and at full strength the
   crack fought the reading. Same crack, same motion, drawn fainter there. */
.page-legal .vl{ opacity:.45; }
@media (max-width:820px){ .page-legal .vl{ opacity:.35; } }

/* =========================================================
   HERO
   ========================================================= */
.hero{ padding-block:clamp(64px,9vw,132px) clamp(56px,7vw,96px); }
.hero__in{
  display:grid; gap:clamp(40px,5vw,72px);
  grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);
  align-items:center;
}
.eyebrow{
  font-size:10.5px; letter-spacing:.30em; text-transform:uppercase;
  color:var(--text-3); margin:0 0 26px;
}
.hero__title{
  font-family:var(--f-display);
  font-size:clamp(52px,8.6vw,122px);
  line-height:.94;
  letter-spacing:-.008em;
  margin:0 0 26px;
}
.hero__title em{
  display:block; font-style:italic;
  color:var(--brown);
  font-size:.92em;
}
.hero__sub{
  font-size:clamp(17px,1.5vw,20px);
  color:var(--text-2);
  max-width:34ch; margin-bottom:34px;
}
.hero__sub em{ font-family:var(--f-display); font-style:italic; font-size:1.12em; }

.hero__art{ position:relative; }
.hero__slab{
  aspect-ratio:4/5;
  background:url("../img/slab-portrait.webp") center/cover no-repeat;
  box-shadow:0 30px 70px -50px rgba(36,28,21,.5);
}
/* The vessel, small. Its source is only 185px wide, so it is never scaled up
   past what that can carry. */
.hero__vessel{
  position:absolute; right:6%; bottom:-7%;
  width:clamp(54px,7vw,88px);
  filter:drop-shadow(0 22px 34px rgba(36,28,21,.18));
}

/* credentials: a static line. The old build ran these as an infinite marquee,
   which is continuous motion, and the brief allows exactly one moving thing. */
.creds{
  margin-top:clamp(56px,7vw,92px);
  padding-top:26px;
  border-top:1px solid var(--line-soft);
  display:flex; flex-wrap:wrap; gap:10px 36px;
}
.creds li{
  font-size:11px; letter-spacing:.20em; text-transform:uppercase;
  color:var(--text-3);
}

/* =========================================================
   SECTION FURNITURE
   ========================================================= */
.sect{ padding-block:var(--sect); position:relative; }
.sect__head{ max-width:52ch; margin-bottom:clamp(48px,6vw,84px); }
.h2{
  font-family:var(--f-display);
  font-size:clamp(34px,4.6vw,62px);
  line-height:1.04; letter-spacing:-.006em;
  margin:0 0 22px;
}
.h2 em{ font-style:italic; color:var(--brown); }
.lede{ font-size:clamp(16.5px,1.35vw,18.5px); color:var(--text-2); max-width:56ch; }

/* =========================================================
   SERVICES — asymmetric, texture-paired blocks.
   No card borders anywhere: the pairing of a texture panel with a text column
   is what separates one service from the next.
   ========================================================= */
.svc{
  display:grid;
  grid-template-columns:repeat(12,1fr);
  gap:clamp(28px,4vw,64px);
  align-items:center;
  margin-bottom:clamp(72px,9vw,150px);
}
.svc:last-child{ margin-bottom:0; }

.svc__art{ position:relative; }
.svc__art img{ width:100%; height:100%; object-fit:cover; }

/* Each block takes a different span and a different side, so the eye never
   settles into a rhythm. This is the asymmetry the brief asked for, and it is
   why these are not three equal cards in a row. */
.svc--a .svc__art{ grid-column:1 / span 6; aspect-ratio:5/4; }
.svc--a .svc__copy{ grid-column:8 / span 5; }

.svc--b .svc__copy{ grid-column:1 / span 5; }
.svc--b .svc__art{ grid-column:7 / span 6; aspect-ratio:4/5; }

.svc--c .svc__art{ grid-column:1 / span 7; aspect-ratio:16/10; }
.svc--c .svc__copy{ grid-column:9 / span 4; }

.svc__num{
  font-family:var(--f-display);
  font-size:13px; letter-spacing:.2em;
  color:var(--brown);
  display:block; margin-bottom:18px;
}
.svc__title{
  font-family:var(--f-display);
  font-size:clamp(27px,3vw,40px);
  line-height:1.1; margin-bottom:16px;
}
.svc__copy p{ color:var(--text-2); font-size:16.5px; }
.svc__tags{
  display:flex; flex-wrap:wrap; gap:8px 20px;
  margin-top:22px; padding-top:18px;
  border-top:1px solid var(--line-soft);
}
.svc__tags li{
  font-size:11px; letter-spacing:.14em; text-transform:uppercase;
  color:var(--text-3);
}

/* the "still figuring it out" note, set as an aside rather than a card */
.nudge{
  margin-top:clamp(72px,9vw,140px);
  padding-top:44px;
  border-top:1px solid var(--line);
  display:grid; gap:28px;
  grid-template-columns:minmax(0,1fr) auto;
  align-items:end;
}
.nudge h3{
  font-family:var(--f-display);
  font-size:clamp(24px,2.6vw,34px);
  margin-bottom:10px;
}
.nudge p{ color:var(--text-2); margin:0; max-width:46ch; }

/* =========================================================
   ABOUT — the founder, woven in beside the copy
   ========================================================= */
.about{
  display:grid; gap:clamp(36px,5vw,80px);
  grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);
  align-items:center;
}
.about__art{ position:relative; }
.about__art img{ width:100%; }
/* a slab peeking out behind the portrait, so the photograph sits on stone */
.about__art::before{
  content:""; position:absolute;
  left:-22px; top:-22px; width:56%; aspect-ratio:1;
  background:url("../img/slab-quiet.webp") center/cover no-repeat;
  z-index:-1;
}
.about__copy p{ color:var(--text-2); }
.sig{
  font-family:var(--f-display); font-style:italic;
  font-size:26px; color:var(--brown); margin-top:26px;
}

/* =========================================================
   PROCESS: "The Desk" (2.7, prototype B in process-lab.html)
   The desk photo is a full-bleed ground with the heading on its empty wall.
   The four steps sit on a cream panel laid over the photo's lower edge, then
   the call to action. The photo and the opaque panel both cover the crack
   across their height, as the service textures do; it resumes below.
   Motion (proto.js, off under Reduce Motion): the photo drifts a few percent
   as it passes through the screen, and the steps rise in once.
   ========================================================= */
.process{ padding-top:0; }
.process__head{
  position:absolute; top:0; left:0; right:0; z-index:1;
  padding-top:clamp(64px,8vw,130px);
}
.process__head .sect__head{ margin-bottom:0; }
.process__head .eyebrow{ color:var(--text-2); }   /* text-3 is tuned for plain cream, not the photo */
.process__head .h2{ max-width:11em; }
.process__photo{ position:relative; height:clamp(460px,58vw,820px); overflow:hidden; }
.process__photo img{
  position:absolute; left:0; top:-6%;
  width:100%; height:112%; object-fit:cover; object-position:62% 60%;
  filter:sepia(.1) saturate(.88);   /* the site's photo cap: warmer reads orange */
}
.proc-js .process__photo img{ will-change:transform; }
.process__photo::after{   /* a cream wash behind the heading, over the wall */
  content:""; position:absolute; inset:0;
  background:linear-gradient(90deg, rgba(246,244,237,.62), rgba(246,244,237,.18) 44%, transparent 62%);
}

.steps{
  position:relative; z-index:2;
  margin-top:calc(-1 * clamp(110px,13vw,200px));
  background:var(--cream);
  display:grid; grid-template-columns:repeat(4,minmax(0,1fr));
  padding-block:clamp(32px,3.4vw,52px);
  box-shadow:0 40px 80px -60px rgba(36,28,21,.45);
}
.step{ padding:6px clamp(20px,2.2vw,36px); border-left:1px solid var(--line-soft); }
.step:first-child{ border-left:0; }
.step__n{
  display:block; margin-bottom:20px;
  font-family:var(--f-display); font-size:13px; letter-spacing:.2em; color:var(--brown);
}
.step h3{ font-family:var(--f-display); font-size:clamp(22px,2vw,28px); line-height:1.15; margin-bottom:12px; }
.step p{ color:var(--text-2); font-size:15.5px; margin:0; }
.proc-js .step{ transition:opacity .9s var(--ease-out), transform .9s var(--ease-out); }
.proc-js .step:nth-child(2){ transition-delay:.08s; }
.proc-js .step:nth-child(3){ transition-delay:.16s; }
.proc-js .step:nth-child(4){ transition-delay:.24s; }
.proc-js .step:not(.is-on){ opacity:0; transform:translateY(18px); }

.process__cta{ margin-top:clamp(40px,5vw,64px); }

/* =========================================================
   VALUES — a wide statement over the desk photograph
   ========================================================= */
.values__list{
  display:grid; gap:clamp(30px,4vw,58px);
  grid-template-columns:repeat(auto-fit,minmax(240px,1fr));
  margin-top:clamp(40px,5vw,70px);
}
.value h3{
  font-family:var(--f-display);
  font-size:clamp(21px,2.1vw,27px);
  margin-bottom:12px; padding-top:20px;
  border-top:1px solid var(--line);
}
.value p{ color:var(--text-2); font-size:16px; margin:0; }
.values__cta{ margin-top:clamp(52px,6vw,88px); }
/* 2.4: the desk photo that closed this section ("the plate") moved up to be
   the Process section's background, so it is not shown twice. */

/* =========================================================
   IN THEIR WORDS — testimonials
   Three pull-quotes at staggered heights rather than equal bordered cards, so
   it reads as one editorial spread instead of a review-widget grid. A quiet
   slab texture sits behind the whole section as a watermark, tying it to the
   same material as everything else on the page.
   ========================================================= */
.sect--testimonials{ overflow:hidden; }
.testi__bg{
  position:absolute; inset:0; z-index:-1;
  background:url("../img/slab-quiet.webp") center 30%/cover no-repeat;
  opacity:.5;
}
.testi__bg::after{
  /* fades the texture into the page cream at both edges so it reads as a
     watermark, not a photograph dropped onto the section */
  content:""; position:absolute; inset:0;
  background:linear-gradient(var(--cream), transparent 20%, transparent 80%, var(--cream));
}

.sect--testimonials .eyebrow{ font-family:var(--f-body); font-weight:400; }

/* 2.7: a carousel, one review at a time. Every slide sits in the same grid
   cell, so the track is always as tall as the longest review and nothing
   below it jumps when they change. proto.js adds .is-live and moves .is-on.
   The hairline under the controls fills over the 10 seconds a review is
   shown; its animationend is what advances the carousel, so the bar and the
   timing can never drift apart. Hover or focus pauses it. */
.testi__track{ display:grid; }
.testi{ grid-area:1 / 1; margin:0; }
/* 2.9: the fade carries direction. proto.js sets each slide's transform
   inline: next comes in from the right and the old one leaves to the left,
   previous the other way round, so the arrows (and a swipe) visibly send the
   review where they point. The transform eases on the same curve as the fade. */
.testi__car.is-live .testi{
  transition:opacity .7s var(--ease-out), transform .7s var(--ease-out), visibility 0s linear .7s;
}
.testi__car.is-live .testi:not(.is-on){ opacity:0; visibility:hidden; }
.testi__car.is-live .testi.is-on{ transition:opacity .7s var(--ease-out) .15s, transform .7s var(--ease-out) .15s, visibility 0s; }
/* 2.9 swipe (touch and pen only; the arrows serve the mouse). pan-y leaves
   vertical scrolling to the browser and hands sideways drags to proto.js,
   which moves the review 1:1 with the finger. */
.testi__car.is-live .testi__track{ touch-action:pan-y; }
.testi__car.is-dragging .testi__bar i{ animation-play-state:paused; }
.testi__mark{
  display:block;
  font-family:var(--f-display); font-style:italic;
  font-size:72px; line-height:1; color:var(--brown);
  opacity:.55; margin-bottom:0;
}
.testi__quote{
  font-family:var(--f-display); font-style:italic;
  font-size:clamp(23px,2.5vw,34px); line-height:1.38;
  color:var(--text); margin:0 0 28px;
}
.testi__quote p{ margin:0; }
.testi__who{
  display:block; padding-top:16px; max-width:22rem;
  border-top:1px solid var(--line);
  font-size:11px; letter-spacing:.18em; text-transform:uppercase;
  color:var(--text-2);
}

/* 2.8: an arrow either side of the review, the progress line under the
   whole review. No counter: visitors don't need to know how many there are.
   On phones the arrows move down to either end of the progress line. */
.testi__car{
  display:grid; max-width:64rem;
  grid-template-columns:44px minmax(0,1fr) 44px;
  grid-template-areas:"prev track next" ". foot .";
  column-gap:clamp(20px,4vw,56px); row-gap:clamp(32px,4vw,48px);
  align-items:center;
}
.testi__track{ grid-area:track; }
.testi__btn--prev{ grid-area:prev; }
.testi__btn--next{ grid-area:next; }
.testi__car.is-single .testi__btn, .testi__car.is-single .testi__foot{ display:none; }
.testi__foot{ grid-area:foot; display:flex; align-items:center; gap:14px; }
.testi__btn,.testi__play{
  flex:none; padding:0; cursor:pointer;
  display:grid; place-items:center;
  background:transparent; color:var(--text);
  border-radius:50%;
  transition:border-color .3s var(--ease-out), color .3s var(--ease-out), transform .18s var(--ease-out);
}
.testi__btn{ width:44px; height:44px; border:1px solid var(--line); }
.testi__btn svg,.testi__play svg{
  width:12px; height:12px; fill:none; stroke:currentColor;
  stroke-width:1; stroke-linecap:round; stroke-linejoin:round;
}
/* pause stays (automatic motion longer than 5 seconds needs a way to stop
   it under WCAG 2.2.2, which the Accessibility page says the site meets),
   but it is the quietest thing here: no ring, text-3, at the line's end */
.testi__play{ width:32px; height:32px; margin-right:-8px; border:0; color:var(--text-3); position:relative; }
/* 2.9: still drawn at 32px, but the tap area reaches 44px, the smallest
   target a fingertip hits reliably */
.testi__play::after{ content:""; position:absolute; inset:-6px; }
.testi__play svg.i-play{ fill:currentColor; stroke:none; }
.testi__play .i-play{ display:none; }
.testi__play[aria-pressed="true"] .i-pause{ display:none; }
.testi__play[aria-pressed="true"] .i-play{ display:block; }
@media (hover:hover) and (pointer:fine){
  .testi__btn:hover{ border-color:var(--brown); }
  .testi__play:hover{ color:var(--brown); }
}
.testi__btn:active{ border-color:var(--brown); color:var(--brown); transform:scale(.93); transition-duration:0s, 0s, .08s; }
.testi__play:active{ color:var(--brown); transform:scale(.9); transition-duration:0s, 0s, .08s; }
@media (prefers-reduced-motion: reduce){
  .testi__btn:active,.testi__play:active{ transform:none; }
}
@media (max-width:640px){
  .testi__car{
    grid-template-columns:44px minmax(0,1fr) 44px;
    grid-template-areas:"track track track" "prev foot next";
    column-gap:16px;
  }
}
.testi__bar{
  flex:1; height:1px; background:var(--line-soft);
  position:relative; overflow:hidden;
}
.testi__bar i{
  position:absolute; inset:0; background:var(--brown);
  transform-origin:0 50%; transform:scaleX(0);
}
.testi__car.is-running .testi__bar i{
  animation-name:testi-bar; animation-duration:10s;
  animation-timing-function:linear; animation-fill-mode:forwards;
}
.testi__car.is-held .testi__bar i{ animation-play-state:paused; }
.testi__car.is-stopped .testi__bar i{ visibility:hidden; }
@keyframes testi-bar{ to{ transform:scaleX(1); } }
@media (prefers-reduced-motion: reduce){
  .testi__car.is-live .testi,.testi__car.is-live .testi.is-on{ transition:none; }
}

/* =========================================================
   FOOTER — the single dark surface on the page.
   One terminus, not an alternating band: the cream runs unbroken from the nav
   all the way down to here.
   ========================================================= */
.foot{
  position:relative;
  background:
    radial-gradient(1400px 700px at 40% 0%, rgba(74,58,44,.55) 0%, rgba(35,27,20,.5) 45%, rgba(19,14,9,.72) 100%),
    url("../img/stone.webp") center/cover no-repeat,
    var(--cocoa-2);
  color:var(--on-dark);
  padding-block:clamp(80px,9vw,140px) 48px;
  margin-top:var(--sect);
}
.foot__cta{
  display:grid; gap:32px;
  grid-template-columns:minmax(0,1fr) auto;
  align-items:end;
  padding-bottom:clamp(56px,7vw,90px);
  border-bottom:1px solid var(--line-dark);
}
.foot__cta .h2{ color:var(--on-dark); margin-bottom:14px; }
.foot__cta .h2 em{ color:var(--on-dark-3); }
.foot__cta p{ color:var(--on-dark-2); margin:0; max-width:46ch; }

.foot__info{
  display:grid; gap:40px;
  grid-template-columns:repeat(auto-fit,minmax(200px,1fr));
  padding-block:clamp(48px,6vw,72px);
}
.foot__ch{
  font-size:10.5px; letter-spacing:.26em; text-transform:uppercase;
  color:var(--on-dark-3); margin-bottom:18px;
}
.foot__list li{ margin-bottom:9px; font-size:15px; color:var(--on-dark-2); }
.foot__list a{ text-decoration:none; border-bottom:1px solid transparent; }
@media (hover:hover) and (pointer:fine){
  .foot__list a:hover{ border-bottom-color:var(--line-dark); color:var(--on-dark); }
}
.foot__disc{
  font-size:12.5px; line-height:1.75; color:var(--on-dark-3);
  max-width:92ch; padding-top:36px;
  border-top:1px solid var(--line-dark);
}
.foot__base{
  display:flex; flex-wrap:wrap; gap:8px 28px;
  padding-top:28px;
  font-size:12px; color:var(--on-dark-3);
}
.foot__brand{
  font-family:var(--f-display); letter-spacing:.2em;
  text-transform:uppercase; color:var(--on-dark-2);
}

/* =========================================================
   INNER PAGES (2.6)
   What's included, FAQ, the three legal pages and the 404, rebuilt on the
   homepage's system. Same cream ground, same two faces, no illustrations:
   the old paper airplanes, line drawings, phone mockup and aurora blobs are
   gone. Imagery is texture, or Jessica herself. The crack runs on every page,
   starting at the hairline under the page head ([data-crack-start]).
   ========================================================= */
.phead{ padding-block:clamp(56px,8vw,120px) 0; }
.phead__in{ display:grid; gap:clamp(40px,5vw,72px); align-items:center; }
.phead--art .phead__in{ grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr); }
.phead__title{
  font-family:var(--f-display);
  font-size:clamp(46px,7.2vw,104px);
  line-height:.96; letter-spacing:-.008em;
  margin:0 0 26px;
}
.phead__title em{ display:block; font-style:italic; color:var(--brown); font-size:.9em; }
.phead__sub{
  font-size:clamp(16.5px,1.4vw,19px); color:var(--text-2);
  max-width:44ch; margin:0;
}
.phead__art{ position:relative; }
.phead__art img{
  width:100%; aspect-ratio:4/5; object-fit:cover;
  box-shadow:0 30px 70px -50px rgba(36,28,21,.5);
}
/* no sepia cap here: the portrait file is already graded to the cream ground (2.10) */
/* the portrait sits on stone, like the About portrait on the homepage */
.phead__art--photo::before{
  content:""; position:absolute;
  right:-22px; bottom:-22px; width:52%; aspect-ratio:1;
  background:url("../img/slab-quiet.webp") center/cover no-repeat;
  z-index:-1;
}
/* the vessel keeps its own small size; the full-width rule above is for the slab */
.phead__art .hero__vessel{
  width:clamp(54px,7vw,88px); aspect-ratio:auto; bottom:-6%;
  box-shadow:none;
}
.phead__rule{
  height:0; margin-top:clamp(56px,7vw,92px);
  border-top:1px solid var(--line-soft);
}
.sect--first{ padding-top:clamp(64px,8vw,120px); }

/* ---------- What's included: a numbered two-column ledger ---------- */
.incl{
  display:grid; column-gap:clamp(40px,6vw,110px);
  grid-template-columns:repeat(2,minmax(0,1fr));
  counter-reset:incl;
}
.incl__item{
  counter-increment:incl;
  display:grid; grid-template-columns:56px minmax(0,1fr);
  padding-block:clamp(30px,3.6vw,48px);
  border-top:1px solid var(--line-soft);
}
.incl__item::before{
  content:counter(incl, decimal-leading-zero);
  font-family:var(--f-display); font-size:15px;
  color:var(--brown); letter-spacing:.16em; padding-top:.5em;
}
.incl__item h3{
  font-family:var(--f-display); font-size:clamp(23px,2.3vw,31px);
  line-height:1.15; margin-bottom:12px;
}
.incl__item p{ grid-column:2; color:var(--text-2); font-size:16px; margin:0; }
.incl__item:nth-last-child(-n+2){ border-bottom:1px solid var(--line-soft); }

/* ---------- FAQ: hairline rows, a plus that becomes a minus ---------- */
.faqwrap{ display:grid; grid-template-columns:repeat(12,1fr); }
.faq{ grid-column:3 / -1; 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:28px;
  padding-block:clamp(24px,2.8vw,36px);
  font-family:var(--f-display); font-size:clamp(22px,2.4vw,31px); line-height:1.2;
}
.faq__item summary::-webkit-details-marker{ display:none; }
.faq__icon{
  position:relative; flex:none; width:34px; height:34px;
  border:1px solid var(--line); border-radius:50%;
  transition:border-color .3s var(--ease-out), transform .18s var(--ease-out);
}
/* 2.9 press feedback: the ring answers as soon as the question is pressed */
.faq__item summary:active .faq__icon{ border-color:var(--brown); transform:scale(.9); transition-duration:0s, .08s; }
@media (prefers-reduced-motion: reduce){
  .faq__item summary:active .faq__icon{ transform:none; }
}
.faq__icon::before,.faq__icon::after{
  content:""; position:absolute; left:50%; top:50%;
  width:11px; height:1px; margin:-.5px 0 0 -5.5px;
  background:var(--text);
}
.faq__icon::after{ transform:rotate(90deg); }
.faq__item[open] .faq__icon::after{ display:none; }   /* static swap: the crack stays the only motion */
@media (hover:hover) and (pointer:fine){
  .faq__item summary:hover .faq__icon{ border-color:var(--brown); }
}
.faq__body{ padding:0 62px clamp(26px,3vw,38px) 0; }
.faq__body p{ color:var(--text-2); max-width:62ch; margin:0; }

/* the closing ask on the FAQ and 404: set like the footer's call to action */
.askmore{
  display:grid; gap:32px 64px;
  grid-template-columns:minmax(0,1fr) auto;
  align-items:end;
  padding-top:clamp(40px,5vw,64px);
  border-top:1px solid var(--line);
}
.askmore .h2{ margin-bottom:14px; }
.askmore__sub{ color:var(--text-2); margin:0; max-width:46ch; }
.askmore__cta{ display:flex; flex-wrap:wrap; gap:12px; }
.askmore__contact{
  grid-column:1 / -1; margin:0;
  font-size:15px; color:var(--text-2);
}
.askmore__contact a{ text-decoration-color:var(--line); text-underline-offset:3px; }
.askmore__contact a[href^="sms:"], .legal__body a[href^="sms:"]{ white-space:nowrap; }
/* directly under the page head's hairline, a second rule would double it */
.sect--first > .askmore{ border-top:0; padding-top:0; }

/* ---------- legal pages: a contents rail and a reading column ---------- */
.legal{
  display:grid; gap:clamp(40px,6vw,96px);
  grid-template-columns:minmax(0,15rem) minmax(0,1fr);
  align-items:start;
}
.legal__aside{ position:sticky; top:calc(var(--nav-h) + 28px); }
.legal__meta{
  font-size:10.5px; letter-spacing:.26em; text-transform:uppercase;
  color:var(--text-3); margin:0 0 22px;
}
.legal__toc{ border-top:1px solid var(--line-soft); }
.legal__toc li{ border-bottom:1px solid var(--line-soft); }
.legal__toc a{
  display:block; padding:10px 0;
  font-size:13.5px; color:var(--text-2); text-decoration:none;
}
@media (hover:hover) and (pointer:fine){ .legal__toc a:hover{ color:var(--brown); } }
.legal__body{ grid-column:2; max-width:66ch; }
.legal__body > p, .legal__body li{ color:var(--text-2); }
.legal__body h2{
  font-family:var(--f-display); font-size:clamp(28px,3vw,38px);
  line-height:1.1; margin:2.1em 0 .6em;
  scroll-margin-top:calc(var(--nav-h) + 24px);
}
.legal__body > h2:first-of-type{ margin-top:1.4em; }
.legal__body h3{
  font-size:11px; font-weight:500; letter-spacing:.2em; text-transform:uppercase;
  color:var(--text); margin:1.8em 0 .8em;
}
.legal__body ul{ margin:0 0 1.2em; }
.legal__body ul li{ position:relative; padding-left:26px; margin-bottom:.55em; }
.legal__body ul li::before{
  content:""; position:absolute; left:0; top:.85em;
  width:12px; height:1px; background:var(--brown);
}
.legal__body strong{ font-weight:500; color:var(--text); }
.legal__body a{ text-decoration-color:var(--line); text-underline-offset:3px; }
@media (hover:hover) and (pointer:fine){ .legal__body a:hover{ text-decoration-color:var(--brown); } }
.legal__note{
  margin-top:3em; padding-top:24px; border-top:1px solid var(--line);
}
.legal__note p{
  font-family:var(--f-display); font-style:italic;
  font-size:clamp(19px,1.7vw,22px); line-height:1.45; color:var(--text-2);
}

/* =========================================================
   RESPONSIVE
   Every asymmetric span above collapses to a single column. The overlaps and
   offsets that make the desktop layout are exactly what break touch targets
   and line lengths on a phone.
   ========================================================= */
@media (max-width:1100px){
  .steps{ grid-template-columns:repeat(2,minmax(0,1fr)); row-gap:36px; }
  .step:nth-child(3){ border-left:0; }
}

@media (max-width:1000px){
  .hero__in{ grid-template-columns:1fr; }
  .hero__art{ max-width:400px; }
  .about{ grid-template-columns:1fr; }
  .about__art{ max-width:420px; }
  .phead--art .phead__in{ grid-template-columns:1fr; }
  .phead__art{ max-width:400px; }
  .legal{ grid-template-columns:1fr; }
  .legal__aside{ position:static; }
  .legal__body{ grid-column:1; }
  .faq{ grid-column:1 / -1; }
}

@media (max-width:820px){
  .nav__links{ display:none; }
  .nav__cta{ display:none; }
  .burger{ display:block; }

  .svc{ grid-template-columns:1fr; gap:26px; }
  .svc--a .svc__art, .svc--b .svc__art, .svc--c .svc__art,
  .svc--a .svc__copy, .svc--b .svc__copy, .svc--c .svc__copy{
    grid-column:1 / -1;
  }
  .svc--a .svc__art, .svc--c .svc__art{ aspect-ratio:16/10; }
  .svc--b .svc__art{ aspect-ratio:4/5; max-width:340px; }
  /* photo above copy in every block once stacked, whatever the desktop order */
  .svc__art{ order:-1; }

  /* the heading moves above the photo; the steps stack on the panel */
  .process{ padding-top:var(--sect); }
  .process__head{ position:static; padding-top:0; padding-bottom:32px; }
  .process__photo{ height:max(300px,70vw); }
  .process__photo img{ object-position:74% 60%; }
  .process__photo::after{ display:none; }
  .steps{ grid-template-columns:1fr; row-gap:0; margin-top:-48px; padding-block:12px; }
  .step, .step:nth-child(3){ border-left:0; padding:26px 22px; }
  .step + .step{ border-top:1px solid var(--line-soft); }



  .nudge{ grid-template-columns:1fr; align-items:start; }
  .foot__cta{ grid-template-columns:1fr; align-items:start; }
  .askmore{ grid-template-columns:1fr; align-items:start; }
  .incl{ grid-template-columns:1fr; }
  .incl__item:nth-last-child(2){ border-bottom:0; }
  .incl__item{ grid-template-columns:44px minmax(0,1fr); }
  .faq__body{ padding-right:0; }
  .phead__art--photo::before{ right:-12px; bottom:-12px; }

}

@media (max-width:520px){
  body{ font-size:16.5px; }
  .hero__title{ line-height:.98; }
  .creds{ gap:8px 22px; }
  .creds li{ font-size:10px; letter-spacing:.16em; }
}
