/* Package E — the opener (public/storefront/js/play-opener.js).
 * last13's gacha foil peel + pack scissor cut + manga climax, re-dressed in
 * the storefront theme: violet-black space with a synthwave floor, cyan /
 * magenta light, Orbitron titles; gold is kept for the room's best card only.
 * Loaded only by storefront/play/{gacha,packs}/show (@push('head')).
 *
 * Every animated element that STAYS on screen rests in its visible state and
 * animates FROM hidden (fill: both) — colorful.css's .effects-off sets
 * `animation: none !important` on everything, and a base state of opacity:0
 * would leave the card invisible. Transient FX (flash, confetti, sparks,
 * the manga page, the carousel) are not spawned at all under reduced motion. */

/* ---------- Page bits the opener drives ---------- */
.sf-play-machine.is-locked .sf-play-slot { pointer-events: none; }
.sf-play-slot.is-opening, .sf-play-seal.is-opening .sf-play-seal-art { box-shadow: 0 0 0 2px #00f0ff, 0 0 30px #00f0ff88; animation: sf-op-pulse 1s ease-in-out infinite alternate; }
.sf-play-seal.is-opening .sf-play-seal-art { box-shadow: none; filter: drop-shadow(0 0 16px #00f0ffaa); }
.sf-play-hint.is-guest { border-left-color: #3ee8a0; }
.sf-play-hint.is-guest .icon { color: #3ee8a0; }
.sf-play-hint.is-guest a { color: #3ee8a0; text-decoration: underline; }

/* ---------- Overlay shell ---------- */
html.sf-op-open, html.sf-op-open body { overflow: hidden; }
html.sf-op-open body { position: fixed; left: 0; right: 0; width: 100%; }
/* The stage's backdrop is opaque: once it has faded in (play-opener.js adds
   .sf-op-covered) the page under it is not drawn — compositing it on every
   frame for nothing was about half of the stage's GPU time. Only the page's
   own blocks: the stage, the manga and their flying bits are body children too. */
html.sf-op-covered body > :is(.sf-chrome-test, .announcement, .site-header, main, .site-footer, .sf-chrome-tabs),
html.sf-op-covered body::before { visibility: hidden; }
/* GpuWarm (play-opener.js): copies of the stage and the manga drawn ONCE on
   a fresh visit so the GPU compiles their programs before the first real
   open. Opacity .01 = drawn with the same programs, the page changes by at
   most 3/255 for ~1 s (.004 was invisible too but warmed far fewer). */
.sf-op-warm { position: fixed; inset: 0; z-index: 3990; opacity: .01; overflow: hidden; contain: strict; pointer-events: none; }
.sf-op-warm * { pointer-events: none !important; }
.sf-op {
  --op-cyan: #00f0ff; --op-pink: #ff006e; --op-violet: #b98cff; --op-gold: #ffcf00; --op-green: #3ee8a0;
  --op-ink: #f4f0ff; --op-muted: #aaa0ba;
  --op-display: var(--v2-display, Orbitron, 'Noto Sans Thai', sans-serif);
  --op-mono: var(--v2-mono, 'Space Mono', 'Noto Sans Thai', monospace);
  --op-rail: max(18px, calc((100vw - 1100px) / 2 + 24px));
  --op-top: calc(clamp(96px, 12vh, 118px) + env(safe-area-inset-top, 0px));
  --op-bottom: calc(clamp(96px, 12vh, 128px) + env(safe-area-inset-bottom, 0px));
  position: fixed; inset: 0; z-index: 4000; overflow: hidden;
  color: var(--op-ink); font-family: var(--op-mono);
  animation: sf-op-in .3s ease both;
}
.sf-op[hidden] { display: none; }
.sf-op .icon { fill: none; }

.sf-op-bg {
  position: absolute; inset: 0; overflow: hidden;
  background:
    radial-gradient(760px 620px at 18% 14%, rgba(120, 40, 200, .34), transparent 60%),
    radial-gradient(720px 640px at 86% 84%, rgba(255, 0, 110, .2), transparent 62%),
    radial-gradient(900px 700px at 50% 42%, rgba(0, 240, 255, .07), transparent 70%),
    radial-gradient(circle at 50% 46%, #12052a 0%, #07000f 58%, #030008 100%);
}
.sf-op-nebula {
  position: absolute; inset: -12%; pointer-events: none; mix-blend-mode: screen; transform: rotate(-18deg);
  background:
    radial-gradient(620px 240px at 30% 40%, rgba(150, 70, 255, .26), transparent 70%),
    radial-gradient(540px 220px at 66% 58%, rgba(0, 200, 255, .18), transparent 72%),
    radial-gradient(320px 160px at 48% 30%, rgba(255, 0, 110, .16), transparent 72%);
  animation: sf-op-breathe 15s ease-in-out infinite;
}
.sf-op-floor {
  position: absolute; left: -30%; right: -30%; bottom: -34%; height: 62%; pointer-events: none;
  transform: perspective(520px) rotateX(64deg);
  background-image: linear-gradient(#b069dd38 1px, transparent 1px), linear-gradient(90deg, #b069dd38 1px, transparent 1px);
  background-size: 64px 64px;
  -webkit-mask-image: radial-gradient(ellipse at 50% 0, #000 12%, transparent 70%);
  mask-image: radial-gradient(ellipse at 50% 0, #000 12%, transparent 70%);
  animation: sf-op-floor 5s linear infinite;
}
.sf-op-stars { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.sf-op-stars i {
  position: absolute; width: var(--s, 2px); height: var(--s, 2px); border-radius: 50%;
  background: var(--c, #fff); box-shadow: 0 0 var(--g, 6px) var(--c, #fff);
  animation: sf-op-tw var(--dur, 2s) ease-in-out var(--delay, 0s) infinite;
}
.sf-op-rays { position: absolute; top: 50%; left: 50%; width: 130vmax; height: 130vmax; transform: translate(-50%, -50%); pointer-events: none; will-change: transform; }
.sf-op-rays.is-spinning {
  background: repeating-conic-gradient(from 0deg, rgba(0, 240, 255, .1) 0deg 6deg, transparent 6deg 18deg, rgba(255, 0, 110, .07) 18deg 24deg, transparent 24deg 36deg);
  animation: sf-op-spin 30s linear infinite;
}
.sf-op-rays.is-paused { animation-play-state: paused; }
.sf-op-rays::after { content: ''; position: absolute; inset: 0; border-radius: 50%; opacity: 0; background: repeating-conic-gradient(from 0deg, rgba(170, 255, 255, .42) 0deg 2deg, transparent 2deg 15deg); }
.sf-op-rays.is-burst::after { animation: sf-op-rayburst 1.1s cubic-bezier(.2, .7, .2, 1) both; }

/* The scroller. Its padding keeps the stage clear of the head and foot bands
   (their MEASURED heights, --op-top / --op-bottom); the stage centres with an
   auto margin, so a stage taller than the screen still starts reachable. */
.sf-op-inner {
  position: absolute; inset: 0; z-index: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start;
  padding: var(--op-top) 8px var(--op-bottom); box-sizing: border-box;
  overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
}
/* tilt(): the face-down card leaning under the mouse, with a glare. */
.sf-op-stage { perspective: 1100px; }
.sf-op-tilt { transition: rotate .45s cubic-bezier(.2, .8, .3, 1); }
.sf-op-tilt.is-tilting { transition: rotate .08s linear; }
.sf-op-glare { position: absolute; inset: 0; z-index: 6; border-radius: 12px; pointer-events: none; opacity: 0; mix-blend-mode: screen; transition: opacity .3s; background: radial-gradient(circle at var(--gx, 50%) var(--gy, 50%), rgba(255, 255, 255, .3), rgba(0, 240, 255, .1) 32%, transparent 60%); }
.sf-op-rinner > .sf-op-glare { z-index: 2; }
.sf-op-tilt.is-tilting .sf-op-glare { opacity: 1; }
.sf-op-stage { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px; width: 100%; max-width: min(1180px, 96vw); flex: 0 0 auto; margin: auto 0; }

.sf-op-head {
  position: absolute; top: 0; left: 0; right: 0; z-index: 3; box-sizing: border-box;
  display: flex; align-items: center; justify-content: center; min-height: 44px;
  padding: calc(26px + env(safe-area-inset-top, 0px)) var(--op-rail) 16px;
  background: linear-gradient(180deg, rgba(7, 0, 15, .94) 0%, rgba(7, 0, 15, .74) 60%, rgba(7, 0, 15, 0) 100%);
}
.sf-op-title {
  margin: 0; padding: 0 60px; max-width: 900px; text-align: center; word-break: break-word;
  font: 900 clamp(24px, 4.2vw, 38px)/1.25 var(--op-display); letter-spacing: .5px;
  color: #fff;
  background: linear-gradient(100deg, #7ffcff 0%, #ffffff 35%, #ff5fa2 65%, #7ffcff 100%);
  background-size: 220% 100%;
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 0 18px rgba(0, 240, 255, .35));
  animation: sf-op-shine 4s ease-in-out infinite alternate;
}
.sf-op-title.is-new { animation: sf-op-shine 4s ease-in-out infinite alternate, sf-op-titlein .55s var(--ease-back, ease) both; }
.sf-op-kicker { display: block; margin-bottom: 4px; font: 700 12px/1.6 var(--op-mono); letter-spacing: .5px; color: var(--op-cyan); -webkit-text-fill-color: var(--op-cyan); }
.sf-op.is-best .sf-op-title { background-image: linear-gradient(100deg, #fff3b0 0%, #ffcf00 35%, #ffffff 55%, #ff9d00 80%, #fff3b0 100%); filter: drop-shadow(0 0 22px rgba(255, 207, 0, .55)); }
.sf-op.is-best .sf-op-kicker { color: var(--op-gold); -webkit-text-fill-color: var(--op-gold); }
.sf-op-x, .sf-op-mute {
  position: absolute; top: 50%; margin-top: 5px; transform: translateY(-50%);
  display: grid; place-items: center; padding: 0; touch-action: manipulation; -webkit-tap-highlight-color: transparent;
  transition: background .15s, color .15s, border-color .15s, box-shadow .15s;
}
.sf-op-x { right: var(--op-rail); width: 44px; height: 44px; color: #fff; background: #ff006e1f; border: 1px solid var(--op-pink); }
.sf-op-x::after { content: ''; position: absolute; inset: -10px; }
.sf-op-x:hover, .sf-op-x:focus-visible { background: #ff006e55; box-shadow: 0 0 20px #ff006e66; outline: none; }
.sf-op-x .icon { width: 20px; height: 20px; }
.sf-op-mute { left: var(--op-rail); width: 40px; height: 40px; color: var(--op-muted); background: #ffffff08; border: 1px solid #ffffff26; }
.sf-op-mute:hover, .sf-op-mute:focus-visible { color: var(--op-cyan); border-color: #00f0ff88; outline: none; }
.sf-op-mute[aria-pressed="true"] { color: var(--op-pink); border-color: #ff006e66; }
.sf-op-mute .icon { width: 18px; height: 18px; }

.sf-op-foot {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 3; box-sizing: border-box;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 10px 12px;
  padding: 18px var(--op-rail) calc(18px + env(safe-area-inset-bottom, 0px));
  background: linear-gradient(0deg, rgba(7, 0, 15, .95) 0%, rgba(7, 0, 15, .76) 60%, rgba(7, 0, 15, 0) 100%);
}
.sf-op-count { padding: 6px 10px; font: 700 13px var(--op-mono); color: var(--op-cyan); border: 1px solid #00f0ff44; background: #00f0ff0d; }
.sf-op-actions { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; }
.sf-op-note { flex-basis: 100%; text-align: center; font-size: 11px; line-height: 1.6; color: var(--op-muted); }
.sf-op-note:empty { display: none; }
.sf-op-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px; min-height: 46px; padding: 11px 22px;
  font: 700 13px var(--op-mono); color: var(--op-ink); text-decoration: none;
  background: #ffffff0d; border: 1px solid #ffffff2e;
  transition: background .15s, box-shadow .15s, transform .15s, color .15s, border-color .15s;
}
.sf-op-btn .icon { width: 18px; height: 18px; }
.sf-op-btn:hover, .sf-op-btn:focus-visible { background: #ffffff1c; border-color: #00f0ff88; color: #fff; outline: none; }
.sf-op-btn.is-hot { color: #06101a; background: var(--op-cyan); border-color: transparent; box-shadow: 0 0 26px #00f0ff55; }
.sf-op-btn.is-hot:hover, .sf-op-btn.is-hot:focus-visible { background: #b3ffff; color: #06101a; transform: translateY(-2px); box-shadow: 0 0 34px #00f0ff88; }
.sf-op.is-best .sf-op-btn.is-hot { background: var(--op-gold); box-shadow: 0 0 26px #ffcf0066; }

.sf-op-error { display: flex; flex-direction: column; align-items: center; gap: 12px; max-width: 460px; padding: 26px 24px; text-align: center; color: #ffc2dc; background: #ff006e14; border: 1px solid #ff006e55; animation: sf-op-deal .45s var(--ease-out, ease) both; }
.sf-op-error .icon { width: 40px; height: 40px; color: var(--op-pink); }
.sf-op-error p { font-size: 14px; line-height: 1.7; }
.sf-op-link { color: var(--op-cyan); font-weight: 700; text-decoration: underline; }

/* ---------- Gacha: one card, foil on top ---------- */
.sf-op-gcard {
  position: relative; width: min(350px, 74vw, 50vh); aspect-ratio: var(--op-ar, 5 / 7);
  touch-action: none; -webkit-user-select: none; user-select: none; -webkit-touch-callout: none;
  animation: sf-op-deal .7s var(--ease-out, ease) both;
}
.sf-op-gcard::after {
  content: ''; position: absolute; inset: -2px; z-index: 6; border-radius: 14px; pointer-events: none;
  box-shadow: 0 0 0 1px #00f0ff66, 0 0 30px #00f0ff33, 0 0 60px #ff006e22;
  animation: sf-op-glow 2.4s ease-in-out infinite alternate;
}
.sf-op-gcard.is-revealed::after { box-shadow: 0 0 0 2px #00f0ffaa, 0 0 44px #00f0ff66, 0 0 100px #ff006e44; }
.sf-op-gcard.is-revealed.is-best::after { box-shadow: 0 0 0 3px var(--op-gold), 0 0 54px #ffcf00aa, 0 0 120px #ff9d0055; }
.sf-op-face { position: absolute; inset: 0; border-radius: 12px; overflow: hidden; background: radial-gradient(circle at 50% 40%, #2a1248, #0b0616); box-shadow: 0 24px 54px #000c; }
.sf-op-img, .sf-op-img img { width: 100%; height: 100%; }
.sf-op-img img { display: block; object-fit: cover; animation: sf-op-fade .35s ease both; }
.sf-op-holo {
  position: absolute; inset: 0; pointer-events: none; opacity: 0; mix-blend-mode: color-dodge; transition: opacity .6s;
  background: linear-gradient(115deg, transparent 20%, rgba(0, 240, 255, .35) 35%, rgba(255, 0, 110, .3) 45%, rgba(255, 207, 0, .3) 55%, transparent 70%);
  background-size: 250% 250%;
}
.sf-op-gcard.is-revealed .sf-op-holo { opacity: .5; animation: sf-op-holo 3.2s ease-in-out infinite alternate; }
.sf-op-gcard.is-revealed.is-best .sf-op-holo { opacity: .8; }
.sf-op-foil { position: absolute; inset: 0; z-index: 4; display: block; width: 100%; height: 100%; border-radius: 12px; cursor: grab; touch-action: none; }
.sf-op-foil.is-grabbing { cursor: grabbing; }
.sf-op-foil.is-open { pointer-events: none; opacity: 0; transform: scale(1.04); transition: opacity .45s ease, transform .45s ease; }
.sf-op-scan { position: absolute; inset: 0; z-index: 5; border-radius: 12px; overflow: hidden; pointer-events: none; }
.sf-op-scan::before { content: ''; position: absolute; left: 0; right: 0; top: -24%; height: 22%; mix-blend-mode: screen; opacity: 0; background: linear-gradient(180deg, transparent, rgba(0, 240, 255, .22) 45%, rgba(255, 255, 255, .5) 50%, rgba(0, 240, 255, .22) 55%, transparent); animation: sf-op-scan 2.8s ease-in-out infinite; }
.sf-op-gcard.is-torn .sf-op-scan { display: none; }
.sf-op-foilhint { position: absolute; inset: 0; z-index: 7; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; text-align: center; pointer-events: none; transition: opacity .25s; }
.sf-op-foilhint.is-gone { opacity: 0; }
.sf-op-hand { display: grid; place-items: center; color: #fff; filter: drop-shadow(0 2px 6px #000b) drop-shadow(0 0 10px #00f0ff88); animation: sf-op-drag 1.5s ease-in-out infinite; }
.sf-op-hand .icon { width: 38px; height: 38px; stroke-width: 1.8; }
.sf-op-pill { padding: 6px 13px; font: 700 12px var(--op-mono); color: var(--op-cyan); background: rgba(7, 0, 15, .74); border: 1px solid #00f0ff66; -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); }
/* The mouse trail's sparks, drawn by play-opener.js (Glitter) — 64px of room
   round the card so they can drift off its edge. */
.sf-op-glitter { position: absolute; left: -64px; top: -64px; z-index: 8; width: calc(100% + 128px); height: calc(100% + 128px); pointer-events: none; }
.sf-op-cap { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; align-items: center; min-height: 1.8em; font: 700 13px var(--op-mono); color: var(--op-cyan); }
.sf-op-cap:empty { visibility: hidden; }
.sf-op-tag { padding: 2px 8px; font-size: 11px; font-weight: 700; color: var(--op-green); border: 1px solid #3ee8a088; }

/* ---------- Pack: the wrapper + scissors ---------- */
/* Width must stay definite — every child is absolute, so width:auto would
   collapse the aspect-ratio box to nothing. */
.sf-op-pack { position: relative; width: min(340px, 80vw, 40vh); aspect-ratio: 794 / 1217; transition: transform .48s var(--ease-out, ease), opacity .48s; animation: sf-op-deal .7s var(--ease-out, ease) both; }
/* The canvas overspills the pack (45% a side and on top) so the torn head can
   fly clear. 190% = 100 + 45 + 45, 145% = 100 + 45 — keep in sync with
   PAD_X / PAD_TOP in play-opener.js. max-width:none beats any img/canvas cap. */
.sf-op-packfoil { position: absolute; top: -45%; left: -45%; width: 190%; height: 145%; max-width: none; z-index: 2; cursor: grab; touch-action: none; transition: opacity .3s; filter: drop-shadow(0 16px 26px rgba(0, 0, 0, .55)) drop-shadow(0 0 26px rgba(0, 240, 255, .28)); }
.sf-op-packfoil.is-grabbing { cursor: grabbing; }
.sf-op-packfoil.is-open { pointer-events: none; }
.sf-op-pack.is-torn { transform: scale(1.15) rotate(3deg); opacity: 0; }
.sf-op-packhint { position: absolute; left: 50%; top: 50%; z-index: 3; transform: translate(-50%, -50%); display: inline-flex; align-items: center; gap: 8px; padding: 7px 14px; white-space: nowrap; font: 700 12px var(--op-mono); color: var(--op-cyan); background: rgba(7, 0, 15, .84); border: 1px solid #00f0ff66; pointer-events: none; transition: opacity .3s; animation: sf-op-bob 1.6s ease-in-out infinite; }
.sf-op-packhint .sf-op-hand { animation: sf-op-wiggle 1.6s ease-in-out infinite; filter: none; color: var(--op-cyan); }
.sf-op-packhint .icon { width: 18px; height: 18px; }
.sf-op-packhint.is-gone { opacity: 0; }
.sf-op-cutdemo { position: absolute; left: 0; right: 0; top: var(--y, 12%); height: 0; z-index: 3; pointer-events: none; opacity: 0; transition: opacity .3s; }
.sf-op-cutdemo.is-ready { opacity: 1; }
.sf-op-cutdemo.is-ready.is-gone { opacity: 0; }
.sf-op-cutline { position: absolute; top: 0; left: var(--x0, 8%); width: calc(var(--x1, 92%) - var(--x0, 8%)); border-top: 2px dashed rgba(0, 240, 255, .85); animation: sf-op-guide 1.9s ease-in-out infinite; }
.sf-op-cutblade { position: absolute; top: 0; left: var(--x0, 8%); transform: translate(-50%, -50%); color: #fff; filter: drop-shadow(0 2px 6px #000d) drop-shadow(0 0 10px #00f0ffaa); animation: sf-op-cutrun 2.6s ease-in-out infinite, sf-op-cutface 2.6s linear infinite; }
.sf-op-cutblade > i { display: block; animation: sf-op-snip .3s ease-in-out infinite; }
.sf-op-cutblade .icon, .sf-op-scissors .icon { display: block; width: 28px; height: 28px; stroke-width: 1.8; }
.sf-op-scissors { position: absolute; left: 0; top: 0; z-index: 4; transform: translate3d(var(--bx, 0px), var(--by, 0px), 0); will-change: transform; pointer-events: none; color: #fff; opacity: 0; transition: opacity .2s; filter: drop-shadow(0 2px 6px #000d) drop-shadow(0 0 10px #00f0ffaa); }
.sf-op-scissors > i { display: block; transform: translate(-50%, -50%); }
.sf-op-scissors.is-cutting { opacity: 1; }
.sf-op-scissors.is-cutting > i { animation: sf-op-snip2 .22s ease-in-out infinite; }
.sf-op-scissors.is-rtl > i { transform: translate(-50%, -50%) scaleX(-1); }
.sf-op-scissors.is-rtl.is-cutting > i { animation-name: sf-op-snip2-rtl; }

/* ---------- Pack: the row of cards, and one card alone ---------- */
.sf-op-row {
  --n: 5; --cols: min(var(--n), 5); --gap: 28px;
  display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: center;
  gap: var(--gap); width: 100%; padding: 8px 16px; box-sizing: border-box;
}
.sf-op-row.is-hidden { visibility: hidden; }
/* …but a card that has flown home out of the manga shows in its slot. */
.sf-op-row.is-enter .sf-op-rcard { animation: sf-op-rise .6s var(--ease-back, ease) both; animation-delay: calc(var(--i, 0) * 70ms); }
.sf-op-rcard {
  width: min(200px, 30vh, calc((100% - (var(--cols) - 1) * var(--gap)) / var(--cols)));
  padding: 0; color: inherit; text-align: center; background: none; border: 0; transition: transform .18s;
}
.sf-op-rinner { position: relative; width: 100%; aspect-ratio: var(--op-ar, 5 / 7); border-radius: 10px; }
.sf-op-seal { position: absolute; inset: 0; display: grid; place-items: center; overflow: hidden; border-radius: 10px; background: var(--op-back-bg, radial-gradient(circle at 50% 35%, #2a1248, #0b0616)); box-shadow: 0 10px 24px #000a; transition: box-shadow .18s; }
.sf-op-seal img { width: 100%; height: 100%; max-width: none; object-fit: contain; }
.sf-op-seal span, .sf-op-orbit-card span { font: 900 24px var(--op-display); letter-spacing: .1em; color: #ffffff66; }
.sf-op-rcard.is-sealed { cursor: pointer; }
.sf-op-rcard.is-sealed:hover, .sf-op-rcard.is-sealed:focus-visible { transform: translateY(-6px); outline: none; }
.sf-op-rcard.is-sealed:hover .sf-op-seal, .sf-op-rcard.is-sealed:focus-visible .sf-op-seal { box-shadow: 0 14px 30px #000a, 0 0 0 2px #00f0ffaa, 0 0 24px #00f0ff55; }
.sf-op-front { position: absolute; inset: 0; display: grid; place-items: center; overflow: hidden; border-radius: 10px; background: #0c0718; color: #ffffff40; }
.sf-op-front img { width: 100%; height: 100%; object-fit: contain; }
.sf-op-front .icon { width: 30px; height: 30px; }
.sf-op-rcard.is-pop, .sf-op-rone.is-pop { animation: sf-op-cardpop .5s var(--ease-out, ease) both; }
.sf-op-rcard.is-turned .sf-op-rinner { animation: sf-op-turn .3s var(--ease-out, ease) both; }
.sf-op-rcard.is-turned .sf-op-rinner::after { content: ''; position: absolute; inset: -3px; border-radius: 12px; pointer-events: none; opacity: 0; box-shadow: 0 0 0 2px #7ffcffe6, 0 0 26px #00f0ffbb; animation: sf-op-land .9s ease-out .12s both; }
.sf-op-rcard.is-turned.is-best .sf-op-rinner::after { box-shadow: 0 0 0 2px #ffe680, 0 0 26px #ffcf00cc; }
.sf-op-rcap { margin-top: 6px; }
.sf-op-rcap b { display: block; font: 700 12px/1.5 var(--op-mono); color: var(--op-cyan); }
.sf-op-rcap span { display: block; max-width: 100%; overflow: hidden; font-size: 12px; line-height: 1.5; color: #d9d0e6; white-space: nowrap; text-overflow: ellipsis; }
.sf-op-rone { display: flex; flex-direction: column; gap: 10px; width: min(340px, 74vw, 46vh); animation: sf-op-deal .6s var(--ease-out, ease) both; }
.sf-op-rone .sf-op-rinner { border-radius: 12px; touch-action: none; }
.sf-op-rone .sf-op-front { border-radius: 12px; box-shadow: 0 18px 44px #000b; }
.sf-op-rone .sf-op-rcap { text-align: center; opacity: 0; transition: opacity .3s .25s; }
.sf-op-rone.is-open .sf-op-rcap { opacity: 1; }
.sf-op-rone .sf-op-rcap b, .sf-op-rone .sf-op-rcap span { font-size: 14px; }
.sf-op-rfoil { position: absolute; inset: 0; z-index: 2; display: block; width: 100%; height: 100%; border-radius: 12px; cursor: grab; touch-action: none; transition: opacity .3s; }
.sf-op-rfoil.is-grabbing { cursor: grabbing; }
.sf-op-rfoil.is-open { opacity: 0; pointer-events: none; }
.sf-op-rhint { position: absolute; left: 50%; top: calc(100% + 10px); z-index: 3; transform: translateX(-50%); display: flex; align-items: center; gap: 6px; padding: 5px 12px; white-space: nowrap; font: 700 11px var(--op-mono); color: #fff; background: rgba(7, 0, 15, .78); border: 1px solid #ffffff2a; pointer-events: none; transition: opacity .3s; }
.sf-op-rhint .icon { width: 15px; height: 15px; }
.sf-op-rone.is-open .sf-op-rhint { opacity: 0; }

/* ---------- The hit (is_best): gold on the card's edge, Super-Saiyan style ----------
   Gold at the EDGE only — nothing across the picture, no rays behind it.
   Sealed (.is-hit on a row back, or the single view before the peel) and open
   (.is-best) alike: a hot gold rim round the card, and BEHIND it
   <canvas class="sf-op-ki"> where Ki (play-opener.js) draws small gold flames
   flickering up off its border — calmer while sealed, fiercer once open (a
   power-up flare as it opens). Open also gets a gold ring turning round the
   card and the crown. The hit is its
   own stacking context UNDER the other row cards (z-index 0 vs 1), so its
   flames go behind its neighbours, never over them. .is-fresh = the card that
   has JUST opened in the row (the manga card flies onto it): its crown and
   ring wait for the landing (Ki waits too), and a re-rendered row shows them
   at rest instead of popping again. */
@property --op-spin { syntax: '<angle>'; inherits: false; initial-value: 0deg; }
.sf-op-row .sf-op-rcard { position: relative; z-index: 1; }
.sf-op-row .sf-op-rcard.is-hit, .sf-op-row .sf-op-rcard.is-best { z-index: 0; }
.sf-op-rone { position: relative; z-index: 0; }
.sf-op-row .sf-op-rcard.is-best { transform: translateY(-8px); }
/* A canvas is a replaced element — left+right would not stretch it, so the
   box is width/height: 14% spare a side, 16% above (flames rise), 8% below.
   Ki reads the card's place in it from offsetLeft/offsetTop. */
.sf-op-ki { position: absolute; left: -14%; top: -16%; z-index: -2; display: block; width: 128%; height: 124%; max-width: none; pointer-events: none; }
.sf-op-rcard.is-hit .sf-op-seal, .sf-op-rone.is-best:not(.is-open) .sf-op-rinner {
  box-shadow: 0 0 0 2px #ffe27a, 0 0 10px 2px #ffcf00cc, 0 0 30px #ff9d0088;
  animation: sf-op-kirim .9s ease-in-out infinite alternate;
}
/* The rim's inner edge: over the back art (an inset shadow on the box would
   sit under the <img> / the foil canvas). */
.sf-op-rcard.is-hit .sf-op-seal::after, .sf-op-rone.is-best:not(.is-open) .sf-op-rinner::after {
  content: ''; position: absolute; inset: 0; z-index: 3; border-radius: inherit; pointer-events: none;
  box-shadow: inset 0 0 0 1px #fff3b0cc, inset 0 0 18px rgba(255, 190, 0, .55);
}
.sf-op-rcard.is-best .sf-op-rinner::before, .sf-op-rone.is-best.is-open .sf-op-rinner::before {
  content: ''; position: absolute; inset: -3px; z-index: -1; border-radius: 13px; pointer-events: none;
  background: conic-gradient(from var(--op-spin), #ffcf00, #fff7d1 12%, #ff9d00 25%, #ffcf00 38%, #fff7d1 50%, #ff9d00 63%, #ffcf00 76%, #fff7d1 88%, #ffcf00);
  animation: sf-op-spin 2.4s linear infinite;
}
.sf-op-rone.is-best.is-open .sf-op-rinner::before { inset: -4px; border-radius: 16px; }
.sf-op-rcard.is-best .sf-op-front, .sf-op-rone.is-best.is-open .sf-op-front { box-shadow: 0 0 12px 2px #ffcf00cc, 0 0 36px #ff9d0088; animation: sf-op-kiglow .9s ease-in-out infinite alternate; }
.sf-op-rcard.is-best .sf-op-rcap b { color: var(--op-gold); text-shadow: 0 0 10px #ffcf0099; }
.sf-op-rcard.is-best .sf-op-rcap span { color: #ffe9a8; }
.sf-op-crown {
  position: absolute; left: 50%; top: 0; z-index: 4; transform: translate(-50%, -58%);
  display: inline-flex; align-items: center; gap: 5px; padding: 3px 10px 3px 8px; white-space: nowrap; pointer-events: none;
  font: 900 11px/1.4 var(--op-display); color: #3a2400;
  background: linear-gradient(135deg, #fff3b0, #ffcf00 50%, #ff9d00); border: 1.5px solid #fff; border-radius: 999px;
  box-shadow: 0 4px 14px rgba(255, 170, 0, .6), 0 1px 3px rgba(0, 0, 0, .35);
}
.sf-op-crown .icon { width: 13px; height: 13px; stroke-width: 2.4; }
.sf-op-rone .sf-op-crown { font-size: 13px; padding: 4px 13px 4px 10px; }
.sf-op-rone .sf-op-crown .icon { width: 16px; height: 16px; }
.sf-op-rone.is-open .sf-op-crown { animation: sf-op-crownin .5s var(--ease-back, ease) .15s both; }
.sf-op-rone:not(.is-open) .sf-op-crown { display: none; }
.sf-op-rcard.is-fresh .sf-op-crown { animation: sf-op-crownin .5s var(--ease-back, ease) .62s both; }
.sf-op-rcard.is-fresh .sf-op-rinner::before { animation: sf-op-spin 2.4s linear infinite, sf-op-fadein .45s ease .58s both; }

/* เปิดทั้งหมด — a true 3D carousel: a zero-size preserve-3d pivot at the
   screen centre turning round the vertical axis, each back at rotateY(--op-a)
   translateZ(--r). Appended to the (fixed) overlay, so absolute = viewport.
   z-index 0 = BEHIND the scroller: the cards landing in the row stay in front
   of the ring instead of being crossed by it. --op-a is registered so the
   backs left glide to even spacing when one leaves (.is-dim once they do). */
@property --op-a { syntax: '<angle>'; inherits: false; initial-value: 0deg; }
.sf-op-orbit { position: absolute; inset: 0; z-index: 0; pointer-events: none; perspective: 1200px; }
.sf-op-orbit-ring { position: absolute; left: 50%; top: 50%; width: 0; height: 0; transform-style: preserve-3d; animation: sf-op-orbit 5.2s linear infinite; }
.sf-op-orbit-card {
  position: absolute; left: 0; top: 0; width: min(200px, 30vh, 42vmin); aspect-ratio: var(--op-ar, 5 / 7);
  transform: translate(-50%, -50%) rotateY(var(--op-a, 0deg)) translateZ(var(--r, 300px));
  display: grid; place-items: center; overflow: hidden; border-radius: 10px; background: var(--op-back-bg, #0c0718);
  box-shadow: 0 10px 30px #000b, 0 0 20px #00f0ff55;
  animation: sf-op-orbitin .55s var(--ease-out, ease) var(--d, 0ms) both;
  transition: opacity .35s, filter .35s, --op-a .7s cubic-bezier(.3, .7, .2, 1);
}
.sf-op-orbit-card img { width: 100%; height: 100%; object-fit: contain; }
.sf-op-orbit-card.is-out { opacity: 0; filter: brightness(2.2); }
.sf-op-orbit.is-dim .sf-op-orbit-card:not(.is-out):not(.is-face) { filter: brightness(.62) saturate(.8); }
/* A card back in the ring after its manga: face on the outside, the back on
   the inside, so it turns over as it goes round. overflow / filter would
   flatten the 3D (and show the face mirrored from behind), so a face card
   has neither — its two faces clip themselves, and .is-dim skips it. */
.sf-op-orbit-card.is-face { overflow: visible; background: none; box-shadow: none; transform-style: preserve-3d; }
.sf-op-oface, .sf-op-oback { position: absolute; inset: 0; display: grid; place-items: center; overflow: hidden; border-radius: 10px; -webkit-backface-visibility: hidden; backface-visibility: hidden; }
.sf-op-oface { color: #ffffff40; background: #0c0718; box-shadow: 0 10px 30px #000b, 0 0 22px #00f0ff66; }
.sf-op-oback { background: var(--op-back-bg, #0c0718); transform: rotateY(180deg); box-shadow: 0 10px 30px #000b, 0 0 20px #00f0ff55; }
.sf-op-oface img, .sf-op-oback img { width: 100%; height: 100%; object-fit: contain; }
.sf-op-oface .icon { width: 30px; height: 30px; }
.sf-op-orbit-card.is-best .sf-op-oface { box-shadow: 0 0 0 2px #ffe27a, 0 0 16px 3px #ffcf00cc, 0 0 44px #ff9d0088; }
/* The finale: a copy of each card flying from the ring to its row slot. */
.sf-op-flyto { position: fixed; z-index: 4245; border-radius: 10px; pointer-events: none; background: #0c0718 center / contain no-repeat; box-shadow: 0 10px 26px #000a, 0 0 18px #00f0ff55; will-change: transform; }
.sf-op-flyto.is-best { box-shadow: 0 0 0 2px #ffe27a, 0 0 18px 3px #ffcf00cc; }
.sf-op-rcard.is-arriving { visibility: hidden; }

/* ---------- FX (appended to <body>, above the overlay) ---------- */
/* The soft flash as a pack is torn (burstFromPack). fanfare() lays nothing
   over the cards — its glows are Stardust's, behind them. */
.sf-op-flash { position: fixed; inset: 0; z-index: 4300; pointer-events: none; opacity: 0; background: radial-gradient(circle at 50% 45%, rgba(255, 255, 255, .7) 0%, rgba(0, 240, 255, .32) 22%, rgba(255, 0, 110, .12) 42%, transparent 62%); animation: sf-op-flash .9s ease-out both; }
.sf-op-flash.is-soft { background: radial-gradient(circle at 50% 42%, #fff, rgba(200, 255, 255, .4) 30%, transparent 62%); animation: sf-op-flashsoft .74s ease-out both; }
/* Stardust's canvas: inside the overlay above its backdrop, under the cards
   (z-index 0 < .sf-op-inner); .is-page = no overlay to sit in. */
.sf-op-dust { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; pointer-events: none; }
.sf-op-dust.is-page { position: fixed; z-index: 4260; }
.sf-op-spk { position: fixed; z-index: 4310; width: var(--ss, 5px); height: var(--ss, 5px); margin: calc(var(--ss, 5px) / -2) 0 0 calc(var(--ss, 5px) / -2); border-radius: 50%; pointer-events: none; opacity: 0; background: radial-gradient(circle, #fff, var(--c, #00f0ff) 45%, transparent 75%); box-shadow: 0 0 8px var(--c, #00f0ff); animation: sf-op-spk .95s ease-out var(--sd, 0ms) both; }
.sf-op-flyback { position: fixed; z-index: 4250; border-radius: 12px; pointer-events: none; opacity: 0; background: linear-gradient(155deg, #3a1470, #140726 60%, #07000f) center / cover no-repeat; box-shadow: 0 14px 34px #000a, 0 0 30px #00f0ff55; animation: sf-op-cardfly 1.9s cubic-bezier(.16, .7, .3, 1) var(--bd, 0ms) both; }
.sf-op-collect { position: fixed; left: 0; top: 0; z-index: 4400; object-fit: cover; border-radius: 10px; border: 2px solid #fff; box-shadow: 0 10px 24px #0008, 0 0 16px #00f0ff88; pointer-events: none; will-change: transform, opacity; }
.sf-op-got { animation: sf-op-got .55s var(--ease-back, ease) both; }

/* ---------- Manga climax (Manga in play-opener.js) ---------- */
.sf-mg {
  position: fixed; inset: 0; z-index: 4500; display: flex; align-items: center; justify-content: center; cursor: pointer;
  background: radial-gradient(1000px 600px at 50% -10%, rgba(255, 0, 110, .16), transparent 60%), radial-gradient(800px 500px at 50% 110%, rgba(0, 240, 255, .12), transparent 60%), #05000b;
  opacity: 0; transition: opacity .25s ease; -webkit-tap-highlight-color: transparent; -webkit-user-select: none; user-select: none;
}
.sf-mg.is-show { opacity: 1; }
.sf-mg.is-hide { opacity: 0; transition-duration: .32s; }
/* The framed card leaving the manga page and shrinking onto the settled card. */
.sf-mg-fly { position: fixed; z-index: 4600; border-radius: 10px; pointer-events: none; background-size: cover; background-position: center; transform-origin: 50% 50%; will-change: transform, box-shadow; }
.sf-op-landed { animation: sf-op-landed .55s ease-out; }
/* A card settling into the row at the end of เปิดทั้งหมด — a gentle glow, not a flash. */
.sf-op-settled { animation: sf-op-settle .7s ease-out; }
.sf-mg-page { position: relative; width: min(95vw, 560px); aspect-ratio: 5 / 7; max-height: 94vh; overflow: hidden; border-radius: 6px; background: #000; box-shadow: 0 0 0 2px #f4f0ff, 0 0 40px #00f0ff44, 0 0 80px #ff006e33, 0 24px 54px rgba(0, 0, 0, .65); will-change: transform; }
/* The page scales in over the backdrop WITH its first panel — an empty black
   page with its white ring no longer pops in over the half-faded scene.
   A transition, not an animation: .shake takes the page's animation, and
   dropping that class would replay an entrance animation. */
.sf-mg .sf-mg-page { opacity: 0; transform: scale(.9); transition: opacity .3s ease .1s, transform .5s cubic-bezier(.2, .8, .3, 1) .1s; }
.sf-mg.is-show .sf-mg-page { opacity: 1; transform: none; }
.sf-mg-page.shake { animation: sf-mg-shake .55s cubic-bezier(.36, .07, .19, .97); }
.sf-mg-wedge { position: absolute; inset: 0; z-index: 3; overflow: hidden; opacity: 0; background-size: cover; background-position: center; transform: translate(var(--fx, 0), var(--fy, 0)); will-change: transform, opacity; }
.sf-mg-wedge.in { animation: sf-mg-wedgein .6s cubic-bezier(.22, .7, .25, 1) forwards; }
.sf-mg-p1 { clip-path: polygon(0 0, 100% 0, 50% 50%); --fy: -80px; }
.sf-mg-p2 { clip-path: polygon(100% 0, 100% 100%, 50% 50%); --fx: 80px; }
.sf-mg-p3 { clip-path: polygon(100% 100%, 0 100%, 50% 50%); --fy: 80px; }
.sf-mg-p4 { clip-path: polygon(0 100%, 0 0, 50% 50%); --fx: -80px; }
.sf-mg-halftone { position: absolute; inset: 0; z-index: 1; opacity: .5; pointer-events: none; background-image: radial-gradient(#000 1.1px, transparent 1.3px); background-size: 6px 6px; -webkit-mask: linear-gradient(120deg, #000, transparent 75%); mask: linear-gradient(120deg, #000, transparent 75%); }
.sf-mg-speed { position: absolute; inset: -40%; z-index: 2; pointer-events: none; background: repeating-conic-gradient(from 0deg at 50% 50%, #000 0 .9deg, transparent .9deg 3.4deg); -webkit-mask: radial-gradient(circle, transparent 24%, #000 62%); mask: radial-gradient(circle, transparent 24%, #000 62%); }
.sf-mg-gutter { position: absolute; top: 50%; left: 50%; z-index: 5; width: 200%; height: 30px; background: #000; pointer-events: none; }
.sf-mg-g1 { transform: translate(-50%, -50%) rotate(55deg); }
.sf-mg-g2 { transform: translate(-50%, -50%) rotate(-55deg); }
/* cyber scanlines over the whole page — this theme's touch on the manga */
.sf-mg-scan { position: absolute; inset: 0; z-index: 7; pointer-events: none; background: repeating-linear-gradient(0deg, transparent 0 3px, rgba(0, 0, 0, .18) 3px 4px); mix-blend-mode: multiply; }
.sf-mg-scan::after { content: ''; position: absolute; left: 0; right: 0; height: 18%; top: -20%; background: linear-gradient(180deg, transparent, rgba(0, 240, 255, .16), transparent); animation: sf-op-scan 3.2s linear infinite; mix-blend-mode: screen; }
.sf-mg-big { position: absolute; inset: 0; z-index: 6; display: flex; align-items: center; justify-content: center; }
.sf-mg-burst { position: absolute; inset: -30%; z-index: 0; opacity: 0; background: repeating-conic-gradient(from 0deg at 50% 50%, rgba(255, 255, 255, .85) 0 1.2deg, transparent 1.2deg 5deg); -webkit-mask: radial-gradient(circle, transparent 28%, #000 72%); mask: radial-gradient(circle, transparent 28%, #000 72%); animation: sf-mg-rayspin 12s linear infinite; }
.sf-mg-big.in .sf-mg-burst { opacity: .5; }
.sf-mg-glow { position: absolute; inset: -25%; z-index: 0; opacity: 0; filter: blur(6px); background: radial-gradient(ellipse at center, var(--mg-col, #00f0ff), transparent 60%); transition: opacity .4s ease .2s; }
.sf-mg-big.in .sf-mg-glow { opacity: .6; }
.sf-mg-full { position: relative; z-index: 2; width: min(80vw, 325px); aspect-ratio: 5 / 7; border-radius: 12px; overflow: visible; background-size: cover; background-position: center; border: 5px solid #f4f0ff; box-shadow: 0 0 0 3px #0a0014, 0 0 52px var(--mg-col, #00f0ff), 0 18px 40px rgba(0, 0, 0, .75); transform: scale(0); }
.sf-mg-big.in .sf-mg-full { animation: sf-mg-bigpop .55s cubic-bezier(.2, 1.5, .3, 1) forwards; }
.sf-mg-holo { position: absolute; inset: 0; border-radius: 7px; pointer-events: none; mix-blend-mode: color-dodge; opacity: .45; background: linear-gradient(115deg, transparent 25%, rgba(0, 240, 255, .4) 40%, rgba(255, 0, 110, .35) 50%, rgba(255, 207, 0, .35) 60%, transparent 75%); background-size: 250% 250%; animation: sf-op-holo 2.6s ease-in-out infinite alternate; }
.sf-mg-crown { display: none; }
.sf-mg.is-best .sf-mg-crown { position: absolute; top: 0; left: 50%; z-index: 3; transform: translate(-50%, -58%); display: flex; align-items: center; gap: 6px; padding: 5px 14px; white-space: nowrap; font: 900 13px var(--v2-display, Orbitron, 'Noto Sans Thai', sans-serif); color: #3a2400; background: linear-gradient(135deg, #fff3b0, #ffcf00 50%, #ff9d00); border: 2px solid #fff; box-shadow: 0 6px 18px rgba(255, 180, 0, .6), 0 2px 5px rgba(0, 0, 0, .35); }
.sf-mg-crown .icon { width: 16px; height: 16px; fill: none; }
.sf-mg-flash { position: absolute; inset: -30%; z-index: 7; opacity: 0; pointer-events: none; background: radial-gradient(circle, #fff 30%, transparent 65%); }
.sf-mg-flash.go { animation: sf-mg-flash .4s ease-out; }
.sf-mg-particle { position: absolute; left: 50%; top: 50%; z-index: 5; border-radius: 50%; pointer-events: none; will-change: transform, opacity; }
.sf-mg-sfx-layer { position: absolute; inset: 0; z-index: 8; pointer-events: none; }
.sf-mg-sfx { position: absolute; opacity: 0; font-family: 'Noto Sans JP', 'Yu Gothic', 'Hiragino Sans', 'Meiryo', sans-serif; font-weight: 900; color: #fff; -webkit-text-stroke: 3px #000; paint-order: stroke fill; transform: scale(0) rotate(var(--r, -8deg)); }
.sf-mg-sfx.show { animation: sf-mg-sfxpop .26s cubic-bezier(.2, 1.6, .3, 1) forwards; }
.sf-mg-s1 { top: 16%; left: 3%; font-size: clamp(22px, 7vw, 38px); --r: -12deg; text-shadow: 3px 3px 0 #ff006e; }
.sf-mg-s2 { top: 13%; right: 4%; font-size: clamp(20px, 6vw, 34px); --r: 8deg; text-shadow: 3px 3px 0 #00c8ff; }
.sf-mg-s3 { bottom: 28%; left: 2%; font-size: clamp(20px, 6.5vw, 36px); --r: -6deg; text-shadow: 3px 3px 0 #00c8ff; }
.sf-mg-s4 { bottom: 24%; right: 3%; font-size: clamp(18px, 5.5vw, 32px); --r: 10deg; text-shadow: 3px 3px 0 #ff006e; }
.sf-mg-gogo { top: 11%; right: 1%; font-size: clamp(18px, 5vw, 28px); line-height: .92; writing-mode: vertical-rl; color: #000; -webkit-text-stroke: 0; text-shadow: none; --r: 0deg; }
.sf-mg-gogo.show { animation: sf-mg-gogopop .3s ease forwards; }
.sf-mg-boom { left: 50%; bottom: 7%; font-size: clamp(40px, 13vw, 74px); letter-spacing: -.02em; color: var(--mg-col, #00f0ff); -webkit-text-stroke: 3.5px #000; text-shadow: 5px 5px 0 #ff006e, 0 0 24px var(--mg-col, #00f0ff); --r: -4deg; }
.sf-mg-boom.show { animation: sf-mg-boompop .6s cubic-bezier(.2, 1.6, .3, 1) forwards; }
.sf-mg-name { position: absolute; left: 50%; top: 4%; z-index: 9; max-width: 84%; transform: translateX(-50%) rotate(-2deg); padding: 6px 14px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font: 800 clamp(13px, 3.6vw, 17px) 'Noto Sans Thai', sans-serif; color: #000; background: #fff; border: 3px solid #000; box-shadow: 4px 4px 0 var(--mg-col, #00f0ff); opacity: 0; transition: opacity .25s .15s; }
.sf-mg-name:empty { display: none; }
.sf-mg-big.in ~ .sf-mg-name { opacity: 1; }
.sf-mg-hint { position: absolute; left: 0; right: 0; bottom: max(18px, env(safe-area-inset-bottom)); z-index: 9; text-align: center; font: 700 13px var(--v2-mono, monospace); letter-spacing: .04em; color: var(--op-cyan, #00f0ff); opacity: 0; pointer-events: none; }
.sf-mg-hint.show { animation: sf-mg-pulse 1.6s ease-in-out infinite; }

/* ---------- Keyframes ---------- */
@keyframes sf-op-in { from { opacity: 0; } }
@keyframes sf-op-fade { from { opacity: 0; } }
@keyframes sf-op-pulse { from { transform: none; } to { transform: translateY(-4px) scale(1.03); } }
@keyframes sf-op-breathe { 0%, 100% { opacity: .5; } 50% { opacity: .95; } }
@keyframes sf-op-floor { to { background-position: 0 64px, 0 0; } }
@keyframes sf-op-tw { 0%, 100% { opacity: var(--min, .15); transform: scale(.5); } 50% { opacity: 1; transform: scale(1.35); } }
@keyframes sf-op-spin { to { transform: translate(-50%, -50%) rotate(360deg); } }
@keyframes sf-op-rayburst { from { transform: scale(.12); opacity: .9; } to { transform: scale(1); opacity: 0; } }
@keyframes sf-op-shine { from { background-position: 0% 50%; } to { background-position: 100% 50%; } }
@keyframes sf-op-titlein { from { opacity: 0; transform: scale(.6) rotate(-4deg); } 60% { opacity: 1; transform: scale(1.08) rotate(1deg); } }
@keyframes sf-op-deal { from { opacity: 0; transform: translateY(90px) rotate(10deg) scale(.8); } }
@keyframes sf-op-glow { from { opacity: .55; } to { opacity: 1; } }
@keyframes sf-op-holo { from { background-position: 0% 0%; } to { background-position: 100% 100%; } }
@keyframes sf-op-scan { 0% { top: -24%; opacity: 0; } 15% { opacity: 1; } 70% { top: 102%; opacity: 1; } 100% { top: 102%; opacity: 0; } }
@keyframes sf-op-drag { 0%, 100% { transform: translate(16px, -16px) rotate(6deg); } 50% { transform: translate(-14px, 14px) rotate(6deg); } }
@keyframes sf-op-bob { 0%, 100% { transform: translate(-50%, -50%); } 50% { transform: translate(-50%, calc(-50% - 4px)); } }
@keyframes sf-op-wiggle { 0%, 100% { transform: translateX(-4px) rotate(-8deg); } 50% { transform: translateX(4px) rotate(8deg); } }
@keyframes sf-op-guide { 0%, 100% { opacity: .45; } 50% { opacity: .95; } }
@keyframes sf-op-cutrun { 0%, 10% { left: var(--x0, 8%); } 55%, 65% { left: var(--x1, 92%); } 100% { left: var(--x0, 8%); } }
@keyframes sf-op-cutface { 0%, 60% { transform: translate(-50%, -50%) scaleX(1); } 60.01%, 100% { transform: translate(-50%, -50%) scaleX(-1); } }
@keyframes sf-op-snip { 0%, 100% { transform: rotate(-10deg); } 50% { transform: rotate(10deg); } }
@keyframes sf-op-snip2 { 0%, 100% { transform: translate(-50%, -50%) rotate(-9deg); } 50% { transform: translate(-50%, -50%) rotate(9deg); } }
@keyframes sf-op-snip2-rtl { 0%, 100% { transform: translate(-50%, -50%) scaleX(-1) rotate(-9deg); } 50% { transform: translate(-50%, -50%) scaleX(-1) rotate(9deg); } }
@keyframes sf-op-rise { from { opacity: 0; transform: translateY(70px) rotate(calc((var(--i, 0) - 2) * 6deg)) scale(.7); } }
@keyframes sf-op-cardpop { 45% { transform: scale(1.12); } }
@keyframes sf-op-turn { from { transform: perspective(760px) rotateY(-88deg); } }
@keyframes sf-op-land { 18% { opacity: 1; } 100% { opacity: 0; } }
@keyframes sf-op-spin { to { --op-spin: 360deg; } }
@keyframes sf-op-kirim { from { box-shadow: 0 0 0 2px #ffd84a, 0 0 8px 1px #ffcf00aa, 0 0 22px #ff9d0066; } to { box-shadow: 0 0 0 2px #fff3b0, 0 0 14px 3px #ffe066, 0 0 40px #ffae00aa; } }
@keyframes sf-op-kiglow { from { box-shadow: 0 0 10px 1px #ffcf00aa, 0 0 28px #ff9d0066; } to { box-shadow: 0 0 16px 3px #ffe066, 0 0 48px #ffae00aa; } }
@keyframes sf-op-crownin { from { opacity: 0; transform: translate(-50%, -58%) scale(.2) rotate(-18deg); } }
@keyframes sf-op-fadein { from { opacity: 0; } }
@keyframes sf-op-orbit { from { transform: rotateY(0deg); } to { transform: rotateY(360deg); } }
@keyframes sf-op-orbitin { from { opacity: 0; transform: translate(-50%, -50%) rotateY(var(--op-a, 0deg)) translateZ(0) scale(.3); } }
@keyframes sf-op-flash { 0% { opacity: 0; transform: scale(.2); } 15% { opacity: 1; transform: scale(1.2); } 45% { opacity: .6; transform: scale(1.4); } 100% { opacity: 0; transform: scale(1.8); } }
@keyframes sf-op-flashsoft { 0% { opacity: 0; } 12% { opacity: 1; } 100% { opacity: 0; } }
@keyframes sf-op-spk { 0% { opacity: 1; transform: translate(0, 0) scale(1); } 100% { opacity: 0; transform: translate(var(--sx, 0), var(--sy, 0)) scale(.2); } }
@keyframes sf-op-cardfly { 0% { transform: translate(0, 0) rotate(0) scale(.3); opacity: 0; } 10% { opacity: 1; } 45%, 62% { transform: translate(var(--bx, 0), var(--by, -300px)) rotate(var(--br, 0)) scale(1); opacity: 1; } 100% { transform: translate(calc(var(--bx, 0) * .18), 0) rotate(calc(var(--br, 0) * .15)) scale(.72); opacity: 0; } }
@keyframes sf-op-landed { from { filter: brightness(1.8) saturate(1.25); } }
@keyframes sf-op-settle { from { filter: brightness(1.28) saturate(1.1); } }
@keyframes sf-op-got { 40% { transform: scale(1.22); filter: drop-shadow(0 0 10px #00f0ffe6); } }
@keyframes sf-mg-shake { 0%, 100% { transform: translate(0, 0) rotate(0); } 15% { transform: translate(-8px, 5px) rotate(-.6deg); } 35% { transform: translate(9px, -6px) rotate(.6deg); } 55% { transform: translate(-7px, 6px) rotate(-.4deg); } 75% { transform: translate(5px, -4px) rotate(.3deg); } }
@keyframes sf-mg-wedgein { from { opacity: 0; transform: translate(var(--fx, 0), var(--fy, 0)); } to { opacity: 1; transform: translate(0, 0); } }
@keyframes sf-mg-rayspin { to { transform: rotate(360deg); } }
@keyframes sf-mg-bigpop { 0% { transform: scale(.2) rotate(-14deg); } 60% { transform: scale(1.12) rotate(5deg); } 100% { transform: scale(1) rotate(0); } }
@keyframes sf-mg-flash { 0% { opacity: .95; } 100% { opacity: 0; } }
@keyframes sf-mg-sfxpop { 0% { opacity: 0; transform: scale(0) rotate(var(--r, -8deg)); } 60% { opacity: 1; transform: scale(1.25) rotate(var(--r, -8deg)); } 100% { opacity: 1; transform: scale(1) rotate(var(--r, -8deg)); } }
@keyframes sf-mg-gogopop { 0% { opacity: 0; transform: translateY(10px) scale(.8); } 100% { opacity: .9; transform: translateY(0) scale(1); } }
@keyframes sf-mg-boompop { 0% { opacity: 0; transform: translateX(-50%) scale(0) rotate(-12deg); } 55% { opacity: 1; transform: translateX(-50%) scale(1.3) rotate(5deg); } 100% { opacity: 1; transform: translateX(-50%) scale(1) rotate(-4deg); } }
@keyframes sf-mg-pulse { 0%, 100% { opacity: .45; } 50% { opacity: 1; } }

/* ---------- Phones / short screens ---------- */
@media (min-width: 900px) { .sf-mg-full { width: 400px; } }
@media (min-width: 1280px) { .sf-mg-full { width: 445px; } }
@media (max-width: 1100px) { .sf-op-row { --gap: 18px; padding: 8px 22px; } }
@media (max-width: 640px) {
  .sf-op { --op-rail: 12px; --op-top: calc(clamp(106px, 16vh, 124px) + env(safe-area-inset-top, 0px)); --op-bottom: calc(clamp(110px, 16vh, 140px) + env(safe-area-inset-bottom, 0px)); }
  .sf-op-inner { padding-left: 4px; padding-right: 4px; }
  .sf-op-head { padding: calc(22px + env(safe-area-inset-top, 0px)) 12px 14px; }
  .sf-op-title { font-size: 22px; line-height: 1.35; padding: 0 48px; }
  .sf-op-kicker { font-size: 11px; }
  .sf-op-x { width: 38px; height: 38px; }
  .sf-op-mute { width: 34px; height: 34px; }
  .sf-op-foot { gap: 8px; padding: 12px 12px calc(14px + env(safe-area-inset-bottom, 0px)); }
  .sf-op-btn { min-height: 42px; padding: 9px 16px; font-size: 12px; }
  .sf-op-row { --cols: min(var(--n), 3); --gap: 12px; padding: 8px 6px; }
  .sf-op-rcap b, .sf-op-rcap span { font-size: 11px; }
  .sf-mg-page { width: 100vw; max-height: 96vh; border-radius: 0; box-shadow: none; }
}
@media (max-width: 360px) { .sf-op-row { --cols: min(var(--n), 2); } }
/* PC: the sealed pack takes ~90% of the room between the head and foot bands
   (their measured heights), up to 460px wide — 794 / 1217 is its aspect-ratio. */
@media (min-width: 900px) and (min-height: 521px) {
  .sf-op-pack { width: min(460px, 80vw, calc((100vh - var(--op-top) - var(--op-bottom)) * .9 * 794 / 1217)); }
}
@media (max-height: 520px) {
  .sf-op-head { padding: calc(10px + env(safe-area-inset-top, 0px)) var(--op-rail) 8px; }
  .sf-op-foot { padding: 8px var(--op-rail) calc(8px + env(safe-area-inset-bottom, 0px)); }
  .sf-op-title { font-size: 19px; }
  .sf-op-gcard { width: min(350px, 74vw, 38vh); }
  .sf-op-pack { width: min(340px, 80vw, 30vh); }
  .sf-op-rone { width: min(340px, 74vw, 34vh); }
  .sf-op-rcard { width: min(200px, 22vh, calc((100% - (var(--cols) - 1) * var(--gap)) / var(--cols))); }
}
@media (prefers-reduced-motion: reduce) {
  .sf-op-nebula, .sf-op-floor, .sf-op-stars i, .sf-op-scan::before { animation: none; }
}

/* ---------- Coach: the mascot teaches the gesture (play-opener.js Coach; owner 2026-09-30: "อยากให้ออกแบบและให้มี
   ตัวละครมาสอนจริงๆ ในตัวทดลองฟรี ตัวสุ่มการ์ดก็เช่นกัน") ----------
   .sf-coach (in the opener, over the stage, under the head/foot) = the mascot + a white comic speech bubble with
   the steps (the current one lit, done ones ticked); .sf-coach-layer (inside the card / pack) = the pointing
   hand, its trail and the press ripple. JS places both; everything here is how they look and move. */
.sf-coach { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.sf-coach.is-leaving, .sf-coach-layer.is-leaving { opacity: 0; transition: opacity .25s; }
.sf-coach-mascot { position: absolute; width: auto; max-width: none; pointer-events: none; transform-origin: 50% 100%;
  filter: drop-shadow(0 12px 16px #000b) drop-shadow(0 0 24px #00f0ff38);
  animation: sf-coach-in .6s cubic-bezier(.2, 1.35, .4, 1) both, sf-coach-bob 1.9s ease-in-out .6s infinite; }
.sf-coach-mascot.is-hop { animation: sf-coach-hop .46s cubic-bezier(.3, 1.4, .5, 1), sf-coach-bob 1.9s ease-in-out .46s infinite; }
.sf-coach-mascot.is-articulated { aspect-ratio: 1079 / 1153; animation: sf-coach-in .6s cubic-bezier(.2, 1.35, .4, 1) both; }
.sf-coach-mascot.is-articulated > svg { display: block; width: 100%; height: 100%; overflow: visible; }
.sf-coach-arm { transform-box: view-box; }
.sf-coach-bubble { position: absolute; width: 276px; box-sizing: border-box; padding: 13px 16px 12px; pointer-events: auto;
  background: #fff; color: #1b0d33; border: 3px solid #160a2a; border-radius: 16px;
  box-shadow: 5px 6px 0 #00e5f0, 0 18px 36px #000b; font: 600 14px/1.45 'Noto Sans Thai', system-ui, sans-serif;
  transform-origin: var(--tail, 50%) 100%; animation: sf-coach-pop .5s cubic-bezier(.2, 1.5, .4, 1) .18s both; }
/* the tail: down to the mascot (side / over), left to it (below) */
.sf-coach-bubble::after { content: ''; position: absolute; left: var(--tail, 50%); bottom: -12px; width: 18px; height: 18px; margin-left: -9px;
  background: #fff; border: 3px solid #160a2a; border-top: 0; border-left: 0; transform: rotate(45deg); }
.sf-coach.is-below .sf-coach-bubble { transform-origin: 0 var(--tail, 50%); }
.sf-coach.is-below .sf-coach-bubble::after { left: -12px; top: var(--tail, 50%); bottom: auto; margin: -9px 0 0 0;
  border: 3px solid #160a2a; border-top: 0; border-right: 0; }
.sf-coach.no-mascot .sf-coach-bubble::after { display: none; }
.sf-coach-title { display: block; margin: 0 0 7px; font: 800 15px/1.3 'Noto Sans Thai', system-ui, sans-serif; color: #e0006e; }
.sf-coach-steps { list-style: none; margin: 0; padding: 0; display: grid; gap: 5px; }
.sf-coach-step { display: flex; align-items: center; gap: 9px; color: #8b7f9d; }
.sf-coach-step i { flex: 0 0 24px; height: 24px; display: grid; place-items: center; border-radius: 50%; font: 800 12px/1 var(--op-mono, monospace); font-style: normal;
  background: #ece7f4; color: #8b7f9d; transition: transform .25s cubic-bezier(.3, 1.6, .5, 1); }
.sf-coach-step.is-on { color: #160a2a; font-weight: 800; }
.sf-coach-step.is-on i { background: #00e5f0; color: #160a2a; transform: scale(1.18); box-shadow: 0 0 0 3px #00e5f055; }
.sf-coach-step.is-done { color: #54476a; }
.sf-coach-step.is-done i { background: #160a2a; color: #00f0ff; }
.sf-coach-ok { display: block; margin: 9px 0 0 auto; min-height: 30px; padding: 0 14px; border: 0; border-radius: 999px; cursor: pointer;
  font: 700 12px 'Noto Sans Thai', system-ui, sans-serif; color: #fff; background: #160a2a; transition: background .15s; }
.sf-coach-ok:hover, .sf-coach-ok:focus-visible { background: #e0006e; outline: none; }
/* Phones: numbers in a row, only the current step's words, a small × — fits the strip under the card */
.sf-coach.is-compact .sf-coach-bubble { width: min(236px, calc(100vw - 110px)); padding: 8px 30px 9px 11px; border-radius: 13px; font-size: 13px; box-shadow: 4px 4px 0 #00e5f0, 0 12px 26px #000b; }
.sf-coach.is-compact .sf-coach-title { display: none; }
.sf-coach.is-compact .sf-coach-steps { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 5px; }
.sf-coach.is-compact .sf-coach-step { display: contents; }
.sf-coach.is-compact .sf-coach-step i { flex-basis: 20px; width: 20px; height: 20px; font-size: 11px; }
.sf-coach.is-compact .sf-coach-step.is-on i { transform: scale(1.1); }
.sf-coach.is-compact .sf-coach-step span { display: none; order: 1; flex: 1 1 100%; line-height: 1.35; }
.sf-coach.is-compact .sf-coach-step.is-on span { display: block; }
.sf-coach.is-compact .sf-coach-ok { position: absolute; top: 3px; right: 3px; min-height: 0; width: 24px; height: 24px; margin: 0; padding: 0; overflow: hidden; color: transparent; background: transparent; }
.sf-coach.is-compact .sf-coach-ok::before { content: '×'; position: absolute; inset: 0; display: grid; place-items: center; font: 700 18px/1 system-ui, sans-serif; color: #8b7f9d; }
/* Card selection: an in-flow lesson leaves all cards and the footer clickable. */
.sf-op-row.has-coach .sf-op-rcap[aria-hidden] { display: none; }
.sf-op-coach-dock { display: flex; align-items: center; justify-content: center; flex: 0 0 auto; width: 100%; min-height: 166px; }
.sf-coach.is-choice { position: relative; inset: auto; display: flex; align-items: center; justify-content: center; gap: 14px; width: min(100%, 470px); padding: 4px 8px 10px; box-sizing: border-box; }
.sf-coach.is-choice .sf-coach-mascot { position: relative; flex: 0 0 auto; height: 140px; align-self: flex-end; }
.sf-coach.is-choice .sf-coach-bubble { position: relative; flex: 0 1 310px; width: 310px; transform-origin: 0 50%; }
.sf-coach.is-choice .sf-coach-bubble::after { left: -12px; top: 50%; bottom: auto; margin: -9px 0 0; border: 3px solid #160a2a; border-top: 0; border-right: 0; }
.sf-coach.is-choice.is-compact { gap: 8px; }
.sf-coach.is-choice.is-compact .sf-coach-mascot { height: 84px; max-width: 76px; object-fit: contain; }
.sf-coach.is-choice.is-compact .sf-coach-bubble { flex-basis: 236px; width: min(236px, calc(100vw - 106px)); }
@media (max-width: 699px) { .sf-op-coach-dock { min-height: 120px; } }
@media (max-width: 640px) {
  .sf-op-row.has-coach { --cols: min(var(--n), 3); --choice-rows: var(--choice-rows-phone); }
  .sf-op-row.has-coach .sf-op-rinner { margin-inline: auto;
    max-width: max(48px, calc((100dvh - var(--op-top) - var(--op-bottom) - 168px - (var(--choice-rows) - 1) * var(--gap)) / var(--choice-rows) * var(--op-ar, 5 / 7))); }
}
/* Room selection: readable before choosing a slot, above the complete grid. */
.sf-room-coach { display: flex; align-items: center; gap: 18px; margin: 0 0 24px; padding: 0 8px; }
.sf-room-coach[hidden] { display: none; }
.sf-play-tabs [data-room-coach-toggle][hidden] { display: none; }
.sf-room-coach-figure { flex: 0 0 146px; }
.sf-room-coach .sf-coach-mascot { position: relative; display: block; width: 100%; height: auto; }
.sf-room-coach .sf-coach-arm { transform-origin: 63.67% 53.17%; animation: sf-room-coach-arm 3.3s ease-in-out infinite; }
.sf-room-coach-bubble { position: relative; flex: 1; width: auto; min-width: 0; padding: 16px 20px 12px; transform-origin: 0 50%; }
.sf-room-coach-bubble::after { left: -12px; top: 50%; bottom: auto; margin: -9px 0 0; border: 3px solid #160a2a; border-top: 0; border-right: 0; }
.sf-room-coach-bubble .sf-coach-title { margin-bottom: 14px; font-size: 17px; }
.sf-room-coach-steps { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; margin: 0; padding: 0; list-style: none; }
.sf-room-coach-steps li { display: flex; align-items: flex-start; gap: 10px; }
.sf-room-coach-steps i { flex: 0 0 26px; height: 26px; display: grid; place-items: center; border-radius: 50%; background: #160a2a; color: #00ffff; font: 800 13px/1 var(--v2-mono, monospace); }
.sf-room-coach-steps li:first-child i { color: #160a2a; background: #00e5f0; box-shadow: 0 0 0 3px #00e5f033; }
.sf-room-coach-steps b { display: block; margin-bottom: 5px; font-size: 14px; font-weight: 800; }
.sf-room-coach-steps span { display: block; color: #625373; font-size: 12px; line-height: 1.55; }
.sf-room-coach-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 12px 20px; margin-top: 18px; padding-top: 14px; border-top: 1px solid #ece7f4; }
.sf-room-coach-actions .sf-coach-ok { min-height: 44px; margin: 0; padding-inline: 22px; font-size: 14px; }
.sf-room-coach-never { display: inline-flex; align-items: center; gap: 10px; min-height: 44px; min-width: 0; max-width: 100%; box-sizing: border-box; padding: 0; color: #160a2a; font: 700 14px/1.5 'Noto Sans Thai', system-ui, sans-serif; cursor: pointer; }
.sf-room-coach-never input { appearance: none; -webkit-appearance: none; display: grid; place-content: center; flex: 0 0 24px; width: 24px; height: 24px; box-sizing: border-box; margin: 0; padding: 0; border: 2px solid #625373; border-radius: 50%; background: #fff; cursor: pointer; }
.sf-room-coach-never input::before { content: ''; width: 11px; height: 6px; border-left: 3px solid #fff; border-bottom: 3px solid #fff; transform: translateY(-1px) rotate(-45deg); opacity: 0; }
.sf-room-coach-never input:checked { background: #160a2a; border-color: #160a2a; }
.sf-room-coach-never input:checked::before { opacity: 1; }
.sf-room-coach-never span { min-width: 0; }
.sf-room-coach-never b { display: block; font-weight: 800; }
.sf-room-coach-never small { display: block; margin-top: 2px; color: #625373; font-size: 12px; font-weight: 500; }
.sf-room-coach-never:hover input { border-color: #e0006e; }
.sf-room-coach-never input:focus-visible { outline: 2px solid #e0006e; outline-offset: 3px; }
.sf-room-coach-point { position: absolute; z-index: 3; left: 44%; top: 34%; width: clamp(28px, 50%, 72px); pointer-events: none; transform-origin: 40% 7%; transform: translate(-40%, -7%); animation: sf-room-coach-tap 3.3s ease-in-out infinite; filter: drop-shadow(0 3px 5px #0009); }
.sf-play-slot.has-coach-pointer { border-color: #00ffff; box-shadow: 0 0 0 1px #00ffff66, 0 0 24px #00ffff33; }
.sf-play-seal.has-coach-pointer .sf-play-seal-art { filter: drop-shadow(0 0 12px #00ffff77); }
@keyframes sf-room-coach-arm { 0%, 70%, 100% { transform: rotate(7deg); } 20%, 45% { transform: rotate(-9deg); } 30% { transform: rotate(-3deg); } }
@keyframes sf-room-coach-tap { 0%, 85%, 100% { opacity: 0; transform: translate(-15%, 6%) scale(1.08); } 15%, 48% { opacity: 1; transform: translate(-40%, -7%) scale(1); } 25%, 38% { opacity: 1; transform: translate(-40%, -7%) scale(.86); } 65% { opacity: 0; transform: translate(-40%, -18%) scale(1); } }
@media (max-width: 1000px) {
  .sf-room-coach-figure { flex-basis: 122px; }
  .sf-room-coach-steps { grid-template-columns: 1fr; gap: 12px; }
  .sf-room-coach-steps b { margin-bottom: 2px; }
}
@media (max-width: 640px) {
  .sf-room-coach { gap: 10px; padding: 0 5px 0 0; align-items: flex-start; }
  .sf-room-coach-figure { flex-basis: 68px; margin-top: 30px; }
  .sf-room-coach-bubble { padding: 12px 11px 10px; border-radius: 13px; box-shadow: 4px 4px 0 #00e5f0; }
  .sf-room-coach-bubble::after { top: 52px; }
  .sf-room-coach-bubble .sf-coach-title { font-size: 14px; margin-bottom: 12px; }
  .sf-room-coach-steps { gap: 10px; }
  .sf-room-coach-steps li { gap: 7px; }
  .sf-room-coach-steps i { flex-basis: 20px; height: 20px; font-size: 11px; }
  .sf-room-coach-steps b { font-size: 12px; }
  .sf-room-coach-steps span { font-size: 11px; }
  .sf-room-coach-actions { align-items: stretch; flex-direction: column; gap: 12px; }
}
@media (prefers-reduced-motion: reduce) {
  .sf-room-coach .sf-coach-arm, .sf-room-coach-point { animation: none; }
}
.effects-off .sf-room-coach .sf-coach-arm, .effects-off .sf-room-coach-point { animation: none; }

/* the hand layer, inside the card / pack */
.sf-coach-layer { position: absolute; inset: 0; z-index: 9; pointer-events: none; --hw: 100px; }
.sf-coach-hand { position: absolute; left: 0; top: 0; width: var(--hw); opacity: 0; will-change: transform, opacity;
  margin: calc(var(--hw) * -8 / 88) 0 0 calc(var(--hw) * -35 / 88);
  transform-origin: calc(var(--hw) * 35 / 88) calc(var(--hw) * 8 / 88);
  filter: drop-shadow(0 2px 1px #0a001488) drop-shadow(0 9px 8px #0009) drop-shadow(0 0 9px #00ffff45); }
.sf-coach-hand-art { display: block; width: 100%; height: auto; overflow: visible; }
.sf-coach-touch { position: absolute; left: 0; top: 0; width: 26px; height: 26px; border-radius: 50%; opacity: 0;
  background: radial-gradient(circle, #fff 0 14%, #00ffffa6 20% 38%, #00ffff00 70%);
  box-shadow: 0 0 0 1px #b9ffffb3, 0 0 18px #00ffff80; will-change: transform, opacity; }
.sf-coach-trail { position: absolute; left: 0; top: 0; height: 4px; margin-top: -2px; transform-origin: 0 50%; opacity: 0; border-radius: 3px;
  background: linear-gradient(90deg, #00ffff26, #00ffffb3 60%, #e5ffff); box-shadow: 0 0 10px #00ffff80; }
.sf-coach-trail::before { content: ''; position: absolute; left: -9px; top: -6px; width: 18px; height: 18px; box-sizing: border-box; border-radius: 50%;
  border: 3px solid #fff; background: #00f0ff; box-shadow: 0 0 14px #00f0ff; }
.sf-coach-ring { position: absolute; left: 0; top: 0; width: 64px; height: 64px; box-sizing: border-box; border-radius: 50%; opacity: 0;
  border: 2px solid #d9ffff; box-shadow: 0 0 0 2px #00ffff66, 0 0 18px #00ffff99; }
.sf-op-rone .sf-coach-layer { --hw: 80px; }
@media (max-width: 640px) {
  .sf-coach-layer { --hw: 76px; }
  .sf-op-rone .sf-coach-layer { --hw: 64px; }
  .sf-coach-ring { width: 50px; height: 50px; }
}
@keyframes sf-coach-in { from { opacity: 0; translate: -46px 22px; scale: .7; } to { opacity: 1; translate: 0 0; scale: 1; } }
@keyframes sf-coach-bob { 0%, 100% { translate: 0 0; } 50% { translate: 0 -5px; } }
@keyframes sf-coach-hop { 0% { translate: 0 0; rotate: 0deg; } 35% { translate: 0 -16px; rotate: -4deg; } 70% { translate: 0 2px; rotate: 2deg; } 100% { translate: 0 0; rotate: 0deg; } }
@keyframes sf-coach-pop { from { opacity: 0; scale: .5; } to { opacity: 1; scale: 1; } }
@media (prefers-reduced-motion: reduce) {
  .sf-coach-mascot, .sf-coach-mascot.is-hop, .sf-coach-mascot.is-articulated, .sf-coach-bubble { animation: none; }
  .sf-coach-arm { transform: none; }
}
.effects-off .sf-coach-mascot, .effects-off .sf-coach-mascot.is-hop, .effects-off .sf-coach-mascot.is-articulated, .effects-off .sf-coach-bubble { animation: none; }
.effects-off .sf-coach-arm { transform: none; }
