/* ============================================================================
   Ripple - shared design system (site.css)
   The single, page-agnostic system for Home, How it works, and About.
   Per docs/redesign-direction.md (LOCKED). Page-only layout lives in each
   page's own <style>. No em dashes anywhere. AA contrast on every label.

   REUSABLE CLASSES / COMPONENTS (so other pages reuse, not reinvent):
     Layout      .wrap  .section  .stack  .eyebrow  .lead  .section-head
     Buttons     .btn  .btn--primary  .btn--ghost  .btn .ico  .chip
     Header      header.site-head  .brand  .brand-mark  .nav  .nav a  .head-cta
                 .menu-btn  .mobile-nav (+ body.nav-open)
     Footer      footer.site-foot  .foot-grid  .foot-brand  .foot-nav  .foot-fine
     Cards       .card  .card--pad  .card-title  .card-eyebrow
     Droplets    .droplets  .drop (data-... variants)  .drop-ripple
     Motion      .reveal  .reveal-group (>*)  .line-mask > .line  html.js gate
     Form        form.rippll-form  .field  .field-row  .field label  .req
                 .form-actions  .form-note  .form-status  .form-success  .hp
   ============================================================================ */

/* ---------- tokens (LOCKED palette + scale) ---------- */
:root{
  --paper:    #F4F1DE;  /* warm parchment cream, page ground */
  --paper-2:  #FBFAF1;  /* near-white card surface */
  --ink:      #1F2622;  /* green-black, text + dark sections */
  --ink-soft: #3C443D;  /* body text on cream */
  --muted:    #6E6A61;  /* secondary / captions (AA on cream) */
  --accent:   #F65324;  /* coral-orange, the droplet + primary accent (large fills/marks) */
  --accent-2: #BE3E18;  /* deeper coral for small accent TEXT/links + solid-button fill.
                           AA on both cream grounds (paper 4.75:1, paper-2 5.15:1) and AA
                           for a white label (5.40:1). A hair deeper than the doc's #C8421B
                           so every small accent passes WCAG AA, per the hard a11y guardrail. */
  --pop:      #F1ED3C;  /* electric yellow, rare punctuation; DARK text on it */
  --sage:     #5C7150;  /* secondary green */
  --sage-2:   #B5CFAE;  /* soft green tint, fills */
  --line:     #C8C9B7;  /* warm-grey hairlines */

  /* tints derived from the palette (kept on-system) */
  --accent-wash: rgba(246,83,36,.10);
  --ink-wash:    rgba(31,38,34,.06);
  --paper-glass: rgba(244,241,222,.82);

  /* fluid type scale */
  --fs-h1:    clamp(2.7rem, 6.5vw, 5.8rem);
  --fs-h2:    clamp(2rem, 4.4vw, 3.4rem);
  --fs-h3:    clamp(1.25rem, 2.3vw, 1.6rem);
  --fs-lead:  clamp(1.1rem, 1.5vw, 1.32rem);
  --fs-body:  1.0625rem;            /* 17px */
  --fs-small: .9rem;
  --fs-eyebrow: .8rem;

  /* spacing (8px system) */
  --s-1:4px; --s-2:8px; --s-3:12px; --s-4:16px; --s-5:24px;
  --s-6:32px; --s-7:48px; --s-8:64px; --s-9:96px; --s-10:128px;
  --sec-pad: clamp(72px, 10vw, 140px);
  --gutter:  clamp(20px, 3vw, 24px);
  --maxw:    1180px;
  --head-h:  72px;

  /* radii */
  --r-card:28px; --r-btn:14px; --r-input:10px; --r-pill:999px;

  --ease: cubic-bezier(.22,.61,.36,1);
}

/* ---------- reset / base ---------- */
*{margin:0; padding:0; box-sizing:border-box}
html{
  background:var(--paper);
  overscroll-behavior:none;
  -webkit-text-size-adjust:100%;
}
/* Lenis helper CSS (smooth-scroll lib). When Lenis is active it sets these
   classes; height:auto lets it own the scroll. Inactive/no-JS = native scroll. */
