/* =========================================================================
   Solae Global — enhance.css
   Layered ON TOP of theme.css (loads after it). Three concerns:
   (A) Mobile refinements   (B) Premium micro-interactions   (C) Imagery
   Calm, minimal, editorial. Reuses theme.css tokens. No harsh black.
   ====================================================================== */

/* =========================================================================
   GLOBAL SAFETY — never allow horizontal overflow on any viewport
   ====================================================================== */
html,body{max-width:100%;overflow-x:hidden;}
img,svg,video,canvas{max-width:100%;height:auto;}
*{min-width:0;}            /* let grid/flex children shrink instead of pushing width */


/* =========================================================================
   (A) MOBILE REFINEMENTS
   ====================================================================== */

/* ---------- Tablet & down (<= 900px) ---------- */
@media (max-width:900px){

  /* Slightly tighter rhythm for reading on smaller screens */
  body{font-size:15.5px;}
  section{padding:clamp(56px,12vw,84px) 0;}

  /* Heading scale — keep the editorial serif elegant, never cramped */
  .hero h1{font-size:clamp(38px,9vw,58px);}
  .sec-head h2{font-size:clamp(27px,6vw,38px);}
  .close-strip h2{font-size:clamp(30px,8vw,48px);}
  .thesis-q{font-size:clamp(26px,6.4vw,40px);}

  /* Balanced hero on phones: centered column, comfortable globe */
  .hero{padding-top:104px;padding-bottom:48px;}
  .hero .sub{margin-top:20px;}
  .hero-actions{margin-top:28px;gap:12px;}
  .proofbar{gap:22px 32px;padding-top:22px;}

  /* Comfortable tap targets everywhere (>= 44px) */
  .btn,.hd-cta,.fnav .btn{min-height:48px;display:inline-flex;align-items:center;justify-content:center;}
  nav.primary a.nl,.textlink,.ft li a,.crumb a,.note-card .read{min-height:44px;display:inline-flex;align-items:center;}
  .burger{min-width:44px;min-height:44px;display:inline-flex;align-items:center;justify-content:center;}
  .acc-head,.faq-q{min-height:48px;}

  /* Cards stack to two-up gracefully (most already do at 880px) */
  .mand-grid,.sector-grid,.j-grid{gap:14px;}

  /* Founder card: drop the sticky behaviour so it flows naturally */
  .f-card{position:static;top:auto;}

  /* Record band breathes a touch more */
  .record .lbl{margin-bottom:26px;}
}

