/* ============================================================================
   MOTION-PLUS — 2026-08-09
   The award pass. Loaded AFTER styles.css and signature.css on the marketing
   pages. Every effect here performs the site's argument; none is decoration.

   NOT LOADED ON get-help.html. That page carries no motion.js, no .rv and no
   third-party JS by founder ruling — it is read by someone in crisis, possibly
   on an old phone on cellular data. Nothing in this file may ever be linked
   from it. The same goes for anything that would delay reaching 211.

   Everything degrades to a finished static state under prefers-reduced-motion.
   ========================================================================== */

/* --- 1. THE RAIL STAMPS ----------------------------------------------------
   Crossing into a section stamps the readout like a docket stamp hitting
   paper, and the spine flashes a notch at that point. signature.js adds
   .is-swap on the readout; .sig--stamp is added on the rail for one beat. */
.sig__now{transform-origin:50% 50%}
.sig--stamp .sig__now{animation:sig-stamp 420ms var(--ease-punch)}
@keyframes sig-stamp{
  0%{transform:rotate(180deg) scale(1.14);opacity:.35}
  55%{transform:rotate(180deg) scale(.97);opacity:1}
  100%{transform:rotate(180deg) scale(1);opacity:1}
}
.sig--stamp .sig__tok{animation:sig-notch 460ms var(--ease-punch)}
@keyframes sig-notch{
  0%{box-shadow:0 0 0 3px var(--canvas),0 0 14px 2px rgba(224,122,47,.5)}
  40%{box-shadow:0 0 0 3px var(--canvas),0 0 0 8px rgba(224,122,47,.28),0 0 22px 6px rgba(224,122,47,.7)}
  100%{box-shadow:0 0 0 3px var(--canvas),0 0 14px 2px rgba(224,122,47,.5)}
}

/* --- 2. THE FIGURE THAT REFUSES TO CLOSE -----------------------------------
   01's fourth figure is ZERO, outlined, and the tape under it is empty. It
   used to simply arrive with the other three. Now it TRIES: the tape starts to
   fill, stops, and retracts, and the outline flickers as it fails to resolve.
   One beat, once, on entry. This is the whole thesis as an animation — a case
   that cannot be closed into a number. */
.rcpt.is-in .rcpt__c:nth-child(4) .rcpt__bar{
  background-image:linear-gradient(90deg,var(--navy) 0 100%);
  background-repeat:no-repeat;background-size:0% 100%;
  animation:rcpt-refuse 1900ms var(--ease-scrub) 620ms 1}
@keyframes rcpt-refuse{
  0%{background-size:0% 100%}
  34%{background-size:19% 100%}
  46%{background-size:19% 100%}
  100%{background-size:0% 100%}
}
.rcpt.is-in .rcpt__fig--hollow{animation:rcpt-flicker 1500ms steps(1,end) 900ms 1}
@keyframes rcpt-flicker{
  0%,100%{opacity:1}
  22%,30%{opacity:.42}
  26%{opacity:1}
  54%{opacity:.62}
}

/* --- 3. THE DOORS BREATHE --------------------------------------------------
   The record sheet inside each card's head panel drifts one cell, slowly and
   permanently, so the cards read as live surfaces rather than printed ones.
   The docket numeral pulses once as the card arrives.

   The drift animates TRANSLATE, not background-position: styles.css already
   uses background-position for the hover shift, and a running animation beats
   a normal declaration, so animating the same property silently killed that
   hover. Different property, both behaviours live. The sheet is inset -34px so
   the translated grid never exposes an edge. */
.door__head::before{inset:-34px;animation:door-drift 46s linear infinite}
@keyframes door-drift{from{transform:translate3d(0,0,0)}to{transform:translate3d(34px,34px,0)}}
/* hover keeps its own nudge, on top of the drift */
.door:hover .door__head::before{background-position:6px 6px}
/* Fires off .is-loaded, not .is-in: .hero__doors carries no data-rv, so the
   scroll observer never touches it and the .is-in selector was dead. The
   doors are above the fold — load IS their arrival. */
.is-loaded .door__head::after{animation:door-stamp 900ms var(--ease-enter) 620ms 1}
.door--org .door__head::after{animation-delay:420ms}
@keyframes door-stamp{
  0%{-webkit-text-stroke-color:rgba(20,35,63,.03)}
  40%{-webkit-text-stroke-color:rgba(224,122,47,.5)}
  100%{-webkit-text-stroke-color:rgba(20,35,63,.09)}
}

