/* Grip Sock shared stylesheet.
   Extracted 2026-08-09 from the single-file blue page (8 stacked <style> blocks
   left by the retired patch chain). Per-page colour themes are appended at the
   bottom. NOTE: the gs-* namespace belongs to the GRIP SELECTOR. New components
   use sp-* (sport). Do not add gs-* classes. */

*,*::before,*::after{box-sizing:border-box}html,body{margin:0;padding:0}body{-webkit-text-size-adjust:100%}

/* ============================================================
     GRIP SOCK — "BASELINE"
     A court seen from above, turned into a page. Flat court
     green, thick white painted lines as the layout grid, one
     optic ball. Zero gradients, zero shadows, barely any words.
     ============================================================ */
  .bl-root{
    --court:#1B4DD8; --court-deep:#1740B0; --lineW:#FFFFFF; --ink:#FFFFFF;
    --dim:rgba(255,255,255,.80); --faint:rgba(255,255,255,.42);
    --optic:#4ADE68; --optic-hi:#6CEA85;
    --ball:#FFFFFF; --ball-seam:rgba(11,36,94,.55); --dark:#0B245E;
    --lw:4px; /* painted line weight */
    --f-cond:"Arial Narrow","Roboto Condensed",system-ui,sans-serif;
    --f-ui:"Helvetica Neue",Helvetica,Arial,system-ui,sans-serif;
    margin:0;color:var(--ink);font-family:var(--f-ui);line-height:1.5;background:var(--court);
    -webkit-font-smoothing:antialiased;overflow-x:hidden;
  }
  .bl-root *,.bl-root *::before,.bl-root *::after{box-sizing:border-box}
  .bl-root h1,.bl-root h2,.bl-root h3,.bl-root p,.bl-root ul{margin:0;padding:0}
  .bl-root ul{list-style:none}
  .bl-root a{color:inherit;text-decoration:none}
  .bl-root button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
  .bl-root :focus-visible{outline:3px solid var(--optic);outline-offset:3px}
  .bl-caps{font-family:var(--f-cond);text-transform:uppercase;font-weight:800}

  /* the page is the court: one big white-lined frame */
  .bl-court{max-width:1080px;margin:clamp(14px,3vw,40px) auto;border:var(--lw) solid var(--lineW);
    padding:0}

  /* header = top rail inside the court */
  .bl-head{display:flex;align-items:center;justify-content:space-between;gap:14px;
    padding:16px clamp(16px,3vw,32px);border-bottom:var(--lw) solid var(--lineW)}
  .bl-mark{font-family:var(--f-cond);font-weight:800;font-size:20px;letter-spacing:.06em;text-transform:uppercase;font-style:italic}
  .bl-mark b{color:var(--optic)}
  .bl-nav{display:flex;gap:22px}
  .bl-nav a{font-family:var(--f-cond);font-weight:800;font-size:12.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--dim)}
  .bl-nav a:hover{color:var(--optic)}
  @media (max-width:720px){.bl-nav{display:none}}
  .bl-root .bl-btn{display:inline-block;font-family:var(--f-cond);font-weight:800;font-size:13px;letter-spacing:.1em;
    text-transform:uppercase;color:var(--dark);background:var(--optic);padding:11px 20px;
    white-space:nowrap;cursor:pointer;border:0;transition:background .12s ease}
  .bl-root .bl-btn:hover{background:var(--optic-hi)}
  .bl-btn.ghost{background:transparent;color:var(--lineW);border:2.5px solid var(--lineW)}
  .bl-btn.ghost:hover{background:rgba(255,255,255,.12)}

  /* The one button at the top that jumps straight to the list. Sticky for
     EVERYONE: this used to sit inside the html.mo block, so any visitor with
     prefers-reduced-motion lost the header the moment they scrolled. */
  .bl-head{position:sticky;top:0;z-index:30;background:var(--court)}
  .bl-root .bl-btn.bl-cta{display:inline-flex;align-items:center;gap:9px;
    font-size:14px;padding:12px 22px}
  .bl-root .bl-btn.bl-cta::after{content:"";width:0;height:0;flex:0 0 auto;
    border-left:5px solid transparent;border-right:5px solid transparent;
    border-top:6px solid currentColor;transition:transform .16s ease}
  .bl-root .bl-btn.bl-cta:hover::after{transform:translateY(2px)}
  @media (max-width:420px){.bl-root .bl-btn.bl-cta{font-size:13px;padding:11px 16px}}

  /* hero — the service box with a giant call */
  .bl-hero{position:relative;padding:clamp(50px,8vw,110px) clamp(16px,4vw,48px) clamp(46px,7vw,90px);
    border-bottom:var(--lw) solid var(--lineW);overflow:hidden}
  .bl-hero::before{content:"";position:absolute;top:0;bottom:0;left:50%;width:var(--lw);margin-left:calc(var(--lw) / -2);
    background:var(--lineW);opacity:.25}
  .bl-hero-in{position:relative;text-align:center}
  .bl-call{display:inline-block;font-family:var(--f-cond);font-weight:800;font-size:12px;letter-spacing:.3em;
    text-transform:uppercase;color:var(--dark);background:var(--lineW);padding:6px 14px;margin-bottom:26px}
  .bl-h1{font-family:var(--f-cond);font-weight:800;text-transform:uppercase;font-style:italic;
    font-size:clamp(2rem,7.25vw,5.5rem);line-height:.92;letter-spacing:-.01em;text-wrap:balance}
  .bl-h1 .go{color:var(--optic);-webkit-text-stroke:0}
  .bl-root .bl-lede{color:var(--dim);max-width:46ch;margin:24px auto 32px;font-size:clamp(1rem,1.7vw,1.15rem)}
  .bl-ctas{display:flex;justify-content:center;gap:14px;flex-wrap:wrap}
  .bl-ball{position:absolute;right:8%;bottom:-16px;width:56px;height:56px;border-radius:50%;background:var(--ball);
    border:3px solid var(--court-deep)}
  .bl-ball::before{content:"";position:absolute;inset:6px;border-radius:50%;
    border-top:3px solid var(--ball-seam);transform:rotate(30deg)}

  /* credibility strip — line judge calls */
  .bl-cred{display:grid;grid-template-columns:repeat(3,1fr);border-bottom:var(--lw) solid var(--lineW)}
  @media (max-width:560px){.bl-cred{grid-template-columns:1fr}}
  .bl-cred span{font-family:var(--f-cond);font-weight:800;font-size:13px;letter-spacing:.16em;text-transform:uppercase;
    text-align:center;padding:16px 10px;border-right:var(--lw) solid var(--lineW)}
  .bl-cred span:last-child{border-right:0}
  @media (max-width:560px){.bl-cred span{border-right:0;border-bottom:var(--lw) solid var(--lineW)}.bl-cred span:last-child{border-bottom:0}}
  .bl-cred i{color:var(--optic);font-style:normal;margin-right:6px}

  /* section scaffolding */
  .bl-sec{border-bottom:var(--lw) solid var(--lineW)}
  .bl-sec-head{padding:clamp(30px,5vw,52px) clamp(16px,4vw,48px) clamp(20px,3vw,34px);text-align:center}
  .bl-h2{font-family:var(--f-cond);font-weight:800;text-transform:uppercase;font-style:italic;
    font-size:clamp(1.6rem,4vw,2.6rem);letter-spacing:0;line-height:.96}
  .bl-h2 .go{color:var(--optic)}
  .bl-root .bl-sub{color:var(--dim);font-size:.95rem;margin-top:8px;max-width:52ch;margin-left:auto;margin-right:auto}

  /* two sports — split court */
  .bl-two{display:grid;grid-template-columns:1fr 1fr;border-top:var(--lw) solid var(--lineW)}
  @media (max-width:640px){.bl-two{grid-template-columns:1fr}}
  .bl-half{padding:clamp(26px,4vw,44px);border-right:var(--lw) solid var(--lineW)}
  .bl-half:last-child{border-right:0}
  @media (max-width:640px){.bl-half{border-right:0;border-bottom:var(--lw) solid var(--lineW)}.bl-half:last-child{border-bottom:0}}
  .bl-half .tag{display:inline-block;font-family:var(--f-cond);font-weight:800;font-size:12px;letter-spacing:.2em;
    text-transform:uppercase;color:var(--dark);background:var(--optic);padding:5px 12px;margin-bottom:14px}
  .bl-half h3{font-family:var(--f-cond);font-weight:800;text-transform:uppercase;font-size:clamp(1.3rem,2.6vw,1.8rem);letter-spacing:.02em;margin-bottom:8px}
  .bl-half p{color:var(--dim);font-size:.98rem;max-width:38ch}

  /* product-shot placeholder — a framed court box */
  .bl-shot{position:relative;min-height:clamp(220px,34vw,360px);display:flex;align-items:center;justify-content:center;
    border-top:var(--lw) solid var(--lineW);background:
      repeating-linear-gradient(45deg,transparent,transparent 22px,rgba(255,255,255,.05) 22px,rgba(255,255,255,.05) 44px);}
  .bl-shot .ph{text-align:center;padding:24px}
  .bl-shot .ph .ico{font-size:44px;line-height:1;margin-bottom:12px}
  .bl-shot .ph b{display:block;font-family:var(--f-cond);font-weight:800;text-transform:uppercase;letter-spacing:.16em;font-size:14px}
  .bl-shot .ph span{display:block;color:var(--faint);font-size:.82rem;margin-top:6px}

  /* features — the four service boxes (2×2 court grid) */
  .bl-boxes{display:grid;grid-template-columns:1fr 1fr;border-top:var(--lw) solid var(--lineW)}
  @media (max-width:640px){.bl-boxes{grid-template-columns:1fr}}
  .bl-box{padding:clamp(24px,4vw,44px);border-right:var(--lw) solid var(--lineW);border-bottom:var(--lw) solid var(--lineW);position:relative}
  .bl-box:nth-child(2n){border-right:0}
  .bl-box:nth-child(n+3){border-bottom:0}
  @media (max-width:640px){.bl-box{border-right:0;border-bottom:var(--lw) solid var(--lineW)}.bl-box:last-child{border-bottom:0}}
  .bl-box .no{position:absolute;top:14px;right:16px;font-family:var(--f-cond);font-weight:800;font-size:15px;color:var(--faint);letter-spacing:.1em}
  .bl-box h3{font-family:var(--f-cond);font-weight:800;text-transform:uppercase;font-size:clamp(1.1rem,2.2vw,1.5rem);letter-spacing:.03em;margin-bottom:6px}
  .bl-box h3 u{text-decoration:none;border-bottom:4px solid var(--optic)}
  .bl-box p{color:var(--dim);font-size:.95rem;max-width:34ch}

  /* how it works — three-call rally */
  .bl-steps{display:grid;grid-template-columns:repeat(3,1fr);border-top:var(--lw) solid var(--lineW)}
  @media (max-width:640px){.bl-steps{grid-template-columns:1fr}}
  .bl-step{padding:clamp(22px,4vw,40px);border-right:var(--lw) solid var(--lineW);text-align:center}
  .bl-step:last-child{border-right:0}
  @media (max-width:640px){.bl-step{border-right:0;border-bottom:var(--lw) solid var(--lineW)}.bl-step:last-child{border-bottom:0}}
  .bl-step .sn{display:inline-block;font-family:var(--f-cond);font-weight:800;font-size:13px;letter-spacing:.18em;
    text-transform:uppercase;color:var(--dark);background:var(--optic);padding:4px 12px;margin-bottom:12px}
  .bl-step h3{font-family:var(--f-cond);font-weight:800;text-transform:uppercase;font-size:1.15rem;letter-spacing:.04em;margin-bottom:4px}
  .bl-step p{color:var(--dim);font-size:.92rem;max-width:26ch;margin:0 auto}

  /* video slot */
  .bl-video{position:relative;border-top:var(--lw) solid var(--lineW);aspect-ratio:16/7;min-height:200px;
    display:flex;align-items:center;justify-content:center;background:var(--court-deep);overflow:hidden}
  .bl-video::before{content:"";position:absolute;inset:0;
    background:repeating-linear-gradient(90deg,transparent,transparent 60px,rgba(255,255,255,.04) 60px,rgba(255,255,255,.04) 61px)}
  .bl-video .play{position:relative;text-align:center}
  .bl-video .disc{width:74px;height:74px;border-radius:50%;border:3px solid var(--optic);display:flex;align-items:center;justify-content:center;margin:0 auto 14px}
  .bl-video .disc::before{content:"";width:0;height:0;border-left:22px solid var(--optic);border-top:14px solid transparent;border-bottom:14px solid transparent;margin-left:6px}
  .bl-video .play b{display:block;font-family:var(--f-cond);font-weight:800;text-transform:uppercase;letter-spacing:.16em;font-size:14px}
  .bl-video .play span{display:block;color:var(--faint);font-size:.82rem;margin-top:6px}

  /* founder — coach story */
  .bl-founder{padding:clamp(34px,6vw,72px) clamp(16px,4vw,48px);display:grid;grid-template-columns:1fr 1.3fr;gap:clamp(24px,4vw,48px);align-items:center;border-bottom:var(--lw) solid var(--lineW)}
  @media (max-width:720px){.bl-founder{grid-template-columns:1fr;text-align:center}}
  .bl-portrait{aspect-ratio:1/1;border:var(--lw) solid var(--lineW);display:flex;align-items:center;justify-content:center;
    background:repeating-linear-gradient(45deg,transparent,transparent 22px,rgba(255,255,255,.05) 22px,rgba(255,255,255,.05) 44px)}
  .bl-portrait span{font-family:var(--f-cond);font-weight:800;text-transform:uppercase;letter-spacing:.14em;font-size:12px;color:var(--faint);text-align:center;padding:16px}
  .bl-founder h2{font-family:var(--f-cond);font-weight:800;text-transform:uppercase;font-style:italic;font-size:clamp(1.7rem,4vw,2.8rem);line-height:.94;margin-bottom:14px}
  .bl-founder h2 .go{color:var(--optic)}
  .bl-founder p{color:var(--dim);font-size:1rem;max-width:52ch;margin:0 0 12px}
  @media (max-width:720px){.bl-founder p{margin-left:auto;margin-right:auto}}
  .bl-founder .sig{font-family:var(--f-cond);font-weight:800;text-transform:uppercase;letter-spacing:.12em;font-size:13px;color:var(--lineW);margin-top:4px}

  /* FAQ */
  .bl-faq{border-top:var(--lw) solid var(--lineW)}
  .bl-faq details{border-bottom:var(--lw) solid var(--lineW);padding:0}
  .bl-faq details:last-child{border-bottom:0}
  .bl-faq summary{list-style:none;cursor:pointer;padding:clamp(18px,3vw,26px) clamp(16px,4vw,48px);
    display:flex;justify-content:space-between;align-items:center;gap:16px;
    font-family:var(--f-cond);font-weight:800;text-transform:uppercase;letter-spacing:.03em;font-size:clamp(1rem,2vw,1.25rem)}
  .bl-faq summary::-webkit-details-marker{display:none}
  .bl-faq summary::after{content:"+";color:var(--optic);font-size:1.6em;line-height:1;transition:transform .15s ease}
  .bl-faq details[open] summary::after{transform:rotate(45deg)}
  .bl-faq .ans{padding:0 clamp(16px,4vw,48px) clamp(20px,3vw,28px);color:var(--dim);font-size:.98rem;max-width:64ch}

  /* reserve — the dark end zone */
  .bl-res{background:var(--dark);padding:clamp(44px,7vw,84px) clamp(16px,4vw,48px);text-align:center}
  .bl-res h2{font-family:var(--f-cond);font-weight:800;text-transform:uppercase;font-style:italic;
    font-size:clamp(2.2rem,6vw,4rem);line-height:.94}
  .bl-res h2 .go{color:var(--optic)}
  .bl-res .note{color:var(--dim);max-width:48ch;margin:14px auto 28px;font-size:.98rem}
  /* The form grew from one email box to name + email + sport + phone on
     2026-08-27, so it stacks in rows rather than sitting on one line. */
  .bl-form{display:flex;flex-direction:column;gap:10px;align-items:center;max-width:520px;margin:0 auto}
  .bl-root .bl-row{display:flex;gap:10px;width:100%;flex-wrap:wrap}
  .bl-form input,.bl-root .bl-form select{flex:1;min-width:150px;padding:14px 16px;font-size:1rem;font-family:inherit;
    border:2.5px solid var(--lineW);background:transparent;color:var(--lineW);outline:none;
    -webkit-appearance:none;appearance:none;border-radius:0}
  /* Native select options render on the OS surface, so they need a colour
     that is legible on white as well as on the dark court. */
  .bl-root .bl-form select option{color:#0B245E;background:#fff}
  .bl-root .bl-form select{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23fff' stroke-width='2'/%3E%3C/svg%3E");
    background-repeat:no-repeat;background-position:right 14px center;background-size:12px;padding-right:38px}
  /* Consent sits ON the field it refers to, not in the footer fine print:
     permission to text has to be given where the number is handed over. */
  .bl-root .bl-consent{color:var(--faint);font-size:12.5px;line-height:1.45;
    max-width:44ch;margin:2px auto 4px;text-align:center}
  /* Off-canvas rather than display:none, so a bot filling every input still
     finds it. Screen readers skip it via aria-hidden on the wrapper. */
  .bl-root .bl-hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
  .bl-root .bl-form .bl-btn{width:100%;padding:14px 20px;font-size:14px}
  @media (min-width:520px){.bl-root .bl-form .bl-btn{width:auto;min-width:220px}}
  .bl-form input::placeholder{color:var(--faint)}
  .bl-form input:focus{border-color:var(--optic)}
  .bl-form button[disabled]{opacity:.6;cursor:default}
  .bl-msg{display:none;font-family:var(--f-cond);font-weight:800;text-transform:uppercase;letter-spacing:.12em;font-size:16px;margin-top:14px}
  .bl-msg.show{display:block}
  .bl-msg.ok{color:var(--optic)}
  .bl-msg.err{color:#ff9a9a}
  .bl-root .bl-fine{margin-top:12px;font-size:.78rem;color:var(--faint)}

  /* footer rail */
  .bl-foot{display:flex;justify-content:space-between;gap:12px;flex-wrap:wrap;
    padding:14px clamp(16px,3vw,32px);border-top:var(--lw) solid var(--lineW);
    font-family:var(--f-cond);font-weight:700;font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--dim)}

/* ============================================================
     MOTION — court lines get painted; balls obey gravity.
     Gated behind html.mo (set by JS, skipped for reduced motion),
     so without it every element sits in its final visible state.
     ============================================================ */

  /* scroll progress = a painted baseline across the top */
  .bl-prog{display:none}
  @supports (animation-timeline: scroll()){
    html.mo .bl-prog{display:block;position:fixed;top:0;left:0;right:0;height:3px;
      background:var(--optic);transform:scaleX(0);transform-origin:0 50%;z-index:60;
      animation:mo-prog linear both;animation-timeline:scroll(root block)}
    @keyframes mo-prog{to{transform:scaleX(1)}}
  }

  /* sticky lives outside the motion layer now, see .bl-head above */

  /* ---- section reveal: the white lines paint themselves left -> right ----
     Negative insets so the finished state never clips focus rings.        */
  html.mo .bl-cred,
  html.mo .bl-sec,
  html.mo .bl-founder,
  html.mo .bl-res{clip-path:inset(-14px 100% -14px -14px)}
  html.mo .bl-cred.in,
  html.mo .bl-sec.in,
  html.mo .bl-founder.in,
  html.mo .bl-res.in{clip-path:inset(-14px);
    transition:clip-path .9s cubic-bezier(.22,1,.36,1)}

  /* ---- shared primitives ---- */
  html.mo .mo-rise{opacity:0;transform:translateY(20px)}
  html.mo .in .mo-rise,
  html.mo .mo-rise.in{opacity:1;transform:none;
    transition:opacity .6s ease,transform .7s cubic-bezier(.22,1,.36,1);
    transition-delay:calc(var(--i,0) * 90ms + var(--d,0ms))}

  /* a line of type that wipes in like a brush stroke */
  html.mo .mo-wipe{clip-path:inset(0 100% 0 0);transform:translateX(-18px)}
  html.mo .in .mo-wipe,
  html.mo .mo-wipe.in{clip-path:inset(0 -2px 0 0);transform:none;
    transition:clip-path .8s cubic-bezier(.22,1,.36,1),transform .8s cubic-bezier(.22,1,.36,1);
    transition-delay:calc(var(--i,0) * 130ms + var(--d,0ms))}

  /* ---- header ---- */
  html.mo .bl-head{opacity:0;transform:translateY(-14px)}
  html.mo .bl-head.in{opacity:1;transform:none;transition:opacity .5s ease,transform .6s cubic-bezier(.22,1,.36,1)}
  html.mo .bl-nav a{position:relative}
  html.mo .bl-nav a::after{content:"";position:absolute;left:0;right:0;bottom:-7px;height:2px;
    background:var(--optic);transform:scaleX(0);transform-origin:100% 50%;
    transition:transform .3s cubic-bezier(.22,1,.36,1)}
  html.mo .bl-nav a:hover::after{transform:scaleX(1);transform-origin:0 50%}

  /* ---- buttons: tactile, no shadow ---- */
  html.mo .bl-root .bl-btn{transition:background .14s ease,transform .14s ease,color .14s ease}
  html.mo .bl-root .bl-btn:hover{transform:translateY(-2px)}
  html.mo .bl-root .bl-btn:active{transform:translateY(1px)}

  /* ---- hero ---- */
  /* the centre service line draws downward */
  html.mo .bl-hero::before{transform:scaleY(0);transform-origin:50% 0}
  html.mo .bl-hero.in::before{transform:scaleY(1);transition:transform 1.1s cubic-bezier(.22,1,.36,1) .15s}

  /* the ball drops in, bounces twice, then breathes */
  html.mo .bl-ball{opacity:0}
  html.mo .bl-hero.in .bl-ball{animation:mo-drop 1.15s cubic-bezier(.3,.7,.4,1) .55s both,
                                         mo-bob 4.5s ease-in-out 1.8s infinite}
  @keyframes mo-drop{
    0%{opacity:0;transform:translateY(-320px) rotate(-140deg)}
    12%{opacity:1}
    45%{transform:translateY(0) rotate(0deg)}
    62%{transform:translateY(-46px) rotate(14deg)}
    80%{transform:translateY(0) rotate(0deg)}
    90%{transform:translateY(-13px) rotate(5deg)}
    100%{opacity:1;transform:translateY(0) rotate(0deg)}
  }
  @keyframes mo-bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-7px)}}

  /* ---- credibility strip: three calls, ticked off one at a time ---- */
  html.mo .bl-cred span{opacity:0;transform:translateY(10px)}
  html.mo .bl-cred.in span{opacity:1;transform:none;
    transition:opacity .45s ease,transform .55s cubic-bezier(.22,1,.36,1);
    transition-delay:calc(var(--i,0) * 130ms + 250ms)}
  html.mo .bl-cred span:nth-child(1){--i:0}
  html.mo .bl-cred span:nth-child(2){--i:1}
  html.mo .bl-cred span:nth-child(3){--i:2}
  html.mo .bl-cred.in i{animation:mo-pop .4s cubic-bezier(.34,1.56,.64,1) both;
    animation-delay:calc(var(--i,0) * 130ms + 330ms)}
  @keyframes mo-pop{from{transform:scale(0)}to{transform:scale(1)}}

  /* ---- two sports ---- */
  html.mo .bl-half:nth-child(1){--i:0}
  html.mo .bl-half:nth-child(2){--i:1}
  html.mo .bl-half{transition:background .25s ease}
  html.mo .bl-half:hover{background:rgba(255,255,255,.05)}

  /* ---- features: boxes settle, then the accent underline draws ---- */
  html.mo .bl-box:nth-child(1){--i:0} html.mo .bl-box:nth-child(2){--i:1}
  html.mo .bl-box:nth-child(3){--i:2} html.mo .bl-box:nth-child(4){--i:3}
  html.mo .bl-box{transition:background .25s ease}
  html.mo .bl-box:hover{background:rgba(255,255,255,.05)}
  html.mo .bl-box .no{transition:color .25s ease}
  html.mo .bl-box:hover .no{color:var(--optic)}
  html.mo .bl-box h3 u{border-bottom-color:transparent;position:relative}
  html.mo .bl-box h3 u::after{content:"";position:absolute;left:0;right:0;bottom:-4px;height:4px;
    background:var(--optic);transform:scaleX(0);transform-origin:0 50%}
  html.mo .in .bl-box h3 u::after{transform:scaleX(1);
    transition:transform .55s cubic-bezier(.22,1,.36,1);
    transition-delay:calc(var(--i,0) * 90ms + 480ms)}

  /* ---- how it works: a ball rallies across the three steps ---- */
  html.mo .bl-steps{position:relative}
  .bl-rally{display:none}
  html.mo .bl-rally{display:block;position:absolute;top:12px;left:16.6%;width:14px;height:14px;
    margin-left:-7px;opacity:0;pointer-events:none;z-index:2}
  html.mo .bl-rally i{display:block;width:14px;height:14px;border-radius:50%;
    background:var(--ball);border:2px solid var(--court-deep)}
  html.mo .in .bl-rally{animation:mo-rally-x 1.9s cubic-bezier(.45,0,.55,1) .5s both}
  html.mo .in .bl-rally i{animation:mo-rally-y 1.9s linear .5s both}
  @keyframes mo-rally-x{
    0%{opacity:0;left:16.6%}
    8%{opacity:1}
    50%{left:50%}
    92%{opacity:1}
    100%{opacity:1;left:83.4%}
  }
  /* two parabolas -- up-over-down, twice */
  @keyframes mo-rally-y{
    0%{transform:translateY(0)}
    12%{transform:translateY(-34px)}
    25%{transform:translateY(0)}
    32%{transform:translateY(-10px)}
    40%{transform:translateY(0)}
    62%{transform:translateY(-34px)}
    82%{transform:translateY(0)}
    89%{transform:translateY(-10px)}
    100%{transform:translateY(0)}
  }
  html.mo .bl-step:nth-child(1){--i:0} html.mo .bl-step:nth-child(2){--i:1}
  html.mo .bl-step:nth-child(3){--i:2}

  /* ---- video slot: the play disc pings like radar ---- */
  html.mo .bl-video .disc{animation:mo-ping 2.8s ease-in-out infinite}
  @keyframes mo-ping{0%,100%{transform:scale(1);opacity:1}50%{transform:scale(1.07);opacity:.72}}
  /* hatched placeholders drift, so the empty slots still feel alive */
  html.mo .bl-shot,html.mo .bl-portrait{animation:mo-hatch 34s linear infinite}
  @keyframes mo-hatch{to{background-position:88px 0}}

  /* ---- FAQ ---- */
  html.mo .bl-faq summary{transition:background .2s ease}
  html.mo .bl-faq summary:hover{background:rgba(255,255,255,.05)}
  html.mo .bl-faq summary::after{transition:transform .25s cubic-bezier(.34,1.56,.64,1)}
  html.mo .bl-faq details[open] .ans{animation:mo-ans .38s ease both}
  @keyframes mo-ans{from{opacity:0;transform:translateY(-8px)}}

  /* ---- reserve ---- */
  html.mo .bl-form input{transition:border-color .2s ease}
  html.mo .bl-msg.show{animation:mo-msg .45s cubic-bezier(.34,1.56,.64,1) both}
  @keyframes mo-msg{from{opacity:0;transform:scale(.85)}}

  /* belt and braces: if the OS asks for calm, everything sits still */
  @media (prefers-reduced-motion: reduce){
    html.mo *,html.mo *::before,html.mo *::after{
      animation:none !important;transition:none !important;
      clip-path:none !important;transform:none !important;opacity:1 !important}
    html.mo .bl-prog{display:none}
  }

  .bl-h1 .ln,.bl-founder h2 .ln,.bl-res h2 .ln{display:block}