/* ---------- Phone (<= 600px) ---------- */
@media (max-width:600px){

  /* Section padding tuned for narrow screens, still airy */
  section{padding:52px 0;}
  .sec-head{margin-bottom:30px;}

  /* Hero — full single column, generous but balanced */
  .hero{min-height:auto;padding-top:96px;padding-bottom:44px;}
  .hero h1{font-size:clamp(34px,10vw,46px);line-height:1.06;margin-top:16px;}
  .hero .sub{font-size:15.5px;max-width:100%;}
  #globe{max-width:260px;}
  .globe-cap{font-size:8px;}

  /* Hero actions become full-width stacked buttons — easy thumbs */
  .hero-actions{flex-direction:column;align-items:stretch;width:100%;}
  .hero-actions .btn,.hero-actions .textlink{width:100%;text-align:center;justify-content:center;}
  .hero-actions .textlink{border-bottom:0;}

  /* Proofbar: two-column ledger reads cleaner than a wrap pile */
  .proofbar{display:grid;grid-template-columns:1fr 1fr;gap:20px 24px;}

  /* Platform strip stacks label over names */
  .strip .inner{flex-direction:column;align-items:flex-start;gap:10px;}

  /* ----- Cards: always single column on phones ----- */
  .mand-grid,.sector-grid,.j-grid,.method-grid{grid-template-columns:1fr;}

  /* ----- Accordion: tags wrap above headings comfortably ----- */
  .acc-head{grid-template-columns:minmax(0,1fr) auto;gap:14px;padding:20px 0;}
  .acc-head h3{font-size:clamp(21px,6.2vw,26px);}
  .acc-inner{grid-template-columns:1fr;gap:20px;}

  /* ----- FAQ: comfortable on the smallest screens ----- */
  .faq-q{font-size:17px;padding:18px 0;gap:14px;}
  .faq-a p{font-size:14.5px;}

  /* ----- Record band at 375px: two-up, large brass numerals ----- */
  .record{padding:48px 0;}
  .rec-grid{grid-template-columns:1fr 1fr;gap:26px 20px;}
  .rec .v{font-size:clamp(34px,11vw,44px);}
  .record .foot{margin-top:28px;}

  /* ----- Proposal / evaluation form: roomy, tappable, no overflow ----- */
  .eval-grid{gap:32px;}
  .form-card{padding:22px 18px;border-radius:6px;}
  .field{margin-bottom:18px;}
  /* 16px inputs prevent iOS auto-zoom (which causes layout shift/overflow) */
  .field input,.field select,.field textarea{font-size:16px;padding:14px 14px;}
  .field textarea{min-height:104px;}
  .fnav{flex-direction:column;gap:10px;}
  .fnav .btn,.fnav .btn.back{width:100%;flex:1 1 auto;}
  .received .ref{flex-direction:column;gap:8px;}

  /* ----- Footer at 375px: single column, generous spacing ----- */
  .ft-grid{grid-template-columns:1fr;gap:30px;}
  .ft-bottom{flex-direction:column;gap:10px;}

  /* Closing meta wraps to a calm centred stack */
  .close-meta{gap:10px 24px;}

  /* Interior page heroes */
  .page-hero{padding-top:clamp(120px,26vw,150px);}
  .page-hero h1{font-size:clamp(32px,10vw,44px);}
}

/* ---------- Very small phones (<= 380px / 375px target) ---------- */
@media (max-width:380px){
  .wordmark{font-size:11.5px;letter-spacing:.28em;}
  .hd-cta{padding:11px 14px;letter-spacing:.1em;}
  .hero h1{font-size:clamp(30px,11vw,40px);}
  .rec .v{font-size:34px;}
  .proofbar{gap:18px 18px;}
}


/* =========================================================================
   (A2) MOBILE OVERLAP HARDENING  —  reported on real phones
   Two breakpoints (<=720px, <=560px) that GUARANTEE no clipped or
   overlapping text anywhere: Journal index (.j-grid of .note-card +
   .note-card.lock + .brief-box), plus hero, .record stat grid, .svc-grid,
   .prac-grid, cards and footer. Grids collapse to one clean column, every
   text block flows in normal document order (no transforms, no absolute
   positioning over copy), and line-height stays comfortable.
   ====================================================================== */

