/* ==========================================================
   /referral (VLP-1234): the page layer only.

   WHAT THIS FILE OWNS
   Everything that is this page and no other: the two-column hero and the
   reward panel beside it, the four signal rows, the referral form and its
   inline success state, the closer, this page's act seams by id, and the
   no-JS, static and reduced-motion restatements for exactly those moves.

   WHAT IT DEPENDS ON
   /folio.css, loaded first: tokens, reset, base type, the section formula,
   buttons, the nav, frames and the window device, the grids, the .rules list,
   the form fields, the footer, the sticky CTA. This file adds to that layer
   and never restates it.

   LOAD ORDER
   critical fallback <style> -> /folio.css -> /referral-v2.css ->
   /scrollcraft.css. The engine sheet is last so the page can override its
   tokens; folio.css restates every engine base rule it changes at a higher
   specificity.
   ========================================================== */

/* ---------------- hero ----------------
   Ink only, lifted by one very faint radial so the field is not a flat wall.
   Two columns: the claim on the left, the reward and its terms on the right. */
.hero{position:relative;min-height:100svh}
/* The act is only a length. Everything the reader sees lives on the stage, which is what the
   engine sticks; when the hero is not pinned (phones, coarse pointers, reduced motion) the same
   block simply flows, because every rule here is on the stage rather than on the act. */
/* The stage opens at the top of the screen, not in the middle of it. Centring a full-height stage
   against a tall reward card put the eyebrow at y=277 and the h1 at y=306 while every other folio
   hero opens at 116 to 120, so the page began on a third of a screen of nothing. Same 120px under
   the pill as /capabilities, and the reward card starts on the eyebrow's line rather than on its
   own. */
.hero-stage{position:relative;display:flex;flex-direction:column;justify-content:flex-start;
  min-height:100svh;background:var(--ink);
  padding:calc(var(--nav-h) + var(--nav-inset) + 38px) 0 48px}
.hero-stage::before{content:"";position:absolute;inset:0;pointer-events:none;z-index:0;
  background:radial-gradient(ellipse at 50% 0%,rgba(244,241,234,.06),transparent 60%)}
/* margin-inline:auto on a flex item cancels the cross-axis stretch, so a .wrap inside a stage
   shrinks to its own content and the grid comes out narrow. */
.hero-stage>.wrap,.closer-stage>.wrap{width:100%}
.ref-hero-grid{position:relative;z-index:1;display:grid;
  grid-template-columns:minmax(0,1.06fr) minmax(0,.94fr);gap:56px;align-items:start}
.hero-in{min-width:0;display:flex;flex-direction:column;align-items:flex-start;text-align:left}
/* Line masks reserve descender room. Instrument Serif hangs its g, y and p a long way below the
   baseline, and the engine's default 0.14em shears them at this line-height. */
.hero h1 .sc-split--line{padding-bottom:.26em;margin-bottom:-.26em}
.hero h1{margin-top:20px;max-width:13ch}
.hero-lead{margin-top:22px;max-width:50ch;font-size:clamp(16px,1.4vw,18.5px)}
.hero-cta{margin-top:28px;display:flex;align-items:center;gap:22px;flex-wrap:wrap}
.hero-note{margin-top:22px;font-family:var(--mono);font-size:10.5px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--dim);line-height:1.9;max-width:52ch}

/* ---------------- the reward panel ----------------
   The page's one piece of evidence, and the thing the hero asks to be believed on, so it is set
   as a panel of terms rather than as a badge: the payout, the model and the scope, in the
   previous page's own words. It carries no cue: it grounds the pinned stage at p = 0 and it is
   still there through the whole un-pin slide, which is what a stage needs to travel with. */
.reward{min-width:0;background:var(--surface);border:1px solid var(--line);border-radius:20px;
  padding:26px 26px 28px;display:flex;flex-direction:column;
  /* The panel comes up to meet the reader as the claim leaves. Driven from --sc-p rather than
     from a cue, because a cue would take the panel with it when it went dark and leave the
     sliding stage empty. --sc-p defaults to 1, so a browser that never runs the script and a
     capture tool both get the arrived panel. */
  transform:translate3d(0,calc((1 - clamp(0,calc(var(--sc-p,1) / .7),1)) * 44px),0)}