html.lenis, html.lenis body{height:auto}
.lenis.lenis-smooth{scroll-behavior:auto !important}
.lenis.lenis-smooth [data-lenis-prevent]{overscroll-behavior:contain}
.lenis.lenis-stopped{overflow:clip}
html{scroll-behavior:smooth}
@media (prefers-reduced-motion: reduce){ html{scroll-behavior:auto} }

body{
  background:var(--paper);
  color:var(--ink-soft);
  font:400 var(--fs-body)/1.62 'Inter',system-ui,-apple-system,sans-serif;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  overflow-x:clip;
  overscroll-behavior:none;
}
/* the page ground bleeds past the foot so an overscroll shows the ink bookend,
   never a white flash */
body::after{
  content:''; position:fixed; left:0; right:0; bottom:0; height:46vh;
  background:var(--ink); z-index:-2; pointer-events:none;
}
::selection{background:var(--accent); color:#fff}
a{color:inherit; text-decoration:none}
img,svg{display:block; max-width:100%}
button{font:inherit}

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

.wrap{max-width:var(--maxw); margin:0 auto; padding:0 var(--gutter)}
.section{padding:var(--sec-pad) 0}
.stack > * + *{margin-top:var(--s-4)}
:where(section,footer,[id]){scroll-margin-top:calc(var(--head-h) + 12px)}

.sr-only{position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0}

/* skip link */
.skip{
  position:absolute; left:50%; top:-64px; transform:translateX(-50%);
  background:var(--accent); color:#fff; padding:11px 20px; border-radius:0 0 12px 12px;
  font:600 14px/1 'Inter',sans-serif; z-index:300; transition:top .2s var(--ease);
}
.skip:focus{top:0}

/* ---------- typography ---------- */
h1,h2,h3,h4{color:var(--ink); font-family:'Fraunces',Georgia,serif; font-weight:420}
h1{
  font-size:var(--fs-h1); line-height:1.03; letter-spacing:-.02em;
  font-variation-settings:'opsz' 144; text-wrap:balance;
}
h2{
  font-size:var(--fs-h2); line-height:1.06; letter-spacing:-.014em;
  font-variation-settings:'opsz' 96; text-wrap:balance;
}
h3{
  font-size:var(--fs-h3); line-height:1.18; letter-spacing:-.01em; font-weight:460;
  font-variation-settings:'opsz' 40;
}
em, .fr-italic{font-style:italic}
.accent-word{color:var(--accent-2)}            /* one key word in a headline */

.eyebrow{
  display:inline-flex; align-items:center; gap:.6em;
  font:600 var(--fs-eyebrow)/1 'Inter',sans-serif; letter-spacing:.14em;
  text-transform:uppercase; color:var(--accent-2);
}
.eyebrow::before{
  content:''; width:24px; height:2px; background:var(--accent);
  border-radius:2px; flex:none;
}
.lead{
  font-size:var(--fs-lead); line-height:1.55; color:var(--ink-soft);
  max-width:42rem;
}
.muted{color:var(--muted)}
.section-head{max-width:46rem; margin-bottom:clamp(40px,6vw,64px)}
.section-head .lead{margin-top:var(--s-5)}
.section-head h2{margin-top:var(--s-4)}

/* ---------- buttons ---------- */
.btn{
  --bg:var(--accent); --fg:#fff; --bd:var(--accent);
  appearance:none; cursor:pointer; white-space:nowrap;
  display:inline-flex; align-items:center; justify-content:center; gap:9px;
  font:600 15px/1 'Inter',sans-serif; letter-spacing:.005em;
  min-height:48px; padding:0 22px; border-radius:var(--r-btn);
  background:var(--bg); color:var(--fg); border:1.5px solid var(--bd);
  transition:transform .18s var(--ease), box-shadow .22s var(--ease),
             background .2s ease, color .2s ease, border-color .2s ease;
  will-change:transform;
}
.btn .ico{width:16px; height:16px; flex:none}
/* solid coral fill uses --accent-2 so the white label is AA (5.4:1); --accent
   itself stays for droplets/marks/large fills where it reads as the brighter coral. */
.btn--primary{
  --bg:var(--accent-2); --bd:var(--accent-2); --fg:#fff;
  box-shadow:0 1px 1px rgba(31,38,34,.10);
}
.btn--primary:hover{
  background:#A8350F; border-color:#A8350F;
  transform:translateY(-2px); box-shadow:0 12px 26px -12px rgba(190,62,24,.55);
}
.btn--ghost{
  --bg:transparent; --fg:var(--ink); --bd:var(--line);
}
.btn--ghost:hover{
  border-color:var(--ink); background:var(--paper-2);
  transform:translateY(-2px); box-shadow:0 10px 22px -14px rgba(31,38,34,.4);
}
.btn:active{transform:translateY(0)}
/* arrow nudges on hover, a small satisfying micro-interaction */
.btn:hover .ico.arrow{transform:translateX(3px)}
.btn .ico.arrow{transition:transform .2s var(--ease)}

/* pill chip / tag */
.chip{
  display:inline-flex; align-items:center; gap:9px;
  padding:8px 15px 8px 13px; border-radius:var(--r-pill);
  background:var(--paper-2); border:1px solid var(--line);
  font:600 12.5px/1 'Inter',sans-serif; letter-spacing:.04em;
  color:var(--ink-soft);
}
.chip .pip{position:relative; width:8px; height:8px; flex:none}
.chip .pip i{position:absolute; inset:0; border-radius:50%; background:var(--accent)}
.chip .pip i.live{animation:pip-ping 2.6s cubic-bezier(0,0,.2,1) infinite}
@keyframes pip-ping{0%{transform:scale(1); opacity:.55} 80%,100%{transform:scale(2.6); opacity:0}}
.chip .pip-sep{width:1px; height:11px; background:var(--line)}
@media (prefers-reduced-motion: reduce){ .chip .pip i.live{animation:none; opacity:0} }

/* ============================================================
   HEADER (sticky, cream-translucent, hairline bottom)
   Left = mark + Ripple.  Centre = nav.  Right = Start the ripple.
   ============================================================ */
.site-head{
  position:fixed; top:0; left:0; right:0; z-index:100; height:var(--head-h);
  background:var(--paper-glass);
  backdrop-filter:blur(14px) saturate(1.05);
  -webkit-backdrop-filter:blur(14px) saturate(1.05);
  border-bottom:1px solid transparent;
  transition:background .35s ease, border-color .35s ease, box-shadow .35s ease;
}
.site-head.is-scrolled{
  background:rgba(244,241,222,.94);
  border-bottom-color:var(--line);
  box-shadow:0 10px 30px -24px rgba(31,38,34,.4);
}
.head-row{
  max-width:var(--maxw); margin:0 auto; height:100%; padding:0 var(--gutter);
  display:grid; grid-template-columns:1fr auto 1fr; align-items:center; gap:16px;
}
.brand{
  justify-self:start; display:inline-flex; align-items:center; gap:11px;
  height:44px; padding:0 2px;
  font-family:'Fraunces',Georgia,serif; font-weight:500; font-size:23px;
  letter-spacing:-.018em; color:var(--ink);
}
.brand-mark{width:28px; height:28px; flex:none; overflow:visible}
.brand-mark .ring{transform-origin:center}
.brand-mark .ring.r1{animation:mark-breathe 7s ease-in-out infinite}
.brand-mark .ring.r2{animation:mark-breathe 7s ease-in-out infinite .8s}
@keyframes mark-breathe{0%,64%,100%{opacity:.5; transform:scale(1)} 18%{opacity:.85; transform:scale(1.05)}}
@media (prefers-reduced-motion: reduce){ .brand-mark .ring{animation:none} }

.nav{justify-self:center; display:flex; align-items:center; gap:2px}
.nav a{
  position:relative; padding:11px 14px; min-height:44px;
  display:inline-flex; align-items:center; border-radius:9px;
  font:500 14.5px/1 'Inter',sans-serif; color:var(--ink-soft);
  transition:color .18s ease;
}
.nav a::after{
  content:''; position:absolute; left:14px; right:14px; bottom:8px; height:1.5px;
  background:var(--accent); transform:scaleX(0); transform-origin:left;
  transition:transform .28s var(--ease);
}
.nav a:hover, .nav a[aria-current="page"]{color:var(--ink)}
.nav a:hover::after, .nav a[aria-current="page"]::after{transform:scaleX(1)}

.head-cta{justify-self:end; display:flex; align-items:center; gap:8px}
.head-cta .btn{min-height:44px; padding:0 18px; font-size:14px}

.menu-btn{
  display:none; cursor:pointer; width:44px; height:44px; border-radius:11px;
  background:var(--paper-2); border:1px solid var(--line); color:var(--ink);
  align-items:center; justify-content:center;
}
.menu-btn svg{width:22px; height:22px}
.menu-btn .x{display:none}
body.nav-open .menu-btn .bars{display:none}
body.nav-open .menu-btn .x{display:block}

@media (max-width:860px){
  :root{--head-h:64px}
  .head-row{grid-template-columns:auto 1fr auto; padding:0 16px}
  .nav{display:none}
  .brand{justify-self:start; font-size:21px}
  .menu-btn{display:inline-flex}
}

/* mobile slide-down nav panel */
.mobile-nav{
  position:fixed; top:var(--head-h); left:0; right:0; z-index:99;
  background:rgba(251,250,241,.98);
  backdrop-filter:blur(16px); -webkit-backdrop-filter:blur(16px);
  border-bottom:1px solid var(--line);
  box-shadow:0 22px 48px -30px rgba(31,38,34,.5);
  padding:14px 16px calc(20px + env(safe-area-inset-bottom));
  transform:translateY(-12px); opacity:0; visibility:hidden; pointer-events:none;
  transition:opacity .26s var(--ease), transform .26s var(--ease), visibility .26s;
}
body.nav-open .mobile-nav{opacity:1; transform:none; visibility:visible; pointer-events:auto}
.mobile-nav a{
  display:flex; align-items:center; justify-content:space-between;
  font-family:'Fraunces',Georgia,serif; font-weight:480; font-size:1.3rem;
  color:var(--ink); padding:16px 8px; min-height:56px;
  border-bottom:1px solid var(--line);
}
.mobile-nav a:last-of-type{border-bottom:0}
.mobile-nav a .arr{color:var(--accent-2); font-size:1.1rem}
.mobile-nav .btn{width:100%; margin-top:14px; min-height:54px; font-size:16px}
@media (min-width:861px){ .mobile-nav, .menu-btn{display:none !important} }

/* ============================================================
   THE DROPLET / RIPPLE MOTIF (signature)
   Organic coral blobs (not perfect circles). Settle on load,
   gentle idle drift, cursor-driven ripple ring. Editorial decoration,
   never reduces headline legibility (low opacity / kept to margins).
   ============================================================ */
.droplets{position:absolute; inset:0; z-index:0; pointer-events:none; overflow:hidden}
.drop{
  position:absolute; width:var(--d,70px); height:var(--d,70px);
  background:var(--accent);
  /* irregular organic blob */
  border-radius:62% 38% 54% 46% / 56% 44% 56% 44%;
  opacity:var(--o,.92);
  transform:rotate(var(--rot,0deg));
  will-change:transform;
}
.drop.is-soft{background:var(--sage-2)}
.drop.is-pop{background:var(--pop)}
.drop.is-hollow{
  background:transparent; border:2.5px solid var(--accent);
}
/* idle breathing drift (low amplitude). html.js + not reduced-motion. */
@keyframes drop-drift{
  0%,100%{transform:rotate(var(--rot,0deg)) translateY(0) scale(1)}
  50%    {transform:rotate(var(--rot,0deg)) translateY(var(--drift,-7px)) scale(1.035)}
}
html.js .droplets .drop{animation:drop-drift var(--dur,9s) ease-in-out infinite var(--delay,0s)}
@media (prefers-reduced-motion: reduce){ html.js .droplets .drop{animation:none} }

/* the single expanding ripple ring (one droplet emits it on load; cursor reuses) */
.drop-ripple{
  position:absolute; border-radius:50%; border:2px solid var(--accent);
  pointer-events:none; opacity:0; transform:translate(-50%,-50%) scale(.3);
  z-index:1;
}
html.js .drop-ripple.go{animation:ripple-out 1.4s var(--ease) forwards}
@keyframes ripple-out{
  0%{opacity:.55; transform:translate(-50%,-50%) scale(.3)}
  100%{opacity:0; transform:translate(-50%,-50%) scale(2.4)}
}
@media (prefers-reduced-motion: reduce){ html.js .drop-ripple{display:none} }

/* very subtle ripple that follows the cursor across the hero background.
   Spawned by site.js into the .droplets layer (behind content). */
.hero-ring{
  position:absolute; width:12px; height:12px; margin:-6px 0 0 -6px;
  border-radius:50%; border:1.5px solid var(--accent);
  opacity:0; pointer-events:none; z-index:0; will-change:transform,opacity;
  animation:heroRipple 1s cubic-bezier(.2,.6,.3,1) forwards;
}
@keyframes heroRipple{
  0%{ transform:scale(.5); opacity:.15 }
  100%{ transform:scale(7); opacity:0 }
}
@media (prefers-reduced-motion: reduce){ .hero-ring{ display:none } }

/* ============================================================
   MOTION: progressive-enhancement reveal classes
   Hidden initial state ONLY under html.js, so content is fully
   visible with JS off. Reduced-motion reveals everything.
   ============================================================ */
html.js .reveal{opacity:0; transform:translateY(20px); transition:opacity .7s var(--ease), transform .7s var(--ease)}
html.js .reveal.is-in{opacity:1; transform:none}
html.js .reveal-group > *{opacity:0; transform:translateY(20px); transition:opacity .7s var(--ease), transform .7s var(--ease)}
html.js .reveal-group.is-in > *{opacity:1; transform:none}
@media (prefers-reduced-motion: reduce){
  html.js .reveal, html.js .reveal-group > *{opacity:1 !important; transform:none !important; transition:none !important}
}

/* clip-masked headline lines (hero on-load choreography). Each .line sits in an
   overflow:hidden wrapper and rises into view. Static + visible without JS. */
/* clip-masked headline lines. CSS hides them under html.js via a single custom
   property that JS animates to 0% (no transform stacking with GSAP). */
.line-mask{display:block; overflow:hidden; padding-bottom:.08em}
html.js .line-mask > .line{display:block; transform:translateY(110%); animation:lineRise .85s cubic-bezier(.2,.8,.2,1) both}
@keyframes lineRise{from{transform:translateY(110%)} to{transform:translateY(0)}}
html.js .hero h1 .line-mask:nth-of-type(1) > .line{animation-delay:.04s}
html.js .hero h1 .line-mask:nth-of-type(2) > .line{animation-delay:.13s}
html.js .hero h1 .line-mask:nth-of-type(3) > .line{animation-delay:.22s}
html.js .hero h1 .line-mask:nth-of-type(4) > .line{animation-delay:.31s}
@media (prefers-reduced-motion: reduce){ html.js .line-mask > .line{transform:none; animation:none} }

/* link with an underline wipe (used in body copy / footer) */
.wipe{
  position:relative; color:var(--accent-2); font-weight:500;
  background:linear-gradient(var(--accent-2),var(--accent-2)) no-repeat left bottom / 0% 1.5px;
  padding-bottom:1px; transition:background-size .3s var(--ease);
}
.wipe:hover{background-size:100% 1.5px}

/* ============================================================
   CARDS (shared surface)
   ============================================================ */
.card{
  background:var(--paper-2); border:1px solid var(--line); border-radius:var(--r-card);
  transition:transform .2s var(--ease), box-shadow .25s var(--ease), border-color .2s ease;
}
.card--pad{padding:clamp(24px,3vw,34px)}
@media (hover:hover){
  .card.is-lift:hover{
    transform:translateY(-4px); border-color:rgba(190,62,24,.35);
    box-shadow:0 24px 50px -28px rgba(31,38,34,.28);
  }
}
.card-eyebrow{
  font:600 12px/1 'Inter',sans-serif; letter-spacing:.14em; text-transform:uppercase;
  color:var(--accent-2);
}
.card-title{margin:var(--s-3) 0 var(--s-2)}

/* ============================================================
   CONTACT FORM (restyled; same /api/contact behaviour)
   ============================================================ */
.rippll-form{
  background:var(--paper-2); border:1px solid var(--line); border-radius:var(--r-card);
  padding:clamp(26px,3.5vw,38px); display:grid; gap:18px;
  box-shadow:0 1px 2px rgba(31,38,34,.04), 0 26px 56px -34px rgba(31,38,34,.24);
}
.field{display:grid; gap:8px}
.field-row{display:grid; grid-template-columns:1fr 1fr; gap:18px}
@media (max-width:560px){ .field-row{grid-template-columns:1fr} }
.field label{
  display:inline-flex; align-items:center; gap:8px;
  font:600 12px/1 'Inter',sans-serif; letter-spacing:.08em; text-transform:uppercase;
  color:var(--ink);
}
.field .req{
  font:600 9px/1 'Inter',sans-serif; letter-spacing:.1em; color:var(--accent-2);
  border:1px solid rgba(190,62,24,.4); border-radius:var(--r-pill); padding:3px 7px;
}
.field input, .field textarea{
  width:100%; font:400 16px/1.5 'Inter',sans-serif; color:var(--ink);
  background:#fff; border:1.5px solid var(--line); border-radius:var(--r-input);
  padding:13px 15px; min-height:48px;
  transition:border-color .16s ease, box-shadow .16s ease;
}
.field textarea{resize:vertical; min-height:130px}
.field input::placeholder, .field textarea::placeholder{color:#9b988d}
.field input:focus, .field textarea:focus{
  outline:none; border-color:var(--accent); box-shadow:0 0 0 3px rgba(246,83,36,.16);
}
.form-actions .btn{width:100%; min-height:52px; font-size:16px}
.form-note{font-size:.84rem; color:var(--muted); text-align:center}
.form-status{font:500 .95rem/1.4 'Inter',sans-serif; min-height:1.2em}
.form-status.ok{color:var(--sage)}
.form-status.err{color:var(--accent-2)}
/* honeypot: visually + AT hidden, never tab-reachable */
.hp{position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden}
.form-success{text-align:center; padding:14px 6px}
.form-success .tick{
  width:58px; height:58px; margin:0 auto 16px; border-radius:50%;
  background:rgba(92,113,80,.14); border:1px solid rgba(92,113,80,.5);
  display:flex; align-items:center; justify-content:center; color:var(--sage);
}
.form-success h3{margin-bottom:8px}
.form-success p{color:var(--muted)}

/* ============================================================
   FOOTER (the ink bookend)
   Page bg bleeds past it (body::after) so no white overscroll.
   ============================================================ */
.site-foot{
  position:relative; z-index:1;
  background:var(--ink); color:#b9bdb3;
  padding:clamp(56px,8vw,84px) 0 clamp(40px,5vw,56px);
}
.foot-grid{
  display:grid; grid-template-columns:1.4fr 1fr 1fr; gap:clamp(28px,5vw,56px);
  align-items:start;
}
@media (max-width:760px){ .foot-grid{grid-template-columns:1fr 1fr} }
@media (max-width:480px){ .foot-grid{grid-template-columns:1fr} }
.foot-brand .brand{color:#F4F1DE}
.foot-brand .brand-mark .ring{stroke:var(--accent)}
.foot-tag{margin-top:var(--s-4); max-width:30ch; color:#9aa096; font-size:.95rem; line-height:1.6}
.foot-col h3{
  font-family:'Inter',sans-serif; font-weight:600; font-size:12px; letter-spacing:.14em;
  text-transform:uppercase; color:#8D9388; margin-bottom:16px;   /* AA on ink (4.9:1) */
}
.foot-nav{display:grid; gap:11px}
.foot-nav a{color:#c8ccc2; font-size:.95rem; width:max-content;
  border-bottom:1px solid transparent; transition:color .18s ease, border-color .18s ease}
.foot-nav a:hover{color:#fff; border-bottom-color:rgba(246,83,36,.6)}
.foot-fine{
  margin-top:clamp(40px,5vw,56px); padding-top:24px; border-top:1px solid rgba(244,241,222,.12);
  display:flex; flex-wrap:wrap; gap:12px 24px; align-items:center; justify-content:space-between;
  color:#959B8E; font-size:.85rem;   /* AA on ink (5.4:1) */
}
.foot-fine .no-track{display:inline-flex; align-items:center; gap:8px; color:#9aa096}
.foot-fine .no-track svg{width:15px; height:15px; color:var(--accent)}