/* ---------- Tablet / large phone (<= 720px) ---------- */
@media (max-width:720px){

  /* Kill any leftover 3D tilt that the JS may have applied on touch: a
     persisted perspective()/rotate() is the usual cause of cards visually
     overlapping their neighbours on phones. JS also guards this now, but
     CSS makes the static end-state certain. */
  .note-card,.mand,.sector,.step,.geo-demo,[data-tilt]{
    transform:none !important;
    perspective:none;
    transform-style:flat;
  }

  /* Journal index — single, comfortable reading column on real phones.
     Each card is a normal flex column; restating it here protects against
     any inherited transform/stacking from the animation layer. */
  .j-grid{grid-template-columns:1fr;gap:16px;}
  .note-card{
    position:relative;
    transform:none !important;
    display:flex;flex-direction:column;gap:12px;
    overflow:hidden;                 /* contain the bleed image, never the text */
  }
  .note-card h3{
    font-size:clamp(20px,5.6vw,24px);
    line-height:1.28;
    overflow-wrap:anywhere;          /* long titles wrap, never clip */
    word-break:break-word;
  }
  .note-card p{line-height:1.6;overflow-wrap:anywhere;}
  .note-card .nc-meta{position:static;row-gap:6px;}
  /* Lock cards: the "Private" pill sits in normal flow above the heading,
     never floating over it. */
  .note-card.lock .lockpill{position:static;align-self:flex-start;margin-bottom:2px;}

  /* The Brief signup box spans the column cleanly, no fixed max that could
     leave it stranded beside following copy. */
  .brief-box{max-width:100%;}

  /* Generic card grids fold to one column with breathing room. */
  .svc-grid,.mand-grid,.sector-grid,.method-grid,.prac-grid{
    grid-template-columns:1fr;
    gap:16px;
  }
  /* Practice split (text + aside) stacks; aside follows the prose. */
  .prac-grid > *{min-width:0;}

  /* Record stat band: two-up grid, no value clipping. */
  .rec-grid{grid-template-columns:1fr 1fr;gap:28px 20px;}
  .rec .v{line-height:1.04;overflow-wrap:break-word;}
  .rec .lbl,.rec .k{line-height:1.4;}

  /* Footer collapses to a single column, links stay tappable & unclipped. */
  .ft-grid{grid-template-columns:1fr;gap:30px;}
  .ft-grid li{line-height:1.6;}

  /* Headings everywhere: comfortable leading, wrap don't clip. */
  .sec-head h2,.close-strip h2,.page-hero h1,.hero h1{
    overflow-wrap:anywhere;
  }
  h1,h2,h3{line-height:1.18;}
  p,li{line-height:1.6;}

  /* The platform strip label + marquee never collide. */
  .strip .inner{margin-bottom:10px;}
}

/* ---------- Phone (<= 560px) ---------- */
@media (max-width:560px){

  /* Single column for EVERY card grid, including the Journal index. */
  .j-grid,.svc-grid,.mand-grid,.sector-grid,.method-grid{
    grid-template-columns:1fr;
  }

  /* Record band: still two-up reads best for short numerals; if a label is
     long it now wraps instead of overlapping the next cell. */
  .rec-grid{grid-template-columns:1fr 1fr;gap:24px 16px;}

  /* Tighten card inner padding a touch so long words have room to wrap. */
  .note-card{padding:20px 18px;}
  .note-card h3{font-size:clamp(19px,6vw,23px);}

  /* Brief signup form: full-width, no horizontal overflow from the button. */
  .brief-box{padding:22px 18px;}
  .brief-box .btn{width:100%;}

  /* Footer single column already set at 720px; keep bottom row stacked. */
  .ft-bottom{flex-direction:column;gap:10px;align-items:flex-start;}
}


/* =========================================================================
   (B) PREMIUM MICRO-INTERACTIONS
   Everything here is purely decorative and disabled under
   prefers-reduced-motion: reduce (see the guard block at the end of B).
   ====================================================================== */

/* ---------- Scroll-progress bar (width driven by JS) ---------- */
.scroll-progress{
  position:fixed;top:0;left:0;
  height:2px;width:0;            /* JS sets width: 0–100% */
  background:var(--brass);
  z-index:200;                   /* above header (z-index:90) and mmenu (80) */
  pointer-events:none;
  transition:width .12s linear;
  will-change:width;
}

/* ---------- Refined .btn hover: soft gold sheen + 1px lift ---------- */
.btn{position:relative;overflow:hidden;will-change:transform;}
.btn::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(120deg,
    transparent 0%,
    rgba(255,255,255,.18) 48%,
    rgba(231,201,139,.30) 50%,
    rgba(255,255,255,.18) 52%,
    transparent 100%);
  transform:translateX(-120%);
  transition:transform .7s cubic-bezier(.22,.61,.36,1);
  pointer-events:none;
}
.btn:hover{transform:translateY(-1px);}        /* softer than theme's -2px */
.btn:hover::after{transform:translateX(120%);} /* sheen sweeps across */
.btn.ghost::after{display:none;}               /* ghost stays understated */