/* ---- photography ---------------------------------------------------
     Every shot is a cut-out on transparency, so it sits straight on the
     court blue. No cards, no shadows -- concept 14 stays flat.          */
  .bl-root .bl-shots{display:grid;grid-template-columns:1fr 1fr;gap:clamp(18px,4vw,52px);
    align-items:end;padding:clamp(30px,5vw,64px) clamp(16px,4vw,48px)}
  @media (max-width:640px){.bl-root .bl-shots{gap:22px}}
  .bl-root .bl-fig{margin:0;text-align:center}
  .bl-root .bl-fig img{display:block;width:auto;max-width:100%;max-height:clamp(240px,44vw,430px);
    margin:0 auto}
  .bl-root .bl-fig figcaption{margin-top:16px;font-family:var(--f-cond);font-weight:800;
    text-transform:uppercase;letter-spacing:.14em;font-size:11.5px;color:var(--dim)}
  .bl-root .bl-fig figcaption b{display:block;color:var(--optic);margin-bottom:4px;letter-spacing:.18em}

  /* line art sits in the sports band like a diagram on the court */
  .bl-root .bl-art{padding:0 clamp(16px,4vw,48px) clamp(26px,4vw,44px);text-align:center}
  .bl-root .bl-art img{display:block;margin:0 auto;width:100%;max-width:clamp(240px,42vw,400px);height:auto}

  /* the pack, above the reserve headline: this is the thing being reserved */
  .bl-root .bl-pack{margin:0 auto clamp(22px,3vw,34px)}
  .bl-root .bl-pack img{display:block;margin:0 auto;width:auto;height:auto;
    max-height:clamp(150px,22vw,230px);max-width:70%}

  /* real logo replaces the type-set wordmark */
  .bl-root .bl-mark img{display:block;height:26px;width:auto}
  @media (max-width:480px){.bl-root .bl-mark img{height:22px}}

