/* Miami Nights shot scene + Locker resource cards + login modal.
   Relies on tokens.css (--miami-teal / --teal-glow / --teal-line reserved for
   these two sections only) and the shared band/shell/head/eyebrow/zr/rise/stg
   classes in base.css. Load this stylesheet AFTER base.css so .nite's
   gradient background wins over .band-dark's flat fill. */

/* ---------- MIAMI NIGHTS ---------- */
.nite{position:relative;overflow:hidden;background:linear-gradient(180deg,#04040B 0%,#0A0A0C 44%,#160609 76%,#1D070C 100%);}
.nite-stars{position:absolute;inset:0 0 42% 0;background-image:radial-gradient(1.4px 1.4px at 8% 24%,rgba(255,255,255,.8),transparent 60%),radial-gradient(1px 1px at 21% 60%,rgba(255,255,255,.6),transparent 60%),radial-gradient(1.2px 1.2px at 34% 18%,rgba(255,255,255,.7),transparent 60%),radial-gradient(1px 1px at 48% 44%,rgba(255,255,255,.5),transparent 60%),radial-gradient(1.4px 1.4px at 62% 12%,rgba(255,255,255,.8),transparent 60%),radial-gradient(1px 1px at 73% 52%,rgba(255,255,255,.55),transparent 60%),radial-gradient(1.2px 1.2px at 86% 30%,rgba(255,255,255,.7),transparent 60%),radial-gradient(1px 1px at 94% 64%,rgba(255,255,255,.5),transparent 60%);animation:nTwinkle 4.6s ease-in-out infinite;}
.nite-stars.s2{background-image:radial-gradient(1px 1px at 14% 40%,rgba(255,255,255,.6),transparent 60%),radial-gradient(1.3px 1.3px at 28% 8%,rgba(255,255,255,.75),transparent 60%),radial-gradient(1px 1px at 43% 66%,rgba(255,255,255,.5),transparent 60%),radial-gradient(1.2px 1.2px at 57% 28%,rgba(255,255,255,.65),transparent 60%),radial-gradient(1px 1px at 69% 6%,rgba(255,255,255,.6),transparent 60%),radial-gradient(1.3px 1.3px at 81% 46%,rgba(255,255,255,.7),transparent 60%),radial-gradient(1px 1px at 97% 16%,rgba(255,255,255,.55),transparent 60%);animation-delay:2.3s;}
@keyframes nTwinkle{0%,100%{opacity:.45}50%{opacity:1}}
.nite-horizon{position:absolute;left:-10%;right:-10%;bottom:96px;height:280px;background:radial-gradient(60% 100% at 50% 100%,rgba(230,12,32,.26),transparent 70%);pointer-events:none;}
.nite-stage{position:relative;max-width:1240px;height:560px;margin:0 auto;cursor:pointer;}
.nite-city{position:absolute;left:24px;right:24px;bottom:96px;height:200px;display:flex;align-items:flex-end;gap:6px;opacity:.92;pointer-events:none;}
.nite-city i{flex:1;background-color:#0C0C13;background-image:radial-gradient(rgba(37,224,208,.26) 1px,transparent 1.4px);background-size:11px 15px;border-top:1px solid rgba(37,224,208,.28);}
.nite-floor{position:absolute;left:0;right:0;bottom:0;height:96px;background:linear-gradient(180deg,#0C0509,#050507);border-top:1px solid rgba(37,224,208,.22);}
.nite-floor::before{content:"";position:absolute;left:50%;top:0;width:60%;height:100%;transform:translateX(-50%);background:radial-gradient(50% 90% at 50% 0%,rgba(230,12,32,.14),transparent 70%);}
.nite-guide{position:absolute;left:0;top:0;width:1240px;height:520px;pointer-events:none;}
.nite-guide path{stroke:rgba(255,255,255,.10);stroke-width:2;stroke-dasharray:2 11;stroke-linecap:round;fill:none;}
.hoop{position:absolute;left:940px;top:150px;width:130px;pointer-events:none;}
.board{display:block;width:120px;height:86px;border:2px solid rgba(255,255,255,.28);border-radius:6px;background:rgba(255,255,255,.05);box-shadow:0 0 24px -6px var(--teal-glow);position:relative;transition:box-shadow .3s;}
.board::after{content:"";position:absolute;left:43px;bottom:6px;width:34px;height:26px;border:2px solid rgba(255,255,255,.22);border-radius:2px;}
.board.hit{box-shadow:0 0 46px -2px rgba(37,224,208,.8);}
.rim{position:absolute;left:26px;top:78px;width:68px;height:10px;border-radius:6px;background:var(--red-hot);box-shadow:0 0 18px rgba(230,12,32,.8);}
.rim.hit{animation:nRimPulse .5s;}
@keyframes nRimPulse{40%{transform:translateY(3px)}}
.net{position:absolute;left:30px;top:86px;width:60px;height:58px;transform-origin:top center;}
.net path{stroke:rgba(255,255,255,.5);stroke-width:1.5;fill:none;}
.net.sway{animation:nNetSway .9s var(--ease-rush);}
@keyframes nNetSway{25%{transform:skewX(7deg) scaleY(1.07)}55%{transform:skewX(-5deg)}80%{transform:skewX(2deg)}}
.nball{position:absolute;width:44px;height:44px;offset-path:path("M140 430 Q560 -30 1000 236 L1002 330");offset-rotate:0deg;animation:nShot 1.15s cubic-bezier(.33,.05,.55,1) forwards;pointer-events:none;filter:drop-shadow(0 0 14px rgba(230,12,32,.55));}
@keyframes nShot{0%{offset-distance:0%;opacity:1}86%{opacity:1}100%{offset-distance:100%;opacity:0}}
.nball i{display:block;width:100%;height:100%;border-radius:50%;background:radial-gradient(circle at 34% 30%,#FF5A60,#E60C20 58%,#8E0F14 100%);position:relative;overflow:hidden;animation:nSpin 1.15s linear;}
.nball i::before{content:"";position:absolute;top:0;left:50%;width:2px;height:100%;background:rgba(10,10,12,.5);border-radius:2px;}
.nball i::after{content:"";position:absolute;top:50%;left:0;height:2px;width:100%;background:rgba(10,10,12,.5);border-radius:2px;}
@keyframes nSpin{to{transform:rotate(540deg)}}
.nball.idle{offset-path:none;left:118px;top:408px;animation:nIdleB 1.8s ease-in-out infinite;}
.nball.idle i{animation:none;}
@keyframes nIdleB{0%,100%{transform:translateY(0)}50%{transform:translateY(-14px)}}
/* Filled miami-teal, not the hollow text-stroke treatment .hollow uses elsewhere:
   color:transparent falls back to invisible (not the stroke) wherever -webkit-text-stroke
   isn't supported, which measured as ~1:1 contrast against the near-black nite background. */
.swish-flash{position:absolute;left:730px;top:56px;font-family:var(--font-display);font-size:4.2rem;text-transform:uppercase;letter-spacing:.02em;color:var(--miami-teal);filter:drop-shadow(0 0 22px rgba(37,224,208,.6));opacity:0;pointer-events:none;}
.swish-flash.on{animation:nSwishIn .9s var(--ease-reveal);}
@keyframes nSwishIn{0%{opacity:0;transform:scale(.6)}20%{opacity:1;transform:scale(1.06)}70%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(1.15)}}
.nite-copy{position:relative;z-index:2;left:24px;top:84px;max-width:440px;cursor:auto;}
.nite-copy h2{margin-top:16px;}
.nite-copy .lede{font-size:1.02rem;margin-top:16px;}
.nite-cta{display:flex;align-items:center;gap:18px;margin-top:26px;flex-wrap:wrap;}
.makes{font-family:var(--font-eyebrow);letter-spacing:.16em;text-transform:uppercase;font-size:.74rem;color:#8C8C99;}
.makes b{font-family:var(--font-num);font-size:1.6rem;color:var(--miami-teal);margin-right:8px;letter-spacing:.03em;}
@media(min-width:961px) and (max-width:1239px){
  .nite-stage{width:1240px;max-width:none;position:relative;left:50%;transform:translateX(-50%) scale(.77);transform-origin:top center;margin:0 0 -119px;}
}
@media(max-width:960px){
  .nite-stage{height:auto;padding:64px 0 140px;cursor:auto;}
  .hoop,.nite-guide,.nball{display:none;}
  .nite-copy{position:static;margin:0 24px;max-width:60ch;}
  .swish-flash{left:50%;top:auto;bottom:120px;margin-left:-120px;font-size:3rem;}
}
@media(prefers-reduced-motion:reduce){
  .nite-stars,.nite-stars.s2{animation:none;opacity:.7;}
  .nball.idle{animation:none;}
}
/* html[data-motion="off"] / html[data-night="off"] twin of the block above. */
html[data-motion="off"] .nite-stars,html[data-motion="off"] .nite-stars.s2,
html[data-night="off"] .nite-stars,html[data-night="off"] .nite-stars.s2{animation:none;opacity:.7;}
html[data-motion="off"] .nball.idle,
html[data-night="off"] .nball.idle{animation:none;}

/* ---------- THE LOCKER (resource cards) ---------- */
.res{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;}
.res-c{background:var(--surface-card);border:var(--border-card);border-radius:var(--r-card);padding:26px 24px 20px;display:flex;flex-direction:column;transition:transform var(--t-lift) var(--ease-rush),border-color var(--t-hover);}
.res-c:hover{transform:translateY(-6px);border-color:rgba(230,12,32,.45);}
.res-c.openres:hover{border-color:var(--teal-line);}
.res-top{display:flex;justify-content:space-between;align-items:center;margin-bottom:14px;gap:10px;}
.res-meta{font-family:var(--font-eyebrow);font-weight:700;font-size:.66rem;letter-spacing:.2em;text-transform:uppercase;color:var(--red-hot);}
.res-lock,.res-open{display:inline-flex;align-items:center;gap:7px;font-family:var(--font-eyebrow);font-size:.62rem;letter-spacing:.18em;text-transform:uppercase;color:#8C8C99;white-space:nowrap;}
.res-open{color:var(--miami-teal);}
.lk{width:11px;height:8px;border:2px solid currentColor;border-radius:2px;position:relative;display:inline-block;}
.lk::before{content:"";position:absolute;top:-7px;left:.5px;width:6px;height:7px;border:2px solid currentColor;border-bottom:0;border-radius:5px 5px 0 0;}
.res-c h3{font-size:1.02rem;margin-bottom:8px;}
.res-c p{font-size:.88rem;color:var(--text-dim-dark);flex-grow:1;margin-bottom:18px;}
/* Proper button, not an underline-link: full-width ghost pill at >=44px so it's
   a real touch target, matching .btn-ghost's border/radius language. */
.res-get{
  width:100%;min-height:44px;
  display:inline-flex;align-items:center;justify-content:center;
  font-family:var(--font-eyebrow);font-weight:700;font-size:.8rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--red-hot);border:1.5px solid var(--line-dark);border-radius:var(--r-pill);
  padding:12px 18px;transition:transform .25s var(--ease-rush),border-color var(--t-hover);
}
.res-get:hover{transform:translateY(-3px);border-color:var(--red-hot);}
.res-get:disabled{opacity:.5;cursor:not-allowed;pointer-events:none;}
.openres .res-get{color:var(--miami-teal);}
.openres .res-get:hover{border-color:var(--teal-line);}
@media(max-width:1040px){.res{grid-template-columns:repeat(2,1fr);}}
@media(max-width:640px){.res{grid-template-columns:1fr;}}

/* ---------- LOGIN MODAL ---------- */
.modal-ovl{position:fixed;inset:0;background:rgba(4,4,8,.66);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);z-index:var(--z-drawer);display:grid;place-items:center;padding:20px;}
/* The author display:grid above outranks the UA [hidden]{display:none}, so the
   closed overlay stayed on top of the whole page and ate every click. */
.modal-ovl[hidden]{display:none;}
.modal{position:relative;width:min(440px,100%);background:#0E0E13;border:var(--border-card);border-radius:var(--r-card-light);padding:32px 30px;animation:zrIn .5s var(--ease-reveal);}
.modal h3{font-size:1.5rem;}
.modal-p{font-size:.95rem;color:var(--text-body-dark);margin-bottom:20px;}
.modal-row{display:flex;gap:12px;flex-wrap:wrap;}
/* 44px box, not 40 (WCAG 2.5.5). The X strokes are 18x2, so centring them in the
   box is left:(44-18)/2=13px, top:(44-2)/2=21px — was 11/19 for the 40px box. */
.modal-x{position:absolute;top:12px;right:12px;width:44px;height:44px;flex-shrink:0;}
.modal-x::before,.modal-x::after{content:"";position:absolute;top:21px;left:13px;width:18px;height:2px;background:#8C8C99;transition:background .2s;}
.modal-x::before{transform:rotate(45deg);}
.modal-x::after{transform:rotate(-45deg);}
.modal-x:hover::before,.modal-x:hover::after{background:var(--red-hot);}

/* ---------- NIGHT COURT EASTER EGG (footer ball / Konami code, main.js) ---------- */
/* Same display:grid-vs-UA-[hidden] trap .modal-ovl documents above: the author
   display:grid would otherwise outrank [hidden]'s UA display:none and the closed
   overlay would sit on top of the page eating clicks. */
.egg-ovl{position:fixed;inset:0;z-index:var(--z-drawer);background:rgba(4,4,8,.94);overflow:auto;display:grid;place-items:center;padding:0;}
.egg-ovl[hidden]{display:none;}
.egg-ovl .nite{width:100%;padding:56px 0;}
.egg-x{position:fixed;top:16px;right:16px;z-index:3;width:44px;height:44px;flex-shrink:0;}
.egg-x::before,.egg-x::after{content:"";position:absolute;top:21px;left:13px;width:18px;height:2px;background:#8C8C99;transition:background .2s;}
.egg-x::before{transform:rotate(45deg);}
.egg-x::after{transform:rotate(-45deg);}
.egg-x:hover::before,.egg-x:hover::after{background:var(--red-hot);}
.egg-ball{display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;flex-shrink:0;color:var(--fast-red);opacity:.55;transition:opacity .2s,transform .2s;}
.egg-ball svg{width:22px;height:22px;}
.egg-ball:hover,.egg-ball:focus-visible{opacity:1;animation:eggBounce .6s var(--ease-rush);}
@keyframes eggBounce{30%{transform:translateY(-5px) rotate(-12deg);}60%{transform:translateY(0) rotate(6deg);}100%{transform:rotate(0);}}
@media(prefers-reduced-motion:reduce){.egg-ball:hover,.egg-ball:focus-visible{animation:none;}}
html[data-motion="off"] .egg-ball:hover,html[data-motion="off"] .egg-ball:focus-visible{animation:none;}
body.egg-open{overflow:hidden;}
/* The slingshot court only renders at >=961px (see .nite-stage's own @media(max-width:960px)
   block above, which hides .hoop/.nite-guide/.nball) — hide the trigger so mobile visitors
   never open an easter egg with no court inside it. */
@media(max-width:960px){.egg-ball{display:none;}}

/* ---------- ENROLL (/enroll) ----------
   One form, three fieldsets. Plan and pay options are real radios so the no-JS path
   works; the input in a plan card is visually hidden and the card is its label, with
   the checked state drawn on the card (border plus a check mark, not colour alone). */
/* --sel is the ink for prices and for a chosen card's outline: white on the dark theme, black on
   the light one, never brand red (Josiah, 7 October 2026). The focus ring stays red. */
.en-form{display:grid;gap:44px;--sel:var(--bone);--sel-soft:rgba(255,255,255,.45);}
html.fb-light .en-form{--sel:var(--court-black);--sel-soft:rgba(10,10,12,.45);}
.en-fs{border:0;padding:0;margin:0;min-width:0;}
/* Author display on these would outrank the UA [hidden]{display:none}; same trap
   .modal-ovl documents above. */
.en-fs[hidden],.en-card[hidden]{display:none;}
.en-lg{display:flex;align-items:baseline;gap:14px;margin-bottom:22px;padding:0;font-family:var(--font-display);font-size:clamp(1.3rem,2.4vw,1.9rem);letter-spacing:.01em;line-height:1;text-transform:uppercase;color:var(--bone);}
.en-n{font-family:var(--font-num);font-size:1.25em;color:var(--fast-red);line-height:.85;}
.en-plans{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;}
.en-card{position:relative;display:block;cursor:pointer;}
.en-card input{position:absolute;opacity:0;width:1px;height:1px;margin:0;}
.en-card-b{display:flex;flex-direction:column;gap:10px;height:100%;padding:24px 22px;border-radius:16px;background:var(--ink-lift);border:1px solid var(--line-dark);transition:border-color .25s,box-shadow .25s;}
.en-card-t{font-family:var(--font-eyebrow);font-size:.82rem;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--bone);}
.en-card .prog-price{font-size:1.9rem;color:var(--sel);}
.en-card-d{font-size:.9rem;line-height:1.5;color:var(--text-body-dark);}
.en-card:hover .en-card-b{border-color:var(--sel-soft);}
.en-card input:checked+.en-card-b{border-color:var(--sel);box-shadow:inset 0 0 0 1px var(--sel);}
.en-card input:checked+.en-card-b .en-card-t::after{content:" \2713";color:var(--fast-red);}
.en-card input:focus-visible+.en-card-b{outline:3px solid var(--fast-red);outline-offset:3px;}
/* The evaluation alone on its row reads as a strip, not a tall card: name and line on the
   left, the figure on the right. One card in a 1fr track was 1190px of mostly nothing. */
@media(min-width:641px){
  .en-plans-eval .en-card-b{display:grid;grid-template-columns:1fr auto;column-gap:28px;align-items:center;}
  .en-plans-eval .en-card-t{grid-column:1;grid-row:1;}
  .en-plans-eval .en-card-d{grid-column:1;grid-row:2;}
  .en-plans-eval .prog-price{grid-column:2;grid-row:1/3;text-align:right;}
}
/* Evaluation, or Individual / Group training (October 2026). One grid holds both program
   tiles and both panels so `order` can seat a panel directly under its own tile on a phone,
   and under both tiles once they sit side by side. Without JS the tiles stay [hidden] and
   both panels list in full under their headings. */
.en-choose{display:grid;grid-template-columns:1fr;gap:14px;margin-top:30px;}
.en-choose[hidden],.en-track[hidden],.en-panel[hidden]{display:none;}
.en-or{grid-column:1/-1;margin:0;font-family:var(--font-eyebrow);font-size:.82rem;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--text-dim-dark);}
.en-panel{grid-column:1/-1;}
.en-panel-h{margin:14px 0 14px;font-family:var(--font-eyebrow);font-size:.95rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--bone);}
.en-live .en-panel-h{display:none;}
@media(max-width:699px){
  .en-live .en-track[data-track="individual"]{order:1;}
  .en-live .en-panel[data-track="individual"]{order:2;}
  .en-live .en-track[data-track="group"]{order:3;}
  .en-live .en-panel[data-track="group"]{order:4;}
}
@media(min-width:700px){
  .en-live{grid-template-columns:1fr 1fr;}
  .en-live .en-track{order:1;}
  .en-live .en-panel{order:2;margin-top:4px;}
}
.en-track{position:relative;display:block;cursor:pointer;}
.en-track input{position:absolute;opacity:0;width:1px;height:1px;margin:0;}
.en-track-b{display:flex;flex-direction:column;gap:8px;height:100%;padding:22px 22px 20px;border-radius:16px;background:var(--ink-lift);border:1px solid var(--line-dark);transition:border-color .25s,box-shadow .25s,background-color .25s;}
.en-track-t{display:flex;justify-content:space-between;align-items:center;gap:14px;font-family:var(--font-display);font-size:clamp(1.25rem,2vw,1.5rem);line-height:1;letter-spacing:.01em;text-transform:uppercase;color:var(--bone);}
.en-track-i{flex:0 0 auto;fill:none;stroke:var(--fast-red);stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;transition:transform .45s var(--ease-rush);}
.en-track-d{font-size:.9rem;line-height:1.5;color:var(--text-body-dark);}
.en-track:hover .en-track-b{border-color:var(--sel-soft);}
.en-track input:checked+.en-track-b{border-color:var(--sel);box-shadow:inset 0 0 0 1px var(--sel);}
.en-track input:checked+.en-track-b .en-track-i{transform:rotate(180deg);}
.en-track input:focus-visible+.en-track-b{outline:3px solid var(--fast-red);outline-offset:3px;}
@media(prefers-reduced-motion:no-preference){
  html:not([data-motion="off"]) .en-live .en-panel:not([hidden]){animation:enPanelIn .5s var(--ease-rush);}
}
@keyframes enPanelIn{from{opacity:0;transform:translateY(-8px);}to{opacity:1;transform:none;}}
.en-pays{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px;}
.en-pay{display:flex;gap:12px;align-items:flex-start;min-height:44px;padding:16px 18px;border-radius:12px;background:var(--ink-lift);border:1px solid var(--line-dark);cursor:pointer;transition:border-color .25s;}
.en-pay input{width:19px;height:19px;flex:0 0 19px;margin:2px 0 0;accent-color:var(--sel);cursor:pointer;}
.en-pay input:focus-visible{outline:3px solid var(--fast-red);outline-offset:3px;}
.en-pay:has(input:checked){border-color:var(--sel);}
.en-card input:checked+.en-card-b .en-card-t::after{color:var(--sel);}
.en-pay-l{display:block;font-family:var(--font-eyebrow);font-size:.82rem;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--bone);}
.en-pay-a{display:block;margin-top:3px;font-size:.9rem;color:var(--text-body-dark);}
.en-pay-a:empty{display:none;}
/* Without JS, syncPay() is not there to disable a pay option the plan does not price, so
   the same gate runs off the card's own data-monthly attribute, which build.mjs writes from
   the catalog — no plan key is repeated here, so it cannot drift from plans.mjs.
   ponytail: an affordance, not a guard. A radio already checked when the plan changes still
   posts, and the server's 422, now visible through #enErr below, is what catches that. */
.en-form:has(.en-card:not([data-monthly]) input:checked) .en-pay:has(input[value="monthly"]){display:none;}
/* Without JS this is the only thing that can show a checkout failure: checkout.mjs 303s
   back to /enroll?...&err=1#enErr and the page ships the copy hidden. !important because
   build.mjs sets display:none inline, which keeps enroll.js in charge on the fetch path.
   :not(:empty) so that once enroll.js clears the text the paragraph collapses again. */
#enErr:target:not(:empty){display:block !important;}
/* --slate is 3.3:1 on the card's dark surface, under AA. This is the value base.css already
   gives the same caption on a dark card (.prog-c.flag .prog-price small); the light theme
   keeps --slate, which passes there and which this value would not. */
html:not(.fb-light) .en-card .prog-price small{color:#8A8A96;}
.en-form .pb-form{max-width:640px;}
/* No-JS form submits. The contact and playbook endpoints answer a plain form post with a
   303 back to the page carrying #ctDone or #pbOut, and :target reveals the same success
   box the scripts show by adding .show. Netlify Forms used to handle this path for us. */
.pb-out:target{display:block;}
.en-intro{display:grid;gap:14px;max-width:72ch;margin-bottom:44px;font-size:.95rem;line-height:1.6;color:var(--text-body-dark);}
.en-intro b{color:var(--bone);}
/* --text-label-dark (#6E6E7C) measured 3.41:1 on the form surface, under AA. This was its
   only consumer, so the fix lives here rather than in the token scale. */
.en-opt{font-size:.62rem;letter-spacing:.12em;color:var(--text-dim-dark);}
/* A select still on "Please select" reads as a placeholder, in the placeholder grey. */
.fld select:has(option[value=""]:checked){color:#8F8F9C;}
html.fb-light .fld select:has(option[value=""]:checked){color:var(--slate);}
html.fb-light .en-intro{color:var(--text-body-light);}
html.fb-light .en-intro b{color:var(--court-black);}
html.fb-light .en-opt{color:var(--text-soft-light);}
html.fb-light .en-lg,html.fb-light .en-card-t,html.fb-light .en-pay-l{color:var(--court-black);}
html.fb-light .en-card-b,html.fb-light .en-pay{background:var(--bone);border-color:var(--chalk-2);}
html.fb-light .en-card input:checked+.en-card-b,html.fb-light .en-pay:has(input:checked){border-color:var(--sel);}
html.fb-light .en-card-d,html.fb-light .en-pay-a{color:var(--text-body-light);}
html.fb-light .en-track-b{background:var(--bone);border-color:var(--chalk-2);}
html.fb-light .en-track input:checked+.en-track-b{border-color:var(--sel);}
html.fb-light .en-track-t,html.fb-light .en-panel-h{color:var(--court-black);}
html.fb-light .en-track-d{color:var(--text-body-light);}
html.fb-light .en-or{color:var(--text-soft-light);}
@media(max-width:640px){.en-form{gap:32px;}.en-card-b{padding:20px 18px;}}

/* --- The "how did you hear about us" confirmation pulse --------------------
   Replaces the old "you enjoyed the website" tick. This answer is the signed
   agreement's primary evidence of attribution (Schedule 1 / Section 7), and
   one particular choice pays the developer a higher rate than the rest. An
   animation that fired only on that choice would nudge a parent toward it
   and corrupt the record, so it plays identically for all six: the trigger
   is "a real answer is picked", never which one.
   Scoped to .en-form and to #en_hearAbout by id: .fld select is shared with
   every other select on this page (gender, experience, contactMethod...) and
   an unscoped rule would pulse on all of them.
   box-shadow/transform animate directly on the select itself rather than on
   a ::after: generated content is not reliably rendered on a native <select>,
   which is why box-shadow (already used above for its own :focus ring) is
   the anchor-free way to do this.
   The default page is LIGHT (html ships class="fb-light"), so the pulse is
   --fast-red (4.7:1 on white); --red-hot is a dark-theme colour and measures
   3.5:1 here. */
/* The final keyframe IS the resting state. base.css's reduced-motion reset does
   not stop keyframes, it collapses them to .001ms, so a pulse that ended at
   full opacity would be left permanently painted around the select. */
@keyframes hearAboutPulse{
  0%{box-shadow:0 0 0 0 rgba(230,12,32,.55);}
  70%{box-shadow:0 0 0 10px rgba(230,12,32,0);}
  100%{box-shadow:0 0 0 10px rgba(230,12,32,0);}
}
@keyframes hearAboutPop{
  0%{transform:scale(1);}
  38%{transform:scale(1.03);}
  100%{transform:scale(1);}
}
.en-form #en_hearAbout:has(option:checked:not([value=""])){
  animation:hearAboutPulse calc(.52s / var(--motion-speed,1)) var(--ease-recoil,cubic-bezier(.2,.9,.3,1.4)) 1,
            hearAboutPop calc(.42s / var(--motion-speed,1)) var(--ease-recoil,cubic-bezier(.2,.9,.3,1.4)) 1;
}
@media(prefers-reduced-motion:reduce){
  .en-form #en_hearAbout:has(option:checked:not([value=""])){animation:none;}
}
/* html[data-motion="off"] twin of the block above. */
html[data-motion="off"] .en-form #en_hearAbout:has(option:checked:not([value=""])){animation:none;}