/* ---------- Animated growing underline ---------- */
/* Applies to inline text links and primary nav items. The theme draws a
   static brass border-bottom; here we replace it with one that grows from
   the left on hover for a refined, intentional feel. */
.textlink,
nav.primary a.nl{
  position:relative;
  border-bottom:0;                /* remove theme's static rule, redraw below */
  padding-bottom:4px;
}
.textlink::after,
nav.primary a.nl::after{
  content:"";position:absolute;left:0;bottom:0;
  width:100%;height:1px;
  background:var(--brass);
  transform:scaleX(0);
  transform-origin:left center;
  transition:transform .4s cubic-bezier(.22,.61,.36,1);
}
.textlink:hover::after,
nav.primary a.nl:hover::after,
nav.primary a.nl:focus-visible::after{transform:scaleX(1);}

/* Keep the active nav item's underline persistently drawn */
nav.primary a.nl.act{border-bottom:0;}
nav.primary a.nl.act::after{
  background:var(--brass);
  transform:scaleX(1);
}

/* ---------- Marquee (horizontal auto-scroll, pause on hover) ---------- */
.marquee{
  overflow:hidden;width:100%;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
}
.marquee-track{
  display:inline-flex;flex-wrap:nowrap;align-items:center;
  gap:clamp(28px,5vw,56px);
  white-space:nowrap;
  width:max-content;
  /* CSS animation is only a FALLBACK for when JS hasn't taken over yet.
     enhance.js adds .js-marquee to the track and then drives the transform
     itself with requestAnimationFrame (works on every device, including iOS
     Safari with Reduce Motion / Low Power on). */
  animation:solae-marquee 38s linear infinite;
  will-change:transform;
}
.marquee:hover .marquee-track{animation-play-state:paused;}
/* Once the JS driver is live it owns the transform — stop the CSS keyframes
   so the two never fight (and so hover-pause is handled by JS instead). */
.marquee-track.js-marquee{animation:none;}
@keyframes solae-marquee{
  from{transform:translateX(0);}
  to{transform:translateX(-50%);}   /* duplicate the content in HTML for a seamless loop */
}

/* ---------- Tilt baseline (JS may set --tx/--ty/--rx/--ry) ---------- */
[data-tilt]{
  transition:transform .35s cubic-bezier(.22,.61,.36,1);
  transform-style:preserve-3d;
  will-change:transform;
}

/* ---------- Reduced-motion guard for ALL of section B ---------- */
@media (prefers-reduced-motion:reduce){
  .scroll-progress{transition:none;}
  .btn{transition:none;}
  .btn::after{display:none;}
  .btn:hover{transform:none;}
  .textlink::after,
  nav.primary a.nl::after{transition:none;transform:scaleX(0);}
  /* Without motion, fall back to the theme's clear static underline */
  .textlink:hover,
  nav.primary a.nl:hover{border-bottom:1px solid var(--brass);}
  nav.primary a.nl.act{border-bottom:1px solid var(--brass);}
  /* The founder wants the platform marquee to scroll on EVERY device, like
     the globe always spins. So we no longer freeze it under reduced motion:
     the JS rAF driver keeps running and owns the transform. We only drop the
     CSS keyframes here (the JS sets .js-marquee anyway) and, if JS never runs,
     a slow CSS fallback still scrolls it gently. */
  .marquee-track{
    animation:solae-marquee 60s linear infinite;
  }
  .marquee-track.js-marquee{animation:none;}
  .marquee{-webkit-mask-image:none;mask-image:none;}
  [data-tilt]{transition:none;transform:none !important;}
}


/* =========================================================================
   (C) IMAGE STYLING
   ====================================================================== */

