/* ==========================================================================
   CricScoring - broadcast/animations/bar-chips.css
   BOTTOM BAR + BALL CHIP LAYER
   Moved from legacy overlay.html  (chip + bar blocks)
   ==========================================================================
   The teal score strip, its gloss/sweep, and the ball chips
   (dot, runs, four, six, wicket, wide, no-ball, byes, retired) with
   their pop-in + attention animations. Loaded right after
   animations.css, before the per-event files and the theme.
   ========================================================================== */

/* =====================================================================
   ⚡ v3 — SHARPER, SHINIER, BOLDER TIMELINE
   ===================================================================== */

/* deeper, punchier bar colours */
.cyan-bg-bar{
    background:
        linear-gradient(180deg, rgba(255,255,255,.48) 0%, rgba(255,255,255,.07) 30%, rgba(0,0,0,.06) 60%, rgba(0,0,40,.26) 100%),
        repeating-linear-gradient(115deg, rgba(255,255,255,.07) 0 2px, rgba(255,255,255,0) 2px 9px),
        linear-gradient(100deg, #1ff3ef 0%, #06d6d3 42%, #009fa4 100%);
    box-shadow: inset 0 3px 0 rgba(255,255,255,.62), inset 0 -5px 14px rgba(0,50,60,.45);
}

/* ---------------------------------------------------------------
   BALL CHIPS — bigger, denser colour, hard dark ring so they cut
   through the teal bar instead of washing out.
   --------------------------------------------------------------- */
.bowl-bot-row{ gap: 9px; overflow: visible; }
.bowl-bot-row.dense{ gap: 6px; }

.tv-ball{
    width: 44px; height: 44px; min-width: 44px;
    border-radius: 999px; border: none;
    display: inline-flex; align-items: center; justify-content: center;
    gap: 1px; padding: 0;
    font-weight: 900; line-height: 1;
    letter-spacing: 0;
    position: relative; overflow: visible;
    box-shadow:
        0 0 0 2.5px rgba(2,32,38,.55),                 /* hard outer ring = contrast */
        0 4px 9px rgba(0,20,25,.5),
        inset 0 2px 3px rgba(255,255,255,.5),
        inset 0 -4px 7px rgba(0,0,0,.32);
    text-shadow: 0 1px 2px rgba(0,0,0,.4);
    animation: ballPop .42s cubic-bezier(.2,1.6,.35,1) both;
}
.bowl-bot-row.dense .tv-ball{ width: 39px; height: 39px; min-width: 39px; }

.tv-ball .tb-main{ font-size: 23px; }
.tv-ball .tb-sup{
    font-size: 12.5px; font-weight: 900; opacity: .95;
    transform: translateY(-5px); letter-spacing: -.2px;
}
.bowl-bot-row.dense .tv-ball .tb-main{ font-size: 20px; }
.bowl-bot-row.dense .tv-ball .tb-sup{ font-size: 11px; }

/* pill shape for Wd+1 / Nb+2Lb etc. — text can breathe */
.tv-ball.tb-pill{
    width: auto; min-width: 44px; padding: 0 12px 0 11px;
    border-radius: 999px;
}
.tv-ball.tb-pill .tb-main{ font-size: 19px; letter-spacing: .3px; }
.bowl-bot-row.dense .tv-ball.tb-pill{ padding: 0 9px 0 8px; }
.bowl-bot-row.dense .tv-ball.tb-pill .tb-main{ font-size: 17px; }

/* specular highlight on every chip */
.tv-ball::after{
    content:""; position:absolute; top:3px; left:12%; width:76%; height:38%;
    background: linear-gradient(180deg, rgba(255,255,255,.62), rgba(255,255,255,0));
    border-radius: 999px; pointer-events:none;
}

@keyframes ballPop{
    0%  { transform: scale(.35) translateY(9px); opacity:0 }
    60% { transform: scale(1.09) translateY(0);  opacity:1 }
    100%{ transform: scale(1);                   opacity:1 }
}

/* ---- colours: saturated, high-contrast ---- */
.tv-ball.dot{
    background: linear-gradient(180deg,#2b2a63,#0d0c2e);
    color:#fff;
}
.tv-ball.run{
    background: linear-gradient(180deg,#ffffff,#dfe7ec);
    color:#08111a;
    text-shadow:none;
    box-shadow: 0 0 0 2.5px rgba(2,32,38,.55), 0 4px 9px rgba(0,20,25,.5),
                inset 0 2px 3px rgba(255,255,255,.95), inset 0 -4px 7px rgba(0,0,0,.14);
}
.tv-ball.four{
    background: linear-gradient(180deg,#ffe870,#ffb400 55%,#f59300);
    color:#1a1200; text-shadow:none;
    box-shadow: 0 0 0 2.5px rgba(60,32,0,.5), 0 4px 10px rgba(0,20,25,.5),
                0 0 18px rgba(255,190,0,.85),
                inset 0 2px 3px rgba(255,255,255,.8), inset 0 -4px 7px rgba(140,80,0,.35);
}
.tv-ball.six{
    background: linear-gradient(180deg,#d0a6ff,#8b3dff 55%,#6a1fd8);
    color:#fff;
    box-shadow: 0 0 0 2.5px rgba(30,0,60,.55), 0 4px 10px rgba(0,20,25,.5),
                0 0 20px rgba(150,70,255,.9),
                inset 0 2px 3px rgba(255,255,255,.6), inset 0 -4px 7px rgba(40,0,90,.4);
}
.tv-ball.wkt{
    background: linear-gradient(180deg,#ff6b81,#f01331 52%,#c00722);
    color:#fff;
    box-shadow: 0 0 0 2.5px rgba(70,0,10,.55), 0 4px 10px rgba(0,20,25,.5),
                0 0 20px rgba(255,35,70,.95),
                inset 0 2px 3px rgba(255,255,255,.6), inset 0 -4px 7px rgba(90,0,15,.45);
    animation: ballPop .42s cubic-bezier(.2,1.6,.35,1) both, wktGlow 1.4s ease-in-out .45s infinite;
}
@keyframes wktGlow{
    0%,100%{ filter: brightness(1) }
    50%    { filter: brightness(1.3) }
}
/* WIDE — teal/ice so it reads as an extra, not a run */
.tv-ball.wide{
    background: linear-gradient(180deg,#eafcff,#8fe6f5 50%,#3fbcd8);
    color:#052733; text-shadow:none;
    box-shadow: 0 0 0 2.5px rgba(0,40,55,.6), 0 4px 10px rgba(0,20,25,.5),
                0 0 14px rgba(120,230,255,.7),
                inset 0 2px 3px rgba(255,255,255,.95), inset 0 -4px 7px rgba(0,70,90,.28);
}
/* NO BALL — hot orange, impossible to miss */
.tv-ball.nb{
    background: linear-gradient(180deg,#ffc178,#ff7a18 52%,#e05500);
    color:#231000; text-shadow:none;
    box-shadow: 0 0 0 2.5px rgba(60,20,0,.55), 0 4px 10px rgba(0,20,25,.5),
                0 0 18px rgba(255,130,30,.9),
                inset 0 2px 3px rgba(255,255,255,.75), inset 0 -4px 7px rgba(120,45,0,.4);
}
/* BYES / LEG BYES — cool slate */
.tv-ball.bye{
    background: linear-gradient(180deg,#cbdaea,#8199b6 55%,#5d7590);
    color:#0a1622; text-shadow:none;
}
.tv-ball.ret{
    background: linear-gradient(180deg,#dfe3e8,#9aa4b0 55%,#71797f);
    color:#141a20; text-shadow:none;
}

/* =====================================================================
   v4 — FLATTER CHIPS (less "3D bubble") + TEXT HOLDS LONGER
   ===================================================================== */

/* kill the glossy dome: no specular cap, no deep inset moulding */
.tv-ball::after{ display: none !important; }

.tv-ball{
    box-shadow:
        0 0 0 2px rgba(3,28,35,.62),      /* crisp ring keeps the contrast */
        0 2px 5px rgba(0,18,24,.32);      /* soft ground shadow only */
    text-shadow: none;
    border: none;
}

/* flat, saturated fills — a hint of shading, not a marble */
.tv-ball.dot  { background: linear-gradient(180deg,#201f4d,#15143a); color:#fff; }
.tv-ball.run  { background: linear-gradient(180deg,#ffffff,#f2f5f7); color:#08111a;
                box-shadow: 0 0 0 2px rgba(3,28,35,.62), 0 2px 5px rgba(0,18,24,.32); }
.tv-ball.four { background: linear-gradient(180deg,#ffca28,#f9b000); color:#1a1200;
                box-shadow: 0 0 0 2px rgba(58,32,0,.55), 0 2px 5px rgba(0,18,24,.32), 0 0 12px rgba(255,190,0,.55); }
.tv-ball.six  { background: linear-gradient(180deg,#9d54ff,#8134f0); color:#fff;
                box-shadow: 0 0 0 2px rgba(28,0,58,.6), 0 2px 5px rgba(0,18,24,.32), 0 0 13px rgba(150,70,255,.6); }
.tv-ball.wkt  { background: linear-gradient(180deg,#ff2b4d,#e00c2c); color:#fff;
                box-shadow: 0 0 0 2px rgba(66,0,10,.6), 0 2px 5px rgba(0,18,24,.32), 0 0 13px rgba(255,40,75,.6); }
.tv-ball.wide { background: linear-gradient(180deg,#7fdcf2,#4cc3e0); color:#04222c;
                box-shadow: 0 0 0 2px rgba(0,38,52,.62), 0 2px 5px rgba(0,18,24,.32); }
.tv-ball.nb   { background: linear-gradient(180deg,#ff9440,#f9721a); color:#231000;
                box-shadow: 0 0 0 2px rgba(58,20,0,.6), 0 2px 5px rgba(0,18,24,.32); }
.tv-ball.bye  { background: linear-gradient(180deg,#a8bccf,#8ba2ba); color:#0a1622; }
.tv-ball.ret  { background: linear-gradient(180deg,#c3cad2,#a2abb4); color:#141a20; }

/* the wicket chip keeps a gentle attention pulse, just calmer */
@keyframes wktGlow{ 0%,100%{ filter: brightness(1) } 50%{ filter: brightness(1.16) } }

/* softer pop-in, no overshoot wobble */
@keyframes ballPop{
    0%  { transform: scale(.6) translateY(5px); opacity:0 }
    100%{ transform: scale(1)  translateY(0);   opacity:1 }
}
.tv-ball{ animation: ballPop .26s cubic-bezier(.2,.9,.3,1) both; }
.tv-ball.wkt{ animation: ballPop .26s cubic-bezier(.2,.9,.3,1) both,
                         wktGlow 1.6s ease-in-out .35s infinite; }

/* =====================================================================
   TEXT STAYS ON SCREEN LONGER
   Panel lives 2500ms; the text used to start fading at 1.68s and was
   gone by 2.0s — half a second of empty panel. It now holds to ~2.2s
   and fades out just before the panel closes.
   ===================================================================== */
.splash-batsman.active .wkt-text,
.splash-bowler.active  #bs-text{
    animation: textSlam  2.4s cubic-bezier(.16,1,.3,1) forwards,
               textShine 1.5s cubic-bezier(.32,0,.24,1) .26s both !important;
}
@keyframes textSlam{
    0%   { transform: scale3d(2.7,2.7,1); opacity:0; letter-spacing: 40px; filter: blur(11px) drop-shadow(0 4px 12px rgba(0,0,0,.8)); }
    11%  { transform: scale3d(1,1,1);     opacity:1; letter-spacing: 5px;  filter: blur(0)    drop-shadow(0 4px 14px rgba(0,0,0,.8)); }
    16%  { transform: scale3d(1.07,.93,1); }
    21%  { transform: scale3d(.975,1.035,1); }
    26%  { transform: scale3d(1.01,.99,1); }
    31%  { transform: scale3d(1,1,1); }
    92%  { transform: scale3d(1,1,1);      opacity:1; letter-spacing: 5px; }
    100% { transform: scale3d(1.09,1.09,1); opacity:0; letter-spacing: 10px; }
}

/* =====================================================================
   v5 — TIGHTER TIMING
   Problems fixed:
     a) panel used the SAME .18s fade for show and hide, so every event
        took ~180ms just to appear  -> felt late.
     b) the text faded itself out at 2400ms while the panel lived to
        2680ms -> ~280ms of empty panel after the word vanished.
   Now: panel snaps in, text is readable in ~150ms, and the word stays
   lit for the panel's whole life then fades out WITH it.
   ===================================================================== */

/* hide = graceful (this is the state we transition TO on removal) */
.splash-batsman, .splash-bowler{ transition: opacity .22s ease; }
/* show = near-instant */
.splash-batsman.active, .splash-bowler.active{ transition: opacity .07s linear; }

/* the word fades on exactly the same curve as its panel */
.wkt-text, .shining-text{ transition: opacity .22s ease; }

/* text: snaps in fast, then holds lit until the panel closes.
   No self-fade at the end any more — the panel carries it out. */
@keyframes textSlam{
    0%   { transform: scale3d(2.35,2.35,1); opacity:0; letter-spacing: 30px; filter: blur(6px) drop-shadow(0 4px 12px rgba(0,0,0,.8)); }
    6%   { transform: scale3d(1,1,1);       opacity:1; letter-spacing: 5px;  filter: blur(0)   drop-shadow(0 4px 14px rgba(0,0,0,.8)); }
    10%  { transform: scale3d(1.07,.93,1); }
    14%  { transform: scale3d(.975,1.035,1); }
    18%  { transform: scale3d(1.012,.99,1); }
    22%  { transform: scale3d(1,1,1); }
    96%  { transform: scale3d(1,1,1);       opacity:1; letter-spacing: 5px; }
    100% { transform: scale3d(1.035,1.035,1); opacity:1; letter-spacing: 6px; }
}

.splash-batsman.active .wkt-text,
.splash-bowler.active  #bs-text{
    animation: textSlam  2.5s cubic-bezier(.16,1,.3,1) forwards,
               textShine 1.25s cubic-bezier(.32,0,.24,1) .14s both !important;
}

/* supporting FX pulled earlier so they land with the word, not after it */
.splash-batsman.active .fx-flash, .splash-bowler.active .fx-flash{
    animation: fxFlash .38s ease-out both;
}
.splash-batsman.active .fx-sheen, .splash-bowler.active .fx-sheen{
    animation: fxSheen .95s cubic-bezier(.35,0,.15,1) .04s both;
}
.splash-batsman.active .fx-rings i, .splash-bowler.active .fx-rings i{
    animation: fxRing .9s cubic-bezier(.12,.85,.25,1) both;
}
.fx-rings i:nth-child(2){ animation-delay:.10s !important; }
.fx-rings i:nth-child(3){ animation-delay:.20s !important; }
.splash-batsman.active .fx-streaks i, .splash-bowler.active .fx-streaks i{
    animation: fxStreak .52s cubic-bezier(.25,.8,.2,1) both;
}
.splash-bowler.active .fx-rays{ animation: fxRays 1.35s cubic-bezier(.2,.7,.3,1) both; }
.splash-batsman.active .fx-debris i, .splash-bowler.active .fx-debris i{
    animation: fxDebris .95s cubic-bezier(.15,.75,.3,1) both;
}
/* impact shake happens immediately, not after the word settles */
.splash-batsman.active{ animation: panelShake .42s cubic-bezier(.36,.07,.19,.97) both; }
.splash-bowler.active[data-fx="six"]{ animation: panelLift .55s cubic-bezier(.16,1,.3,1) both; }

/* =====================================================================
   v6 — ZERO GAP EXIT + FASTER ENTRY
   Why the text still snapped away: underneath the keyframes the text's
   own `opacity` was 0, so when .active was removed the animation simply
   disappeared and the value fell straight back to 0 — a CSS transition
   never fires, because the *underlying* value never changed.
   Fix: give the text a resting opacity of 1. It is harmless (the parent
   panel is opacity:0 when idle), and now the PANEL's fade carries the
   word out with it — they vanish together, gap = 0.
   ===================================================================== */
.wkt-text, .shining-text{ opacity: 1; transition: none; }

/* panel: snap in, fade out */
.splash-batsman.active, .splash-bowler.active{ transition: opacity .05s linear; }
.splash-batsman, .splash-bowler{ transition: opacity .24s ease; }

/* word is fully readable in ~100ms and stays lit for the whole panel */
@keyframes textSlam{
    0%   { transform: scale3d(2.3,2.3,1); opacity:0; letter-spacing: 28px; filter: blur(5px) drop-shadow(0 4px 12px rgba(0,0,0,.8)); }
    4%   { transform: scale3d(1,1,1);     opacity:1; letter-spacing: 5px;  filter: blur(0)   drop-shadow(0 4px 14px rgba(0,0,0,.8)); }
    8%   { transform: scale3d(1.07,.93,1); }
    12%  { transform: scale3d(.975,1.035,1); }
    16%  { transform: scale3d(1.012,.99,1); }
    20%  { transform: scale3d(1,1,1); }
    96%  { transform: scale3d(1,1,1);        opacity:1; letter-spacing: 5px; }
    100% { transform: scale3d(1.03,1.03,1);  opacity:1; letter-spacing: 6px; }
}
.splash-batsman.active .wkt-text,
.splash-bowler.active  #bs-text{
    animation: textSlam  2.5s cubic-bezier(.2,.9,.25,1) forwards,
               textShine 1.15s cubic-bezier(.32,0,.24,1) .1s both !important;
}

/* =====================================================================
   v6b — RENDER COST TRIM (keeps the look, drops the first-frame hitch)
   A full-panel conic-gradient with a drop-shadow filter is very heavy to
   rasterise; on the first frame it could delay the word by ~0.4s. The
   glow is now baked into the gradient instead of a filter.
   ===================================================================== */
.fx-rays{ filter: none; will-change: transform, opacity; }
.fx-sheen, .fx-flash{ will-change: transform, opacity; }
.fx-streaks i{ filter: none; box-shadow: 0 0 7px var(--fx); }
.splash-batsman, .splash-bowler{ contain: paint; }

/* box-shadow animation forces a repaint each frame — use a cheap
   overlay element's opacity instead for the no-ball / free-hit pulse */
/* (v11 fix) this used to be `animation: none`, which — being more
   specific than `.splash-bowler.active` — silently cancelled the panelIn
   entrance for NO BALL / FREE HIT and left them on the slow paint path.
   They now use the same entrance as every other event. */
.splash-bowler.active[data-fx="nb"], .splash-bowler.active[data-fx="fh"]{
    animation: panelIn .42s cubic-bezier(.16,1,.3,1) both;
}
.splash-bowler[data-fx="nb"] .fx-sheen::after,
.splash-bowler[data-fx="fh"] .fx-sheen::after{
    content:""; position:absolute; inset:0;
    box-shadow: inset 0 0 46px 4px var(--fx-soft);
    opacity:0;
}
.splash-bowler.active[data-fx="nb"] .fx-sheen::after,
.splash-bowler.active[data-fx="fh"] .fx-sheen::after{
    animation: alertFade 1.1s ease-in-out 2 both;
}
@keyframes alertFade{ 0%,100%{opacity:0} 50%{opacity:1} }

/* =====================================================================
   v7 — INSTANT WORD
   blur() on live text is the single most expensive thing here; on the
   first paint of an event it delayed the word by up to half a second.
   The slam now reads through scale + letter-spacing alone (no blur),
   and opacity hits 1 within ~50ms, so the word is on screen the moment
   the panel is.
   ===================================================================== */
@keyframes textSlam{
    0%   { transform: scale3d(2.3,2.3,1);   opacity:0; letter-spacing: 28px; }
    2%   { opacity:1; }
    5%   { transform: scale3d(1,1,1);       opacity:1; letter-spacing: 5px; }
    9%   { transform: scale3d(1.075,.925,1); }
    13%  { transform: scale3d(.972,1.038,1); }
    17%  { transform: scale3d(1.014,.99,1); }
    21%  { transform: scale3d(1,1,1); }
    96%  { transform: scale3d(1,1,1);        opacity:1; letter-spacing: 5px; }
    100% { transform: scale3d(1.03,1.03,1);  opacity:1; letter-spacing: 6px; }
}
.wkt-text, .shining-text{
    filter: drop-shadow(0 3px 9px rgba(0,0,0,.85));   /* static, cheap */
    will-change: transform;
}

/* =====================================================================
   v8 — THE REAL CAUSE OF "ANIMATION LATE"
   Two INFINITE animations were animating the `left` property:
     .cyan-bg-bar::after  (bar gloss, runs forever)
     .glare               (sweep inside the splash)
   Animating `left` re-runs layout + paint on EVERY frame, non-stop,
   for the whole broadcast. That eats the frame budget, so when an event
   fired the browser needed several hundred ms to get the first frames
   out — which is exactly the "late" feel.
   Both now use transform (GPU-composited, zero layout), and the glare
   only runs while a splash is actually on screen.
   ===================================================================== */
.cyan-bg-bar::after{
    left: -30%;
    animation: barGlossX 7s cubic-bezier(.5,0,.5,1) infinite;
    will-change: transform;
}
@keyframes barGlossX{
    0%   { transform: translate3d(0,0,0) }
    55%  { transform: translate3d(682%,0,0) }
    100% { transform: translate3d(682%,0,0) }
}

.glare{
    left: -50%;
    transform: skewX(-20deg) translate3d(0,0,0);
    animation: none;
    will-change: transform;
}
.splash-batsman.active .glare, .splash-bowler.active .glare{
    animation: glareSweepX 2.4s cubic-bezier(.45,0,.35,1) infinite;
}
@keyframes glareSweepX{
    0%   { transform: skewX(-20deg) translate3d(0,0,0) }
    50%  { transform: skewX(-20deg) translate3d(769%,0,0) }
    100% { transform: skewX(-20deg) translate3d(769%,0,0) }
}

/* keep the heavy conic rays off the compositor until they are needed */
.fx-rays, .fx-rings, .fx-streaks, .fx-debris, .fx-sheen{ visibility: hidden; }
.splash-batsman.active .fx-rays, .splash-bowler.active .fx-rays,
.splash-batsman.active .fx-rings, .splash-bowler.active .fx-rings,
.splash-batsman.active .fx-streaks, .splash-bowler.active .fx-streaks,
.splash-batsman.active .fx-debris, .splash-bowler.active .fx-debris,
.splash-batsman.active .fx-sheen, .splash-bowler.active .fx-sheen{ visibility: visible; }

/* =====================================================================
   v9 — FREE UP THE FRAME BUDGET (this is what made events feel late)
   Measured: blank page 63fps · this overlay idling 21fps · overlay with
   animations disabled 63fps. So a third of every second was being spent
   on decoration while NOTHING was happening — leaving almost nothing
   for the event animation when a six or wicket actually landed.

   Two compounding causes:
     1. `.scoreboard-bar` carries a double `drop-shadow()` filter. Any
        descendant animating forces the ENTIRE 1920px bar to re-rasterise
        through that filter every single frame.
     2. Several decorative animations ran `infinite` inside it (bar gloss,
        wicket-chip brightness pulse, striker-arrow pulse).

   Fix: drop the ancestor filter (each skewed panel already casts its own
   shadow, so the look survives) and stop the idle loops. The bar now
   idles at full frame rate and every frame is available the instant an
   event fires.
   ===================================================================== */
.scoreboard-bar{ filter: none; }
.cyan-bg-bar{
    box-shadow: inset 0 3px 0 rgba(255,255,255,.62),
                inset 0 -5px 14px rgba(0,50,60,.45),
                0 12px 22px rgba(0,0,0,.5);
}
.team-left-bg { box-shadow: 6px 0 18px rgba(0,0,0,.4),  0 12px 20px rgba(0,0,0,.45), inset 0 3px 0 rgba(255,255,255,.20); }
.team-right-bg{ box-shadow: -6px 0 18px rgba(0,0,0,.4), 0 12px 20px rgba(0,0,0,.45), inset 0 3px 0 rgba(255,255,255,.22); }
.center-top-bg{ box-shadow: 0 10px 26px rgba(0,0,0,.75), inset 0 3px 0 rgba(255,255,255,.16); }
.center-bot-bg{ box-shadow: 0 8px 16px rgba(0,0,0,.5),  inset 0 2px 0 rgba(255,255,255,.9); }
.summary-bg   { box-shadow: 0 -6px 26px rgba(0,0,0,.6), 0 12px 20px rgba(0,0,0,.45), inset 0 3px 0 rgba(255,255,255,.12); }

/* no more idle loops — nothing animates until an event happens */
.cyan-bg-bar::after{ animation: none; opacity: .35; left: 8%; }
.tv-ball.wkt{ animation: ballPop .26s cubic-bezier(.2,.9,.3,1) both; }
.ind-arrow.active{ animation: none; }
.so-badge.active{ animation: none; }

/* =====================================================================
   v10 — EVERY EVENT GETS A COMPOSITED LAYER
   SIX and WICKET appeared in ~48ms while FOUR / NO BALL / FREE HIT took
   ~480ms. The difference: only SIX and WICKET had a transform animation
   on the panel, which promotes it to its own compositor layer. The other
   three had to be repainted the slow way.
   Now every splash gets a transform entrance (and is pre-promoted), so
   all five events pop in at the same speed.
   ===================================================================== */
.splash-batsman, .splash-bowler{
    will-change: transform, opacity;
    transform: skewX(var(--skew)) translateZ(0);
}
.splash-bowler.active{ animation: panelIn .42s cubic-bezier(.16,1,.3,1) both; }
@keyframes panelIn{
    0%   { transform: skewX(var(--skew)) translateZ(0) scale3d(1,.78,1) }
    70%  { transform: skewX(var(--skew)) translateZ(0) scale3d(1,1.03,1) }
    100% { transform: skewX(var(--skew)) translateZ(0) scale3d(1,1,1) }
}

/* =====================================================================
   v11 — NO-BALL / FREE-HIT GLOW MADE CHEAP
   Those two were the last slow ones (~500ms to appear). Their alert glow
   used `box-shadow: inset 0 0 46px 4px` — a 46px blur across the whole
   panel, re-rasterised every frame. A radial-gradient paints the same
   look for a fraction of the cost.
   ===================================================================== */
.splash-bowler[data-fx="nb"] .fx-sheen::after,
.splash-bowler[data-fx="fh"] .fx-sheen::after{
    content:""; position:absolute; inset:0;
    box-shadow: none;
    background: radial-gradient(125% 155% at 50% 50%, transparent 38%, var(--fx-soft) 100%);
    opacity: 0;
    will-change: opacity;
}

/* =====================================================================
   v12 — SHINE SWEEP NO LONGER ERASES THE WORD
   The shine is a gradient clipped to the glyphs (background-clip:text)
   with background-repeat:no-repeat. Animating background-position out to
   -105% slid that gradient completely off the text, so after the sweep
   finished there was nothing left to clip against and the word rendered
   INVISIBLE for the rest of the event.
   With background-size:300%, only the 0%..100% range keeps the text
   covered — the sweep now runs inside that range and parks at 0%, where
   the solid colour section covers every glyph.
   ===================================================================== */
@keyframes textShine{
    0%   { background-position: 100% 0 }
    100% { background-position: 0% 0 }
}
.splash-batsman.active .wkt-text,
.splash-bowler.active  #bs-text{
    background-position: 0% 0;      /* safe resting state */
    animation: textSlam  2.5s cubic-bezier(.2,.9,.25,1) forwards,
               textShine 1.1s cubic-bezier(.35,0,.25,1) .12s both !important;
}
    