.reward .rules{margin-top:20px;border-top:1px solid var(--line-2)}
.reward .rules li p{max-width:42ch}
.reward .price{font-family:var(--mono);font-size:14px;letter-spacing:.02em}

/* ---------------- 02 who to refer ----------------
   The seam after a pinned act is cut, not padded, and stated by id so the value survives the
   hero being demoted to flow on a phone or under reduced motion. */
#fit{padding-top:calc(var(--sec-pad) * .5)}
/* The signal rows are the previous page's fitrows: a number and a sentence, nothing invented in
   between. .steps gives them the four-column measure and the hairline they had. */
.ref-signals li p{margin-top:12px}

/* ---------------- 03 the referral form ----------------
   On the page's own spine, never in a modal: a referral is written rather than applied for, and
   the note is the part that matters, so the field it is written in is on the page the reader is
   already reading. */
.ref-pair{align-items:start}
.ref-pair .card-plain .rules{margin-top:24px}
.ref-form{min-width:0;background:var(--surface);border:1px solid var(--line);border-radius:20px;
  padding:28px;display:flex;flex-direction:column;gap:15px}
.ref-form .frow2{gap:15px}
.ref-form .err{margin-top:2px}
.ref-form .ref-submit{margin-top:6px;width:100%;justify-content:center;min-height:48px}
.ref-form .fine{text-align:center}
/* The permission box is a term, not a field: it reads as a sentence the reader agrees with. */
.consent{margin-top:4px;display:flex;gap:12px;align-items:flex-start;color:var(--muted);
  font-size:13px;line-height:1.55;cursor:pointer}
.consent input{flex:none;margin-top:2px;width:20px;height:20px;accent-color:var(--blue)}
/* The box is a native control at its own size, so the whole label row is the target. */
@media(pointer:coarse),(max-width:760px){.consent{align-items:center;min-height:44px}}
/* The success state replaces nothing: the form is reset behind it, exactly as the previous page
   did, so a second referral costs no reload. */
.ref-form .msuccess{padding:26px 0 0;border-top:1px solid var(--line);margin-top:4px}
.ref-form .msuccess .chk{margin-bottom:14px}
.ref-form .msuccess h3{font-size:19px}
.ref-form .msuccess p{margin-bottom:0}
#refer{padding-bottom:calc(var(--sec-pad) * .62)}

/* ---------------- 04 closer ---------------- */
/* clip, not hidden: an overflow:hidden ancestor turns into the scrollport a sticky stage
   measures itself against, and the pin stops engaging. */
.sec-closer{border-top:1px solid var(--line);overflow:clip}
/* The engine writes height:100svh on a pinned stage, so a closer of copy alone cannot fill it and
   centring left 213px of ink between the last line and the footer, plus the footer's own top pad
   on top of that. The close is bottom-set instead: it reads as the sign-off it is, and the footer
   starts 56px under the last line at every height. */
.closer-stage{display:flex;flex-direction:column;justify-content:flex-end;background:var(--ink);
  min-height:100svh;padding:calc(var(--nav-h) + var(--nav-inset) + 30px) 0 56px}
.closer-in{max-width:860px;margin:0 auto;text-align:center;display:flex;flex-direction:column;
  align-items:center}
.closer-in .display{margin-top:22px;font-size:clamp(30px,3.6vw,52px)}
.closer-in .lead{margin-top:20px;text-align:center;margin-left:auto;margin-right:auto}
.closer-in .inline-cta{margin-top:34px}

/* ---------------- motion ----------------
   The copy greets, then gets out of the reward panel's way: it drifts up while its cues ramp
   out, so the two moves are one gesture rather than a fade over a rise. The drift lives on the
   block, which no cue owns; a cue writes transform on its own element, and stacking a second
   transform there would silently discard one of them. */
.hero-in{transform:translate3d(0,calc(clamp(0,calc(var(--sc-p,0) / .55),1) * -70px),0)}

/* If the script never runs, or a capture tool asks for the static page, nothing may stay
   invisible and nothing may sit mid-animation. folio.css covers the cues, reveals and staggers;
   this is this page's own move. */
html.no-js .hero-in,html.hv-static .hero-in,
html.no-js .reward,html.hv-static .reward{transform:none;transition:none}

/* ---------------- reduced motion ----------------
   Fewer and gentler, not zero: the engine keeps the opacity that carries comprehension and drops
   every position change. This is this page's own position change. */