/* ---------- .img-frame — bordered, rounded, soft-shadowed image well ---------- */
.img-frame{
  overflow:hidden;
  border:1px solid var(--line);
  border-radius:4px;
  background:var(--paper-2);
  box-shadow:0 22px 50px -34px rgba(138,101,38,.45);
  line-height:0;                 /* kill inline-image gap */
}
.img-frame img{
  width:100%;height:100%;
  object-fit:cover;
  transform:scale(1);
  transition:transform .8s cubic-bezier(.22,.61,.36,1);
  will-change:transform;
}
.img-frame:hover img{transform:scale(1.04);}

/* ---------- .reveal-img — blurred/scaled in, clears when JS adds .in ---------- */
.reveal-img{
  opacity:0;
  transform:scale(.98);
  filter:blur(8px);
  transition:opacity 1s cubic-bezier(.22,.61,.36,1),
             transform 1s cubic-bezier(.22,.61,.36,1),
             filter 1s cubic-bezier(.22,.61,.36,1);
  will-change:opacity,transform,filter;
}
.reveal-img.in{
  opacity:1;
  transform:none;
  filter:blur(0);
}

/* ---------- .visual-band — full-width section wrapper for art/imagery ---------- */
.visual-band{
  position:relative;
  width:100%;
  overflow:hidden;
  background:var(--paper-3);
  border-top:1px solid var(--line);
  border-bottom:1px solid var(--line);
}
.visual-band > img,
.visual-band > picture > img{
  width:100%;
  display:block;
  object-fit:cover;
}

/* ---------- .media-grid — responsive auto-fit image grid ---------- */
.media-grid{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(min(100%,240px),1fr));
  gap:clamp(12px,2vw,24px);
  align-items:start;
}
.media-grid .img-frame{aspect-ratio:4/3;}

@media (max-width:600px){
  .media-grid{
    grid-template-columns:repeat(auto-fit,minmax(min(100%,160px),1fr));
    gap:12px;
  }
  .visual-band{border-radius:0;}
}

/* Hover scale is purely decorative — settle it for reduced motion */
@media (prefers-reduced-motion:reduce){
  .img-frame img{transition:none;}
  .img-frame:hover img{transform:none;}
  .reveal-img{opacity:1;transform:none;filter:none;transition:none;}
}


/* =========================================================================
   (D) FINISHING TOUCHES — driven by anim.js
   New, additive flourishes only. anim.js itself does nothing under
   prefers-reduced-motion, so these never activate then; the guard block at
   the end of (D) is belt-and-braces for the static fallbacks.
   Reuses the brand tokens and the house easing cubic-bezier(.22,.61,.36,1).
   ====================================================================== */

/* ---------- 1. Hero entrance — refined staggered clip + rise ----------
   anim.js sets --hi (child index) on each .hero-copy child and adds
   .solae-hero-in once. We start the children clipped + lifted, then settle
   them with a slightly longer, smoother curve than the default .rv. This is
   scoped tightly to .hero-copy so it doesn't touch other .rv elements. */
.hero-copy.solae-hero-in > *{
  --hi:0;
  opacity:0;
  transform:translateY(22px);
  clip-path:inset(0 0 100% 0);
  -webkit-clip-path:inset(0 0 100% 0);
  animation:solae-hero-rise .9s cubic-bezier(.22,.61,.36,1) forwards;
  animation-delay:calc(var(--hi) * .09s + .05s);
  will-change:transform,opacity,clip-path;
}
@keyframes solae-hero-rise{
  to{
    opacity:1;
    transform:none;
    clip-path:inset(0 0 0 0);
    -webkit-clip-path:inset(0 0 0 0);
  }
}

/* ---------- 5. Globe settle — soft scale + opacity on load ----------
   anim.js adds .solae-globe-pre (initial state) then .solae-globe-settle on
   the next frames. The globe canvas keeps spinning underneath; we only ease
   its first appearance. */
#globe.solae-globe-pre{
  opacity:0;
  transform:scale(.94);
}
#globe.solae-globe-settle{
  opacity:1;
  transform:scale(1);
  transition:opacity 1.1s cubic-bezier(.22,.61,.36,1),
             transform 1.1s cubic-bezier(.22,.61,.36,1);
}

