/* The Pulls tab (pulls.js). Only transform / opacity animate — glows are pre-drawn gradients
   whose opacity pulses — and only the pack in front shines, so it stays smooth on a phone. */

/* Cards the player doesn't own yet (the Card Gallery and Card Art views) */
.cg-unowned img { filter: grayscale(1) brightness(.55); }
.cg-unowned .meta { opacity: .6; }

.toggle-btn.pulls-btn { border-color: #f0c040; }
.toggle-btn.pulls-btn.active { border-color: #f0c040; box-shadow: 0 0 0 2px rgba(240,192,64,.18); }
.pulls-badge {
    min-width: 1.35em; padding: 0 .4em; border-radius: 999px;
    background: #f0c040; color: #000; font-size: .78em; font-weight: 800; line-height: 1.35em; text-align: center;
}
body.cg-pulls-view .filter-toggle-btn, body.cg-pulls-view .filters, body.cg-pulls-view .bulk-bar { display: none !important; }

/* A long press on a pack or card (pulls.js: it lifts a pack to turn it over) never opens the
   browser's own image menu / preview, nor drags or selects the picture (pulls.js stops the
   context menu too) */
#pulls-view .pl-stage, #pulls-view .pl-stage img, .pl-ghost img {
    -webkit-touch-callout: none; -webkit-user-drag: none; user-select: none; -webkit-user-select: none;
}
#pulls-view { --pw: clamp(108px, 28vw, 168px); --raku: #a79bbf; --blue: #4fc3ff; --mega: #3fdc7a; }
.pl-wrap { max-width: 980px; margin: 0 auto; text-align: center; }
.pl-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: .6rem 1rem; }
.pl-title { margin: .2rem 0; font-size: 1.35rem; }
.pl-total {
    display: inline-block; min-width: 1.6em; padding: 0 .45em; border-radius: 999px;
    background: #f0c040; color: #000; font-size: .85em; line-height: 1.6em;
}
.pl-chips { display: flex; flex-wrap: wrap; gap: .4rem; justify-content: center; }
.pl-chip {
    display: inline-flex; align-items: center; gap: .4rem; padding: .2rem .6rem .2rem .25rem;
    border: 1px solid #333; border-radius: 999px; background: rgba(26,26,26,.72); font-size: .85rem;
}
.pl-chip img { width: 20px; height: 26px; object-fit: cover; border-radius: 4px; }
.pl-chip.pl-raku { border-color: var(--raku); } .pl-chip.pl-blue { border-color: var(--blue); } .pl-chip.pl-mega { border-color: var(--mega); }
/* Picking the pack type to open next (more than one type, before a pull is opened) */
.pl-chip-pick {
    font: inherit; font-size: .85rem; color: inherit; cursor: pointer; min-height: 34px;
    opacity: .6; transition: opacity .2s, background-color .2s, box-shadow .2s; -webkit-tap-highlight-color: transparent;
}
.pl-chip-pick:hover, .pl-chip-pick:focus-visible { opacity: 1; }
.pl-chip-pick.pl-chip-on { opacity: 1; background: rgba(40,40,40,.92); box-shadow: 0 0 0 1px var(--c), 0 0 12px color-mix(in srgb, var(--c) 45%, transparent); }
.pl-chip-pick:disabled { cursor: default; }
.pl-sub { margin: .5rem 0 0; color: #c9d1d9; }
.pl-msg { min-height: 1.4em; margin: .4rem 0; color: #8b949e; font-size: .92rem; }
.pl-msg.error { color: #f85149; }
.pl-empty { color: #8b949e; padding: 2rem 0; }
.pl-actions { display: flex; gap: .6rem; justify-content: center; align-items: center; margin: 1rem 0 1.5rem; flex-wrap: wrap; }
.pl-btn-main {
    min-height: 46px; padding: 0 1.6rem; border: none; border-radius: 10px;
    background: linear-gradient(90deg, #f0c040, #ff9ad5); color: #000; font-size: 1.05rem; font-weight: 800; cursor: pointer;
}
.pl-btn-sec {
    min-height: 46px; padding: 0 1.2rem; border-radius: 10px; border: 1px solid #444;
    background: rgba(26,26,26,.8); color: #c9d1d9; font-size: 1rem; cursor: pointer;
}
.pl-btn-main:disabled { opacity: .5; cursor: default; }
/* No buttons under the packs: the packs themselves are tapped, turned and torn. The stage keeps
   some room under it at the end of the page. */
.pl-wrap > .pl-stage:last-child { margin-bottom: 2rem; }
.pl-stage { position: relative; display: flex; align-items: center; justify-content: center; }

/* ── A pack ── */
.pl-pack, .pl-big { position: relative; width: var(--pw); aspect-ratio: 0.64; --c: var(--mega); }
.pl-raku { --c: var(--raku); } .pl-blue { --c: var(--blue); } .pl-mega { --c: var(--mega); }
.pl-pack-glow {
    position: absolute; inset: -22%; border-radius: 50%; pointer-events: none;
    background: radial-gradient(closest-side, color-mix(in srgb, var(--c) 70%, transparent), transparent 75%);
    opacity: .3;
}
.pl-pack-body {
    position: absolute; inset: 0; z-index: 1; overflow: hidden; border-radius: 13px;
    background: #111; border: 2px solid var(--c); box-shadow: 0 10px 26px rgba(0,0,0,.55);
}
.pl-pack-art, .pl-pack-back { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; pointer-events: none; user-select: none; }
/* A pack's two sides: the front (art, name, card count) and the back (the card back). Its back
   shows when it's turned away in the carousel or lies face-down (pulls.js packSides()). */
.pl-face-front { position: absolute; inset: 0; }
.pl-pack-back, .pl-showback .pl-face-front { display: none; }
.pl-showback .pl-pack-back { display: block; }
/* Turned away in the carousel the pack is seen mirrored: its sides are mirrored back to read right */
.pl-mirror .pl-face-front, .pl-mirror .pl-pack-back, .pl-mirror .pl-peek img { scale: -1 1; }
/* The carousel's far packs darken (its opacity set per pack as the ring turns, pulls.js layoutCarousel()) */
.pl-shade { position: absolute; inset: 0; z-index: 5; background: #000; opacity: 0; pointer-events: none; border-radius: inherit; will-change: opacity; }
.pl-pack-foil {
    position: absolute; inset: 0; overflow: hidden; pointer-events: none;
    background: linear-gradient(135deg, rgba(255,255,255,.18), transparent 35%, transparent 65%, rgba(255,255,255,.12));
}
.pl-pack-foil::after {
    content: ''; position: absolute; top: -10%; bottom: -10%; left: -60%; width: 45%;
    background: linear-gradient(100deg, transparent, rgba(255,255,255,.45), transparent);
    transform: translateX(-100%) skewX(-12deg); opacity: 0;
}
.pl-crimp {
    position: absolute; left: 0; right: 0; height: 7%;
    background: repeating-linear-gradient(90deg, rgba(255,255,255,.4) 0 3px, rgba(0,0,0,.35) 3px 6px);
    border-bottom: 1px solid rgba(0,0,0,.4);
}
.pl-crimp-top { top: 0; } .pl-crimp-bottom { bottom: 0; border-bottom: none; border-top: 1px solid rgba(0,0,0,.4); }
.pl-pack-label {
    /* Low on the pack, just above the bottom crimp — at the top it would cover the art's head */
    position: absolute; left: 0; right: 0; bottom: 9%; padding: 5% 6%;
    display: flex; flex-direction: column; align-items: center; gap: 2px; text-align: center;
    background: linear-gradient(90deg, transparent, rgba(0,0,0,.78) 16%, rgba(0,0,0,.78) 84%, transparent);
}
.pl-pack-name { font-weight: 900; font-size: calc(var(--pw) * .1); color: var(--c); letter-spacing: .02em; text-shadow: 0 1px 2px #000; }
/* The card count: a badge in the top left, under the top crimp (on the big pack it's on the flap,
   so it tears off with it) — Mega's and Blue's art have their figure on the right; Raku's on the left */
.pl-pack-count {
    position: absolute; top: 10%; left: 6%; padding: .15em .6em; border-radius: 999px;
    background: rgba(0,0,0,.72); border: 1px solid var(--c);
    font-size: calc(var(--pw) * .068); font-weight: 800; color: #fff; line-height: 1.3;
}
/* The Raku Gacha's badge is on the right — its art's head is on the left */
.pl-raku .pl-pack-count { left: auto; right: 6%; }
/* The big pack's badge sits midway between the top crimp (down to 7%) and the tear line (19%),
   the same gap above and below it */
.pl-big .pl-pack-count { top: 13%; translate: 0 -50%; font-size: calc(var(--pw) * .06); }
.pl-upside .pl-pack-body { rotate: 180deg; }

/* A little opened pack: a card's edge showing (the pack itself, crimps and all, stays as it is) */
.pl-peek {
    /* --peek-r: its own tilt; --peek-flip: 180deg when it's upside down (it comes out that way);
       --peek-m: -1 on a face-down pack — turned over, the tilt is seen mirrored */
    --peek-m: 1;
    position: absolute; z-index: 0; left: 14%; width: 72%; top: -13%; aspect-ratio: 563 / 776; overflow: hidden;
    border-radius: 6px; rotate: calc(var(--peek-r, -3deg) * var(--peek-m) + var(--peek-flip, 0deg)); pointer-events: none;
}
.pl-facedown .pl-peek { --peek-m: -1; }
.pl-peek img { display: block; width: 100%; height: 100%; object-fit: cover; pointer-events: none; }
/* Lying upside down it's at the bottom, turned round (a tumble head over heels also turns it face
   down, mirroring its tilt — .pl-facedown; spun round flat it isn't) */
.pl-upside.pl-peeking .pl-peek { top: auto; bottom: -13%; rotate: calc(180deg + var(--peek-r, -3deg) * var(--peek-m) + var(--peek-flip, 0deg)); }
/* The side of the peeking card that shows: its back when the pack's back shows or the card is
   face-down in it — not both (pulls.js packSides()) */
.pl-peek-back, .pl-peek-showback .pl-peek-front { display: none; }
.pl-peek-showback .pl-peek-back { display: block; }

/* The shine and pulse: only on the pack in front (and the big one) */
.pl-front .pl-pack-glow, .pl-big .pl-pack-glow, .pl-float .pl-pack-glow { animation: pl-pulse 2.4s ease-in-out infinite; }
.pl-front .pl-pack-foil::after, .pl-big .pl-pack-foil::after, .pl-float .pl-pack-foil::after { animation: pl-shine 3.2s ease-in-out infinite; }
@keyframes pl-pulse { 0%, 100% { opacity: .45; } 50% { opacity: 1; } }
@keyframes pl-shine { 0%, 55% { transform: translateX(-100%) skewX(-12deg); opacity: 0; } 60% { opacity: 1; } 100% { transform: translateX(420%) skewX(-12deg); opacity: 0; } }

/* ── No pull open yet: the next pack, floating ── */
.pl-idle { min-height: calc(var(--pw) * 1.9); }
/* Room around the floating pack (it bobs up): from the text above, and under it */
.pl-idle { margin-top: 1.5rem; }
.pl-wrap > .pl-idle:last-child { margin-bottom: 3rem; }
.pl-idle .pl-pack:focus-visible { outline: 2px solid #00ffcc; outline-offset: 6px; border-radius: 12px; }
.pl-big:focus-visible { outline: 2px solid #00ffcc; outline-offset: 8px; border-radius: 12px; }
.pl-idle .pl-pack { --pw: clamp(150px, 42vw, 210px); cursor: pointer; touch-action: manipulation; user-select: none; -webkit-user-select: none; -webkit-tap-highlight-color: transparent; }
.pl-float { animation: pl-float 3.6s ease-in-out infinite; }
@keyframes pl-float { 0%, 100% { transform: translateY(0) rotate(-2deg); } 50% { transform: translateY(-10px) rotate(2deg); } }

/* ── Carousel ── */
/* Seen from a little above: the packs behind rise over the one in front (pulls.js RING_RISE) —
   the padding on top is their room, the height the front pack's (scaled up, RING_FRONT_SCALE) */
.pl-carousel {
    box-sizing: content-box; height: calc(var(--pw) / .64 * 1.25 + 40px); padding-top: calc(var(--pw) / .64 * .32);
    overflow: hidden; outline: none;
    touch-action: pan-y; cursor: grab; user-select: none; -webkit-user-select: none;
}
/* A card peeking out below an upside-down pack: the front pack (×1.25) reaches .195 pw under the
   ring box and its card another .254 pw, tilted up to 10° .07 pw more — the stage's own room under
   the ring is .195 pw + 20px (half its spare height), so this is the rest */
.pl-carousel.pl-peek-room-bottom { padding-bottom: calc(var(--pw) * .34 - 12px); }
.pl-carousel:active { cursor: grabbing; }
.pl-carousel:focus-visible { box-shadow: inset 0 0 0 2px #00ffcc; border-radius: 12px; }
.pl-ring { position: relative; width: var(--pw); height: calc(var(--pw) / .64); }
/* Each pack is laid out at the front pack's size (RING_FRONT_SCALE) and only ever scaled down, as a
   layer of its own: turning the ring then just moves the layers. A layer scaled by a style write is
   repainted at every new scale — ten packs each frame, slow on a phone — unless it's will-change,
   which keeps the raster it has (at least its own size, so never blurry here). Its glow fades as a
   layer too (pulls.js sets the far packs' glow opacity). */
.pl-ring { --ring-pw: var(--pw); }
.pl-ring .pl-pack {
    --pw: calc(var(--ring-pw) * 1.25);
    position: absolute; left: 50%; top: 50%; margin: calc(var(--pw) / -1.28) 0 0 calc(var(--pw) / -2);
    will-change: transform; transition: opacity .45s, translate .5s, scale .5s; -webkit-tap-highlight-color: transparent;
}
.pl-ring .pl-pack-glow { will-change: opacity; }
/* The borders and corners as they were at the front pack's scale */
.pl-ring .pl-pack-body { border-width: 2.5px; border-radius: 16px; }
.pl-ring .pl-peek { border-radius: 7.5px; }
.pl-ring .pl-pack.pl-front { cursor: pointer; }
.pl-ring .pl-pack.pl-leaving { opacity: 0 !important; translate: 0 70px; scale: .6; }
.pl-ring .pl-pack.pl-picked { scale: 1.1; }
.pl-dealing .pl-pack { animation: pl-deal .6s cubic-bezier(.2,.8,.3,1.2) backwards var(--d); }
@keyframes pl-deal { from { opacity: 0; translate: 0 -140px; scale: .4; } }

/* ── Selected: the big pack to tear open ── */
.pl-selected { min-height: calc(clamp(170px, 56vw, 250px) / .64 + 50px); padding-top: 24px; touch-action: pan-y; } /* sideways swipes are the tear's */
/* A little opened pack: room for its card peeking out above it (or below, upside down) */
.pl-selected.pl-peek-room-top { padding-top: calc(clamp(170px, 56vw, 250px) / .64 * .13 + 12px); }
.pl-selected.pl-peek-room-bottom { padding-bottom: calc(clamp(170px, 56vw, 250px) / .64 * .13); }
.pl-big { --pw: clamp(170px, 56vw, 250px); }
.pl-lower, .pl-flap { position: absolute; inset: 0; z-index: 1; will-change: transform; } /* layers: the tear re-cuts them each frame without repainting the pack */
.pl-lower { clip-path: inset(19% 0 0 0); }
.pl-flap { clip-path: inset(0 0 81% 0); transform-origin: 100% 19%; z-index: 2; }
/* The whole pack takes the swipe (up and down too — pulls.js bindTear()), and so does a margin
   around it (pulls.js TEAR_REACH), so a swipe may start just outside it — the page doesn't scroll
   instead. The buttons below stay on top of it. */
.pl-selected .pl-big { touch-action: none; cursor: crosshair; }
/* Held (pulls.js LIFT_MS): lifted a little, to be spun over with a swipe */
.pl-selected .pl-big { -webkit-touch-callout: none; user-select: none; -webkit-user-select: none; transition: scale .2s cubic-bezier(.2,.8,.3,1.3); }
.pl-selected .pl-big.pl-lifted { scale: 1.08; cursor: grabbing; }
.pl-tear-reach { position: absolute; z-index: 0; inset: -44px; touch-action: none; cursor: crosshair; }
.pl-ghost .pl-tear-reach { display: none; }
.pl-tear { position: absolute; z-index: 3; left: -6%; right: -6%; top: 4%; height: 30%; touch-action: none; cursor: ew-resize; }
/* The tear line (pulls.js bindTear()): dashed where it's still to be torn, a glowing cut where the
   finger has torn it */
.pl-tear-svg { position: absolute; z-index: 3; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.pl-tear-svg path { fill: none; vector-effect: non-scaling-stroke; stroke-linejoin: round; stroke-linecap: round; }
.pl-tear-dash { stroke: rgba(255,255,255,.55); stroke-width: 2; stroke-dasharray: 6 5; }
.pl-tear-cut { stroke: #fff; stroke-width: 3; filter: drop-shadow(0 0 3px var(--c)) drop-shadow(0 0 2px var(--c)); }
.pl-torn .pl-tear-svg { display: none; }
.pl-tear-hint { position: absolute; left: 4%; top: calc(50% - .8em); font-size: 1.3rem; color: #fff; text-shadow: 0 0 6px var(--c); animation: pl-hint 1.6s ease-in-out infinite; pointer-events: none; }
@keyframes pl-hint { 0% { transform: translateX(0); opacity: 0; } 20% { opacity: 1; } 80% { opacity: 1; } 100% { transform: translateX(calc(var(--pw) * .75)); opacity: 0; } }
.pl-tearing .pl-tear-hint { display: none; }
.pl-burst {
    position: absolute; z-index: 4; left: 50%; top: 19%; width: 120%; aspect-ratio: 1; margin: -60% 0 0 -60%;
    border-radius: 50%; pointer-events: none; opacity: 0; transform: scale(0);
    background: radial-gradient(closest-side, #fff, color-mix(in srgb, var(--c) 80%, transparent) 40%, transparent 72%);
}
.pl-burst::after {
    content: ''; position: absolute; inset: -40%; border-radius: 50%;
    background: repeating-conic-gradient(from 0deg, rgba(255,255,255,.55) 0 4deg, transparent 4deg 22deg);
    -webkit-mask: radial-gradient(closest-side, #000 30%, transparent 75%); mask: radial-gradient(closest-side, #000 30%, transparent 75%);
}
.pl-torn .pl-flap { animation: pl-flap-off .7s cubic-bezier(.3,.5,.4,1) forwards; }
.pl-torn .pl-burst { animation: pl-burst 1.1s ease-out forwards; }
.pl-torn .pl-tear { display: none; }
/* Away from the rest of the pack and the way the tear ran (pulls.js tearFlight(): --fly-x / -y / -r) */
@keyframes pl-flap-off { to { transform: translate(var(--fly-x, 55%), var(--fly-y, -160%)) rotate(var(--fly-r, -38deg)); opacity: 0; } }
@keyframes pl-burst { 0% { opacity: 0; transform: scale(0) rotate(0); } 25% { opacity: 1; } 100% { opacity: 0; transform: scale(2.6) rotate(60deg); } }
/* A gun in the pack (pulls.js gunBoom()): the pack's own burst goes
   off bigger, and over the whole screen a flash, a fireball, light rays, shock rings and sparks */
.pl-gun.pl-torn .pl-burst { animation: pl-burst-gun 1.4s ease-out forwards; }
@keyframes pl-burst-gun { 0% { opacity: 0; transform: scale(0) rotate(0); } 15% { opacity: 1; } 100% { opacity: 0; transform: scale(5) rotate(120deg); } }
.pl-boom { position: fixed; inset: 0; z-index: 70; pointer-events: none; overflow: hidden; }
.pl-boom-flash {
    position: absolute; inset: 0; opacity: 0;
    background: radial-gradient(circle at var(--x) var(--y), #fff 0, rgba(255,240,190,.9) 22%, rgba(227,179,65,.45) 55%, rgba(255,120,40,.15) 85%);
    animation: pl-boom-flash 1s ease-out forwards;
}
@keyframes pl-boom-flash { 0% { opacity: 0; } 6% { opacity: 1; } 25% { opacity: .75; } 100% { opacity: 0; } }
.pl-boom-ball, .pl-boom-rays, .pl-boom-ring, .pl-boom-spark { position: absolute; left: var(--x); top: var(--y); border-radius: 50%; }
.pl-boom-ball {
    width: 70vmax; height: 70vmax; margin: -35vmax 0 0 -35vmax; transform: scale(0);
    background: radial-gradient(closest-side, #fff 0, #ffe08a 22%, #e3b341 42%, rgba(255,120,40,.65) 60%, transparent 76%);
    animation: pl-boom-ball 1.3s cubic-bezier(.1,.8,.3,1) forwards;
}
@keyframes pl-boom-ball { 0% { transform: scale(0); opacity: 1; } 40% { opacity: 1; } 100% { transform: scale(1.25); opacity: 0; } }
.pl-boom-rays {
    width: 150vmax; height: 150vmax; margin: -75vmax 0 0 -75vmax; opacity: 0;
    background: repeating-conic-gradient(rgba(255,236,170,.65) 0 3deg, transparent 3deg 14deg);
    -webkit-mask: radial-gradient(closest-side, #000 8%, transparent 72%); mask: radial-gradient(closest-side, #000 8%, transparent 72%);
    animation: pl-boom-rays 1.6s ease-out forwards;
}
@keyframes pl-boom-rays { 0% { opacity: 0; transform: scale(.1) rotate(0); } 12% { opacity: 1; } 100% { opacity: 0; transform: scale(1) rotate(45deg); } }
.pl-boom-ring {
    width: 150vmax; height: 150vmax; margin: -75vmax 0 0 -75vmax; transform: scale(0);
    border: 5px solid #ffe08a; box-shadow: 0 0 30px #e3b341, inset 0 0 22px #e3b341;
    animation: pl-boom-ring 1.1s cubic-bezier(.1,.7,.3,1) calc(var(--i) * 150ms) both;
}
@keyframes pl-boom-ring { 0% { transform: scale(0); opacity: 1; } 100% { transform: scale(1); opacity: 0; } }
.pl-boom-spark { box-shadow: 0 0 10px 2px rgba(255,211,107,.8); }
/* The torn pack playing out over the cards' view (pulls.js tear()): fixed where it was, over the
   cards rising out of it */
.pl-big.pl-ghost { position: fixed; z-index: 60; margin: 0; pointer-events: none; }

/* ── Torn: the cards to slide out ── */
/* The cards close under the text above (just room for the stacked cards behind, which sit a little higher) */
.pl-torn-stage { flex-direction: column; justify-content: flex-start; min-height: calc(clamp(180px, 60vw, 270px) * 776 / 563 + 46px); padding-top: 12px; }
.pl-stack { position: relative; width: clamp(180px, 60vw, 270px); aspect-ratio: 563 / 776; }
.pl-card {
    position: absolute; inset: 0; border-radius: 14px; perspective: 1100px;
    translate: calc(var(--k) * 7px) calc(var(--k) * -9px); rotate: var(--r, 0deg);
    user-select: none; -webkit-user-select: none;
}
/* Its two sides — the back at 0°, the face turned 180° (like is-back/gameplay's reveal): face up it
   is turned over; a face-down card isn't, until it's tapped (pulls.js turnOver()) */
.pl-card-flip { position: absolute; inset: 0; transform-style: preserve-3d; transform: rotateY(180deg); }
.pl-card-down .pl-card-flip { transform: none; }
.pl-card-face {
    position: absolute; inset: 0; border-radius: 14px; overflow: hidden; background: #111;
    backface-visibility: hidden; -webkit-backface-visibility: hidden; box-shadow: 0 10px 26px rgba(0,0,0,.6);
}
.pl-card-back { transform: translateZ(1px); }
.pl-card-front { transform: rotateY(180deg) translateZ(1px); }
.pl-card img { display: block; width: 100%; height: 100%; object-fit: cover; pointer-events: none; }
/* A card that came out of its pack upside down (both of its sides) */
.pl-card-flipped img { rotate: 180deg; }
/* Just turned over / come to the top face up: a shine sweeping across the whole card (the glow in
   its type's colour is the results screen's, .pl-sum-face) */
.pl-card-shine {
    position: absolute; inset: -20%; pointer-events: none; opacity: 0;
    background: linear-gradient(115deg, transparent 38%, rgba(255,255,255,.6) 49%, rgba(255,240,200,.28) 53%, transparent 62%);
}
.pl-card-lit .pl-card-shine { animation: pl-card-shine 1.6s ease-in-out forwards; }
/* The band is slanted, so it sweeps from well off one side to well off the other, and fades out at
   the end (it ended over the card's bottom-right corner before) */
@keyframes pl-card-shine { 0% { opacity: 1; transform: translateX(-100%); } 80% { opacity: 1; } 100% { opacity: 0; transform: translateX(100%); } }
.pl-card.pl-top { touch-action: none; cursor: grab; outline: none; will-change: transform; } /* the swipe moves a layer */
.pl-card.pl-top.pl-card-down { cursor: pointer; }
.pl-card.pl-top:focus-visible .pl-card-face { box-shadow: 0 0 0 3px #00ffcc; }
.pl-card.pl-dragging { cursor: grabbing; }
.pl-advance .pl-card { animation: pl-advance .35s cubic-bezier(.3,.7,.4,1); }
@keyframes pl-advance { from { translate: calc((var(--k) + 1) * 7px) calc((var(--k) + 1) * -9px); } }
.pl-count { margin-top: .7rem; color: #8b949e; font-size: .9rem; }
.pl-got { display: flex; gap: .45rem; justify-content: center; min-height: 0; margin-top: .6rem; }
.pl-got-card { position: relative; width: 54px; aspect-ratio: 563 / 776; border-radius: 5px; overflow: hidden; border: 1px solid #f0c040; }
.pl-got-card img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pl-got-card.pl-just { animation: pl-got .5s cubic-bezier(.2,.8,.3,1.4); }
@keyframes pl-got { from { opacity: 0; transform: scale(.3) translateY(-30px); } }

/* ── Summary ── */
.pl-summary { display: flex; flex-wrap: wrap; gap: 2.6rem 1.8rem; justify-content: center; margin-top: 3rem; perspective: 900px; }
.pl-summary + .pl-actions { margin-top: 2.4rem; } /* room under the cards before the buttons */
.pl-sum-card { position: relative; width: clamp(120px, 28vw, 200px); rotate: var(--r, 0deg); animation: pl-flip .6s cubic-bezier(.2,.8,.3,1.2) backwards var(--d); }
/* Once the last card has flipped in (--lit, pulls.js renderSummary()), all of them glow and shine
   at once, as each did when it was revealed */
.pl-sum-face { position: relative; border-radius: 10px; overflow: hidden; box-shadow: 0 8px 22px rgba(0,0,0,.55); animation: pl-sum-glow 2.2s ease-out var(--lit); }
.pl-sum-face img { display: block; width: 100%; }
.pl-sum-face .pl-card-shine { animation: pl-card-shine 1.6s ease-in-out var(--lit) forwards; }
@keyframes pl-sum-glow {
    0% { box-shadow: 0 8px 22px rgba(0,0,0,.55), 0 0 0 0 transparent; }
    30% { box-shadow: 0 8px 22px rgba(0,0,0,.55), 0 0 44px 9px color-mix(in srgb, var(--hue) 90%, transparent); }
    100% { box-shadow: 0 8px 22px rgba(0,0,0,.55), 0 0 0 0 transparent; }
}
.pl-sum-new {
    position: absolute; z-index: 1; top: -38px; right: -10px; padding: .15rem .65rem; border-radius: 999px; overflow: hidden;
    background: #f0c040; color: #000; font-weight: 900; font-size: 1rem;
    box-shadow: 0 0 10px rgba(240,192,64,.6);
}
/* …and it shines: a light streak sweeping across now and then */
.pl-sum-new::after {
    content: ''; position: absolute; top: -20%; bottom: -20%; left: -60%; width: 50%; pointer-events: none;
    background: linear-gradient(100deg, transparent, rgba(255,255,255,.85), transparent);
    transform: translateX(-100%) skewX(-15deg); opacity: 0;
    animation: pl-tag-shine 2.6s ease-in-out infinite; animation-delay: calc(var(--d) + .6s);
}
@keyframes pl-tag-shine { 0%, 55% { transform: translateX(-100%) skewX(-15deg); opacity: 0; } 60% { opacity: 1; } 100% { transform: translateX(380%) skewX(-15deg); opacity: 0; } }
.pl-sum-card { cursor: help; outline: none; }
.pl-sum-card:focus-visible .pl-sum-face { box-shadow: 0 0 0 3px #00ffcc, 0 8px 22px rgba(0,0,0,.55); }
/* The results' card preview: the big card + the phone card viewer's info (.cg-viewer-*) */
.pl-tip {
    position: fixed; z-index: 1000; display: none; max-width: 420px; padding: 12px; pointer-events: none;
    background: #161b22; border: 1px solid #30363d; border-radius: 10px; box-shadow: 0 8px 24px #0008; color: #e6edf3; text-align: left;
}
.pl-tip-img { display: block; width: 260px; height: 364px; margin: 0 auto 8px; object-fit: cover; border-radius: 6px; }
.pl-tip-name { font-size: 1.15rem; font-weight: 700; color: #f0f6fc; }
.pl-tip-kv { color: #8b949e; font-size: 0.9rem; margin-top: 0.15rem; }
.pl-tip-kws { list-style: none; margin: 0.75rem 0 0; padding: 0; display: grid; gap: 0.5rem; color: #ccc; font-size: 0.95rem; line-height: 1.5; }
.pl-tip-kws li { padding: 0.5rem 0.75rem; background: rgba(0,255,204,0.05); border-left: 3px solid #00ffcc; border-radius: 0 6px 6px 0; }
.pl-tip-kws strong { color: #00ffcc; margin-right: 0.25rem; }
.pl-tip-kws li.kw-title strong { text-decoration: underline; text-underline-offset: 3px; }
.pl-tip-kws .kw-title-tag { color: #8b949e; }
.pl-tip-kws li.pl-tip-none { padding: 0; background: none; border: 0; color: #8b949e; font-size: 0.9rem; }
/* Phones: a sheet up from the bottom over the dimmed page, starting where the deck builder's card
   sheet does (92% of the height), scrolling to read every keyword; its ✕ stays at the top. The page
   under it is held still (html.pl-tip-lock). */
.pl-tip-head { display: none; }
html.pl-tip-lock, html.pl-tip-lock body { overflow: hidden; }
html.pl-tip-lock body { pointer-events: none; } /* the dimmed page can't be tapped through, only the sheet */
.pl-tip.pl-tip-sheet {
    left: 0 !important; top: 8% !important; right: 0; bottom: 0; width: auto; max-width: none; max-height: none;
    overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; touch-action: pan-y; pointer-events: auto;
    padding: 0 max(16px, env(safe-area-inset-right)) calc(24px + env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
    border: 1px solid #30363d; border-bottom: 0; border-radius: 18px 18px 0 0; background: #11161d;
    box-shadow: 0 0 0 100vmax rgba(0,0,0,.6), 0 -12px 40px rgba(0,0,0,.6);
    animation: pl-tip-up .25s ease;
}
@keyframes pl-tip-up { from { transform: translateY(100%); } }
.pl-tip-sheet .pl-tip-head {
    display: flex; position: sticky; top: 0; z-index: 1; justify-content: flex-end; align-items: center;
    min-height: 52px; margin: 0 -8px 4px; background: #11161d;
}
.pl-tip-sheet .pl-tip-name, .pl-tip-sheet .pl-tip-kv, .pl-tip-sheet .pl-tip-kws { max-width: 32rem; margin-left: auto; margin-right: auto; }
.pl-tip-close {
    width: 40px; height: 40px; border-radius: 50%; border: 1px solid #30363d; background: #21262d;
    color: #e6edf3; font-size: 1rem; cursor: pointer;
}
.pl-tip-sheet .pl-tip-img { width: min(62vw, 260px); height: auto; aspect-ratio: 563 / 776; }
@keyframes pl-flip { from { opacity: 0; transform: rotateY(90deg) scale(.7); } }

/* Hidden tab / page: nothing keeps animating */
#pulls-view.pl-paused *, #pulls-view.pl-paused *::after { animation-play-state: paused !important; }

@media (prefers-reduced-motion: reduce) {
    .pl-float, .pl-front .pl-pack-glow, .pl-big .pl-pack-glow, .pl-float .pl-pack-glow,
    .pl-pack-foil::after, .pl-tear-hint, .pl-sum-new::after, .pl-card-shine, .pl-sum-face, .pl-tip-sheet { animation: none !important; }
    .pl-pack-glow { opacity: .7; }
}

@media (max-width: 760px), (pointer: coarse) and (max-height: 500px) {
    /* The results: the NEW! tags and the room above the cards as they were before desktop got bigger ones */
    .pl-summary { margin-top: 2.1rem; }
    .pl-sum-new { top: -28px; right: -8px; padding: .1rem .5rem; font-size: .8rem; }
    .pl-summary + .pl-actions { margin-top: 2rem; }
    /* Three or more cards are right there, so phones leave out the line naming them (pulls.js renderSummary()) */
    .pl-sum-names { display: none; }
    .pl-title { font-size: 1.15rem; }
    .pl-actions { margin-bottom: 1rem; }
    /* Less room above the carousel: the pack at the very back reaches up to .1 pw + 20px from the
       top, so a card peeking out of it (.11 pw higher, tilted a bit more) still just fits */
    .pl-carousel { padding-top: calc(var(--pw) / .64 * .2); }
    /* Only the pack in front glows: the others' faint glow was a layer each (1.4× a pack's size),
       ten of them, too much GPU memory for a phone */
    .pl-ring .pl-pack:not(.pl-front) .pl-pack-glow { display: none; }
    /* All three pack types: one row, just "Raku", "Blue", "Mega" */
    .pl-chips-3 { flex-wrap: nowrap; gap: .3rem; }
    .pl-chips-3 .pl-chip { gap: .3rem; padding-right: .5rem; white-space: nowrap; }
    .pl-chips-3 .pl-chip-long { display: none; }
    /* No drop shadows behind the far packs on a phone */
    .pl-ring .pl-pack:not(.pl-front) .pl-pack-body { box-shadow: none; }
    /* …nor behind the cards waiting under the top one */
    .pl-card:not(.pl-top) .pl-card-face { box-shadow: none; }
}

/* ── A gift from an admin (pulls.js playGift()): over the whole page, their picture drops the
   packs into the player's pulls under the gift's message. Nothing on the page can be reached
   until it has played. ── */
.pl-gift {
    --pw: clamp(84px, 22vw, 124px); --raku: #a79bbf; --blue: #4fc3ff; --mega: #3fdc7a;
    position: fixed; inset: 0; z-index: 10000; overflow: hidden;
    display: flex; flex-direction: column; align-items: center; justify-content: space-between;
    padding: max(6vh, 2rem) 16px max(6vh, 2rem); box-sizing: border-box; text-align: center;
    touch-action: none; user-select: none; -webkit-user-select: none;
}
.pl-gift-bg {
    position: absolute; inset: 0; z-index: -1;
    background: radial-gradient(ellipse at 50% 30%, rgba(60,44,90,.96), rgba(8,8,12,.98) 70%);
}
.pl-gift-top { display: flex; flex-direction: column; align-items: center; gap: clamp(1rem, 4vh, 2.2rem); width: 100%; }
.pl-gift-msg {
    margin: 0; max-width: 760px; font-size: clamp(1.2rem, 4.2vw, 2rem); font-weight: 800; line-height: 1.3;
    color: #fff; text-shadow: 0 2px 12px rgba(0,0,0,.6); overflow-wrap: anywhere;
}
.pl-gift-giver { display: flex; flex-direction: column; align-items: center; gap: .45rem; }
.pl-gift-avatar {
    position: relative; width: clamp(84px, 20vw, 128px); aspect-ratio: 1; border-radius: 50%; overflow: hidden;
    border: 3px solid #f0c040; background: linear-gradient(135deg, #f0c040, #ff9ad5);
    box-shadow: 0 0 0 6px rgba(240,192,64,.18), 0 10px 30px rgba(0,0,0,.6);
    display: flex; align-items: center; justify-content: center;
}
.pl-gift-avatar img { width: 100%; height: 100%; object-fit: cover; pointer-events: none; }
.pl-gift-avatar span { font-size: calc(clamp(84px, 20vw, 128px) * .45); font-weight: 900; color: #000; }
.pl-gift-avatar.pl-gift-login { background: radial-gradient(circle at 50% 40%, #fff3c4 0%, #f0c040 55%, #b8860b 100%); }
.pl-gift-avatar.pl-gift-login span { font-size: calc(clamp(84px, 20vw, 128px) * .55); line-height: 1; }
.pl-gift-name { font-weight: 700; color: #f0c040; font-size: 1rem; }
.pl-gift-tray { display: flex; flex-wrap: wrap; justify-content: center; gap: .7rem; }
.pl-gift-slot {
    position: relative; display: inline-flex; align-items: center; gap: .55rem; padding: .35rem .9rem .35rem .4rem;
    border: 2px solid var(--c); border-radius: 999px; background: rgba(20,20,24,.85); font-size: 1rem; color: #fff;
    transition: box-shadow .3s, background-color .3s;
}
.pl-gift-slot img { width: 30px; height: 40px; object-fit: cover; border-radius: 5px; }
.pl-gift-slot-n { font-size: 1.15rem; color: var(--c); font-variant-numeric: tabular-nums; }
.pl-gift-slot-on { box-shadow: 0 0 14px color-mix(in srgb, var(--c) 45%, transparent); }
.pl-gift-done .pl-gift-slot { background: color-mix(in srgb, var(--c) 18%, rgba(20,20,24,.9)); box-shadow: 0 0 22px color-mix(in srgb, var(--c) 60%, transparent); }
.pl-gift-ring { position: absolute; inset: -4px; border-radius: inherit; border: 2px solid var(--c); pointer-events: none; }
.pl-gift-fly { position: fixed; z-index: 2; pointer-events: none; will-change: transform, opacity; }
.pl-gift-fly .pl-pack-glow { opacity: .55; }
/* Phones in the play host: the gacha counts stay a little above the docked jukebox strip */
html.rk-shell-dock .pl-gift { padding-bottom: calc(1rem + var(--rk-dock-h, 0px)); }
@media (max-width: 760px) {
    .pl-gift-slot { font-size: .9rem; }
    .pl-gift-slot .pl-chip-long { display: none; }
}