@media(prefers-reduced-motion:reduce){
  .hero-in,.reward{transform:none;transition:none}
  .hero h1 .sc-split__i{animation:none}
}

/* ---------------- the landing ----------------
   A greet cue is already at full opacity when the act begins, so the engine has nothing to
   animate on the one screen every visitor sees. One CSS animation, played once, gives the hero
   its arrival; animation-fill-mode is backwards only, so the engine's inline values take over
   the instant it ends and scroll owns the element from then on. */
@keyframes rf-rise{from{opacity:0;transform:translate3d(0,112%,0)}}
@keyframes rf-greet{from{opacity:0;transform:translate3d(0,14px,0)}}
@media(prefers-reduced-motion:no-preference){
  .hero h1 .sc-split__i{animation:rf-rise 980ms var(--ease-out) backwards}
  .hero h1 .sc-split--line:nth-child(2) .sc-split__i{animation-delay:100ms}
  .hero-in>[data-sc-cue]{animation:rf-greet 720ms var(--ease-out) backwards}
  .hero-in>h1[data-sc-cue]{animation:none}
  .hero-in>.eyebrow{animation-delay:40ms}
  .hero-in>.hero-lead{animation-delay:420ms}
  .hero-in>.hero-cta{animation-delay:530ms}
  .hero-in>.hero-note{animation-delay:630ms}
}
html.no-js .hero-in>[data-sc-cue],html.hv-static .hero-in>[data-sc-cue],
html.no-js .hero h1 .sc-split__i,html.hv-static .hero h1 .sc-split__i{animation:none}

/* ---------------- responsive ---------------- */
@media(max-width:1120px){
  .ref-hero-grid{gap:36px}
  .ref-pair{gap:20px}
}
@media(max-width:900px){
  /* The hero is flow here, so its progress is not a pin's progress and the drift would arrive
     half resolved. */
  .hero-in,.reward{transform:none}
  .ref-hero-grid{grid-template-columns:1fr;gap:34px;align-items:start}
  .hero-stage{min-height:0;justify-content:flex-start}
  .closer-stage{min-height:0}
}
@media(max-width:760px){
  .hero-stage{padding:calc(var(--nav-h) + var(--nav-inset) + 34px) 0 40px}
  .hero h1{margin-top:18px;max-width:none}
  .hero-lead{margin-top:16px}
  .hero-cta{margin-top:24px;gap:16px;flex-direction:column;align-items:stretch;width:100%}
  .hero-cta .btn{width:100%;justify-content:center;min-height:48px}
  .hero-cta .mlink{justify-content:center}
  .hero-note{margin-top:18px;font-size:9.5px;letter-spacing:.1em}
  .reward{padding:22px 22px 24px;border-radius:16px}
  .ref-form{padding:22px;border-radius:16px}
  .closer-stage{padding:calc(var(--nav-h) + var(--nav-inset) + 20px) 0 0}
  .closer-in .inline-cta{margin-top:28px}
}

/* --- the phone crop for the projects console ---
   The whole console at 350px is a smudge. The frame crops to two shoot cards with their names,
   volumes and counts, which is what "who to refer" is actually about. See .frame-crop in
   folio.css. */
@media(max-width:760px){
  .ref-crop-projects{aspect-ratio:4/3;--zoom:300%;--sx:-48%;--sy:-23%;--w-from:0px;--w-to:-44px}
}

/* --- the hero when nothing is pinned ---
   100svh is the pinned stage's own height: the act holds a whole screen and the copy sits in the
   middle of it. Take the pin away, which ?static=1, reduced motion, a coarse pointer and any
   width under 900px all do, and that same screen becomes a fixed measure the copy no longer
   fills, so the fold opened on a band of ground and closed on another one before the next
   section. Unpinned, the hero is as tall as the hero. .sc-act--pinned and .sc-stage are the two
   classes the engine adds to a pinned act and its stage, so this is exactly "not pinned". */
.hero:not(.sc-act--pinned){min-height:0}
.hero-stage:not(.sc-stage){min-height:0}

/* ---------------- type floors on a phone ----------------
   Body copy to 15.5px, mono captions to 11px, the fine print that carries the terms to 12px.
   folio.css sets the shared floors; these are the sizes this page authors itself. */
@media(max-width:760px){
  .hero-note{font-size:11px;letter-spacing:.08em}
  .consent{font-size:15.5px}
}