/* ---------- 2. Staggered groups — re-time the existing .rv reveal ----------
   anim.js adds .solae-stagger to a grid (when it scrolls into view) and sets
   --si (child index) on each child. We ONLY add a transition-delay so the
   theme's own .rv -> .rv.in reveal sequences child-by-child. The opacity /
   transform of the reveal still belong to theme.css; we never redefine them.
   The inline transition-delay some children carry is overridden here. */
.solae-stagger > *{
  --si:0;
  transition-delay:calc(var(--si) * .08s) !important;
}

/* ---------- 4. Heading underline draw ----------
   anim.js tags each .sec-head h2 with .solae-uline, then adds .drawn when it
   enters view. A thin gold line grows from the left beneath the heading. */
.sec-head h2.solae-uline{
  position:relative;
  padding-bottom:.18em;
}
.sec-head h2.solae-uline::after{
  content:"";
  position:absolute;
  left:0;
  bottom:0;
  width:clamp(48px,7vw,84px);
  height:2px;
  background:var(--brass-deep,var(--brass));
  transform:scaleX(0);
  transform-origin:left center;
  transition:transform .8s cubic-bezier(.22,.61,.36,1);
  will-change:transform;
}
.sec-head h2.solae-uline.drawn::after{
  transform:scaleX(1);
}

/* ---------- 3. Magnetic buttons ----------
   The drift itself is applied as an inline transform by anim.js. We only make
   sure the base .btn carries a transform-friendly hint; the theme/enhance
   already set will-change:transform on .btn, so there is little to add here. */
.btn:not(.ghost){
  transform-origin:center;
}

/* ---------- Reduced-motion guard for ALL of section (D) ----------
   anim.js is a no-op under reduced motion, so the JS-added classes never
   appear. These rules simply guarantee a calm static end-state in case any
   class is present for other reasons. */
@media (prefers-reduced-motion:reduce){
  .hero-copy.solae-hero-in > *{
    animation:none;
    opacity:1;
    transform:none;
    clip-path:none;
    -webkit-clip-path:none;
  }
  #globe.solae-globe-pre,
  #globe.solae-globe-settle{
    opacity:1;
    transform:none;
    transition:none;
  }
  .solae-stagger > *{transition-delay:0s !important;}
  .sec-head h2.solae-uline::after{
    transition:none;
    transform:scaleX(1);
  }
}


/* =========================================================================
   (E) REFINED INTERACTIVITY — driven by anim.js (sections 6–8) + pure CSS
   New, additive flourishes layered on top of (D). anim.js does nothing under
   prefers-reduced-motion, so the JS-driven pieces never activate then; the
   guard block at the end of (E) settles every static fallback regardless.
   All easing uses the house curve cubic-bezier(.22,.61,.36,1) and brand
   tokens only (--ink, --brass, --brass-deep, --paper).
   ====================================================================== */

/* ---------- 1b. Homepage service grid stagger ----------
   anim.js now includes .svc-grid in its stagger groups, so each .svc card
   re-times the theme's .rv reveal via --si (handled by the .solae-stagger
   rule in section D). Nothing extra is required for the timing; we only add
   a gentle, on-brand hover lift for the cards themselves so the grid feels
   as tactile as the tilt cards elsewhere. Harmless if .svc is absent. */
.svc{
  transition:transform .4s cubic-bezier(.22,.61,.36,1),
             box-shadow .4s cubic-bezier(.22,.61,.36,1),
             border-color .4s cubic-bezier(.22,.61,.36,1);
  will-change:transform;
}
.svc:hover{
  transform:translateY(-3px);
  box-shadow:0 22px 50px -34px rgba(138,101,38,.5);
}

/* ---------- 6. Cursor follower (fine-pointer only) ----------
   anim.js injects .solae-cursor (a fixed, non-interactive layer) holding a
   ring and a dot. The dot tracks the cursor exactly; the ring lags with
   eased rAF. Both grow + shift toward brass over interactive elements
   (.hot) and contract on press (.down). Low opacity, strictly on-brand.
   Only ever created on (pointer:fine) + (hover:hover) devices. */
