body{
    color: white;
    font-size: 100px;
    text-align: center;
    font-family: copperplate;
    background-color: rgb(20, 37, 77);
    background-image:
        radial-gradient(circle at 20% 0%, rgba(255, 140, 40, 0.18), transparent 45%),
        radial-gradient(circle at 85% 15%, rgba(60, 120, 255, 0.20), transparent 40%);
    /* No background-attachment: fixed. On iOS a fixed background forces the
       browser to repaint the whole viewport on every single scroll frame,
       and these two gradients are subtle enough to scroll with the page. */
    margin: 0;
    padding: 40px 20px 80px;
}

.logo{
    font-weight: normal;
    margin: 0;
    line-height: 1;
}
.logo .supa{
    display: block;
    font-size: 68px;
    letter-spacing: 1px;
    color: rgb(255, 160, 70);
    text-shadow: 0 0 34px rgba(255, 140, 40, 0.5);
}
.logo .sub{
    display: block;
    font-size: 30px;
    letter-spacing: 5px;
    margin-top: 10px;
    opacity: 0.7;
}

.info{
    font-size: 26px;
    margin-top: 34px;
}

.works-with{
    display: block;
    margin-top: 14px;
    font-size: 15px;
    letter-spacing: 1px;
    opacity: 0.5;
}

.text{
    font-size: 19px;
    margin-top: 48px;
    margin-bottom: 24px;
    max-width: 560px;
    text-align: center;
    display: inline-block;
    line-height: 1.6;
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 16px;
    padding: 24px 28px;
}

/* the little chips under the paragraph */
.facts{
    font-size: 0;
    margin-top: 26px;
}
/* These are just labels. They deliberately avoid the rounded, tinted,
   bordered look the real buttons use, so nobody tries to press them. */
.fact{
    display: inline-block;
    font-size: 16px;
    font-family: copperplate;
    letter-spacing: 1px;
    color: rgba(255, 255, 255, 0.5);
    margin: 4px 0;
    cursor: default;
}
.fact:not(:last-child)::after{
    content: "·";
    margin: 0 13px;
    opacity: 0.4;
}

/* ===== the name gate on the way in ===== */
.namegate{
    position: fixed;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    z-index: 50;
    background: rgba(8, 16, 38, 0.94);
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.25s;
}
.namegate.show{
    opacity: 1;
    pointer-events: auto;
}
.nameinput{
    display: block;
    width: 260px;
    max-width: 100%;
    margin: 22px auto 0;
    padding: 12px 16px;
    font-family: copperplate;
    font-size: 22px;
    letter-spacing: 3px;
    text-align: center;
    text-transform: uppercase;
    color: white;
    background: rgba(255, 255, 255, 0.08);
    border: 2px solid rgba(255, 150, 60, 0.6);
    border-radius: 12px;
    outline: none;
}
.nameinput:focus{
    border-color: rgb(255, 190, 90);
    background: rgba(255, 255, 255, 0.13);
}
.nameinput::placeholder{
    color: rgba(255, 255, 255, 0.3);
    letter-spacing: 2px;
}
.nameerror{
    font-size: 14px;
    color: rgb(255, 130, 120);
    margin-top: 10px;
    min-height: 18px;
}

/* ===== the game ===== */
.green-word{
    color: rgb(120, 240, 140);
}
.money-word{
    color: rgb(255, 210, 90);
}

.court{
    position: relative;
    width: 100%;
    max-width: 640px;
    height: 470px;
    margin: 0 auto;
    background: #0a1330;
    border: 2px solid rgba(255, 255, 255, 0.18);
    border-radius: 18px;
    overflow: hidden;
    cursor: pointer;
    user-select: none;
    -webkit-user-select: none;
    -webkit-tap-highlight-color: transparent;
    /* holding a shot must not scroll or zoom the page */
    touch-action: none;
}

/* ===== the arena ===== */

/* the bleachers: tiered steps going up and back */
.stands{
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 27%;
    overflow: hidden;
    pointer-events: none;
    background-color: #0a1029;
    background-image:
        repeating-linear-gradient(180deg,
            rgba(255, 255, 255, 0.05) 0 1px,
            rgba(0, 0, 0, 0.30) 1px 4px,
            transparent 4px 26px),
        linear-gradient(180deg, rgba(0, 0, 0, 0.8), rgba(0, 0, 0, 0.05));
}

/* the fans sitting in them, built by the script */
.crowd{
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
}
/* a whole row of fans moves as one piece */
.crowd-row{
    position: absolute;
    left: 0;
    width: 100%;
    height: 0;
    will-change: transform;
    animation-name: bob;
    animation-iteration-count: infinite;
    animation-timing-function: ease-in-out;
}
.fan{
    position: absolute;
    top: 0;
    border-radius: 40% 40% 22% 22%;
}
.fan i{
    position: absolute;
    border-radius: 50%;
    background: #e6c39c;
    opacity: 0.9;
}
@keyframes bob{
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(-2px); }
}

/* everybody stands up when a shot goes in */
.stands.cheer .crowd-row{
    animation-name: jump;
    animation-duration: 0.35s !important;
}
@keyframes jump{
    0%, 100% { transform: translateY(0); }
    45%      { transform: translateY(-7px); }
}

/* camera flashes going off in the crowd */
.flash{
    position: absolute;
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: white;
    opacity: 0;
    box-shadow: 0 0 10px 3px rgba(255, 255, 255, 0.9);
    animation: flash 5s infinite;
}
.f1{ left: 12%; top: 30%; animation-delay: 0.4s; }
.f2{ left: 41%; top: 62%; animation-delay: 2.1s; }
.f3{ left: 68%; top: 22%; animation-delay: 3.3s; }
.f4{ left: 88%; top: 55%; animation-delay: 4.4s; }
@keyframes flash{
    0%, 4%, 100% { opacity: 0; }
    1%           { opacity: 1; }
}

