/* ==================================================================
   Chrome star sprites.
   ==================================================================

   Rotation sheets built by scripts/build-star-sprites.py. They exist
   because a CSS rotateY() on the flat art keeps the highlights welded
   where they were painted -- the star turns, but the metal never
   catches the light, so it reads as spinning paper. The flash as the
   star goes edge-on is baked into the frames instead.

   Sizing is driven by --star-size, so one sheet serves a 13px bullet
   and a 200px hero without a second export. The step count has to be a
   literal in steps(), so each sheet gets its own timing rule.
   ================================================================== */

.cs-star {
    display: inline-block;
    flex: none;
    width: var(--star-size, 16px);
    height: var(--star-size, 16px);
    background-repeat: no-repeat;
    /* The strip is --star-frames boxes wide; one frame fills the box. */
    background-size: calc(var(--star-size, 16px) * var(--star-frames)) var(--star-size, 16px);
    background-position-x: 0;
    pointer-events: none;
    -webkit-user-drag: none;
}

/* Frame 0 is face-on, so anything that is not playing rests on the pose
   the static artwork always had. */
@keyframes cs-star-play {
    to { background-position-x: calc(var(--star-size, 16px) * var(--star-frames) * -1); }
}

.cs-star--5 {
    --star-frames: 32;
    background-image: url("../assets/star5-spin.webp");
}
.cs-star--4 {
    --star-frames: 24;
    background-image: url("../assets/star4-spin.webp");
}
.cs-star--tumble {
    --star-frames: 32;
    background-image: url("../assets/star5-tumble.webp");
}

/* ---------------- playback ----------------
   is-playing loops; spin-once is the celebratory single turn a result
   makes as it is pinned, after which it settles back on frame 0. */
.cs-star.is-playing,
.cs-star.spin-once {
    animation-name: cs-star-play;
    animation-duration: var(--star-dur, 2.4s);
    animation-fill-mode: none;
}
.cs-star.is-playing { animation-iteration-count: infinite; }
.cs-star.spin-once  { animation-iteration-count: 1; }

.cs-star--5.is-playing,      .cs-star--5.spin-once      { animation-timing-function: steps(32); }
.cs-star--tumble.is-playing, .cs-star--tumble.spin-once { animation-timing-function: steps(32); }
.cs-star--4.is-playing,      .cs-star--4.spin-once      { animation-timing-function: steps(24); }

/* Seating shadow, so a sprite sits on the void like the static art. */
.cs-star--seated {
    filter: drop-shadow(0 1px 2px rgba(0,0,0,.85))
            drop-shadow(0 0 5px rgba(142,220,255,.5));
}

/* ---------------- where they are used ---------------- */

/* Module headings. Two of them are on screen permanently, so they turn
   slowly and out of phase -- fast enough to be alive, slow enough that
   nothing is competing with the board for attention. */
.cs-star-bullet {
    --star-size: 13px;
    --star-dur: 7s;
}
#board .cs-star-bullet { animation-delay: -3.5s; }

/* The badge on a held result. */
.pin-star {
    --star-size: 22px;
    --star-dur: 900ms;
    position: absolute;
    top: -9px; right: -9px;
    z-index: 2;
}
/* Turning while its matchup is under the pointer: the animation is the
   affordance that says this mark is a thing, not a decoration. */
.matchup-box:hover .pin-star { animation-name: cs-star-play; animation-duration: 2s;
    animation-iteration-count: infinite; animation-timing-function: steps(32); }

/* The invitation in an empty champion slot. Hidden the moment the slot
   is filled -- and even without :has() support the card is opaque and
   sits above it, so the fallback is simply that it is covered. */
.champion-marker {
    --star-size: 26px;
    --star-dur: 3.2s;
    position: absolute;
    top: 50%; left: 50%;
    transform: translate(-50%, -50%);
    opacity: .3;
    z-index: 0;
    transition: opacity var(--cs-normal);
}
.champion-zone:hover .champion-marker { opacity: .55; }
.champion-zone:has(.player-card) .champion-marker { opacity: 0; }

/* The context-menu glyph, which turns only while its row is hovered. */
.context-menu-item .cs-star {
    --star-size: 13px;
}
.context-menu-item:hover .cs-star {
    animation-name: cs-star-play;
    animation-duration: 1.4s;
    animation-iteration-count: infinite;
    animation-timing-function: steps(24);
}

/* The champion overlay's hero. */
#winner-star {
    --star-size: min(200px, 38vw);
    --star-dur: 3.6s;
    filter: drop-shadow(0 0 40px rgba(221,246,255,.45));
}

/* The sheets are deliberately not gated. The stars are the scene a
   crossing arrives into -- stopped on frame 0 they are a still image
   of space, which is not what the page is for. */

/* The hero runs two animations at once. They touch different properties
   — one steps the sheet, the other scales the element — so they compose
   instead of one replacing the other, which is what a single `animation`
   shorthand in bracket.css used to do. */
#winner-star.is-playing {
    animation:
        cs-star-play var(--star-dur) steps(32) infinite,
        tm-pop 700ms cubic-bezier(.2, .9, .25, 1.15) both;
}
/* The champion star turns for everyone too. */