.solae-cursor{
  position:fixed;
  inset:0;
  z-index:300;                 /* above the scroll-progress bar (200) */
  pointer-events:none;         /* never blocks clicks / hovers */
  opacity:0;
  transition:opacity .35s cubic-bezier(.22,.61,.36,1);
}
.solae-cursor.on{opacity:1;}
.solae-cursor-dot,
.solae-cursor-ring{
  position:absolute;
  top:0;
  left:0;
  border-radius:50%;
  pointer-events:none;
  will-change:transform;       /* transform set inline by anim.js */
}
.solae-cursor-dot{
  width:6px;
  height:6px;
  margin:-3px 0 0 -3px;        /* centring is also handled inline; this is a safety net */
  background:var(--ink);
  opacity:.55;
  transition:width .25s cubic-bezier(.22,.61,.36,1),
             height .25s cubic-bezier(.22,.61,.36,1),
             background-color .25s cubic-bezier(.22,.61,.36,1),
             opacity .25s cubic-bezier(.22,.61,.36,1);
}
.solae-cursor-ring{
  width:34px;
  height:34px;
  margin:-17px 0 0 -17px;
  border:1px solid var(--ink);
  opacity:.22;
  transition:width .3s cubic-bezier(.22,.61,.36,1),
             height .3s cubic-bezier(.22,.61,.36,1),
             border-color .3s cubic-bezier(.22,.61,.36,1),
             opacity .3s cubic-bezier(.22,.61,.36,1);
}
/* Over interactive elements — the ring opens up and warms to brass. */
.solae-cursor.hot .solae-cursor-ring{
  width:54px;
  height:54px;
  margin:-27px 0 0 -27px;
  border-color:var(--brass-deep);
  opacity:.5;
}
.solae-cursor.hot .solae-cursor-dot{
  width:4px;
  height:4px;
  margin:-2px 0 0 -2px;
  background:var(--brass-deep);
  opacity:.7;
}
/* Over dark sections (footer, cookie bar) — switch to a light cursor so it never disappears. */
.solae-cursor.on-dark .solae-cursor-dot{background:var(--paper);opacity:.7;}
.solae-cursor.on-dark .solae-cursor-ring{border-color:var(--paper);opacity:.34;}
.solae-cursor.on-dark.hot .solae-cursor-dot{background:var(--brass);}
.solae-cursor.on-dark.hot .solae-cursor-ring{border-color:var(--brass);opacity:.6;}
/* Press — a subtle contraction for tactile feedback. */
.solae-cursor.down .solae-cursor-ring{
  width:26px;
  height:26px;
  margin:-13px 0 0 -13px;
  opacity:.4;
}
/* Hide the native arrow only while our follower is live, so the two don't
   compete. Inputs/text keep their own cursors for usability. */
@media (pointer:fine) and (hover:hover){
  html:has(.solae-cursor) body{cursor:none;}
  html:has(.solae-cursor) a,
  html:has(.solae-cursor) button,
  html:has(.solae-cursor) .btn,
  html:has(.solae-cursor) .svc,
  html:has(.solae-cursor) [data-tilt]{cursor:none;}
  /* Always keep a real caret where typing happens. */
  html:has(.solae-cursor) input,
  html:has(.solae-cursor) textarea,
  html:has(.solae-cursor) select,
  html:has(.solae-cursor) [contenteditable]{cursor:auto;}
}

/* ---------- 7. Scroll-linked heading parallax ----------
   anim.js sets an inline translate3d on .eyebrow / .sec-head h2 while they
   pass through the viewport and tags them .solae-parallax. We only declare
   will-change + a soft transition for the reset so the drift reads as depth,
   never jitter. The transform value itself is owned by JS. */
.solae-parallax{
  will-change:transform;
  transition:transform .1s linear;
}