/* the LED ribbon board around the arena */
.ledboard{
    position: absolute;
    left: 0;
    top: 27%;
    width: 100%;
    height: 22px;
    overflow: hidden;
    pointer-events: none;
    background: linear-gradient(180deg, #16295e, #0a1533);
    border-top: 1px solid rgba(255, 255, 255, 0.18);
    border-bottom: 2px solid rgba(0, 0, 0, 0.6);
}
.ledboard span{
    display: inline-block;
    white-space: nowrap;
    font-size: 11px;
    letter-spacing: 3px;
    line-height: 22px;
    color: rgb(255, 165, 60);
    text-shadow: 0 0 8px rgba(255, 140, 40, 0.8);
    animation: ribbon 24s linear infinite;
}
@keyframes ribbon{
    from { transform: translateX(0); }
    to   { transform: translateX(-50%); }
}

/* the hardwood */
.floor{
    position: absolute;
    left: 0;
    top: calc(27% + 22px);
    right: 0;
    bottom: 0;
    pointer-events: none;
    background-color: #a4682f;
    background-image:
        radial-gradient(ellipse at 50% -12%, rgba(255, 230, 190, 0.32), transparent 52%),
        radial-gradient(ellipse at 12% 30%, rgba(255, 220, 175, 0.10), transparent 40%),
        radial-gradient(ellipse at 88% 30%, rgba(255, 220, 175, 0.10), transparent 40%),
        linear-gradient(180deg, #4d2e16 0%, #75471f 45%, #9c6531 100%);
    box-shadow: inset 0 8px 26px rgba(0, 0, 0, 0.7);
}

/* the dark corners of the arena, so the spotlights stand out */
.lights{
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    background: radial-gradient(ellipse at 50% 42%,
        transparent 45%, rgba(0, 0, 0, 0.45) 100%);
}

/* the spotlight beam coming down from the roof onto the live spot */
/* drawn at a fixed size, then moved and squashed to fit with transform */
.beam{
    position: absolute;
    top: 0;
    left: 0;
    width: 110px;
    height: 400px;
    margin-left: -55px;
    transform-origin: top center;
    will-change: transform;
    pointer-events: none;
    background: linear-gradient(180deg,
        rgba(255, 250, 232, 0.55) 0%,
        rgba(255, 246, 220, 0.28) 45%,
        rgba(255, 240, 200, 0.14) 100%);
    -webkit-clip-path: polygon(41% 0, 59% 0, 100% 100%, 0 100%);
    clip-path: polygon(41% 0, 59% 0, 100% 100%, 0 100%);
    transition: transform 0.95s cubic-bezier(0.42, 0, 0.22, 1);
    /* No blur filter here on purpose. Blurring a big element that also
       moves and fades makes iPhones redraw it constantly; the soft edge
       comes from the gradient instead, which costs nothing. */
    animation: haze 4.5s ease-in-out infinite;
}
@keyframes haze{
    0%, 100% { opacity: 0.92; }
    50%      { opacity: 1; }
}

/* the pool of light each spot sits in */
.spot{
    position: absolute;
    border-radius: 50%;
    pointer-events: none;
    background: radial-gradient(ellipse at center,
        rgba(255, 248, 226, 0.42) 0%,
        rgba(255, 240, 200, 0.16) 55%,
        transparent 78%);
    transition: background 0.5s, box-shadow 0.5s;
}

/* the one being shot from right now is lit right up */
.spot.here{
    background: radial-gradient(ellipse at center,
        rgba(255, 253, 245, 1) 0%,
        rgba(255, 240, 205, 0.75) 38%,
        rgba(255, 214, 140, 0.32) 62%,
        transparent 82%);
    box-shadow: 0 0 54px 10px rgba(255, 232, 180, 0.6);
}

/* the shadow the overhead light throws under the shooter */
.pshadow{
    position: absolute;
    left: 0;
    top: 0;
    width: 30px;
    height: 9px;
    margin-left: -15px;
    margin-top: -4px;
    border-radius: 50%;
    pointer-events: none;
    background: radial-gradient(ellipse at center,
        rgba(0, 0, 0, 0.55) 0%,
        rgba(0, 0, 0, 0.28) 55%,
        transparent 78%);
    will-change: transform;
    transition: transform 0.95s cubic-bezier(0.42, 0, 0.22, 1);
}

/* ===== the shooter ===== */
.player{
    position: absolute;
    left: 0;
    top: 0;
    width: 34px;
    height: 56px;
    transform-origin: bottom center;
    pointer-events: none;
    will-change: transform;
    transition: transform 0.95s cubic-bezier(0.42, 0, 0.22, 1);
    /* no drop-shadow here on purpose: his arms and legs animate, and a
       filter would make the browser redraw the whole figure every frame.
       The .pshadow ellipse under his feet does the job for free. */
}
.player .head{
    position: absolute;
    left: 9px;
    top: 1px;
    width: 16px;
    height: 16px;
    border-radius: 50% 50% 46% 46%;
    background: radial-gradient(circle at 35% 30%, #b07c52 0%, #9c6a44 55%, #6d4525 100%);
    box-shadow: inset -2px -2px 3px rgba(0, 0, 0, 0.3);
}
/* the neck, so the head is not floating on the jersey */
.player .head::after{
    content: "";
    position: absolute;
    left: 5px;
    bottom: -4px;
    width: 6px;
    height: 5px;
    background: #7d5334;
}
/* short dark hair */
.player .hair{
    position: absolute;
    left: -1px;
    top: -2px;
    width: 18px;
    height: 9px;
    border-radius: 9px 9px 3px 3px;
    background: #1d140d;
}

/* the jersey — the colours come from the kit class further down */
.player .torso{
    position: absolute;
    left: 6px;
    top: 16px;
    width: 22px;
    height: 21px;
    border-radius: 7px 7px 3px 3px;
    background: #555;
    border-bottom: 2px solid #fff;
}
.player .num{
    position: absolute;
    left: 0;
    top: 5px;
    width: 100%;
    text-align: center;
    font-family: copperplate;
    font-size: 9px;
    line-height: 9px;
    letter-spacing: 0;
    color: #fff;
}

/* the shorts */
.player .shorts{
    position: absolute;
    left: 5px;
    top: 35px;
    width: 24px;
    height: 11px;
    border-radius: 4px 4px 3px 3px;
    background: #555;
    border-left: 2px solid #fff;
    border-right: 2px solid #fff;
}

.player .leg{
    position: absolute;
    top: 44px;
    width: 7px;
    height: 10px;
    border-radius: 2px 2px 1px 1px;
    background: linear-gradient(90deg, #ab7549 0%, #9c6a44 45%, #6f472a 100%);
    transform-origin: top center;
    transition: height 0.15s;
}
.player .leg.l{ left: 8px; }
.player .leg.r{ left: 19px; }

/* the sneakers */
.player .leg::after{
    content: "";
    position: absolute;
    left: -2px;
    bottom: -4px;
    width: 11px;
    height: 5px;
    border-radius: 3px 4px 2px 2px;
    background: #f4f1ea;
    border-bottom: 2px solid #ffc72c;
}

.player .arm{
    position: absolute;
    top: 18px;
    width: 6px;
    height: 17px;
    border-radius: 3px;
    background: linear-gradient(90deg, #ab7549, #7d5334);
    transform-origin: top center;
    transition: transform 0.18s ease-out;
}
.player .arm.l{ left: 2px;  transform: rotate(20deg); }
.player .arm.r{ left: 26px; transform: rotate(-20deg); }

/* walking to the next rack: legs and arms swing */
.player.walking .leg.l{ animation: step 0.5s ease-in-out infinite; }
.player.walking .leg.r{ animation: step 0.5s ease-in-out infinite reverse; }
.player.walking .arm.l{ animation: swingl 0.5s ease-in-out infinite; }
.player.walking .arm.r{ animation: swingr 0.5s ease-in-out infinite; }
@keyframes step{
    0%, 100% { transform: rotate(16deg); }
    50%      { transform: rotate(-16deg); }
}
@keyframes swingl{
    0%, 100% { transform: rotate(34deg); }
    50%      { transform: rotate(6deg); }
}
@keyframes swingr{
    0%, 100% { transform: rotate(-6deg); }
    50%      { transform: rotate(-34deg); }
}

/* loading up the shot */
.player.crouch .leg{ height: 6px; }
.player.crouch .arm.l{ transform: rotate(45deg); }
.player.crouch .arm.r{ transform: rotate(-45deg); }

/* the follow-through: both arms straight up, held until the ball lands */
.player.shoot .arm.l{ transform: rotate(168deg); }
.player.shoot .arm.r{ transform: rotate(-168deg); }
.player.shoot .leg{ height: 12px; }

/* ===== the two kits =====
   whoever is shooting wears one of these */

/* blue and gold, number 30 */
.player.curry .torso{
    background: linear-gradient(180deg, #2453a8 0%, #1d428a 100%);
    border-bottom-color: #ffc72c;
    box-shadow: inset 0 0 0 1px rgba(255, 199, 44, 0.35);
}
.player.curry .num{ color: #ffc72c; }
.player.curry .shorts{
    background: #1d428a;
    border-left-color: #ffc72c;
    border-right-color: #ffc72c;
}
.player.curry .hair{ background: #1d140d; }
.player.curry .leg::after{ background: #f4f1ea; border-bottom-color: #ffc72c; }

/* red and black, number 23 */
.player.jordan .torso{
    background: linear-gradient(180deg, #e0164b 0%, #ce1141 100%);
    border-bottom-color: #111;
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.45);
}
.player.jordan .num{ color: #ffffff; }
.player.jordan .shorts{
    background: #ce1141;
    border-left-color: #111;
    border-right-color: #111;
}
/* bald */
.player.jordan .hair{
    display: none;
}
.player.jordan .head{
    box-shadow:
        inset -2px -2px 0 rgba(0, 0, 0, 0.2),
        inset 3px 3px 4px rgba(255, 255, 255, 0.35);
}
.player.jordan .leg::after{ background: #111; border-bottom-color: #ce1141; }

/* ===== the hoop =====
   104px wide, hung from the top of the court.
   backboard 6-68, rim ring 64-78, net hangs down to 110.
   If you resize any of this, change rimY() and rimHalf() in the script too. */
.hoop{
    position: absolute;
    top: 0;
    left: 50%;
    margin-left: -52px;
    width: 104px;
    height: 115px;
}

/* the bracket holding it up */
.mount{
    position: absolute;
    top: 0;
    left: 50%;
    margin-left: -7px;
    width: 14px;
    height: 10px;
    background: linear-gradient(90deg, #8c93a3, #dfe4ee, #8c93a3);
    border-radius: 0 0 3px 3px;
}

/* glass backboard */
.backboard{
    position: absolute;
    top: 6px;
    left: 3px;
    width: 98px;
    height: 62px;
    border: 3px solid rgba(255, 255, 255, 0.85);
    border-radius: 3px;
    overflow: hidden;
    background:
        linear-gradient(150deg,
            rgba(255, 255, 255, 0.26) 0%,
            rgba(210, 235, 255, 0.06) 38%,
            rgba(255, 255, 255, 0.03) 62%,
            rgba(190, 225, 255, 0.16) 100%);
    box-shadow:
        0 8px 20px rgba(0, 0, 0, 0.5),
        inset 0 0 18px rgba(180, 215, 255, 0.2);
}

/* the streak of arena light reflecting off the glass */
.backboard::after{
    content: "";
    position: absolute;
    left: -30%;
    top: -60%;
    width: 45%;
    height: 220%;
    background: linear-gradient(90deg,
        transparent, rgba(255, 255, 255, 0.28), transparent);
    transform: rotate(22deg);
}

/* the shooter's square you bank off */
.square{
    position: absolute;
    bottom: 5px;
    left: 50%;
    margin-left: -22px;
    width: 44px;
    height: 31px;
    border: 2px solid rgba(255, 255, 255, 0.9);
    border-radius: 2px;
}

/* the back half of the rim, drawn behind the net */
.rim-back{
    position: absolute;
    top: 64px;
    left: 16px;
    width: 72px;
    height: 14px;
    border: 4px solid #b8441a;
    border-radius: 50%;
}

/* the front half of the rim, drawn over the net.
   the top edge catches the light, the underside stays dark */
.rim{
    position: absolute;
    top: 64px;
    left: 16px;
    width: 72px;
    height: 14px;
    border: 4px solid transparent;
    border-bottom-color: #ff7c2c;
    border-left-color: rgba(228, 88, 24, 0.8);
    border-right-color: rgba(228, 88, 24, 0.8);
    border-radius: 50%;
    box-shadow:
        0 0 14px rgba(255, 106, 31, 0.5),
        inset 0 -3px 4px rgba(255, 190, 130, 0.5);
}

/* the bracket bolting the rim to the board */
.rim-plate{
    position: absolute;
    top: 60px;
    left: 50%;
    margin-left: -7px;
    width: 14px;
    height: 9px;
    border-radius: 2px;
    background: linear-gradient(180deg, #d9dde6, #7d8494);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
}

/* the net: two sets of crossing strands, clipped into a cone */
.net{
    position: absolute;
    top: 71px;
    left: 18px;
    width: 68px;
    height: 39px;
    background-image:
        repeating-linear-gradient(22deg,
            transparent 0 6px, rgba(255, 255, 255, 0.7) 6px 7.2px),
        repeating-linear-gradient(-22deg,
            transparent 0 6px, rgba(255, 255, 255, 0.7) 6px 7.2px),
        repeating-linear-gradient(180deg,
            transparent 0 9px, rgba(255, 255, 255, 0.28) 9px 10px);
    -webkit-clip-path: polygon(2% 0, 98% 0, 76% 100%, 24% 100%);
    clip-path: polygon(2% 0, 98% 0, 76% 100%, 24% 100%);
    transform-origin: top center;
    transition: transform 0.25s ease-out;
}

/* the net snapping down as a ball drops through it */
.net.swish{
    animation: netsnap 0.75s cubic-bezier(0.25, 1.4, 0.4, 1);
}
@keyframes netsnap{
    0%   { transform: scaleY(1)    scaleX(1); }
    18%  { transform: scaleY(1.35) scaleX(0.86); }
    45%  { transform: scaleY(0.92) scaleX(1.06); }
    70%  { transform: scaleY(1.06) scaleX(0.98); }
    100% { transform: scaleY(1)    scaleX(1); }
}

/* ===== the ball =====
   a shaded leather sphere, lit from the top left like everything else */
.ball{
    position: absolute;
    left: 0;
    top: 0;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    will-change: transform;
    background:
        radial-gradient(circle at 33% 27%,
            #ffc48d 0%,
            #f89b4c 16%,
            #ed8433 33%,
            #d0671f 54%,
            #a8480f 75%,
            #752d06 92%,
            #4b1b03 100%);
    box-shadow:
        /* the shaded side away from the spotlight */
        inset -5px -6px 11px rgba(45, 14, 0, 0.6),
        /* the lit side facing it */
        inset 4px 4px 8px rgba(255, 215, 175, 0.42),
        /* warm light bouncing back up off the hardwood */
        inset 0 -3px 5px rgba(255, 150, 60, 0.28),
        0 3px 8px rgba(0, 0, 0, 0.45);
}

/* the pebbled leather, faded off towards the edge of the sphere */
.ball::before{
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    border-radius: 50%;
    background-image:
        radial-gradient(circle, rgba(60, 20, 0, 0.34) 0.55px, transparent 0.7px),
        radial-gradient(circle, rgba(255, 205, 155, 0.22) 0.5px, transparent 0.65px);
    background-size: 3.2px 3.2px, 3.2px 3.2px;
    background-position: 0 0, 1.6px 1.6px;
    opacity: 0.8;
}

/* the shine of the arena lights on the leather */
.ball::after{
    content: "";
    position: absolute;
    left: 6px;
    top: 4px;
    width: 9px;
    height: 6px;
    border-radius: 50%;
    background: radial-gradient(ellipse at center,
        rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0) 70%);
    transform: rotate(-25deg);
}
/* only while he's carrying it between racks — never during a shot */
.ball.gliding{
    transition: transform 0.95s cubic-bezier(0.42, 0, 0.22, 1);
}
.ball.in-air{
    box-shadow:
        inset -4px -5px 9px rgba(60, 20, 0, 0.55),
        inset 3px 3px 7px rgba(255, 210, 165, 0.45),
        0 8px 16px rgba(0, 0, 0, 0.5);
}

/* the seams: one across, one down, and two curving round the sides */
/* this is the layer that spins; the ball's shading underneath does not */
.ball .seams{
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    will-change: transform;
}

/* The seams are grooves, not painted lines, so each one gets a thin lit
   edge just below it where the leather rises back up. */
/* no filter on these — they rotate every frame while the ball is in the air */
.ball .seam{
    position: absolute;
    border-color: rgba(32, 11, 1, 0.92);
    border-style: solid;
    border-width: 0;
}
.ball .seam.v{
    left: 50%;
    top: 1px;
    height: 30px;
    margin-left: -0.9px;
    border-left-width: 1.8px;
}
.ball .seam.h{
    top: 50%;
    left: 1px;
    width: 30px;
    margin-top: -0.9px;
    border-top-width: 1.8px;
}
.ball .seam.curve{
    top: 1px;
    width: 15px;
    height: 30px;
    border-radius: 50%;
}
.ball .seam.curve.left{
    left: 2px;
    border-right-width: 1.8px;
}
.ball .seam.curve.right{
    right: 2px;
    border-left-width: 1.8px;
}

/* the SWISH! / SHORT! text that pops over the rim */
.callout{
    position: absolute;
    top: 124px;
    left: 0;
    width: 100%;
    text-align: center;
    font-size: 26px;
    letter-spacing: 2px;
    opacity: 0;
    pointer-events: none;
    white-space: nowrap;
}
.callout.pop{
    animation: pop 0.9s ease-out;
}

/* the big shout that flashes up on every made shot */
.banner{
    position: absolute;
    left: 0;
    top: 38%;
    width: 100%;
    text-align: center;
    font-size: 46px;
    letter-spacing: 5px;
    color: rgb(255, 205, 70);
    text-shadow:
        0 0 18px rgba(255, 160, 40, 0.9),
        0 3px 0 rgba(0, 0, 0, 0.55);
    opacity: 0;
    pointer-events: none;
    white-space: nowrap;
}
.banner.pop{
    animation: shout 1.2s ease-out;
}

/* every fifth make in a row gets a bigger, hotter shout */
.banner.streak{
    font-size: 54px;
    color: rgb(255, 240, 190);
    text-shadow:
        0 0 26px rgba(255, 120, 30, 1),
        0 0 50px rgba(255, 80, 20, 0.8),
        0 3px 0 rgba(0, 0, 0, 0.6);
}
.banner.streak.pop{
    animation: shout 1.6s ease-out;
}
@keyframes shout{
    0%   { opacity: 0; transform: scale(0.5); }
    14%  { opacity: 1; transform: scale(1.14); }
    26%  { transform: scale(1); }
    72%  { opacity: 1; transform: scale(1); }
    100% { opacity: 0; transform: scale(1.06); }
}
@keyframes pop{
    0%   { opacity: 1; transform: translateY(0) scale(0.8); }
    100% { opacity: 0; transform: translateY(-40px) scale(1.3); }
}

/* ===== the shot meter ===== */
.meter{
    position: absolute;
    right: 14px;
    bottom: 30px;
    width: 26px;
    height: 260px;
    background: rgba(0, 0, 0, 0.45);
    border: 2px solid rgba(255, 255, 255, 0.3);
    border-radius: 14px;
    overflow: hidden;
    transition: border-color 0.15s, box-shadow 0.15s;
}
.meter.active{
    border-color: rgba(255, 255, 255, 0.7);
}
.meter.good{
    border-color: rgb(120, 240, 140);
    box-shadow: 0 0 18px rgba(120, 240, 140, 0.7);
}
.meter.bad{
    border-color: rgb(255, 120, 110);
    box-shadow: 0 0 18px rgba(255, 120, 110, 0.6);
}

/* the green window you're aiming to release in */
.meter-green{
    position: absolute;
    left: 0;
    width: 100%;
    background: rgba(120, 240, 140, 0.55);
    box-shadow: 0 0 12px rgba(120, 240, 140, 0.5);
}

/* The bar that fills up while you hold. It is drawn full height and
   squashed with a transform, which the browser can do without redoing
   the layout sixty times a second. */
.meter-fill{
    position: absolute;
    left: 0;
    bottom: 0;
    width: 100%;
    height: 100%;
    transform: scaleY(0);
    transform-origin: bottom center;
    will-change: transform;
    background: linear-gradient(180deg, rgba(255, 190, 90, 0.9), rgba(255, 110, 40, 0.55));
}

/* the white line showing exactly where you'd release */
.meter-marker{
    position: absolute;
    left: -3px;
    bottom: 0;
    width: calc(100% + 6px);
    height: 3px;
    background: white;
    box-shadow: 0 0 8px white;
    will-change: transform;
}

/* ===== confetti =====
   Each piece is two elements: the outer one falls, the inner one spins and
   sways. Two separate transforms, both composited, no filters — so a heavy
   burst doesn't cost a repaint. */
.confetti{
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    overflow: hidden;
    pointer-events: none;
}
/* thrown out of the middle: quick off the mark, then slowing down */
.cpiece{
    position: absolute;
    animation-name: cburst;
    animation-timing-function: cubic-bezier(0.12, 0.85, 0.25, 1);
    animation-fill-mode: forwards;
}
@keyframes cburst{
    from { transform: translate(0, 0); }
    to   { transform: translate(var(--dx), var(--dy)); }
}

/* then gravity takes over: slow at first, speeding up all the way down */
.cfall{
    display: block;
    animation-name: cdrop;
    animation-timing-function: cubic-bezier(0.5, 0, 1, 1);
    animation-fill-mode: forwards;
}
@keyframes cdrop{
    0%   { transform: translateY(0);            opacity: 1; }
    72%  { opacity: 1; }
    100% { transform: translateY(var(--fall));  opacity: 0; }
}

/* and it tumbles the whole way */
.cpiece i{
    display: block;
    animation-name: cspin;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
}
@keyframes cspin{
    0%   { transform: rotate(0deg)   translateX(0); }
    50%  { transform: rotate(180deg) translateX(7px); }
    100% { transform: rotate(360deg) translateX(0); }
}

/* ===== fireworks ===== */
.fw{
    position: absolute;
}
/* the bright flash at the moment it goes off */
.fwflash{
    position: absolute;
    left: -16px;
    top: -16px;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: radial-gradient(circle,
        rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0) 70%);
    animation: fwflash 0.45s ease-out forwards;
}
@keyframes fwflash{
    from { transform: scale(0.3); opacity: 1; }
    to   { transform: scale(2.4); opacity: 0; }
}
/* the sparks flying out of it */
.fwp{
    position: absolute;
    display: block;
    width: 4px;
    height: 4px;
    border-radius: 50%;
    animation-name: fwout;
    animation-timing-function: cubic-bezier(0.15, 0.85, 0.3, 1);
    animation-fill-mode: forwards;
}
@keyframes fwout{
    0%   { transform: translate(0, 0) scale(1.4); opacity: 1; }
    68%  { opacity: 0.9; }
    100% { transform: translate(var(--dx), var(--dy)) scale(0.3); opacity: 0; }
}

/* the court sits inside this so fullscreen can scale it as one piece */
.court-wrap{
    width: 100%;
    max-width: 640px;
    margin: 22px auto 0;
    transform-origin: top center;
}

/* ===== the fullscreen button ===== */
/* the buttons that sit over the top-left of the court */
.court-tools{
    position: absolute;
    top: 12px;
    left: 12px;
    z-index: 20;
    display: flex;
    gap: 7px;
}
.fsbtn{
    padding: 6px 14px;
    font-family: copperplate;
    font-size: 11px;
    letter-spacing: 2px;
    color: rgba(255, 255, 255, 0.75);
    background: rgba(10, 18, 40, 0.7);
    border: 1px solid rgba(255, 255, 255, 0.3);
    border-radius: 999px;
    cursor: pointer;
    touch-action: manipulation;
    transition: border-color 0.2s, color 0.2s;
}
.fsbtn:hover{
    border-color: rgba(255, 150, 60, 0.8);
    color: rgb(255, 190, 120);
}

/* ===== fullscreen =====
   The two prefixes have to live in separate blocks — a browser that doesn't
   know one of the selectors throws out the whole rule it's in. */
.stage:fullscreen{
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    padding: 16px;
    background: rgb(12, 22, 50);
}
.stage:fullscreen .rackbar{ margin-top: 20px; }
.stage:fullscreen .scoreboard{ margin-top: 14px; }

.stage:-webkit-full-screen{
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    padding: 16px;
    background: rgb(12, 22, 50);
}
.stage:-webkit-full-screen .rackbar{ margin-top: 20px; }
.stage:-webkit-full-screen .scoreboard{ margin-top: 14px; }

/* ===== the quit button ===== */
.quit{
    position: absolute;
    top: 12px;
    right: 12px;
    padding: 6px 14px;
    font-family: copperplate;
    font-size: 11px;
    letter-spacing: 2px;
    color: rgba(255, 255, 255, 0.75);
    background: rgba(10, 18, 40, 0.7);
    border: 1px solid rgba(255, 255, 255, 0.3);
    border-radius: 999px;
    cursor: pointer;
    touch-action: manipulation;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.25s, background 0.2s, border-color 0.2s, color 0.2s;
}
.quit.show{
    opacity: 1;
    pointer-events: auto;
}
.quit:hover{
    border-color: rgba(255, 150, 60, 0.8);
    color: rgb(255, 190, 120);
}
/* tapped once — a second tap really quits */
.quit.armed{
    background: rgba(200, 40, 30, 0.85);
    border-color: rgb(255, 120, 110);
    color: white;
}

/* ===== start / results card ===== */
.overlay{
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    /* no curtain by default, so the arena shows through behind the card */
    background: transparent;
    display: flex;
    align-items: center;
    justify-content: center;
    /* if the results card is taller than the court, let it scroll rather
       than getting cut off by the court's rounded edges */
    overflow-y: auto;
    padding: 10px 0;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s;
}
.overlay.show{
    opacity: 1;
    pointer-events: auto;
}

/* the results screen dims the court behind it; the start screen doesn't */
.overlay.dim{
    background: rgba(8, 16, 38, 0.78);
}

/* before a round we only need the two pickers and the button */
.overlay.compact .card-title,
.overlay.compact .card-body{
    display: none;
}
.overlay.compact .card{
    padding: 16px 24px 20px;
    background: rgba(14, 26, 58, 0.9);
    box-shadow: 0 14px 44px rgba(0, 0, 0, 0.65);
}
.overlay.compact .pickrow-label:first-child{
    margin-top: 2px;
}

.card{
    max-width: 92%;
    margin: auto;
    padding: 26px 30px;
    background: rgba(20, 37, 77, 0.95);
    border: 2px solid rgba(255, 150, 60, 0.6);
    border-radius: 18px;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
}
.card-title{
    font-size: 38px;
    letter-spacing: 3px;
    color: rgb(255, 170, 70);
}
.card-body{
    font-size: 17px;
    line-height: 1.6;
    margin-top: 12px;
    opacity: 0.85;
}

/* the rack-by-rack breakdown at the end */
.racks{
    margin-top: 18px;
}
.rackblock{
    margin-bottom: 12px;
}
/* the player's name, on its own line so long ones have room */
.rackwho{
    font-size: 14px;
    letter-spacing: 2px;
    margin-bottom: 2px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.rackwho.kit-curry{ color: rgb(255, 199, 44); }
.rackwho.kit-jordan{ color: rgb(240, 70, 105); }

.rackline{
    font-size: 0;
    white-space: nowrap;
}
.rackscore{
    display: inline-block;
    width: 44px;
    font-size: 22px;
    text-align: center;
}
.rackline.labels .rackscore{
    font-size: 11px;
    letter-spacing: 1px;
    opacity: 0.45;
}

/* picking your player and the CPU level */
.pickrow-label{
    font-size: 11px;
    letter-spacing: 3px;
    opacity: 0.45;
    margin-top: 18px;
}
.pickrow{
    font-size: 0;
    margin-top: 8px;
}
.pick{
    touch-action: manipulation;
    font-family: copperplate;
    font-size: 14px;
    letter-spacing: 2px;
    color: white;
    background: rgba(255, 255, 255, 0.07);
    border: 2px solid rgba(255, 255, 255, 0.2);
    border-radius: 999px;
    padding: 9px 18px;
    margin: 0 5px;
    cursor: pointer;
    opacity: 0.55;
}
.pick b{
    font-weight: normal;
    font-size: 11px;
    opacity: 0.8;
    margin-left: 4px;
}
.pick.selected{
    opacity: 1;
}
.pick.curry.selected{
    background: rgba(29, 66, 138, 0.75);
    border-color: #ffc72c;
    color: #ffc72c;
}
.pick.jordan.selected{
    background: rgba(206, 17, 65, 0.7);
    border-color: #ffffff;
    color: #ffffff;
}

.diffrow{
    font-size: 0;
    margin-top: 8px;
}
.diff{
    touch-action: manipulation;
    font-family: copperplate;
    font-size: 13px;
    letter-spacing: 1px;
    color: white;
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.25);
    border-radius: 999px;
    padding: 7px 14px;
    margin: 0 4px;
    cursor: pointer;
}
.diff.selected{
    background: rgba(238, 100, 82, 0.28);
    border-color: rgb(238, 100, 82);
    color: rgb(255, 170, 155);
}

/* not earned yet */
.diff.locked{
    opacity: 0.35;
    cursor: not-allowed;
    border-style: dashed;
}

/* how far off the next unlock you are */
.unlock-note{
    font-size: 11px;
    letter-spacing: 2px;
    opacity: 0.5;
    margin-top: 10px;
}

/* the moment a level opens up, shown on the results card */
.unlocked{
    display: inline-block;
    margin-top: 8px;
    color: rgb(140, 240, 150);
    letter-spacing: 2px;
}

.btn{
    touch-action: manipulation;
    margin-top: 20px;
    padding: 12px 30px;
    font-family: copperplate;
    font-size: 20px;
    letter-spacing: 2px;
    color: white;
    background: linear-gradient(180deg, #ff9247, #e04f16);
    border: none;
    border-radius: 999px;
    cursor: pointer;
}
.btn:hover{
    filter: brightness(1.15);
}

/* ===== which rack you're on ===== */
.rackbar{
    margin-top: 18px;
    font-size: 0;
}
.spot-name{
    font-size: 18px;
    letter-spacing: 2px;
    color: rgb(255, 170, 70);
    vertical-align: middle;
}
.turn-tag{
    display: inline-block;
    font-size: 12px;
    letter-spacing: 2px;
    padding: 5px 12px;
    margin-left: 12px;
    border-radius: 999px;
    vertical-align: middle;
}
.turn-tag.kit-curry{
    background: rgba(36, 83, 168, 0.45);
    border: 1px solid rgb(255, 199, 44);
    color: rgb(255, 199, 44);
}
.turn-tag.kit-jordan{
    background: rgba(206, 17, 65, 0.35);
    border: 1px solid rgb(240, 70, 105);
    color: rgb(255, 160, 180);
}

.balls{
    display: inline-block;
    margin-left: 16px;
    vertical-align: middle;
}
.dot{
    display: inline-block;
    width: 13px;
    height: 13px;
    margin: 0 3px;
    border-radius: 50%;
    background: rgb(255, 120, 45);
    box-shadow: 0 0 8px rgba(255, 120, 45, 0.5);
}
.dot.money{
    background: rgb(255, 205, 80);
    box-shadow: 0 0 10px rgba(255, 205, 80, 0.8);
}
.dot.used{
    background: rgba(255, 255, 255, 0.15);
    box-shadow: none;
}

/* ===== scoreboard ===== */
.scoreboard{
    font-size: 0;
    margin-top: 16px;
}
.score-box{
    display: inline-block;
    width: 120px;
    margin: 0 8px;
    padding: 12px 0;
    background: rgba(0, 0, 0, 0.3);
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: 12px;
}
.score-num{
    display: block;
    font-size: 40px;
    color: rgb(255, 170, 70);
}
/* the scoreboard takes the colour of whichever kit that side is wearing */
.kit-curry .score-num{ color: rgb(255, 199, 44); }
.kit-jordan .score-num{ color: rgb(240, 70, 105); }
.score-box.kit-curry{ border-color: rgba(255, 199, 44, 0.55); }
.score-box.kit-jordan{ border-color: rgba(240, 70, 105, 0.55); }
.score-label{
    display: block;
    font-size: 13px;
    letter-spacing: 2px;
    opacity: 0.6;
}

/* ===== who's playing ===== */
.playing-as{
    font-size: 14px;
    letter-spacing: 2px;
    opacity: 0.6;
    margin-top: 26px;
}
.playing-as b{
    font-weight: normal;
    color: rgb(255, 170, 70);
    opacity: 1;
}
.changename{
    touch-action: manipulation;
    font-family: copperplate;
    font-size: 12px;
    letter-spacing: 1px;
    color: rgba(255, 255, 255, 0.7);
    background: none;
    border: 1px solid rgba(255, 255, 255, 0.25);
    border-radius: 999px;
    padding: 3px 12px;
    margin-left: 10px;
    cursor: pointer;
}
.changename:hover{
    border-color: rgba(255, 150, 60, 0.8);
    color: rgb(255, 190, 120);
}

/* ===== the weekly leaderboards ===== */
.boards{
    max-width: 660px;
    margin: 54px auto 0;
}
.boards-title{
    font-size: 30px;
    letter-spacing: 3px;
    color: rgb(255, 150, 60);
}
.boards-week{
    font-size: 14px;
    letter-spacing: 2px;
    opacity: 0.5;
    margin-top: 6px;
}
.board-group-title{
    font-size: 13px;
    letter-spacing: 4px;
    opacity: 0.5;
    margin-top: 30px;
}
.board-row{
    display: flex;
    gap: 12px;
    justify-content: center;
    margin-top: 12px;
    flex-wrap: wrap;
}
.board{
    flex: 1 1 180px;
    min-width: 170px;
    padding: 14px 12px 12px;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 14px;
}
.board-title{
    font-size: 15px;
    letter-spacing: 2px;
    color: rgb(255, 170, 70);
    padding-bottom: 9px;
    margin-bottom: 6px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}
.board-empty{
    font-size: 13px;
    opacity: 0.35;
    padding: 10px 0;
}
.board-row-item{
    display: flex;
    align-items: baseline;
    font-size: 15px;
    padding: 4px 4px;
}
.board-row-item .rank{
    width: 24px;
    text-align: left;
    font-size: 12px;
    opacity: 0.4;
}
.board-row-item .bname{
    flex: 1;
    text-align: left;
    letter-spacing: 1px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.board-row-item .bvalue{
    color: rgb(255, 190, 90);
    letter-spacing: 1px;
}
/* your own row stands out */
.board-row-item.mine{
    background: rgba(255, 150, 60, 0.16);
    border-radius: 6px;
}
.board-row-item.mine .bname{
    color: rgb(255, 200, 130);
}

.boards-note{
    font-size: 12px;
    letter-spacing: 1px;
    opacity: 0.35;
    margin-top: 22px;
}

.footer{
    font-size: 15px;
    opacity: 0.4;
    margin-top: 60px;
}

@media (max-width: 600px){
    .logo .supa{ font-size: 42px; }
    .logo .sub{ font-size: 20px; letter-spacing: 3px; }
    .info{ font-size: 20px; }
    .text{ font-size: 16px; padding: 16px 18px; margin-top: 28px; margin-bottom: 18px; }
    .works-with{ font-size: 13px; }
    .fact{ font-size: 13px; }
    .fact:not(:last-child)::after{ margin: 0 8px; }
    .court{ height: 420px; }
    .meter{ height: 200px; right: 12px; bottom: 20px; }
    .card-title{ font-size: 28px; }
    .rackscore{ width: 34px; font-size: 18px; }
    .rackwho{ font-size: 12px; }
    .spot-name{ font-size: 15px; }
    .balls{ display: block; margin-left: 0; margin-top: 10px; }
    .diff{ font-size: 11px; padding: 6px 10px; margin: 0 2px; }
    .banner{ font-size: 30px; letter-spacing: 3px; }
    .banner.streak{ font-size: 36px; }
    .boards-title{ font-size: 22px; }
    .board{ min-width: 140px; flex-basis: 140px; padding: 12px 8px 10px; }
    .board-row-item{ font-size: 13px; }
    .board-title{ font-size: 13px; }
}

/* ===== two players on one device ===== */
.hidden{
    display: none;
}
.mode{
    touch-action: manipulation;
    font-family: copperplate;
    font-size: 13px;
    letter-spacing: 2px;
    color: white;
    background: rgba(255, 255, 255, 0.07);
    border: 2px solid rgba(255, 255, 255, 0.2);
    border-radius: 999px;
    padding: 8px 18px;
    margin: 0 5px;
    cursor: pointer;
    opacity: 0.55;
}
.mode.selected{
    opacity: 1;
    background: rgba(255, 150, 60, 0.28);
    border-color: rgb(255, 150, 60);
    color: rgb(255, 190, 120);
}
.p2input{
    display: block;
    width: 210px;
    max-width: 100%;
    margin: 8px auto 0;
    padding: 9px 14px;
    font-family: copperplate;
    font-size: 17px;
    letter-spacing: 2px;
    text-align: center;
    text-transform: uppercase;
    color: white;
    background: rgba(255, 255, 255, 0.08);
    border: 2px solid rgba(120, 170, 255, 0.5);
    border-radius: 10px;
    outline: none;
}
.p2input:focus{
    border-color: rgb(140, 190, 255);
    background: rgba(255, 255, 255, 0.13);
}
.p2input::placeholder{
    color: rgba(255, 255, 255, 0.3);
}

/* ===== passing the device between two players ===== */
.handover{
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    z-index: 15;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: rgba(8, 16, 38, 0.86);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.25s;
}
.handover.show{
    opacity: 1;
}
.handover-name{
    font-size: 46px;
    letter-spacing: 3px;
    color: rgb(255, 170, 70);
}
.handover.kit-curry .handover-name{ color: rgb(255, 199, 44); }
.handover.kit-jordan .handover-name{ color: rgb(240, 70, 105); }
.handover-sub{
    font-size: 16px;
    letter-spacing: 3px;
    opacity: 0.6;
    margin-top: 14px;
}

/* ===== the language picker ===== */
.langbar{
    position: fixed;
    top: 12px;
    right: 12px;
    z-index: 60;
    font-size: 0;
    display: flex;
    gap: 4px;
}
.langbtn{
    font-family: copperplate;
    font-size: 12px;
    letter-spacing: 1px;
    color: rgba(255, 255, 255, 0.65);
    background: rgba(10, 18, 40, 0.75);
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 999px;
    padding: 5px 10px;
    cursor: pointer;
    touch-action: manipulation;
}
.langbtn:hover{
    border-color: rgba(255, 150, 60, 0.7);
    color: rgb(255, 190, 120);
}
.langbtn.selected{
    background: rgba(255, 150, 60, 0.3);
    border-color: rgb(255, 150, 60);
    color: rgb(255, 200, 140);
}
@media (max-width: 600px){
    .langbtn{ font-size: 10px; padding: 4px 7px; }
    .langbar{ top: 8px; right: 8px; }
}

/* shown when you won, but on an easier level than the one you're working on */
.unlock-hint{
    display: inline-block;
    margin-top: 8px;
    font-size: 13px;
    letter-spacing: 1px;
    color: rgb(255, 190, 120);
    opacity: 0.85;
}

/* the two choices offered when a name is already taken */
.nameclash{
    margin-top: 6px;
}
.btn.small{
    font-size: 14px;
    padding: 9px 18px;
    margin: 6px 5px 0;
    letter-spacing: 1px;
}

/* ===== phones =====
   Animations that never stop keep the compositor awake the whole time the
   page is open. On a small screen these three are barely visible anyway,
   so they are switched off rather than run forever. */
@media (max-width: 600px){
    .flash{ display: none; }              /* camera flashes in the crowd */
    .ledboard span{ animation: none; }    /* the scrolling ribbon board */
    .beam{ animation: none; }             /* the slow flicker on the spotlight */

    /* a 54px blur radius is a lot of pixels to fill on a phone */
    .spot.here{ box-shadow: 0 0 22px 4px rgba(255, 232, 180, 0.5); }
}

/* respect the system setting for people who don't want movement */
@media (prefers-reduced-motion: reduce){
    .crowd-row, .flash, .ledboard span, .beam{ animation: none; }
}

/* ===== the last of the phone work =====
   Two things Safari on iOS handles badly, both of which were mine:

   1. A rounded corner plus overflow:hidden makes the browser mask the whole
      court on every frame, and the court is full of moving pieces. Square
      corners on a phone cost nothing and the clip becomes trivial.
   2. The crowd bobbing never stops, which keeps four layers alive for as
      long as the page is open.

   content-visibility lets the browser skip laying out the leaderboards
   until you actually scroll down to them. */
@media (max-width: 600px){
    .court{ border-radius: 0; }
    .crowd-row{ animation: none; will-change: auto; }
    .ball::before{ display: none; }       /* the tiled pebble texture */

    .boards{
        content-visibility: auto;
        contain-intrinsic-size: 1px 900px;
    }
}

/* ===== fullscreen on a phone =====
   iOS Safari won't fullscreen anything but a video, so the stage is pinned
   over the viewport instead and the page behind it is locked. 100dvh is the
   viewport height minus whatever the address bar is currently taking, so
   nothing ends up hidden under it. */
html.faux-full,
body.faux-full{
    overflow: hidden;
    touch-action: none;
}

.stage.faux-full-stage{
    position: fixed;
    left: 0;
    top: 0;
    width: 100vw;
    height: 100vh;
    height: 100dvh;
    z-index: 100;
    margin: 0;
    padding: 10px 0 max(10px, env(safe-area-inset-bottom));
    background: rgb(12, 22, 50);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}
.stage.faux-full-stage .rackbar{ margin-top: 14px; }
.stage.faux-full-stage .scoreboard{ margin-top: 10px; }

/* the exit button needs to clear the notch */
.stage.faux-full-stage .court-tools{
    top: max(12px, env(safe-area-inset-top));
}