/* --- 4. THE READING LIGHT --------------------------------------------------
   On the dark bands only: a soft light follows the pointer and lifts the
   hairline grid where it passes, the way a torch moves over a document.
   motion-plus.js writes --mx / --my as percentages of the band. Deliberately
   built at half the strength it could be — it is atmosphere, not a spotlight,
   and it never sits over body copy that has to be read. */
.band-navy,.band-deep,.gband,.ctb{position:relative}
/* Stacking, the long way round, because both short answers failed:
     z-index:0  → positioned descendant, paints AFTER in-flow content, so the
                  wash hazed the body copy;
     z-index:-1 → the bands establish no stacking context, so the pseudo was
                  hoisted to the root and painted UNDER the band's opaque
                  background — invisible.
   So: the pseudo stays at 0, and every band's content wrapper is lifted to
   z-index 1. The wash sits above the band background and below every word.
   .pull__in already carried z-index:2 and is left alone. */
[data-lamp] > .shell{position:relative;z-index:1}
.band-navy[data-lamp]::before,.band-deep[data-lamp]::before,.ctb[data-lamp]::before{
  content:"";position:absolute;inset:0;pointer-events:none;z-index:0;opacity:0;
  background:radial-gradient(420px 320px at var(--mx,50%) var(--my,50%),
    rgba(255,255,255,.09),rgba(255,255,255,.035) 42%,transparent 72%);
  transition:opacity 420ms var(--ease-enter)}
[data-lamp].is-lit::before{opacity:1}

/* --- 5. SECTION ARRIVAL ----------------------------------------------------
   The existing .rv reveal is a fade-and-rise. On section HEADS only, it now
   also settles its tracking, so a heading resolves into place instead of
   sliding. Tiny, and it is the difference between "animated" and "composed". */
.sec__head.rv,.display-section.rv{letter-spacing:.06em;transition:opacity 620ms var(--ease-enter),
  transform 620ms var(--ease-enter),letter-spacing 780ms var(--ease-enter)}
.sec__head.rv.is-in{letter-spacing:.2em}
.display-section.rv.is-in{letter-spacing:-.01em}

@media (prefers-reduced-motion:reduce){
  .sig--stamp .sig__now,.sig--stamp .sig__tok,
  .rcpt.is-in .rcpt__c:nth-child(4) .rcpt__bar,
  .rcpt.is-in .rcpt__fig--hollow,
  .door__head::before,.hero__doors.is-in .door__head::after{animation:none}
  [data-lamp]::before{display:none}
  .sec__head.rv,.display-section.rv{transition:opacity 200ms linear}
}

/* ============================ 6. THE ASKS, LIT ============================
   Founder ruling 2026-08-09. Five specific elements, each given light and a
   pulse. Contrast is held everywhere: white stays on the dark end of every
   green gradient, and the emphasis colours below are the light-ground inks,
   never raw --orange (3.0:1 on cream). */

/* --- Donate: the one button that should catch the eye from anywhere ------- */
/* Same luminance ceiling as .door__go, for the same reason: the white 13px/600
   label sets it, not taste. #1B8055 = 4.92:1, #14663F = 7.0:1, so the whole
   glyph band clears AA with margin — and it needs margin here, because
   donate-shine lays rgba(255,255,255,.42) across the label as it crosses. */
.nav__cta .btn--primary{position:relative;overflow:hidden;
  background:linear-gradient(180deg,#1B8055,#14663F);
  box-shadow:0 10px 24px -12px rgba(32,103,74,.9),inset 0 1px 0 rgba(255,255,255,.28);
  animation:donate-breathe 3.6s var(--ease-enter) infinite}
@keyframes donate-breathe{
  0%,100%{box-shadow:0 10px 24px -12px rgba(32,103,74,.9),inset 0 1px 0 rgba(255,255,255,.28),0 0 0 0 rgba(63,191,132,0)}
  55%{box-shadow:0 12px 30px -12px rgba(32,103,74,.95),inset 0 1px 0 rgba(255,255,255,.34),0 0 22px 2px rgba(63,191,132,.45)}
}
/* a shine crosses it on its own clock, not only on hover */
.nav__cta .btn--primary::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(105deg,transparent 34%,rgba(255,255,255,.42) 50%,transparent 66%);
  transform:translateX(-130%);animation:donate-shine 4.8s var(--ease-enter) infinite}