/* ---------- 8. Eyebrow reveal — refined fade + rise ----------
   anim.js tags every .eyebrow with .solae-eyebrow, then adds
   .solae-eyebrow-in when it enters view. We use our OWN class so this never
   collides with theme.js's .rv -> .rv.in on the same node. Subtle, slower,
   and with a touch of brass-tracking warmth on arrival. */
.eyebrow.solae-eyebrow{
  opacity:0;
  transform:translateY(10px);
  transition:opacity .9s cubic-bezier(.22,.61,.36,1),
             transform .9s cubic-bezier(.22,.61,.36,1),
             letter-spacing .9s cubic-bezier(.22,.61,.36,1);
}
.eyebrow.solae-eyebrow.solae-eyebrow-in{
  opacity:1;
  transform:none;
}
/* If JS never runs (no IO / disabled), the .rv path or this fallback keeps
   eyebrows fully visible — see the reduced-motion guard below. */

/* ---------- 4b. Link micro-interactions: arrow nudge ----------
   .textlink and .svc-link copy often end in a trailing arrow ("→"). On hover
   we nudge the whole link's trailing glyph forward a touch. The growing
   underline for .textlink already lives in section B; here we add the same
   refined underline to .svc-link and a shared arrow-nudge for both. We shift
   an ::before/inherited arrow by animating padding so we never touch markup. */
.svc-link{
  position:relative;
  display:inline-flex;
  align-items:center;
  gap:.5em;
  padding-bottom:4px;
  transition:color .3s cubic-bezier(.22,.61,.36,1);
}
.svc-link::after{
  content:"";
  position:absolute;
  left:0;
  bottom:0;
  width:100%;
  height:1px;
  background:var(--brass);
  transform:scaleX(0);
  transform-origin:left center;
  transition:transform .4s cubic-bezier(.22,.61,.36,1);
}
.svc-link:hover::after,
.svc-link:focus-visible::after{transform:scaleX(1);}

/* Arrow nudge — animate the trailing arrow on links that end in one.
   We move an inline-block pseudo on the text via a CSS custom translate on a
   trailing-arrow span when present; for plain-text arrows we nudge via a
   transition on the link's text-indent-free trailing margin. Kept gentle. */
.textlink,
.svc-link{
  --arrow-shift:0px;
}
.textlink:hover,
.svc-link:hover{
  --arrow-shift:4px;
}
/* When the link wraps its arrow in <span class="arrow"> it animates cleanly.
   This is progressive: links without it simply get the underline grow. */
.textlink .arrow,
.svc-link .arrow{
  display:inline-block;
  transition:transform .35s cubic-bezier(.22,.61,.36,1);
  transform:translateX(var(--arrow-shift));
}

/* ---------- Reduced-motion guard for ALL of section (E) ----------
   anim.js is a no-op under reduced motion (it early-returns), so none of the
   JS-driven classes appear. These rules guarantee a calm static end-state
   for the pure-CSS pieces and any class that might be present otherwise. */
@media (prefers-reduced-motion:reduce){
  .svc{transition:none;}
  .svc:hover{transform:none;box-shadow:none;}

  /* Cursor follower never gets built (JS early-returns), but settle styling
     and restore the native cursor as belt-and-braces. */
  .solae-cursor{display:none !important;}
  html:has(.solae-cursor) body,
  html:has(.solae-cursor) a,
  html:has(.solae-cursor) button,
  html:has(.solae-cursor) .btn,
  html:has(.solae-cursor) .svc,
  html:has(.solae-cursor) [data-tilt]{cursor:auto;}

  .solae-parallax{transition:none;transform:none !important;}

  .eyebrow.solae-eyebrow{
    opacity:1;
    transform:none;
    transition:none;
  }

  .svc-link::after{transition:none;transform:scaleX(0);}
  .svc-link:hover{border-bottom:1px solid var(--brass);}
  .textlink .arrow,
  .svc-link .arrow{transition:none;transform:none;}
}