/* ============================================================
     LINE-ART DIAGRAMS — white paint on the court, same language
     as the brand card. Every stroke has pathLength="1" so the
     draw-on animation needs no measuring.
     ============================================================ */
  /* Both columns are capped and the pair is centred as a unit. The copy
     column used to be 1fr, which pinned the diagram to the left edge and
     left a ~250px void on the right at desktop widths. */
  .bl-root .gs{padding:clamp(30px,5vw,60px) clamp(16px,4vw,48px);
    display:grid;grid-template-columns:minmax(0,320px) minmax(0,520px);
    gap:clamp(24px,5vw,56px);align-items:center;justify-content:center}
  @media (max-width:720px){.bl-root .gs{grid-template-columns:1fr;gap:24px}}

  .bl-root .gs-oct{width:100%;max-width:320px;height:auto;margin:0 auto;display:block;overflow:visible}
  .gs-face{stroke:rgba(255,255,255,.42);stroke-width:3;fill:none;stroke-linecap:square}
  .gs-hatch circle{fill:none;stroke:rgba(255,255,255,.14);stroke-width:2;stroke-dasharray:2 9}
  .gs-num{fill:rgba(255,255,255,.45);font-family:var(--f-cond);font-weight:800;font-size:15px;
    text-anchor:middle;dominant-baseline:middle}
  .gs-num.on{fill:var(--optic)}
  .gs-seam{stroke:var(--optic);stroke-width:7;stroke-linecap:round;fill:none}
  .gs-lead{stroke:var(--optic);stroke-width:2;stroke-dasharray:3 5;opacity:.75}
  .gs-dot{fill:var(--optic)}
  .gs-marker{transform-box:view-box;transform-origin:132px 132px}

  .bl-root .gs-pick{display:flex;flex-wrap:wrap;gap:10px;margin-bottom:22px}
  .bl-root .gs-btn{font-family:var(--f-cond);font-weight:800;font-size:12.5px;letter-spacing:.12em;
    text-transform:uppercase;padding:11px 18px;border:2.5px solid rgba(255,255,255,.5);
    background:transparent;color:#fff;cursor:pointer}
  .bl-root .gs-btn:hover{border-color:#fff}
  .bl-root .gs-btn[aria-pressed="true"]{background:var(--optic);border-color:var(--optic);color:var(--dark)}
  .bl-root .gs-name{font-family:var(--f-cond);font-weight:800;font-style:italic;text-transform:uppercase;
    font-size:clamp(1.5rem,3.4vw,2.2rem);line-height:1;margin-bottom:10px}
  .bl-root .gs-name em{font-style:italic;color:var(--optic)}
  .bl-root .gs-blurb{color:var(--dim);font-size:1rem;max-width:44ch;margin-bottom:14px}
  .bl-root .gs-hint{font-family:var(--f-cond);font-weight:800;text-transform:uppercase;letter-spacing:.16em;
    font-size:11px;color:var(--faint)}

  /* --- install sequence --- */
  .bl-root .d-row{display:grid;grid-template-columns:repeat(3,1fr);border-top:var(--lw) solid var(--lineW)}
  @media (max-width:640px){.bl-root .d-row{grid-template-columns:1fr}}
  .bl-root .d-cell{padding:clamp(22px,4vw,40px) clamp(14px,2.5vw,26px);text-align:center;
    border-right:var(--lw) solid var(--lineW)}
  .bl-root .d-cell:last-child{border-right:0}
  @media (max-width:640px){.bl-root .d-cell{border-right:0;border-bottom:var(--lw) solid var(--lineW)}
    .bl-root .d-cell:last-child{border-bottom:0}}
    .bl-root .d-svg{width:100%;max-width:182px;height:auto;display:block;margin:0 auto 18px}
  .d-ln{fill:none;stroke:rgba(255,255,255,.78);stroke-width:3.2;stroke-linejoin:round;stroke-linecap:round}
  .d-accent .d-ln{stroke:#fff;stroke-width:3.8}
  .d-arrow,.d-seam,.d-slot{fill:none;stroke:var(--optic);stroke-width:3.8;
    stroke-linecap:round;stroke-linejoin:round}
  .d-tx{fill:var(--optic);font-family:var(--f-cond);font-weight:800;font-size:14px;
    text-anchor:middle;letter-spacing:.1em}
  .bl-root .d-cap{font-family:var(--f-cond);font-weight:800;text-transform:uppercase;
    letter-spacing:.14em;font-size:12px}
  .bl-root .d-sub{color:var(--dim);font-size:.9rem;margin-top:6px;max-width:24ch;
    margin-left:auto;margin-right:auto}

  /* --- draw-on: strokes paint themselves when the band arrives ---
     Target the CLASSES, never [pathLength]: CSS lowercases the attribute
     name to [pathlength] and attribute matching is case-SENSITIVE on SVG
     elements, so the camelCase attribute silently never matches.
     Animation (not transition) so `forwards` pins the finished state. */
  html.mo .d-svg .d-ln,html.mo .d-svg .d-arrow,
  html.mo .d-svg .d-seam,html.mo .d-svg .d-slot{stroke-dasharray:1;stroke-dashoffset:1}
  html.mo .in .d-svg .d-ln,html.mo .in .d-svg .d-arrow,
  html.mo .in .d-svg .d-seam,html.mo .in .d-svg .d-slot{
    animation:d-draw 1.05s cubic-bezier(.22,1,.36,1) forwards;
    animation-delay:calc(var(--i,0) * 200ms + 260ms)}
  @keyframes d-draw{from{stroke-dashoffset:1}to{stroke-dashoffset:0}}
  html.mo .d-cell:nth-child(1){--i:0} html.mo .d-cell:nth-child(2){--i:1}
  html.mo .d-cell:nth-child(3){--i:2}
  html.mo .gs-marker{transition:transform .55s cubic-bezier(.34,1.45,.64,1)}

  @media (prefers-reduced-motion: reduce){
    html.mo .d-svg .d-ln,html.mo .d-svg .d-arrow,
    html.mo .d-svg .d-seam,html.mo .d-svg .d-slot{
      stroke-dasharray:none;stroke-dashoffset:0;animation:none}
  }

/* ---- court photography (duotoned into the palette) ---- */
  .bl-root .bl-court-band{position:relative;border-top:var(--lw) solid var(--lineW);
    aspect-ratio:1800/827;overflow:hidden}
  .bl-root .bl-court-band img{position:absolute;inset:0;width:100%;height:100%;
    object-fit:cover;display:block}
  .bl-root .bl-court-band .cap{position:absolute;left:0;right:0;bottom:0;
    padding:clamp(16px,3vw,30px) clamp(16px,4vw,48px);
    font-family:var(--f-cond);font-weight:800;text-transform:uppercase;
    letter-spacing:.16em;font-size:clamp(11px,1.5vw,13px);color:#fff;
    background:linear-gradient(transparent,rgba(8,26,72,.72))}
  .bl-root .bl-court-band .cap b{color:var(--optic)}

  /* the closing CTA gets a court behind it, under a scrim */
  .bl-root .bl-res{position:relative;isolation:isolate;overflow:hidden}
  .bl-root .bl-res-bg{position:absolute;inset:0;z-index:-2;width:100%;height:100%;
    object-fit:cover;display:block}
  .bl-root .bl-res::before{content:"";position:absolute;inset:0;z-index:-1;
    background:rgba(9,28,78,.84)}

/* ============================================================
     SCROLL-SCRUBBED INSTALL SEQUENCE
     ============================================================ */
  /* .bl-root used overflow-x:hidden, which makes it a scroll container and
     silently breaks every position:sticky inside it. `clip` blocks the same
     horizontal overflow without creating that container. */
  .bl-root{overflow-x:clip}

  .bl-seq{border-bottom:var(--lw) solid var(--lineW);position:relative}
  .bl-seq .ss-track{position:relative;height:340vh}
  .bl-seq .ss-stick{position:sticky;top:0;height:100vh;display:flex;align-items:center;
    justify-content:center;padding:clamp(14px,3vw,40px)}
  .bl-seq .ss-in{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1fr);
    gap:clamp(20px,5vw,60px);align-items:center;width:100%;max-width:940px}
  @media (max-width:760px){
    .bl-seq .ss-in{grid-template-columns:1fr;gap:18px;justify-items:center}
    .bl-seq .ss-track{height:300vh}
  }

  .bl-seq canvas{display:block;width:100%;max-width:330px;height:auto;margin:0 auto}
  @media (max-width:760px){.bl-seq canvas{max-width:min(56vw,240px)}}

  .bl-seq .ss-eyebrow{display:inline-block;font-family:var(--f-cond);font-weight:800;font-size:12px;
    letter-spacing:.3em;text-transform:uppercase;color:var(--dark);background:var(--lineW);
    padding:6px 14px;margin-bottom:18px}
  .bl-seq .ss-h{font-family:var(--f-cond);font-weight:800;font-style:italic;text-transform:uppercase;
    font-size:clamp(1.8rem,5vw,3.2rem);line-height:.94;margin-bottom:16px}
  .bl-seq .ss-h .go{color:var(--optic)}
  .bl-root .bl-seq .ss-cap{font-family:var(--f-cond);font-weight:800;text-transform:uppercase;
    letter-spacing:.1em;font-size:clamp(.95rem,2vw,1.15rem);min-height:2.6em;max-width:26ch}
  .bl-root .bl-seq .ss-cap b{display:block;color:var(--optic);font-size:.72em;letter-spacing:.2em;
    margin-bottom:6px}
  .bl-seq .ss-bar{height:4px;background:rgba(255,255,255,.26);margin:20px 0 10px;max-width:280px}
  .bl-seq .ss-bar i{display:block;height:100%;width:0;background:var(--optic)}
  .bl-root .bl-seq .ss-hint{font-family:var(--f-cond);font-weight:800;text-transform:uppercase;
    letter-spacing:.16em;font-size:11px;color:var(--faint)}

  /* static fallback: no JS, or the visitor asked for less motion */
  .bl-seq.is-static .ss-track{height:auto}
  .bl-seq.is-static .ss-stick{position:static;height:auto}
  .bl-seq.is-static .ss-bar,.bl-seq.is-static .ss-hint{display:none}
  @media (prefers-reduced-motion: reduce){
    .bl-seq .ss-track{height:auto}
    .bl-seq .ss-stick{position:static;height:auto}
    .bl-seq .ss-bar,.bl-seq .ss-hint{display:none}
  }

/* ---- stills pulled from the tutorial footage ---- */
  .bl-root .bl-lead{padding:clamp(24px,4vw,46px) clamp(16px,4vw,48px) 0}
  .bl-root .bl-lead figure{margin:0;text-align:center}
  .bl-root .bl-lead img{display:block;margin:0 auto;width:100%;
    max-width:clamp(240px,38vw,360px);height:auto}
  .bl-root .bl-lead figcaption{margin-top:14px;font-family:var(--f-cond);font-weight:800;
    text-transform:uppercase;letter-spacing:.14em;font-size:11.5px;color:var(--dim)}
  .bl-root .bl-lead figcaption b{color:var(--optic);letter-spacing:.18em}

  /* the real butt cap, under the interactive octagon */
  .bl-root .gs-real{margin-top:20px;text-align:center}
  .bl-root .gs-real img{display:block;margin:0 auto;width:100%;max-width:210px;height:auto}
  .bl-root .gs-real span{display:block;margin-top:10px;font-family:var(--f-cond);font-weight:800;
    text-transform:uppercase;letter-spacing:.16em;font-size:10.5px;color:var(--faint)}

  /* founder portrait replaces the hatched placeholder */
  .bl-root .bl-portrait{padding:0;background:none}
  .bl-root .bl-portrait img{display:block;width:100%;height:100%;object-fit:cover}


/* ============================================================
   PER-PAGE COLOUR THEMES  (added 2026-08-09, three-page split)
   Home carries both colours evenly. Tennis is BLUE and pickleball is
   GREEN (swapped 2026-08-17). Classes are named by COLOUR, not by sport,
   so a future swap does not leave the names lying. Everything above reads these variables, so a theme is
   a token swap and nothing else.

   ⚠ NAMESPACE: gs-* is the GRIP SELECTOR. Components added below
   use sp-* (sport). Never add a gs-* class here.
   ============================================================ */
.bl-root.t-green{
  --court:#2E7D46; --court-deep:#256B3C; --dark:#1B3325;
  --optic:#FFFFFF; --optic-hi:#E6F2EA;
  --ball:#FFFFFF; --ball-seam:rgba(27,51,37,.60);
}
/* Home is plain blue (2026-08-27: Brycen killed the blue/green split). */
.bl-root.t-home{
  --court:#1B4DD8; --court-deep:#1740B0; --dark:#0B245E;
  --optic:#4ADE68; --optic-hi:#6CEA85;
  --ball:#FFFFFF; --ball-seam:rgba(11,36,94,.55);
}
.bl-root.t-blue{
  --court:#1B4DD8; --court-deep:#1740B0; --dark:#0B245E;
  --optic:#4ADE68; --optic-hi:#6CEA85;
  --ball:#FFFFFF; --ball-seam:rgba(11,36,94,.55);
}
/* Home only: sections that flip to pickleball blue, so the page
   reads as both brands instead of picking a side. */
.t-home .band-blue{
  --court:#1B4DD8; --court-deep:#1740B0; --dark:#0B245E;
  --optic:#4ADE68; --optic-hi:#6CEA85;
  background:var(--court);
}
/* Anchor targets sat under the sticky header when jumped to. */
.bl-root [id]{scroll-margin-top:104px}

/* ---------- CHOOSE YOUR SPORT (home) ---------- */
.bl-root .sp-pick{display:grid;grid-template-columns:1fr 1fr;gap:0;
  border-top:var(--lw) solid var(--lineW);border-bottom:var(--lw) solid var(--lineW)}
.bl-root .sp-card{display:block;padding:clamp(26px,5vw,56px);color:#FFFFFF;
  text-decoration:none;position:relative;transition:filter .18s ease}
.bl-root .sp-card+.sp-card{border-left:var(--lw) solid var(--lineW)}
.bl-root .sp-card:hover,.bl-root .sp-card:focus-visible{filter:brightness(1.09)}
.bl-root .sp-card.is-tennis{background:#1B4DD8}
.bl-root .sp-card.is-pickle{background:#2E7D46}
.bl-root .sp-card .tag{display:inline-block;font-family:var(--f-cond);font-weight:800;
  font-size:12px;letter-spacing:.18em;text-transform:uppercase;padding:5px 10px;
  margin-bottom:16px;border:2px solid currentColor}
.bl-root .sp-card.is-tennis .tag{color:#4ADE68}
.bl-root .sp-card.is-pickle .tag{color:#FFFFFF}
.bl-root .sp-card h3{font-family:var(--f-cond);font-weight:800;text-transform:uppercase;
  font-size:clamp(24px,3.4vw,38px);line-height:1.02;margin-bottom:12px}
.bl-root .sp-card p{color:rgba(255,255,255,.82);max-width:34ch;margin-bottom:20px}
.bl-root .sp-card .arw{font-family:var(--f-cond);font-weight:800;font-size:13px;
  letter-spacing:.14em;text-transform:uppercase;display:inline-flex;align-items:center;gap:9px}
.bl-root .sp-card .arw::after{content:"";width:26px;height:2px;background:currentColor;
  transition:width .18s ease}
.bl-root .sp-card:hover .arw::after{width:42px}
@media(max-width:720px){
  .bl-root .sp-pick{grid-template-columns:1fr}
  .bl-root .sp-card+.sp-card{border-left:0;border-top:var(--lw) solid var(--lineW)}
}

/* ---------- SIZE / HANDEDNESS MATRIX (sport pages) ---------- */
.bl-root .sp-sizes{display:grid;grid-template-columns:repeat(4,1fr);gap:0;
  border:var(--lw) solid var(--lineW);margin-top:26px}
.bl-root .sp-size{padding:clamp(16px,2.4vw,26px)}
.bl-root .sp-size+.sp-size{border-left:var(--lw) solid var(--lineW)}
.bl-root .sp-size .who{font-family:var(--f-cond);font-weight:800;text-transform:uppercase;
  font-size:clamp(15px,1.9vw,21px);margin-bottom:6px}
.bl-root .sp-size .hand{color:var(--optic);font-family:var(--f-cond);font-weight:800;
  font-size:12px;letter-spacing:.16em;text-transform:uppercase}
@media(max-width:720px){
  .bl-root .sp-sizes{grid-template-columns:repeat(2,1fr)}
  .bl-root .sp-size:nth-child(odd){border-left:0}
  .bl-root .sp-size:nth-child(n+3){border-top:var(--lw) solid var(--lineW)}
}

/* ---------- CROSS-SPORT BANNER ---------- */
.bl-root .sp-cross{display:flex;align-items:center;justify-content:space-between;gap:18px;
  flex-wrap:wrap;padding:clamp(22px,4vw,38px);border-top:var(--lw) solid var(--lineW);
  background:var(--dark);text-decoration:none;color:var(--ink);transition:filter .18s ease}
.bl-root .sp-cross:hover{filter:brightness(1.16)}
.bl-root .sp-cross .cx-t{font-family:var(--f-cond);font-weight:800;text-transform:uppercase;
  font-size:clamp(17px,2.3vw,25px)}
.bl-root .sp-cross .cx-s{color:var(--dim);font-size:15px;margin-top:4px}
.bl-root .sp-cross .cx-go{font-family:var(--f-cond);font-weight:800;font-size:13px;
  letter-spacing:.14em;text-transform:uppercase;color:var(--optic);white-space:nowrap}

/* Marks copy still waiting on a real product fact. */
.bl-root .sp-todo{margin-top:16px;padding:12px 14px;border:2px dashed var(--faint);
  color:var(--dim);font-size:14px}

/* ---------- TUTORIAL VIDEO (home, added 2026-08-27) ----------
   Vertical phone video, so it is boxed to a phone width and centred
   rather than stretched to the section. */
.bl-root .sp-vid{max-width:min(420px,88vw);margin:0 auto;border:var(--lw) solid var(--lineW);
  background:var(--court-deep);line-height:0}
.bl-root .sp-vid video{display:block;width:100%;height:auto;aspect-ratio:9/16;background:var(--court-deep)}

/* ---------- 2026-08-27 edits (Brycen) ---------- */
/* Sport cards: white ground, sport colour for the words (trial). */
.bl-root .sp-card.is-tennis{background:#FFFFFF;color:#1B4DD8}
.bl-root .sp-card.is-pickle{background:#FFFFFF;color:#2E7D46}
.bl-root .sp-card.is-tennis p{color:rgba(27,77,216,.82)}
.bl-root .sp-card.is-pickle p{color:rgba(46,125,70,.85)}
.bl-root .sp-card.is-tennis .tag{color:#1B4DD8}
.bl-root .sp-card.is-pickle .tag{color:#2E7D46}
.bl-root .sp-card+.sp-card{border-left-color:#1B4DD8}
@media(max-width:720px){.bl-root .sp-card+.sp-card{border-top-color:#1B4DD8}}
/* Grip selector: one centred column on desktop. Octagon and the real
   butt-cap photo sit side by side, the buttons and copy centred under them. */
.bl-root .gs{display:flex;flex-direction:column;align-items:center;text-align:center;gap:clamp(22px,3vw,36px)}
.bl-root .gs-viz{display:flex;flex-wrap:wrap;justify-content:center;align-items:center;gap:clamp(24px,5vw,64px);width:100%}
.bl-root .gs-viz .gs-oct{margin:0}
.bl-root .gs-copy{max-width:56ch}
.bl-root .gs-pick{justify-content:center}
/* Install: a real video replaces the scroll-scrubbed frames. */
.bl-seq .ss-vid{width:100%;max-width:330px;margin:0 auto;border:var(--lw) solid var(--lineW);background:var(--court-deep);line-height:0}
.bl-seq .ss-vid video{display:block;width:100%;height:auto;aspect-ratio:9/16;background:var(--court-deep)}
@media (max-width:760px){.bl-seq .ss-vid{max-width:min(70vw,300px)}}
/* Install steps as a list next to the looping clip (2026-08-27). */
.bl-root .ss-steps{list-style:none;margin:18px 0 0;padding:0;display:grid;gap:14px}
.bl-root .ss-steps li{font-family:var(--f-cond);font-weight:800;text-transform:uppercase;letter-spacing:.04em;
  font-size:clamp(1rem,1.6vw,1.2rem);line-height:1.15;padding-left:14px;border-left:4px solid var(--optic)}
.bl-root .ss-steps li b{display:block;color:var(--optic);font-size:.72em;letter-spacing:.2em;margin-bottom:2px}
/* Hero ball: an actual tennis ball. Yellow is allowed HERE ONLY (Brycen 2026-08-27). */
.bl-root .bl-ball{background:#D7F205;border:3px solid var(--court-deep);overflow:hidden}
.bl-root .bl-ball::before,.bl-root .bl-ball::after{content:"";position:absolute;top:50%;width:100%;height:100%;
  border-radius:50%;border:3px solid #FFFFFF;box-sizing:border-box;inset:auto;transform:translateY(-50%)}
.bl-root .bl-ball::before{left:-62%}
.bl-root .bl-ball::after{right:-62%}

/* ---------- SCROLL BALL + TRAIL (home, motion only, 2026-08-27) ----------
   A second ball takes over once the hero ball has scrolled away. It bounces
   along the bottom of the viewport as you scroll, with a fading trail of
   ghosts behind it and a ground shadow that shrinks as it rises. Built by
   site.js; nothing here renders without html.mo. */
.sb-layer{display:none}
html.mo .sb-layer{display:block;position:fixed;inset:0;pointer-events:none;z-index:40;overflow:hidden;
  opacity:0;transition:opacity .35s ease}
html.mo .sb-layer.on{opacity:1}
.sb-ball,.sb-t{position:absolute;left:0;top:0;width:56px;height:56px;border-radius:50%;
  background:#D7F205;border:3px solid var(--court-deep);overflow:hidden;will-change:transform}
.sb-ball::before,.sb-ball::after,.sb-t::before,.sb-t::after{content:"";position:absolute;top:50%;width:100%;height:100%;
  border-radius:50%;border:3px solid #FFFFFF;box-sizing:border-box;transform:translateY(-50%)}
.sb-ball::before,.sb-t::before{left:-62%} .sb-ball::after,.sb-t::after{right:-62%}
.sb-t{opacity:.35;filter:blur(.5px)}
.sb-t.t2{opacity:.25}.sb-t.t3{opacity:.16}.sb-t.t4{opacity:.09}.sb-t.t5{opacity:.05}
.sb-shadow{position:absolute;left:0;top:0;width:56px;height:14px;border-radius:50%;
  background:rgba(0,0,0,.35);filter:blur(3px);will-change:transform,opacity}
@media (max-width:720px){.sb-ball,.sb-t{width:40px;height:40px}.sb-shadow{width:40px}}

/* ---------- SPORT CARDS: colour sweeps in on hover (2026-08-27) ---------- */
.bl-root .sp-card{overflow:hidden;isolation:isolate;
  transition:color .35s ease .08s,transform .35s cubic-bezier(.22,1,.36,1)}
.bl-root .sp-card>*{position:relative;z-index:1}
.bl-root .sp-card::before{content:"";position:absolute;top:0;bottom:0;left:-25%;width:150%;z-index:0;
  transform:translateX(-100%) skewX(-8deg);
  transition:transform .5s cubic-bezier(.22,1,.36,1)}
.bl-root .sp-card.is-tennis::before{background:#1B4DD8}
.bl-root .sp-card.is-pickle::before{background:#2E7D46}
.bl-root .sp-card:hover,.bl-root .sp-card:focus-visible{filter:none;color:#FFFFFF}
.bl-root .sp-card:hover::before,.bl-root .sp-card:focus-visible::before{transform:translateX(0) skewX(0)}
.bl-root .sp-card p{transition:color .35s ease .08s}
.bl-root .sp-card.is-tennis:hover p,.bl-root .sp-card.is-pickle:hover p,
.bl-root .sp-card.is-tennis:focus-visible p,.bl-root .sp-card.is-pickle:focus-visible p{color:rgba(255,255,255,.88)}
.bl-root .sp-card:hover .tag,.bl-root .sp-card:focus-visible .tag{color:#FFFFFF}
.bl-root .sp-card h3{transition:transform .45s cubic-bezier(.22,1,.36,1)}
.bl-root .sp-card:hover h3{transform:translateX(8px)}
.bl-root .sp-card .arw::after{transition:width .45s cubic-bezier(.22,1,.36,1)}
.bl-root .sp-card:hover .arw::after{width:72px}
html.mo .bl-root .sp-card:hover{transform:translateY(-3px)}
/* No white above the header or below the footer (2026-08-27). The court frame's
   outer margins were collapsing through .bl-root, so the body showed through.
   flow-root stops the collapse; the html background is belt and braces for
   overscroll on Mac. */
.bl-root{display:flow-root}
html{background:#1B4DD8}
html:has(.bl-root.t-green){background:#2E7D46}
/* Mobile header keeps the nav (Brycen 2026-08-27). Logo and CTA on the first
   row, the section links on a second row that scrolls sideways if it must. */
@media (max-width:720px){
  .bl-head{flex-wrap:wrap;row-gap:0}
  .bl-nav{display:flex;order:3;width:100%;justify-content:space-between;gap:12px;
    overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none;
    margin-top:10px;padding-top:9px;border-top:1px solid rgba(255,255,255,.22)}
  .bl-nav::-webkit-scrollbar{display:none}
  .bl-nav a{font-size:11px;letter-spacing:.1em;white-space:nowrap;padding:2px 0}
  .bl-root .bl-cta{padding:9px 12px;font-size:11px}
  .bl-root [id]{scroll-margin-top:118px}
}