@keyframes donate-shine{0%,62%{transform:translateX(-130%)}86%,100%{transform:translateX(130%)}}
.nav__cta .btn--primary:hover{background:linear-gradient(180deg,#1A7D53,#12603C);transform:translateY(-2px)}

/* --- emphasis: the few words that carry the line -------------------------- */
/* On cream: --orange-ink at display size. On the dark closing band: the soft
   orange, which is the only orange legal there. */
.display-hero em{color:var(--orange-ink);font-style:italic}
.close__claim em{color:var(--orange-soft);font-style:italic}
.display-section em{color:var(--orange-ink)}
.band-navy .display-section em,.band-deep .display-section em,
.close__claim em,.pull em{color:var(--orange-soft)}

/* --- "Start here": sharper green, lit, breathing -------------------------- */
/* Fill luminance is capped by the white label, not by taste: white on
   #1B8055 is 4.92:1 and on #14663F is 7.0:1, so the whole glyph band clears
   AA. The "sharp green" reading lives in the GLOW below (bright #3FBF84 at
   50%), which carries no text and is free to be as bright as it likes. A
   lighter fill (#33A96F) was tried this pass and measured 3.7:1 — reverted. */
.door .door__go{background:linear-gradient(180deg,#1B8055,#14663F);
  box-shadow:0 14px 26px -14px rgba(28,122,80,.95),inset 0 1px 0 rgba(255,255,255,.3);
  animation:go-breathe 3.2s var(--ease-enter) infinite}
@keyframes go-breathe{
  0%,100%{box-shadow:0 14px 26px -14px rgba(28,122,80,.95),inset 0 1px 0 rgba(255,255,255,.3),0 0 0 0 rgba(63,191,132,0)}
  54%{box-shadow:0 16px 32px -14px rgba(28,122,80,1),inset 0 1px 0 rgba(255,255,255,.36),0 0 26px 3px rgba(63,191,132,.5)}
}
.door--org .door__go{background:linear-gradient(180deg,#1D3054,#0F1D33);animation:none}
.door:hover .door__go{background:linear-gradient(180deg,#1A7D53,#12603C)}
.door--org:hover .door__go{background:linear-gradient(180deg,#2A4372,#16294A)}

/* --- the arrows ride ------------------------------------------------------ */
.door__go i{animation:go-arrow 2.4s var(--ease-enter) infinite}
@keyframes go-arrow{
  0%,72%,100%{transform:translateX(0)}
  82%{transform:translateX(4px)}
}
.door:hover .door__go i{animation:none;transform:translateX(3px)}

/* --- the status dots pulse ------------------------------------------------ */
/* audience dot: green, a live light */
.door__k::before{animation:dot-live 2.2s var(--ease-enter) infinite}
@keyframes dot-live{
  0%,100%{box-shadow:0 0 0 0 rgba(63,191,132,.5),0 0 6px 1px rgba(63,191,132,.5);transform:scale(1)}
  52%{box-shadow:0 0 0 5px rgba(63,191,132,0),0 0 14px 3px rgba(63,191,132,.9);transform:scale(1.18)}
}
.door--org .door__k::before{animation-name:dot-live-o}
@keyframes dot-live-o{
  0%,100%{box-shadow:0 0 0 0 rgba(224,122,47,.5),0 0 6px 1px rgba(224,122,47,.5);transform:scale(1)}
  52%{box-shadow:0 0 0 5px rgba(224,122,47,0),0 0 14px 3px rgba(224,122,47,.9);transform:scale(1.18)}
}
/* preview-only dot: orange, slower — it is a status, not an invitation */
.door__soon::before{animation:dot-status 2.8s var(--ease-enter) infinite}
@keyframes dot-status{
  0%,100%{box-shadow:0 0 0 0 rgba(224,122,47,.55),0 0 5px 1px rgba(224,122,47,.5);opacity:.9}
  50%{box-shadow:0 0 0 4px rgba(224,122,47,0),0 0 12px 3px rgba(224,122,47,.85);opacity:1}
}

@media (prefers-reduced-motion:reduce){
  .nav__cta .btn--primary,.nav__cta .btn--primary::after,
  .door .door__go,.door__go i,.door__k::before,.door__soon::before{animation:none}
}
