/* Paper system for community.html: the faithful finclarity layout with lifehappens' background language —
   cream paper river ribbons behind selected sections, the Divi wave where the ground colour changes,
   and the square explainer inside the urgency band. Nothing else changes. */

/* ribbons: absolutely behind the section's content, never intercepting input */
.gb-river{position:absolute;inset:0;z-index:0;pointer-events:none;background-repeat:no-repeat;background-size:110% auto;opacity:.95;-webkit-mask-image:linear-gradient(180deg,transparent 0,#000 12%,#000 78%,transparent 97%);mask-image:linear-gradient(180deg,transparent 0,#000 12%,#000 78%,transparent 97%)}
.gb-river-1{background-image:url(assets/img/river-01.png)}
.gb-river-2{background-image:url(assets/img/river-02.png)}
.gb-river-3{background-image:url(assets/img/river-03.png)}
.gb-river--br{background-position:100% 100%}
.gb-river--bl{background-position:0% 100%;transform:scaleX(-1)}
.gb-river--tl{background-position:0% 0%;transform:scaleX(-1)}
.gb-river--tr{background-position:100% 0%}
/* on forest ground the ribbon reads as a soft light band, keep it faint */
.bg-primary .gb-river{opacity:.12;mix-blend-mode:screen}
@media (max-width:900px){.gb-river{background-size:220% auto;opacity:.8}}

/* wave transitions: the source's Divi "wave" path, filled with the colour of the section above,
   sitting on the top edge of the section below */
.gb-pwave{position:absolute;left:0;right:0;top:-1px;height:clamp(48px,7vw,100px);z-index:6;pointer-events:none}
.gb-pwave svg{width:100%;height:100%;display:block}
.gb-pwave--flip{transform:scaleX(-1)}
section.gb-pt{padding-top:clamp(7rem,12vw,10rem)!important}

/* the urgency band: card + square explainer, two columns */
.gb-band-inner{display:flex;justify-content:center}
.gb-band-grid{display:grid;grid-template-columns:minmax(0,1fr);justify-items:center;width:100%;max-width:1200px}
.gb-band-grid .gb-sq{width:100%;max-width:min(1200px,94vw,calc(73vh * 27 / 19));justify-self:center;transition:transform .6s cubic-bezier(.16,1,.3,1)}
.gb-band-grid .gb-sq:hover{transform:translateY(-4px)}
.gb-band-grid .gb-sq .gb-video__cover,.gb-band-grid .gb-sq .gb-video__el{border-radius:1rem 2.5rem 1rem 2.5rem;aspect-ratio:27/19}
.gb-band-grid .gb-sq .gb-video__el,.gb-band-grid .gb-sq .gb-video__cover img{object-fit:cover;object-position:center}
@media (max-width:900px){.gb-band-grid .gb-sq{max-width:min(560px,92vw);margin-inline:auto;transform:none}}

/* square paper video card on the forest ground */
.gb-video{position:relative;width:100%}
.gb-video__cover{position:relative;display:block;width:100%;aspect-ratio:1/1;border-radius:20px;overflow:hidden;border:0;padding:0;cursor:pointer;background:#F7F3EA;box-shadow:0 12px 18px -6px rgba(0,0,0,.3),0 0 0 3px rgba(255,255,255,.14);transition:transform .5s cubic-bezier(.16,1,.3,1),box-shadow .5s}
.gb-video__cover:hover{transform:translateY(-4px);box-shadow:0 30px 60px -16px rgba(0,0,0,.45),0 0 0 3px rgba(237,174,29,.55)}
.gb-video__cover img{width:100%;height:100%;object-fit:cover;display:block}
.gb-video__play{position:absolute;left:50%;top:70%;transform:translate(-50%,-50%);width:84px;height:84px;border-radius:9999px;background:hsl(var(--primary));color:#fff;display:grid;place-items:center;box-shadow:0 12px 24px -8px rgba(0,0,0,.45);transition:transform .35s cubic-bezier(.16,1,.3,1)}
.gb-video__cover:hover .gb-video__play{transform:translate(-50%,-50%) scale(1.06)}
.gb-video__play svg{width:34px;height:34px;fill:currentColor;margin-left:4px}
.gb-video__meta{position:absolute;left:14px;bottom:12px;background:rgba(0,0,0,.72);color:#fff;font-weight:600;font-size:11px;letter-spacing:.06em;text-transform:uppercase;padding:6px 10px;border-radius:6px}
.gb-video__el{width:100%;aspect-ratio:1/1;border-radius:20px;display:block;background:#000;box-shadow:0 12px 18px -6px rgba(0,0,0,.3)}
.gb-video.is-playing .gb-video__cover{display:none}

/* ---- full-bleed community photo hero (community.html) ---- */
.gb-hero-sec{padding:0!important;background:hsl(var(--primary))}
.gb-hero{position:relative;min-height:max(100svh,720px);display:flex;align-items:center;padding:calc(88px + 4vw) 0 clamp(6rem,11vw,9rem);overflow:hidden}
.gb-hero__bg{position:absolute;inset:0}
.gb-hero__bg video,.gb-hero__bg img{width:100%;height:100%;object-fit:cover;object-position:52% 50%;display:block}
/* very slow zoom-in on first load, then holds; the clip itself loops underneath */
.gb-hero__video{transform:scale(var(--gbz,1));transform-origin:52% 58%;will-change:transform}
.gb-hero__veil{position:absolute;inset:0;-webkit-mask-image:linear-gradient(180deg,rgba(0,0,0,.45) 0,rgba(0,0,0,.7) 160px,#000 360px);mask-image:linear-gradient(180deg,rgba(0,0,0,.45) 0,rgba(0,0,0,.7) 160px,#000 360px);background:linear-gradient(270deg,rgba(17,44,40,.86) 0%,rgba(17,44,40,.70) 38%,rgba(17,44,40,.26) 66%,rgba(17,44,40,.08) 100%),linear-gradient(180deg,transparent 0%,transparent 70%,rgba(17,44,40,.5) 100%)}
.gb-hero__in{width:100%;display:flex;justify-content:flex-end}
.gb-hero__copy{max-width:680px}
@media (min-width:1100px){.gb-hero__copy{margin-right:-2vw;padding-right:0}}
.gb-hero__h1{font-size:clamp(2.5rem,4.9vw,3.85rem);line-height:1.02;letter-spacing:-.025em;font-weight:700;color:#fff}
@media (min-width:1024px){.gb-hero__h1 .gb-l{white-space:nowrap}}
.gb-hero__h1 .gb-l{color:#fff}
.gb-hero__h1 .gb-l.text-accent{color:hsl(var(--accent))!important;text-shadow:0 0 30px rgba(237,174,29,.35)}
.gb-hero__sub{margin:1.4rem 0 0;font-size:clamp(1.05rem,1.4vw,1.25rem);line-height:1.6;color:rgba(253,248,240,.9);max-width:30em}
.gb-hero__cta{margin-top:2rem}
html:not([data-gb-motion="on"]) .gb-hero__video{transform:scale(1.02)!important}
@media (max-width:640px){.gb-hero{min-height:82vh;align-items:flex-end}.gb-hero__veil{background:linear-gradient(180deg,rgba(17,44,40,.25),rgba(17,44,40,.85) 70%)}}
/* header over the photo hero: light links until the bar turns solid on scroll */
/* header: logo left (only once the bar turns white), nav centred, CTA right; fully transparent over the hero */
#siteHeader>div{display:grid!important;grid-template-columns:1fr auto 1fr;align-items:center}
#siteHeader>div>a[aria-label]{order:1;justify-self:start;transition:opacity .35s}
#siteHeader>div>nav{order:2;justify-self:center}
#siteHeader>div>button,#siteHeader>div>div{order:3;justify-self:end;width:auto}
.gb-mobile-nav{display:none}
@media (max-width:767px){
  #siteHeader>div{grid-template-columns:minmax(0,1fr) auto auto;gap:.5rem}
  #siteHeader>div>nav{display:none}
  #siteHeader>div>a[aria-label]{min-width:0}
  #siteHeader a[aria-label] img{width:auto;max-width:112px;height:36px!important}
  #siteHeader>div>[data-open-modal]{order:2;min-height:44px;padding-inline:.85rem;font-size:.78rem}
  #siteHeader>div>.gb-mobile-nav{display:block;position:relative;order:3;justify-self:end;width:auto}
  .gb-mobile-nav summary{display:grid;width:44px;height:44px;place-items:center;list-style:none;cursor:pointer;border:1px solid rgba(30,62,57,.16);border-radius:14px;background:rgba(255,255,255,.92);color:hsl(var(--primary));box-shadow:inset 0 1px 0 rgba(255,255,255,.9),0 8px 22px rgba(17,44,40,.12);transition:background .2s,border-color .2s,box-shadow .2s}
  .gb-mobile-nav summary::-webkit-details-marker{display:none}
  .gb-mobile-nav summary svg{width:22px;height:22px}
  .gb-mobile-nav[open] summary{border-color:hsl(var(--accent));background:hsl(var(--accent));box-shadow:inset 0 1px 0 rgba(255,255,255,.35),0 10px 24px rgba(17,44,40,.16)}
  .gb-mobile-nav summary:focus-visible{outline:3px solid hsl(var(--accent));outline-offset:3px}
  .gb-mobile-nav nav{position:absolute;top:calc(100% + .65rem);right:0;width:min(310px,calc(100vw - 2rem));padding:.65rem;border:1px solid rgba(30,62,57,.12);border-radius:16px;background:rgba(255,255,255,.98);box-shadow:0 24px 55px rgba(17,44,40,.2);overflow:hidden}
  .gb-mobile-nav nav a{display:flex;align-items:center;min-height:48px;padding:.7rem .85rem;border-radius:10px;color:hsl(var(--primary));font-size:.95rem;font-weight:700;text-shadow:none}
  .gb-mobile-nav nav a:hover,.gb-mobile-nav nav a:focus-visible{background:#FDF8F0;color:hsl(var(--primary));outline:none}
  #modal input,#modal select{font-size:16px!important}
  .gb-case-close{width:44px!important;height:44px!important;top:.45rem!important;right:.45rem!important}
}
#siteHeader.bg-transparent{background:transparent!important;backdrop-filter:none;-webkit-backdrop-filter:none;border-bottom:0}
#siteHeader.bg-transparent nav a{color:hsl(var(--primary));text-shadow:0 1px 10px rgba(255,255,255,.55)}
#siteHeader.bg-transparent a[aria-label]{opacity:1}
#siteHeader a[aria-label] img{height:44px!important;filter:none}
/* darken the sky under the header so nav, logo and CTA read */
.gb-hero__veil::after{content:none}

/* game plan: the three step cards drift and glint, staggered, as a living pattern interrupt */
.gb-step{animation:gbDrift 9s ease-in-out infinite;animation-delay:calc(var(--i,0)*-3s);will-change:transform;transform-origin:50% 100%}
.gb-step::after{content:"";position:absolute;top:0;left:-60%;width:45%;height:100%;background:linear-gradient(105deg,transparent,rgba(255,255,255,.10),transparent);transform:skewX(-18deg);animation:gbGlint 9s ease-in-out infinite;animation-delay:calc(var(--i,0)*-3s + 1.2s);pointer-events:none}
.gb-step:hover{animation-play-state:paused}
@keyframes gbDrift{0%,100%{transform:translateY(0) rotate(0)}30%{transform:translateY(-10px) rotate(-.4deg)}60%{transform:translateY(-4px) rotate(.35deg)}}
@keyframes gbGlint{0%,55%{left:-60%}75%{left:130%}100%{left:130%}}
/* 22 Aug 2026: was `@media (prefers-reduced-motion:reduce){...}`. A media query cannot see the
   ?motion=1 review flag, so the drift and the glint stayed dead in review even with motion forced
   on -- the cards looked like nothing had been built. Keyed off the gate's attribute instead, which
   is what the gate's own comment says this file does. Same suppression for real reduced-motion
   visitors: no attribute, no animation. */
html:not([data-gb-motion="on"]) .gb-step,html:not([data-gb-motion="on"]) .gb-step::after{animation:none}

/* embossed, glossy CTAs everywhere (no amber ring): top gloss, lower inner shade, soft drop; shine still glides */
.animate-glow-accent,.animate-glow-primary{box-shadow:inset 0 1px 0 rgba(255,255,255,.28),inset 0 -2px 0 rgba(0,0,0,.22),0 10px 22px -8px rgba(0,0,0,.5)!important;background-image:linear-gradient(180deg,rgba(255,255,255,.16) 0%,rgba(255,255,255,0) 52%,rgba(0,0,0,.10) 100%)!important;transition:transform .3s ease,box-shadow .3s ease!important}
.animate-glow-accent:hover,.animate-glow-primary:hover{box-shadow:inset 0 1px 0 rgba(255,255,255,.34),inset 0 -2px 0 rgba(0,0,0,.22),0 16px 30px -10px rgba(0,0,0,.55)!important;transform:translateY(-1px)}
.btn-elegant:after{background:linear-gradient(to right,transparent,rgba(255,255,255,.28),transparent)}
/* over the hero the CTAs get a faint cream rim for separation (light, not amber) */
.gb-hero__cta,#siteHeader.bg-transparent [data-open-modal]{box-shadow:inset 0 1px 0 rgba(255,255,255,.30),inset 0 -2px 0 rgba(0,0,0,.25),0 0 0 1.5px rgba(253,248,240,.45),0 14px 30px -10px rgba(0,0,0,.65)!important}

/* explainer tile: autoplays muted when in view; one tap for sound */
.gb-video__sound{position:absolute;left:50%;bottom:16px;transform:translateX(-50%);z-index:3;background:hsl(var(--accent));color:hsl(var(--primary));font-weight:700;font-size:13px;letter-spacing:.02em;padding:10px 16px;border-radius:9999px;border:0;display:none;align-items:center;gap:8px;cursor:pointer;box-shadow:0 10px 24px -8px rgba(0,0,0,.5);animation:gbPulse 2.2s ease-in-out infinite}
@keyframes gbPulse{0%,100%{transform:translateX(-50%) scale(1)}50%{transform:translateX(-50%) scale(1.05)}}
.gb-video.is-playing .gb-video__sound{display:inline-flex}
.gb-video.has-sound .gb-video__sound{display:none}

/* explainer prompt: a readable invitation on the cover */
.gb-band-grid .gb-video__meta{display:none}
.gb-band-grid .gb-video__cover::after{content:"Watch the 1-minute explainer · sound on";position:absolute;left:50%;bottom:9%;transform:translateX(-50%);white-space:nowrap;font-weight:700;font-size:clamp(14px,1.35vw,17px);color:hsl(var(--primary));background:rgba(253,248,240,.92);padding:8px 14px;border-radius:9999px;box-shadow:0 8px 20px -8px rgba(0,0,0,.35);pointer-events:none}
.gb-band-grid .gb-video__play{top:auto;bottom:16%;width:clamp(84px,8vw,104px);height:clamp(84px,8vw,104px);transform:translateX(-50%)}
.gb-band-grid .gb-video__cover:hover .gb-video__play{transform:translateX(-50%) scale(1.06)}

/* ---- entry motion + hero sketch collage (21 Aug 2026, saybriefly-grade grammar) ----
   One easing curve, 0.9s, small staggers. Entry uses the independent translate/scale/rotate
   properties so it never fights transform-based hover/float rules. */
:root{--gb-ease:cubic-bezier(.22,1,.36,1);
  /* ONE YELLOW FOR EVERY HIGHLIGHTER ON THE SITE (Sarah, 22 Aug 2026: the eyebrow, "The whole
     picture." and "hidden gaps" must match "I made those mistakes too." on About Us).
     The About mark is the source of truth and it is NOT solid amber -- it is the brand amber laid
     down at alpha over the paper, which is why it reads as a softer, paler yellow than a fill. Its
     body sits at .64-.68 (about.css, .who__hl::before). This is the middle of that, and because
     BOTH grounds are the same #FCFAF8 paper the two marks land on the identical rendered colour by
     construction rather than by a hardcoded composite -- change the paper and they still agree.
     It is the WHOLE INK PROFILE, not one flat colour, and copying the profile is the only way the
     two marks match at every point along the stroke instead of at one sample in the middle. The
     stops are about.css's verbatim: thin where the nib lands, heavy through the drag, thin again
     where it lifts. Note that is the OPPOSITE of what this mark used to do -- it pooled dark at the
     two ends and thinned in the centre, which measured about rgb(243,206,120) at the middle against
     About's rgb(242,200,103). Same family, visibly paler, and backwards.
     ⚠️ Do not "simplify" this back to #EDAE1D. Solid amber is a different, harder yellow, and it is
     the exact drift this token exists to stop. */
  --gb-hl-ink:linear-gradient(96deg,
              rgba(237,174,29,.30) 0%,
              rgba(237,174,29,.64) 18%,
              rgba(237,174,29,.68) 64%,
              rgba(237,174,29,.34) 100%)}
/* The solid CTAs briefly carried the logo's teal (#15847B) and Sarah reverted them: deep forest
   reads as the more fitting weight against the paper canvas. Left as a note so it is not retried. */
@keyframes gbFadeUp{0%{opacity:0;translate:0 40px}100%{opacity:1;translate:0 0}}
@keyframes gbSkIn{0%{opacity:0;translate:0 26px;rotate:calc(var(--r,0deg) - 6deg)}100%{opacity:var(--o,.5);translate:0 0;rotate:var(--r,0deg)}}
@keyframes gbSkFloat{0%,100%{transform:translateY(0)}50%{transform:translateY(-9px)}}
/* The hero's entry motion is gated by the <head> script: `.gb-pending` holds the pre-state until
   the page has painted, `.gb-play` runs it. Without JS neither class exists and the hero simply
   renders finished -- so the choreography can never again burn down behind a blank screen. */
/* No prefers-reduced-motion media query here on purpose: the <head> gate script is the one switch.
   It adds .gb-pending/.gb-play ONLY when motion is allowed (OS preference, or the ?motion=1 review
   flag), so a reduced-motion visitor never gets these classes and the hero simply renders finished.
   Duplicating the check in CSS is what made the review flag impossible before. */
.gb-pending .gb-hero__copy>*,.gb-pending .gb-sk{opacity:0}
.gb-play .gb-hero__copy>*{animation:gbFadeUp .9s var(--gb-ease) both}
.gb-play .gb-hero__copy>*:nth-child(1){animation-delay:.08s}
.gb-play .gb-hero__copy>*:nth-child(2){animation-delay:.2s}
.gb-play .gb-hero__copy>*:nth-child(3){animation-delay:.32s}
.gb-play .gb-hero__copy>*:nth-child(4){animation-delay:.44s}
.gb-play .gb-sk{animation:gbSkIn .9s var(--gb-ease) both,gbSkFloat 7.5s ease-in-out infinite;animation-delay:var(--d,.4s),calc(var(--d,.4s) + .9s)}

/* the collage keeps to the photo's quiet zones: top sky + far-left edge; copy sits right */
.gb-sketch{position:absolute;inset:0;z-index:2;pointer-events:none;color:rgba(253,248,240,.9)}
/* a soft veil-toned scrim under the top-left cluster so the white ink holds one strength
   even over the sun-glare sky (same hue as .gb-hero__veil, so it reads as photo grade) */
.gb-sketch::before{content:"";position:absolute;top:5%;left:-4%;width:36%;height:44%;background:radial-gradient(ellipse at 42% 42%,rgba(17,44,40,.44),transparent 72%)}
.gb-sk{position:absolute;opacity:var(--o,.9);rotate:var(--r,0deg);will-change:transform;filter:drop-shadow(0 2px 12px rgba(17,44,40,.9)) drop-shadow(0 0 3px rgba(17,44,40,.6))}
.gb-sk--statement{top:13%;left:3%;width:clamp(84px,9.5vw,150px);--r:-7deg;--o:.92;--d:.35s}
.gb-sk--card{top:17%;left:14.5%;width:clamp(100px,11vw,168px);--r:5deg;--o:.92;--d:.47s}
.gb-sk--policy{bottom:6%;right:5%;left:auto;width:clamp(76px,8.5vw,134px);--r:8deg;--o:.68;--d:.59s}
.gb-sk--umbrella{bottom:7%;left:3%;width:clamp(84px,9.5vw,148px);--r:-4deg;--o:.66;--d:.71s}
.gb-sk--string1{top:23%;left:8.5%;width:clamp(60px,6vw,96px);--o:.78;--d:.83s}
.gb-sk--string2{bottom:15%;right:9%;left:auto;width:clamp(44px,4.5vw,70px);--o:.72;--d:.9s}
.gb-sk--spark1{top:34%;left:12%;width:clamp(18px,1.8vw,28px);--o:.75;--d:.95s;--r:12deg}
.gb-sk--spark2{display:none}
@media (max-width:900px){.gb-sk--card,.gb-sk--policy,.gb-sk--string1,.gb-sk--string2,.gb-sk--spark1{display:none}.gb-sk--statement{top:11%;left:4%}.gb-sk--umbrella{bottom:5%;left:4%}}

/* ---- paper hero (21 Aug 2026): clean canvas, ink collage, card + advisor at the fold.
   Replaces the video hero (archived); the video-hero rules above stay for the archive. ---- */
.gb-hero--paper{background:#FCFAF8;background-image:radial-gradient(ellipse 90% 55% at 50% -5%,rgba(237,174,29,.08),transparent 70%);flex-direction:column;justify-content:center;align-items:center;min-height:max(100svh,760px);padding:calc(88px + 2vw) 0 clamp(48px,7vh,84px)}
.gb-hero--paper .gb-hero__in{justify-content:center}
.gb-hero--paper .gb-hero__copy{max-width:880px;margin:0;padding:0;text-align:center;display:flex;flex-direction:column;align-items:center}
.gb-eyebrow{display:inline-flex;align-items:stretch;margin:0 0 2.2rem;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:15px;font-weight:500;color:hsl(var(--primary))}
.gb-eyebrow__chip{display:inline-flex;align-items:center;justify-content:center;width:38px;background:hsl(var(--primary));color:#FCFAF8;border-radius:6px 0 0 6px}
.gb-eyebrow__chip svg{width:20px;height:20px}
.gb-eyebrow__hl{padding:9px 16px;background:var(--gb-hl-ink);border-radius:2px 12px 3px 10px;transform:rotate(-.4deg);clip-path:polygon(0 8%,1.5% 0,54% 4%,99% 0,100% 14%,99.2% 86%,100% 100%,46% 96%,1.2% 100%,.4% 88%)}
.gb-hero--paper .gb-hero__h1{color:hsl(var(--primary));font-size:clamp(2.5rem,5.6vw,4.35rem);line-height:1.05}
.gb-hero--paper .gb-hero__h1 .gb-l{color:inherit}
@media (min-width:900px){.gb-hero--paper .gb-hero__h1 .gb-l{white-space:nowrap}}
.gb-hero--paper .gb-hero__h1 .gb-l.text-accent{color:hsl(var(--accent))!important;text-shadow:none}
.gb-hero--paper .gb-hero__sub{color:hsl(var(--muted-foreground));margin:1.5rem auto 0;max-width:34em;text-align:center}
.gb-hero__ctas{display:flex;gap:.9rem;flex-wrap:wrap;justify-content:center;margin-top:2.2rem}
.gb-hero--paper .gb-hero__cta{margin-top:0}
.gb-hero__cta2{border:1.5px solid rgba(30,62,57,.25);background:#fff;box-shadow:0 8px 30px rgba(0,0,0,.08)}
.gb-hero__cta2:hover{border-color:rgba(30,62,57,.45)}
/* ---- the last headline line carries an amber highlighter that sweeps in 2s after load.
   Rewritten 22 Aug 2026 (Sarah: "as natural as possible, like true characteristic of highlight, not
   perfect but beautiful"). The old mark was a rounded rectangle scaled 0->1 on X -- cheap and
   composited, but it read as a BAR GROWING, not a pen being dragged: straight edges, a perfectly
   vertical leading edge, one flat coat of colour, and it stopped dead on the last letter. Four
   things separate that from a marker on paper, and all four are now here:

   1. THE NIB IS A CHISEL, so the LEADING EDGE IS SLANTED -- the top corner of the tip runs ahead of
      the bottom corner, and the edge it started from carries the same tilt. This is the most
      recognisable tell of the four, and it is the reason the wipe is a clip-path polygon and no
      longer a scale: scaling squashes the shape it is revealing, so a slant would flatten out and
      the wobble in (2) would compress as the stroke grew. clip-path reveals without distorting.
   2. THE EDGES WOBBLE, because no hand holds a line. --gb-hl-edge is a tileable SVG band with wavy
      top and bottom, used as a mask. It repeats every 2.6em rather than stretching to fit, so the
      wobble keeps the SAME frequency whether the phrase is two words or six; stretched-to-fit
      wobble reads as a wave on a short phrase and as a straight line on a long one.
   3. THE INK IS UNEVEN. It pools where the nib lands and where it lifts, thins through the middle
      where the hand is moving fastest, carries fine streaks off the edge of the tip, and runs dry
      at the tail (the second mask layer, a horizontal fade, is what does the drying).
   ⚠️ ONE STROKE, AND THAT IS A DECISION, NOT AN OMISSION (Sarah, 22 Aug 2026). There WAS a fourth
   ingredient here: a second, shorter pass on ::after that multiplied over the first so the lap went
   darker where two coats overlapped. It was removed on Sarah's instruction -- "must only be one
   highlight stroke". Do not add it back reaching for "more realistic": the phrase is a headline,
   the lap split it into two tones, and one clean pass is what was asked for. The About Us mark
   (.who__hl, about.css) still has its two passes and is a different call on a different line.

   ⚠️ THE SUM IS UNCHANGED ON PURPOSE. The stroke still starts at 2s and finishes at 2.6s. The hero
   choreography is a set of hand-checked totals (see the boot sequence below) and this stroke is the
   last beat in it -- if you retime it, re-add them and check the finish against what the rest of
   the hero expects. ---- */
.gb-hl{position:relative;z-index:0;padding:0 .1em;
  /* one tile of the wobble band. Seam-matched: the path leaves x=40 at exactly the y it entered
     x=0, top and bottom, so the repeat has no visible nick. preserveAspectRatio=none lets it
     stretch to the line's height while mask-size pins its width in em. */
  --gb-hl-edge:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2040%2024'%20preserveAspectRatio='none'%3E%3Cpath%20d='M0%203C6%201.3%2013%204.4%2020%202.7C27%201.2%2034%204.5%2040%203L40%2021.5C34%2022.9%2027%2019.9%2020%2021.6C13%2023%206%2020.1%200%2021.5Z'%20fill='%23fff'/%3E%3C/svg%3E")}
/* Pass one. The box is deliberately TALLER than the mark you see -- the mask band occupies 12.5% to
   89.6% of it and the rest is the room the wobble needs to move in.

   ⚠️ SIZED FROM THE FONT, CENTRED -- NOT INSET FROM THE LINE BOX. This was top/bottom offsets in em
   until 22 Aug 2026, which silently assumed every .gb-hl is an inline span whose box is the font's
   own content height. It is not: "financial review" sits in a `flex flex-wrap` h3, so it is
   BLOCKIFIED, and that h3 sets line-height 40px under a 44px font -- a box SHORTER than the glyphs
   it holds. Insetting from that box drew a mark that covered about the x-height and stopped, which
   reads as a partial highlight rather than a stroke.
   Centring a font-relative band fixes both cases at once and is not a coincidence: for an inline
   box the glyphs' visual centre and the box centre are the same point (both land at roughly .6em,
   half of the ascent+descent), and for the blockified one the half-leading is symmetric, so the
   glyphs stay centred in the shorter box too. 1.42em preserves the height the hero mark already
   had. If you ever put .gb-hl somewhere with a very large line-height, this still holds. */
.gb-hl::before{content:"";position:absolute;z-index:-1;left:-.06em;right:-.06em;top:50%;height:1.42em;translate:0 -50%;rotate:-.6deg;
  background:
    /* ⚠️ THE STREAKS RUN ALONG THE STROKE, NOT ACROSS IT. First pass had them at 82deg -- near
       vertical -- which at this size read as corduroy, a ribbed pattern nobody's pen makes. A
       chisel nib streaks in the DIRECTION it is dragged, so these are near-horizontal (178deg,
       just off true so they drift down the line) and deliberately faint and widely spaced. */
    repeating-linear-gradient(178deg,rgba(255,255,255,.07) 0 2.5px,rgba(255,255,255,0) 2.5px 13px),
    /* The density profile is the token's job now. A white "thin middle" radial and a black
       "pooled ends" gradient used to sit here; both were removed when this mark was matched to
       About Us, because between them they lightened the centre off the reference colour AND ran
       the ink backwards from it. Do not reintroduce a tinting layer over --gb-hl-ink -- anything
       stacked on top moves this mark off the yellow it is supposed to share. The streaks above are
       the exception and are kept deliberately near-invisible for exactly that reason. */
    var(--gb-hl-ink);
  -webkit-mask-image:var(--gb-hl-edge),linear-gradient(90deg,rgba(0,0,0,.8) 0,#000 3%,#000 92%,rgba(0,0,0,.5) 99%,rgba(0,0,0,0) 100%);
  -webkit-mask-size:2.6em 100%,100% 100%;-webkit-mask-repeat:repeat-x,no-repeat;-webkit-mask-composite:source-in;
  mask-image:var(--gb-hl-edge),linear-gradient(90deg,rgba(0,0,0,.8) 0,#000 3%,#000 92%,rgba(0,0,0,.5) 99%,rgba(0,0,0,0) 100%);
  mask-size:2.6em 100%,100% 100%;mask-repeat:repeat-x,no-repeat;mask-composite:intersect;
  clip-path:polygon(1.2% -12%,1.2% -12%,-5% 112%,-5% 112%)}
.gb-play .gb-hl::before{animation:gbHl .6s var(--gb-ease) 2s both}
/* ---- boot sequence (21 Aug 2026): coin, calculator, cards, pens, maple leaf, then the reveal.
   Default is display:none, so no JS / reduced motion / a failed gate can never leave a visitor
   staring at a cover. Only the <head> script's .gb-booting turns it on. ---- */
.gb-boot{display:none}
.gb-booting .gb-boot,.gb-booted .gb-boot{position:fixed;inset:0;z-index:9999;display:grid;place-items:center;background:#FCFAF8;background-image:radial-gradient(ellipse 80% 55% at 50% 45%,rgba(237,174,29,.10),transparent 70%)}
.gb-boot__stage{position:relative;width:clamp(92px,11vw,140px);height:clamp(92px,11vw,140px)}
.gb-boot__ic{position:absolute;inset:0;width:100%;height:100%;color:#1E3E39;opacity:0}
/* The advisor is a detailed character, not a 1.5px line mark — at the icons' size she reads as a
   smudge, so she gets half again the box. She is the payoff; she is allowed to be the biggest thing
   on screen. `max-width:none` is load-bearing: vendor.css carries Tailwind's preflight, whose
   `img{max-width:100%}` silently clamped her width back to the stage while the height honoured the
   150% -- a squashed advisor. */
.gb-boot__ic--her{inset:-25%;width:150%;height:150%;max-width:none;display:block}
/* body and hand share one 520px canvas, so stacking them at the same size re-registers them exactly */
.gb-boot__ic--her img{position:absolute;inset:0;width:100%;height:100%;max-width:none;object-fit:contain}
/* SWAP, don't dissolve. A long cross-fade was tried and rejected: with the cycle running three
   times the step, two icons were on screen together for most of the sequence and it read as
   overlap rather than change. Now the cycle (.4s) barely exceeds the step (.3s), so each icon is
   solid for most of its slot and only the last 60ms crosses over -- fast enough to read as a
   swap, long enough that no frame is ever empty. Opacity only; scale made the overlap worse. */
/* .24s/.18s, down from .4s/.3s (Sarah, 21 Aug 2026: "speed up the whole icons"). The four icons
   were eating 1.3s of a 3s boot -- 43% of it -- which left the advisor, the beat the whole sequence
   exists for, with 0.62s. Now they clear in 0.78s and she gets the rest.
   ⚠️ SCALE BOTH TOGETHER. The swap character is the RATIO (cycle 1.33x the step), not the numbers:
   it is what keeps each icon solid for most of its slot with only a brief cross, and no frame ever
   empty. Cutting the duration alone widens the gap until the stage flashes bare between icons. */
.gb-boot-run .gb-boot__ic{animation:gbBootIc .24s linear both;animation-delay:calc(var(--i) * .18s)}
@keyframes gbBootIc{0%{opacity:0}15%{opacity:1}85%{opacity:1}100%{opacity:0}}
/* The advisor arrives as the icons finish, waves, and then STANDS STILL for the last four tenths of
   a second before the cover lifts -- Sarah's pacing, corrected 21 Aug 2026. She never fades out, so
   the last thing on screen before the site is a person saying hello.

   ⚠️ THE STILLNESS IS THE POINT AND IT USED TO BE 20 MILLISECONDS. The wave once ran a full 2s from
   1.68s, landing at 3.68s against a 3.7s cover lift, so she was still mid-gesture at the cut and
   never settled -- "the woman only pauses less than a sec while waving" (Sarah). Nothing reported
   it, because every duration here was individually correct; it was the SUM that was wrong. If you
   change the wave duration or the delay below, re-add them and check the total against BOOTMS. */
/* .74s: she still starts 40ms before the last icon clears (which is now 0.78s, not 1.3s), so the
   overlap that makes her feel like the icons RESOLVING into her is preserved rather than becoming
   a gap. Move the icon timing above and this delay moves with it. */
.gb-boot-run .gb-boot__ic--her{animation:gbBootHer .28s var(--gb-ease) .74s both}
@keyframes gbBootHer{0%{opacity:0;scale:.9}100%{opacity:1;scale:1}}
/* The wave itself. The hand is a separate raster cut at the wrist; this pivots it about that joint
   (the origin is the measured wrist centre, 459.5/316.5 of the 520px canvas). ONE stroke over 0.7s
   -- out and back, nothing else, per Sarah. Amplitude is a touch wider (-16deg) than when there
   were three, because a single stroke has to register on its own; and it ends at exactly 0deg, so
   she comes to rest rather than being cut off mid-gesture.
   THE ARITHMETIC, which is the only thing that matters here. Sarah capped the advisor at ONE SECOND
   on screen in total, so her whole appearance is now budgeted inside that:
     0.74s in  +0.28s entrance -> 1.02s  +0.44s wave -> 1.46s  +0.28s stillness -> 1.74s lift.
   ⚠️ That cap and the stillness rule are in direct tension and the cap wins by arithmetic. The
   trailing pause was 1.14s and is now 0.28s, because a one-second window cannot hold an entrance, a
   wave and a one-second pause. If Sarah says the pause reads short again, the fix is to widen her
   window -- there is nothing left to take from the wave. If you change any number, re-add them and
   check against BOOTMS; the failure this sequence keeps having is a correct duration in a wrong sum. */
.gb-boot__hand{transform-origin:88.37% 60.87%}
.gb-boot-run .gb-boot__hand{animation:gbBootWave .44s ease-in-out 1.02s both}
@keyframes gbBootWave{0%{rotate:0deg}43%{rotate:-16deg}100%{rotate:0deg}}

/* The progress track. Sarah asked for something that says "loading, wait for it" -- a determinate
   hairline reads as a promise being kept, where a spinner reads as a stall. It is deliberately
   linear and exactly BOOTMS long, so it lands on full at the instant the cover lifts. */
/* sits clear of the advisor, who overflows the stage by 25% on the bottom edge */
.gb-boot__bar{position:absolute;left:50%;translate:-50% 0;bottom:calc(-1 * clamp(62px,7vw,92px));width:clamp(104px,12vw,148px);height:2px;border-radius:2px;background:rgba(30,62,57,.13);overflow:hidden}
.gb-boot__barfill{display:block;width:100%;height:100%;border-radius:2px;background:#1E3E39;transform-origin:0 50%;scale:0 1}
.gb-boot-run .gb-boot__barfill{animation:gbBootBar 1.74s linear both}/* MUST equal BOOTMS in the generator */
@keyframes gbBootBar{0%{scale:0 1}100%{scale:1 1}}

/* The cover lifts rather than just switching off: it drifts up a hair and scales past 1 as it goes,
   which reads as a curtain rising instead of a layer being deleted. */
.gb-booted .gb-boot{animation:gbBootOut .78s var(--gb-ease) both;pointer-events:none}
@keyframes gbBootOut{0%{opacity:1;scale:1;translate:0 0}100%{opacity:0;scale:1.035;translate:0 -1.5%;visibility:hidden}}
/* no-JS, reduced motion, or gate never fired: the highlighter still shows, just without the sweep.
   clip-path:none is the "both coats already down" state -- the mask, the streaks, the pooling and
   the darker lap are all static, so the reduced-motion visitor gets the SAME hand-drawn mark, just
   without watching the pen travel. That is the right reduced-motion answer here: fewer and gentler,
   not stripped. Both pseudos, and the specificity note above applies to both. */
html:not(.gb-pending):not(.gb-play) .gb-hl::before{clip-path:none}
/* The wipe. Four points, and only two of them move: A is the top corner where the nib touched down
   and D the bottom corner, both fixed; B and C are the two corners of the travelling tip. A sits
   6% RIGHT of D and B 6% right of C, which is the chisel angle -- the same tilt on the edge it
   started from and the edge it is cutting. At 0% B sits on A and C on D, so the quad has zero area
   and there is nothing to see; no separate hidden state is needed. */
@keyframes gbHl{
  0%  {opacity:0;clip-path:polygon(1.2% -12%,1.2% -12%,-5% 112%,-5% 112%)}
  3%  {opacity:1}
  100%{opacity:1;clip-path:polygon(1.2% -12%,107% -12%,101% 112%,-5% 112%)}
}
/* ink collage on paper: full-strength single ink, no halos, no scrim */
.gb-hero--paper .gb-sketch{color:#1E3E39}
.gb-hero--paper .gb-sketch::before{content:none}
.gb-hero--paper .gb-sk{filter:none;--o:1}
.gb-hero--paper .gb-sk--statement{top:32%;left:4.5%;bottom:auto;right:auto;width:clamp(130px,13vw,210px);--r:-12deg;--o:1;--d:.35s}
.gb-hero--paper .gb-sk--card{top:56%;bottom:auto;left:15.5%;width:clamp(110px,10.5vw,175px);--r:11deg;--o:1;--d:.47s}
.gb-hero--paper .gb-sk--piggy{bottom:4%;left:6.5%;top:auto;width:clamp(105px,10vw,165px);--r:-6deg;--o:1;--d:.59s}
.gb-hero--paper .gb-sk--calculator{top:31%;right:4%;left:auto;bottom:auto;width:clamp(120px,12vw,195px);--r:12deg;--o:1;--d:.44s}
.gb-hero--paper .gb-sk--policy{top:55%;bottom:auto;right:14.5%;left:auto;width:clamp(115px,11vw,180px);--r:-10deg;--o:1;--d:.56s}
.gb-hero--paper .gb-sk--umbrella{bottom:4%;right:6%;left:auto;top:auto;width:clamp(100px,9.5vw,155px);--r:6deg;--o:1;--d:.68s}
.gb-hero--paper .gb-sk--coins{bottom:6%;left:25%;top:auto;width:clamp(64px,6.5vw,104px);--r:-8deg;--o:1;--d:.74s}
.gb-hero--paper .gb-sk--receipt{bottom:6%;right:25%;left:auto;top:auto;width:clamp(64px,6.5vw,104px);--r:14deg;--o:1;--d:.78s}
.gb-hero--paper .gb-sk--string1{top:41%;left:10%;bottom:auto;width:clamp(90px,9vw,140px);--o:1;--d:.84s}
.gb-hero--paper .gb-sk--string2{top:40%;right:10%;left:auto;bottom:auto;width:clamp(90px,9vw,140px);--o:1;--d:.9s}
.gb-hero--paper .gb-sk--spark1{top:26%;left:13%;--o:.9;--d:.94s}
.gb-hero--paper .gb-sk--spark2{display:block;top:25%;right:14%;left:auto;width:clamp(24px,2.4vw,36px);--o:.9;--d:.98s}
@media (max-width:640px){
  /* The desktop sketch collage has no safe negative space on a phone. Its
     statement crossed the eyebrow and headline, while the umbrella crossed
     both CTAs. The artwork is decorative, so mobile gets the clearer editorial
     composition and desktop keeps the full collage. */
  .gb-hero--paper{min-height:auto;padding:calc(80px + 2rem) 0 4.5rem}
  .gb-hero--paper .gb-sketch{display:none}
  .gb-eyebrow{width:100%;justify-content:center;margin-bottom:1.5rem;font-size:13px;line-height:1.35}
  .gb-eyebrow__hl{display:flex;align-items:center;justify-content:center;flex:1;max-width:300px;padding:8px 12px;text-align:center}
  .gb-hero--paper .gb-hero__h1{font-size:clamp(2.25rem,10vw,2.5rem);line-height:1.04;letter-spacing:-.025em}
  .gb-hero--paper .gb-hero__sub{margin-top:1.25rem;font-size:1.02rem;line-height:1.55}
  .gb-hero__ctas{width:100%;gap:.75rem;margin-top:1.75rem}
  .gb-hero--paper .gb-hero__cta,.gb-hero--paper .gb-hero__cta2{width:100%;max-width:320px;margin-inline:auto}
}

/* NO top-padding rule for #problem. It ships at pt-0 and its scroll cue (h-24/md:h-32 plus margin)
   is the spacing -- decoration and padding are one unit here. A rule was added on 21 Aug 2026 while
   the cue was briefly moved to the Gap Finder's foot, and removed when the cue came back; adding it
   again on top of the cue double-spaces the headline off the hero.
   If this section ever does need its own padding: it cannot be a Tailwind utility. vendor.css is
   the source's COMPILED sheet, carrying .pt-0, .pt-32 and nothing in between, and no md:pt-*
   variants at all -- pt-16/md:pt-24 was tried and computes to 0px in silence. */

/* ---- scroll-triggered beats (22 Aug 2026, Sarah) ----
   Both hang off .in-view, which community.js adds once, on first intersection. The hidden-at-rest
   state is scoped to .gb-js -- a class only community.js sets, and only when the <head> motion gate
   said yes. Without it (reduced motion, no JS) the element renders finished rather than staying
   invisible forever. That scoping is the whole safety property here; do not lift these off .gb-js. */

/* "hidden gaps": the highlighter, but on view instead of 2s after load. The base .gb-play rule
   sweeps every .gb-hl on a timer, which suits a phrase in the first viewport and wrongly pre-draws
   one four sections down.
   Keyed on .gb-js, NOT .gb-play. .gb-play means "the hero's one-time entry choreography is running"
   and is absent on a repeat visit within a session and on the static-reveal path, which would have
   left this pre-drawn in both cases. .gb-js means "motion is on and the observer is live", which is
   the actual precondition. The doubled class is only there to outrank the base .gb-play .gb-hl rule
   without an !important.
   The selectors are heavier than they look for a reason. The fallback that keeps the marker drawn
   for reduced-motion visitors is `html:not(.gb-pending):not(.gb-play) .gb-hl::before`, which scores
   (0,3,2) -- an element, three classes counting both :not() arguments, and a pseudo-element. A
   plain `.gb-js .gb-hl.gb-hl--onview::before` is only (0,3,1) and loses to it. Adding html and
   splitting on :not(.in-view) puts both rules at (0,4,2): strictly higher, so neither depends on
   which one happens to come later in the file. */
.gb-hl.gb-hl--onview{display:inline-block;white-space:nowrap}
html.gb-js .gb-hl.gb-hl--onview:not(.in-view)::before{animation:none;opacity:0;clip-path:polygon(1.2% -12%,1.2% -12%,-5% 112%,-5% 112%)}
html.gb-js .gb-hl.gb-hl--onview.in-view::before{animation:gbHl .62s var(--gb-ease) .15s both}

/* "Clarity is.": movement only, no marker. The script face is drawn with a pen, so it settles out
   of a tilt rather than sliding straight up -- the rotate is what makes it read as handwriting
   arriving instead of a div animating. */
/* transition:none on the at-rest state is load-bearing. This node carries Tailwind's
   `transition-all duration-600` and an inline 200ms delay, and .gb-js is added by community.js at
   the END of body -- after first paint. Without this the word paints fully visible, then FADES OUT
   over 600ms as the hidden state lands, and only then fades back in on scroll. The hide has to
   snap; only .in-view animates. */
.gb-js .gb-rise{opacity:0;translate:0 30px;rotate:-2.5deg;transform-origin:0 80%;transition:none}
.gb-js .gb-rise.in-view{opacity:1;translate:0 0;rotate:0deg;
  transition:opacity .75s var(--gb-ease),translate .85s var(--gb-ease),rotate .85s var(--gb-ease)}

/* ---- game plan cards: pointer-reactive (22 Aug 2026, Sarah asked for playful and interactive) ----
   The card itself is NOT transformed. It already carries gbDrift on `transform` plus Tailwind's
   hover:-translate-y-2, and a third writer on that property is how this turns into a fight. Instead
   the four layers inside it move by different amounts against the pointer, which reads as depth and
   costs nothing to compose. app.js sets --px/--py (-1..1) and --mx/--my (px) on pointermove.
   The transitions are long on purpose: the lag is what makes the layers feel weighted rather than
   glued to the cursor.
   EVERY rule below is scoped to [data-gb-motion="on"] -- the attribute the <head> gate sets. It must
   NOT be a prefers-reduced-motion media query. A media query cannot see the ?motion=1 review flag,
   so it leaves the cards dead in review even with motion forced on; that was written here first and
   is exactly the failure the gate's own comment warns about. The gate is the single switch. */
.gb-step{--px:0;--py:0;--mx:50%;--my:50%}
[data-gb-motion="on"] .gb-step::before{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;opacity:0;
  background:radial-gradient(340px circle at var(--mx) var(--my),rgba(212,168,71,.18),transparent 62%);
  transition:opacity .4s var(--gb-ease)}
[data-gb-motion="on"] .gb-step:hover::before,[data-gb-motion="on"] .gb-step.is-active::before{opacity:1}
[data-gb-motion="on"] .gb-step .step-num,[data-gb-motion="on"] .gb-step__icon,
[data-gb-motion="on"] .gb-step h3,[data-gb-motion="on"] .gb-step p{transition:translate .55s var(--gb-ease),rotate .55s var(--gb-ease)}
/* the ghost numeral sits deepest, so it moves AGAINST the pointer and furthest */
[data-gb-motion="on"] .gb-step:hover .step-num{translate:calc(var(--px) * -16px) calc(var(--py) * -11px)}
[data-gb-motion="on"] .gb-step:hover .gb-step__icon{translate:calc(var(--px) * 11px) calc(var(--py) * 8px);rotate:calc(var(--px) * 7deg)}
[data-gb-motion="on"] .gb-step:hover h3{translate:calc(var(--px) * 6px) calc(var(--py) * 4px)}
[data-gb-motion="on"] .gb-step:hover p{translate:calc(var(--px) * 3px) calc(var(--py) * 2px)}
/* a press that answers back; scale, not translate, so it never fights the drift */
[data-gb-motion="on"] .gb-step:active{scale:.985;transition:scale .12s ease-out}

/* ---- the Gap Finder's reveal (21 Aug 2026, Sarah asked for a loading visual) ----
   Determinate and named on purpose. A bare spinner tells the reader to wait; this tells them what
   is being done with their five answers, which is the difference between a pause and a beat. The
   duration does NOT shrink under reduced motion -- the loader is information, not decoration, and
   a result that appears instantly reads as a result nobody looked at. Only the spin is dropped;
   the maple leaf at the centre is the same mark the boot sequence ends on. */
.gb-scan{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:clamp(2rem,6vh,4rem) 1rem;min-height:320px}
.gb-scan__mark{position:relative;width:72px;height:72px;display:grid;place-items:center;margin-bottom:1.5rem}
.gb-scan__ring{position:absolute;inset:0;color:#D4A847;animation:gbScanSpin 1.15s linear infinite}
.gb-scan__leaf{width:26px;height:26px;color:#1E3E39}
@keyframes gbScanSpin{to{rotate:360deg}}
/* same rule as everywhere else in this file: the gate's attribute, not a media query, so the
   ring still spins under ?motion=1 on a machine that reports reduced motion. */
html:not([data-gb-motion="on"]) .gb-scan__ring{animation:none;opacity:.5}
.gb-scan__title{font-weight:700;color:#1E3E39;font-size:clamp(1.05rem,1.6vw,1.25rem);margin-bottom:.35rem}
.gb-scan__sub{color:hsl(var(--muted-foreground));font-size:.875rem;margin-bottom:1.75rem}
.gb-scan__steps{display:flex;flex-direction:column;gap:.6rem;width:100%;max-width:300px;margin-bottom:1.75rem;text-align:left}
.gb-scan__step{display:flex;align-items:center;gap:.65rem;font-size:.8125rem;font-weight:600;color:#1E3E39;opacity:.3;transition:opacity .4s var(--gb-ease)}
.gb-scan__step.is-on{opacity:1}
.gb-scan__dot{width:18px;height:18px;border-radius:999px;border:2px solid rgba(30,62,57,.25);display:grid;place-items:center;flex:0 0 auto;transition:border-color .4s var(--gb-ease),background .4s var(--gb-ease)}
.gb-scan__step.is-on .gb-scan__dot{border-color:#D4A847;background:#D4A847}
.gb-scan__dot svg{width:11px;height:11px;color:#1E3E39;opacity:0;transition:opacity .3s var(--gb-ease)}
.gb-scan__step.is-on .gb-scan__dot svg{opacity:1}
.gb-scan__track{width:100%;max-width:300px;height:4px;border-radius:999px;background:rgba(30,62,57,.1);overflow:hidden}
/* The fill is full width and slides in from the left behind the track's overflow, rather than
   growing its own width: animating width is a layout animation on every frame. translateX also
   keeps the pill's end caps undistorted, which scaleX would not at this radius. JS sets the
   translate percentage; 0% is a full bar. */
.gb-scan__fill{height:100%;width:100%;border-radius:999px;background:#D4A847;transform:translateX(-100%);transition:transform .45s var(--gb-ease)}

/* the seven fixes, promised as seven marks rather than as the word "seven" */
.gb-fix7{display:flex;align-items:center;justify-content:center;gap:.4rem;margin:0 0 1rem}
.gb-fix7 span{width:22px;height:22px;border-radius:999px;display:grid;place-items:center;font-size:11px;font-weight:800;color:#1E3E39;background:rgba(212,168,71,.18);border:1px solid rgba(212,168,71,.45)}

/* ---- the Gap Finder's collage (21 Aug 2026): the hero's ink, echoed ----
   Same originals, same forest, but this section already has a card and two columns of copy, so the
   objects keep to the outer margins and run at .6 rather than full strength. They are texture here,
   not the event. Below 1280px there is no margin left to keep to, so every piece hides -- crowding
   the card was the failure mode the first attempt hit. */
.gb-sketch--check{color:#1E3E39;z-index:0}
.gb-sketch--check::before{content:none}
.gb-sketch--check .gb-sk{filter:none}
.gb-sketch--check .gb-sk--coins{top:7%;left:1.5%;right:auto;bottom:auto;width:clamp(58px,5.5vw,92px);--r:-9deg;--o:.6;--d:.35s}
.gb-sketch--check .gb-sk--piggy{bottom:6%;left:2.5%;top:auto;right:auto;width:clamp(72px,7vw,116px);--r:7deg;--o:.6;--d:.47s}
.gb-sketch--check .gb-sk--receipt{top:9%;right:2%;left:auto;bottom:auto;width:clamp(58px,5.5vw,92px);--r:12deg;--o:.55;--d:.41s}
.gb-sketch--check .gb-sk--policy{bottom:7%;right:2.5%;left:auto;top:auto;width:clamp(70px,6.5vw,110px);--r:-8deg;--o:.55;--d:.53s}
.gb-sketch--check .gb-sk--string1{top:36%;left:0.6%;right:auto;bottom:auto;width:clamp(52px,5vw,80px);--o:.45;--d:.6s}
.gb-sketch--check .gb-sk--spark1{display:block;bottom:27%;right:1.2%;left:auto;top:auto;width:clamp(18px,1.8vw,26px);--r:14deg;--o:.5;--d:.66s}
@media (max-width:1279px){.gb-sketch--check{display:none}}

/* the explainer band isolates its card: enough forest above and below that, with the card
   centred in the viewport, darkness frames all four edges and the next section's cream
   wave stays below the fold */
section.gb-explainer-band{padding-bottom:clamp(9rem,16vh,13rem)!important}
@media (max-width:767px){
  section.gb-explainer-band{padding-top:5rem!important;padding-bottom:3rem!important}
}

/* explainer tile: scale-in on view (JS adds .in-view via community.js; .gb-js gates the
   hidden state so a no-JS visitor still sees the tile).
   22 Aug 2026: the `@media (prefers-reduced-motion:no-preference)` wrapper is gone. It could not
   see the ?motion=1 review flag, so the tile never scaled in during review on a reduced-motion
   machine. .gb-js alone is the correct gate -- community.js only sets it when the <head> gate
   said yes, which already accounts for the OS preference AND the flag. */
.gb-js .gb-zoom{opacity:0;scale:.93;translate:0 24px}
.gb-js .gb-zoom.in-view{opacity:1;scale:1;translate:0 0;transition:opacity .9s var(--gb-ease),scale .9s var(--gb-ease),translate .9s var(--gb-ease),transform .6s cubic-bezier(.16,1,.3,1)}
