/* FX layer: particles canvas, ribbon banners, floating text, fx toasts, full-screen reward cinematics.
   Arena (Supercell-style) look: ink outlines, bevels, hard drop shadows, sunburst rays and white flashes.
   No glows. Only transform/opacity are animated on big elements to keep 60fps on phones. */

.fx-canvas {
  position: fixed; inset: 0; width: 100vw; height: 100vh; height: 100dvh;
  pointer-events: none; z-index: var(--z-fx);
}

.fx-cine, .fx-cine *, .fx-banner, .fx-banner *, .fx-toasts, .fx-toasts *, .fx-float { box-sizing: border-box; }

/* ---------- shared display type: Lilita + ink outline ---------- */
.fx-kicker, .fx-title, .fx-banner__text, .fx-stamp, .fx-flawless__text, .fx-streak__num,
.fx-challenger__main, .fx-challenger__kicker, .fx-reward__amount, .fx-crate__prompt,
.fx-emblem__tier, .fx-card__lv, .fx-lootcard__value, .fx-float, .fx-ribbon__text, .fx-cine__hint,
.fx-lootcard__back, .fx-lootcard__rarity, .fx-card__rarity, .fx-toast__text, .fx-reward__xp, .fx-fromto b {
  font-family: var(--font-display); font-weight: 400; font-style: normal; letter-spacing: 0.01em;
  color: var(--text); text-shadow: var(--ts-outline);
}
.fx-cine .ic { overflow: visible; }

/* ---------- ribbon (kicker / crate name / reward header / banner) ----------
   DOM: .fx-ribbon > svg.fx-ribbon__tail--l, svg.fx-ribbon__tail--r, .fx-ribbon__face > .fx-ribbon__text
   Tails are painted first, the face after, so no z-index tricks are needed. */
.fx-ribbon {
  --c: var(--yellow); --tail: 34px; --drop: 10px;
  position: relative; display: inline-block; max-width: calc(100vw - 2 * var(--tail) - 24px);
  margin: 0 calc(var(--tail) - 8px) var(--drop);
}
.fx-ribbon__tail {
  position: absolute; top: var(--drop); bottom: calc(-1 * var(--drop)); width: var(--tail); overflow: visible;
}
.fx-ribbon__tail polygon {
  fill: color-mix(in srgb, var(--c) 58%, #000); stroke: var(--ink); stroke-width: 3px;
  stroke-linejoin: round; vector-effect: non-scaling-stroke;
}
.fx-ribbon__tail--l { left: calc(-1 * var(--tail) + 10px); }
.fx-ribbon__tail--r { right: calc(-1 * var(--tail) + 10px); }
.fx-ribbon__face {
  position: relative; min-width: 180px; padding: 7px 22px 10px; text-align: center;
  background: linear-gradient(180deg, color-mix(in srgb, var(--c) 62%, #fff) 0%, var(--c) 42%, color-mix(in srgb, var(--c) 80%, #000) 100%);
  border: 3px solid var(--ink); border-radius: 8px;
  box-shadow: inset 0 3px 0 rgba(255, 255, 255, 0.35), inset 0 -4px 0 rgba(0, 0, 0, 0.18), 0 4px 0 var(--ink-soft);
}
.fx-ribbon__text {
  display: block; font-size: 22px; line-height: 1.1; text-shadow: var(--ts-outline-sm);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.fx-ribbon--crate .fx-ribbon__text { font-size: 26px; }

/* ---------- banner (big ribbon that pops in mid-screen) ---------- */
.fx-banner {
  --c: var(--blue-btn);
  position: fixed; left: 0; right: 0; top: 36%; z-index: calc(var(--z-cinematic) + 20);
  pointer-events: none; display: flex; justify-content: center;
  padding: 0 var(--s-4);
}
.fx-banner__band {
  position: relative; display: flex; flex-direction: column; align-items: center;
  width: min(100%, 380px);
  animation: fx-banner-in 460ms var(--ease-pop) both;
}
.fx-banner__icon {
  position: relative; z-index: 2; font-size: 64px; line-height: 0; margin-bottom: -20px;
  filter: drop-shadow(0 4px 0 var(--ink-soft));
  animation: fx-banner-icon 520ms var(--ease-pop) 120ms both;
}
.fx-banner .fx-ribbon { --c: inherit; }
.fx-ribbon--banner { --tail: 44px; --drop: 14px; width: calc(100% - 2 * var(--tail) + 16px); }
.fx-ribbon--banner .fx-ribbon__face { padding: 10px 14px 14px; border-radius: 10px; box-shadow: inset 0 4px 0 rgba(255, 255, 255, 0.35), inset 0 -5px 0 rgba(0, 0, 0, 0.2), 0 6px 0 var(--ink-soft); }
.fx-banner.has-icon .fx-ribbon--banner .fx-ribbon__face { padding-top: 22px; }
.fx-banner__text {
  font-size: clamp(30px, 9.5vw, 44px); line-height: 1; white-space: normal;
  text-shadow: -2px -2px 0 var(--ink), 2px -2px 0 var(--ink), -2px 2px 0 var(--ink), 2px 2px 0 var(--ink), 0 4px 0 var(--ink);
  animation: fx-banner-text 420ms var(--ease-pop) 90ms both;
}
.fx-banner__sub {
  margin-top: var(--s-2); display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 14px; border-radius: var(--r-pill);
  background: rgba(13, 24, 56, 0.85); border: 2px solid var(--ink);
  font-family: var(--font); font-size: var(--fs-md); font-weight: 800; color: var(--text);
  max-width: 100%; text-align: center;
  animation: fx-fade-up 300ms var(--ease-out) 200ms both;
}
.fx-banner__sub .ic { font-size: 22px; }
.fx-banner.is-out .fx-banner__band { animation: fx-banner-out 300ms cubic-bezier(.7, 0, .84, 0) both; }
.fx-banner.is-reduced .fx-banner__band, .fx-banner.is-reduced .fx-banner__text,
.fx-banner.is-reduced .fx-banner__icon, .fx-banner.is-reduced .fx-banner__sub { animation: fx-fade-in 200ms both; }
.fx-banner.is-reduced.is-out .fx-banner__band { animation: fx-fade-out 200ms both; }
@keyframes fx-banner-in { 0% { transform: scale(0.2, 0.6); opacity: 0; } 60% { transform: scale(1.08, 1.04); opacity: 1; } 100% { transform: none; } }
@keyframes fx-banner-out { from { transform: none; opacity: 1; } to { transform: scale(0.6) translateY(-30px); opacity: 0; } }
@keyframes fx-banner-text { from { transform: scale(1.7); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes fx-banner-icon { from { transform: scale(0) rotate(-30deg); } to { transform: none; } }

/* ---------- floating text ---------- */
.fx-float {
  --c: var(--gt);
  position: fixed; z-index: calc(var(--z-fx) - 1); pointer-events: none;
  display: inline-flex; align-items: center; gap: 6px;
  transform: translate(-50%, -50%); white-space: nowrap;
  color: var(--c);
  animation: fx-float 1.25s var(--ease-out) both;
}
.fx-float .ic { filter: drop-shadow(0 3px 0 var(--ink-soft)); }
.fx-float--lg { font-size: var(--fs-2xl); }
.fx-float--sm { font-size: var(--fs-lg); text-shadow: var(--ts-outline-sm); }
.fx-float.is-reduced { animation: fx-fade-inout 1.2s both; }
@keyframes fx-float {
  0% { transform: translate(-50%, -30%) scale(0.4); opacity: 0; }
  18% { transform: translate(-50%, -60%) scale(1.25); opacity: 1; }
  30% { transform: translate(-50%, -70%) scale(1); }
  75% { opacity: 1; }
  100% { transform: translate(-50%, -190%) scale(0.95); opacity: 0; }
}

/* ---------- fx toasts (reward panel that drops in under the HUD) ---------- */
.fx-toasts {
  position: fixed; left: 50%; top: calc(var(--safe-top) + var(--hud-h) + var(--s-2));
  transform: translateX(-50%); z-index: calc(var(--z-cinematic) + 30);
  width: min(360px, calc(100vw - 2 * var(--s-4)));
  display: flex; flex-direction: column; gap: var(--s-2); pointer-events: none;
}
.fx-toast {
  --c: var(--blue-btn);
  display: flex; align-items: center; gap: var(--s-3);
  padding: 8px var(--s-4) 8px 8px; min-height: 60px;
  background: var(--grad-panel);
  border: 2px solid var(--ink); border-radius: var(--r-lg);
  box-shadow: var(--bevel), var(--shadow-pop);
  animation: fx-toast-in 380ms var(--ease-pop) both;
}
.fx-toast.is-out { animation: fx-toast-out 300ms ease-in both; }
.fx-toast.is-reduced, .fx-toast.is-reduced.is-out { animation-name: fx-fade-in; }
.fx-toast.is-reduced.is-out { animation-name: fx-fade-out; }
.fx-toast__icon {
  flex: none; width: 44px; height: 44px; display: grid; place-items: center; font-size: 32px; line-height: 0;
  border-radius: 12px; border: 2px solid var(--ink);
  background: linear-gradient(180deg, color-mix(in srgb, var(--c) 70%, #fff), var(--c) 55%, color-mix(in srgb, var(--c) 75%, #000));
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.35), inset 0 -3px 0 rgba(0, 0, 0, 0.2);
}
.fx-toast__body { display: flex; flex-direction: column; min-width: 0; gap: 1px; }
.fx-toast__text { font-size: var(--fs-lg); line-height: 1.1; text-shadow: var(--ts-outline-sm); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fx-toast__sub { font-size: var(--fs-sm); color: var(--text-dim); font-weight: 800; }
@keyframes fx-toast-in { from { transform: translateY(-28px) scale(0.85); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes fx-toast-out { to { transform: translateY(-16px) scale(0.92); opacity: 0; } }

/* ---------- cinematic base ---------- */
.fx-backdrop {
  position: fixed; inset: 0; z-index: calc(var(--z-cinematic) - 1); pointer-events: auto;
  background: color-mix(in srgb, var(--ink) 90%, transparent);
  animation: fx-fade-in 220ms ease-out both;
}
.fx-backdrop.is-out { animation: fx-fade-out 260ms ease-in both; pointer-events: none; }
.fx-cine {
  position: fixed; inset: 0; z-index: var(--z-cinematic);
  display: flex; align-items: center; justify-content: center;
  overflow: hidden; touch-action: none; user-select: none; -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
  animation: fx-fade-in 220ms ease-out both;
}
.fx-cine.is-out { animation: fx-fade-out 260ms ease-in both; pointer-events: none; }
.fx-cine__dim {
  position: absolute; inset: 0;
  background:
    radial-gradient(110% 70% at 50% 42%, color-mix(in srgb, var(--arena-bot) 75%, transparent) 0%, transparent 70%),
    color-mix(in srgb, var(--ink) 88%, transparent);
}
.fx-cine__hint {
  position: absolute; left: 0; right: 0; bottom: calc(var(--safe-bottom) + var(--s-6)); z-index: 3;
  text-align: center; font-size: var(--fs-lg); text-shadow: var(--ts-outline-sm);
  opacity: 0; transition: opacity var(--t-med);
}
.fx-cine.can-skip .fx-cine__hint { opacity: 1; animation: fx-blink 1.4s ease-in-out infinite; }
.fx-stage {
  position: relative; z-index: 2; width: 100%; max-width: 420px; padding: var(--s-5) var(--s-4);
  display: flex; flex-direction: column; align-items: center; gap: var(--s-4); text-align: center;
}
.fx-kicker { font-size: var(--fs-lg); }
.fx-kicker--gold { color: var(--yellow); }
.fx-title {
  --c: var(--blue-btn);
  font-size: clamp(32px, 10vw, 46px); line-height: 1.02;
  text-shadow: -2px -2px 0 var(--ink), 2px -2px 0 var(--ink), -2px 2px 0 var(--ink), 2px 2px 0 var(--ink), 0 5px 0 var(--ink);
}
.fx-title--rank { font-size: clamp(36px, 11vw, 52px); }
.fx-sub { font-size: var(--fs-md); color: var(--text-dim); font-weight: 800; max-width: 320px; line-height: 1.35; }
.fx-fromto {
  display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: center;
  padding: 6px 14px; border-radius: var(--r-pill);
  background: rgba(13, 24, 56, 0.55); border: 2px solid var(--ink);
  box-shadow: inset 0 3px 0 rgba(0, 0, 0, 0.2);
}
.fx-fromto b { font-weight: 400; font-size: var(--fs-lg); text-shadow: var(--ts-outline-sm); }
.fx-fromto__arrow { font-size: 22px; }

/* ---------- sunburst rays (Supercell-style, repeating-conic-gradient) ---------- */
.fx-rays {
  --c: var(--yellow);
  position: absolute; left: 50%; top: 50%; width: 760px; height: 760px; z-index: -1;
  margin: -380px 0 0 -380px; pointer-events: none; opacity: 0; border-radius: 50%;
  background:
    radial-gradient(circle, color-mix(in srgb, var(--c) 45%, #fff) 0 5%, color-mix(in srgb, var(--c) 40%, transparent) 11%, transparent 24%),
    repeating-conic-gradient(from 0deg, color-mix(in srgb, var(--c) 50%, #fff) 0deg 9deg, transparent 9deg 22.5deg);
  -webkit-mask: radial-gradient(circle, #000 12%, rgba(0, 0, 0, 0.55) 30%, transparent 50%);
  mask: radial-gradient(circle, #000 12%, rgba(0, 0, 0, 0.55) 30%, transparent 50%);
  scale: 0.4;
  transition: opacity 300ms ease-out, scale 600ms var(--ease-pop);
  animation: fx-spin-ray 20s linear infinite;
}
.fx-rays.is-on { opacity: 0.9; scale: 1; }
.fx-rays--reward { top: 36%; }
.is-reduced .fx-rays { animation: none; transition: opacity 200ms; scale: 1; }
@keyframes fx-spin-ray { to { rotate: 360deg; } }

.fx-flash {
  position: absolute; inset: 0; z-index: 5; pointer-events: none;
  background: #fff;
  animation: fx-flash 520ms ease-out both;
}
.is-reduced .fx-flash { display: none; }
@keyframes fx-flash { 0% { opacity: 0; } 10% { opacity: 0.95; } 100% { opacity: 0; } }

/* ---------- rank emblem: shield badge ---------- */
.fx-emblem-slot { position: relative; width: 200px; height: 200px; display: grid; place-items: center; }
.fx-emblem-slot > .fx-emblem { grid-area: 1 / 1; }
.fx-emblem {
  --c: var(--blue-btn);
  position: relative; display: grid; place-items: center; flex: none;
  filter: drop-shadow(0 6px 0 var(--ink-soft));
}
.fx-emblem__shape { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.fx-emblem__rim { fill: var(--c); stroke: var(--ink); stroke-width: 4; stroke-linejoin: round; }
.fx-emblem__field {
  fill: color-mix(in srgb, var(--c) 62%, #000); stroke: color-mix(in srgb, var(--c) 45%, #000); stroke-width: 2;
}
.fx-emblem__gloss { fill: #fff; opacity: 0.14; }
.fx-emblem__shine { stroke: #fff; stroke-width: 4; stroke-linecap: round; opacity: 0.55; fill: none; }
.fx-emblem__icon {
  position: relative; font-size: calc(var(--sz, 160px) * 0.46); line-height: 0; margin-top: -8%;
  filter: drop-shadow(0 4px 0 rgba(0, 0, 0, 0.3));
}
.fx-emblem__tier {
  position: absolute; bottom: 4%; left: 50%; transform: translateX(-50%);
  min-width: 46px; padding: 2px 12px 4px; border-radius: 8px;
  font-size: calc(var(--sz, 160px) * 0.15); line-height: 1.1; text-shadow: var(--ts-outline-sm);
  background: linear-gradient(180deg, #ffe066, var(--yellow) 50%, var(--yellow-lo));
  border: 3px solid var(--ink);
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.5), 0 3px 0 var(--ink-soft);
}
.fx-emblem.is-cracking { filter: drop-shadow(0 6px 0 var(--ink-soft)) brightness(1.5) saturate(0.6); }
.fx-emblem.is-new { z-index: 2; }

/* ---------- crate / chest ---------- */
.fx-crate-wrap { position: relative; display: grid; place-items: center; width: 240px; height: 230px; }
.fx-crate-wrap.is-gone { height: 0; margin-top: -16px; }
.fx-crate-wrap.is-gone .fx-crate { display: none; }
.fx-crate-wrap.is-gone .fx-rays { top: 160px; }
.fx-crate { --c: var(--r-common); --charge: 0; position: relative; width: 210px; height: 210px; }
.fx-crate__shadow {
  position: absolute; left: 18%; right: 18%; bottom: 4px; height: 22px; border-radius: 50%;
  background: rgba(5, 10, 30, 0.55);
  animation: fx-shadow-bob 1.1s ease-in-out infinite;
}
.fx-crate__box {
  position: absolute; inset: 0; transform-origin: 50% 92%;
  animation: fx-chest-bounce 1.1s ease-in-out infinite;
}
.fx-crate__part { position: absolute; inset: 0; font-size: 210px; line-height: 0; }
.fx-crate__part .ic { width: 210px; height: 210px; display: block; filter: drop-shadow(0 6px 0 rgba(5, 10, 30, 0.35)); }
/* chest icon: lid is y 5..15 of 32 (trim band 13..17). Split just under the trim. */
.fx-crate__lid { clip-path: inset(0 0 46% 0); transform-origin: 50% 54%; transition: transform 220ms var(--ease-pop); }
.fx-crate__base { clip-path: inset(53% 0 0 0); }
.fx-crate.hit-1 .fx-crate__lid { transform: translateY(-4px) rotate(-2deg); }
.fx-crate.hit-2 .fx-crate__lid { transform: translateY(-8px) rotate(3deg); }
.fx-crate.hit-3 .fx-crate__lid { transform: translateY(-14px) rotate(-4deg); }
.fx-crate.hit-2 .fx-crate__box, .fx-crate.hit-3 .fx-crate__box { animation-duration: 0.55s; }
.fx-crate.is-open .fx-crate__box { animation: none; }
.fx-crate.is-open .fx-crate__lid { animation: fx-lid-off 520ms cubic-bezier(.2, .8, .4, 1) both; }
.fx-crate.is-open .fx-crate__base { animation: fx-base-pop 520ms ease-out both; }
.fx-crate.is-open .fx-crate__shadow { animation: fx-fade-out 400ms both; }
.fx-crate__prompt {
  font-size: var(--fs-2xl); min-height: 1.2em; line-height: 1.1;
  animation: fx-throb 0.9s ease-in-out infinite;
}
.fx-crate__pips { display: flex; gap: var(--s-3); }
.fx-crate__pips i {
  width: 22px; height: 22px; border-radius: 50%; border: 3px solid var(--ink);
  background: rgba(13, 24, 56, 0.55); box-shadow: inset 0 3px 0 rgba(0, 0, 0, 0.25);
  transition: background var(--t-fast), transform var(--t-fast);
}
.fx-crate__pips i.is-on {
  background: var(--yellow); transform: scale(1.15);
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.55), inset 0 -3px 0 var(--yellow-lo);
}
.is-reduced .fx-crate__box, .is-reduced .fx-crate__shadow, .is-reduced .fx-crate__prompt { animation: none; }
.is-reduced .fx-crate.is-open .fx-crate__lid, .is-reduced .fx-crate.is-open .fx-crate__base { animation: fx-fade-out 200ms both; }
@keyframes fx-chest-bounce {
  0%, 100% { transform: translateY(0) scale(1, 1); }
  12% { transform: translateY(0) scale(1.08, 0.9); }
  35% { transform: translateY(-22px) scale(0.95, 1.06); }
  55% { transform: translateY(0) scale(1.06, 0.94); }
  70% { transform: translateY(0) scale(0.98, 1.02); }
}
@keyframes fx-lid-off {
  0% { transform: translateY(-14px) rotate(-4deg); opacity: 1; }
  100% { transform: translate(60px, -260px) rotate(38deg) scale(0.9); opacity: 0; }
}
@keyframes fx-base-pop {
  0% { transform: scale(1); opacity: 1; }
  30% { transform: scale(1.2, 0.85); opacity: 1; }
  100% { transform: scale(0.6) translateY(60px); opacity: 0; }
}

/* ---------- loot cards (Clash-style, rarity framed) ---------- */
.fx-loot {
  display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s-3);
  width: 100%; max-width: 360px; perspective: 900px;
}
.fx-loot:empty { display: none; }
.fx-lootcard { --r: var(--r-common); --v: var(--yellow); position: relative; width: 106px; height: 150px; flex: none; }
.fx-loot[data-count='1'] .fx-lootcard { width: 150px; height: 204px; }
.fx-loot[data-count='2'] .fx-lootcard { width: 132px; height: 182px; }
.fx-lootcard__inner {
  position: absolute; inset: 0; transform-style: preserve-3d;
  transition: transform 480ms cubic-bezier(.3, 1.4, .5, 1);
}
.fx-lootcard.is-flipped .fx-lootcard__inner { transform: rotateY(180deg); }
.fx-lootcard__face {
  position: absolute; inset: 0; backface-visibility: hidden; -webkit-backface-visibility: hidden;
  border-radius: var(--r-md); display: flex; flex-direction: column; align-items: center; justify-content: flex-start;
  gap: 2px; padding: 6px 6px 0; overflow: hidden;
  border: 3px solid var(--ink);
  box-shadow: inset 0 3px 0 rgba(255, 255, 255, 0.3), inset 0 -4px 0 rgba(0, 0, 0, 0.2), 0 5px 0 var(--ink-soft);
}
.fx-lootcard__back {
  justify-content: center;
  background:
    repeating-linear-gradient(45deg, rgba(255, 255, 255, 0.06) 0 10px, transparent 10px 20px),
    var(--grad-panel);
  font-size: 56px; line-height: 1;
}
.fx-lootcard__front {
  transform: rotateY(180deg);
  background: linear-gradient(180deg, color-mix(in srgb, var(--r) 70%, #fff) 0%, var(--r) 30%, color-mix(in srgb, var(--r) 72%, #000) 100%);
}
.fx-lootcard__well {
  width: 100%; flex: 1 1 auto; min-height: 0; display: grid; place-items: center;
  border-radius: 8px; border: 2px solid var(--ink);
  background: radial-gradient(circle at 50% 40%, color-mix(in srgb, var(--r) 30%, #fff) 0%, color-mix(in srgb, var(--r) 55%, var(--ink)) 100%);
  box-shadow: inset 0 3px 0 rgba(0, 0, 0, 0.22);
}
.fx-lootcard__icon { font-size: 52px; line-height: 0; filter: drop-shadow(0 3px 0 rgba(0, 0, 0, 0.3)); }
.fx-loot[data-count='1'] .fx-lootcard__icon { font-size: 80px; }
.fx-loot[data-count='2'] .fx-lootcard__icon { font-size: 68px; }
.fx-lootcard__value {
  margin-top: 4px; font-size: var(--fs-lg); line-height: 1.05; text-align: center; max-width: 100%;
  overflow-wrap: break-word; text-shadow: var(--ts-outline-sm);
}
.fx-loot[data-count='1'] .fx-lootcard__value { font-size: var(--fs-xl); }
.fx-lootcard__value.is-long { font-size: var(--fs-md); }
.fx-lootcard__label {
  font-size: 12px; font-weight: 900; color: var(--text); line-height: 1.1;
  text-shadow: 0 1px 0 var(--ink), 0 0 0 var(--ink), -1px 0 0 var(--ink), 1px 0 0 var(--ink), 0 -1px 0 var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;
}
.fx-lootcard__rarity {
  margin: 4px -6px 0; align-self: stretch; padding: 2px 0 3px;
  font-size: 13px; text-shadow: var(--ts-outline-sm); text-align: center;
  background: color-mix(in srgb, var(--r) 55%, #000); border-top: 2px solid var(--ink);
}
.fx-lootcard__rays {
  position: absolute; left: 50%; top: 50%; width: 360px; height: 360px; margin: -180px 0 0 -180px; z-index: -1;
  border-radius: 50%;
  background: repeating-conic-gradient(color-mix(in srgb, var(--r) 55%, #fff) 0deg 9deg, transparent 9deg 22.5deg);
  -webkit-mask: radial-gradient(circle, #000 15%, transparent 60%); mask: radial-gradient(circle, #000 15%, transparent 60%);
  opacity: 0; pointer-events: none;
}
.fx-lootcard.is-legendary .fx-lootcard__rays { opacity: 0.9; animation: fx-spin 10s linear infinite; }
.fx-lootcard.is-legendary .fx-lootcard__front { box-shadow: inset 0 0 0 3px #fff, inset 0 3px 0 rgba(255, 255, 255, 0.3), 0 5px 0 var(--ink-soft); }
.fx-lootcard.is-legendary .fx-lootcard__inner { animation: fx-legend-bob 1.4s ease-in-out 0.5s infinite; }
.is-reduced .fx-lootcard__inner { transition-duration: 1ms; animation: none; }
@keyframes fx-legend-bob { 0%, 100% { translate: 0 0; } 50% { translate: 0 -5px; } }

/* ---------- exercise card (card upgrade) ---------- */
.fx-card {
  --c: var(--blue-btn); --r: var(--r-common);
  position: relative; width: 210px; height: 296px; border-radius: var(--r-lg);
  display: flex; flex-direction: column; align-items: center; padding: 10px 10px 0;
  background: linear-gradient(180deg, color-mix(in srgb, var(--r) 70%, #fff) 0%, var(--r) 25%, color-mix(in srgb, var(--r) 70%, #000) 100%);
  border: 3px solid var(--ink);
  box-shadow: inset 0 3px 0 rgba(255, 255, 255, 0.35), inset 0 -4px 0 rgba(0, 0, 0, 0.2), 0 6px 0 var(--ink-soft);
  overflow: hidden;
}
.fx-card__top {
  width: 100%; display: flex; align-items: center; gap: 8px;
  font-family: var(--font-display); font-size: var(--fs-lg); color: var(--text); text-shadow: var(--ts-outline-sm);
}
.fx-card__slot {
  width: 30px; height: 30px; border-radius: 8px; display: grid; place-items: center;
  background: var(--c); border: 2px solid var(--ink);
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.4), inset 0 -3px 0 rgba(0, 0, 0, 0.2);
}
.fx-card__art {
  margin: 8px 0 8px; width: 100%; height: 124px; border-radius: 10px;
  display: grid; place-items: center; font-size: 92px; line-height: 0;
  background: linear-gradient(180deg, color-mix(in srgb, var(--c) 75%, #fff), var(--c) 50%, color-mix(in srgb, var(--c) 70%, #000));
  border: 2px solid var(--ink);
  box-shadow: inset 0 3px 0 rgba(255, 255, 255, 0.3), inset 0 -4px 0 rgba(0, 0, 0, 0.2);
}
.fx-card__art .ic { filter: drop-shadow(0 4px 0 rgba(0, 0, 0, 0.3)); }
.fx-card__lv { font-size: var(--fs-xl); line-height: 1; }
.fx-card__name {
  margin-top: 4px; font-weight: 900; font-size: var(--fs-md); color: var(--text); line-height: 1.15; min-height: 2.3em;
  display: flex; align-items: center; text-align: center;
  text-shadow: 0 1px 0 var(--ink), -1px 0 0 var(--ink), 1px 0 0 var(--ink), 0 -1px 0 var(--ink), 0 2px 0 var(--ink);
}
.fx-card__rarity {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 3px 0 5px; text-align: center;
  font-size: var(--fs-md); text-shadow: var(--ts-outline-sm);
  background: color-mix(in srgb, var(--r) 55%, #000); border-top: 2px solid var(--ink);
}
.fx-flip-wrap { position: relative; margin: var(--s-3) 0; }
.fx-flip { perspective: 1000px; width: 210px; height: 296px; }
.fx-flip__inner { position: relative; width: 100%; height: 100%; transform-style: preserve-3d; }
.fx-flip__face { position: absolute; inset: 0; backface-visibility: hidden; -webkit-backface-visibility: hidden; }
.fx-flip__face--back { transform: rotateY(180deg); }
.fx-flip.is-charging .fx-card { animation: fx-charge 0.18s linear infinite; }
.fx-stamp {
  position: absolute; left: 50%; top: 82%; z-index: 3; white-space: nowrap; transform: translateX(-50%);
}
.fx-stamp > span {
  display: inline-block; padding: 6px 18px 9px; border-radius: 10px;
  font-size: var(--fs-2xl); line-height: 1;
  background: linear-gradient(180deg, #a6f070, var(--green) 45%, var(--green-lo));
  border: 3px solid var(--ink);
  box-shadow: inset 0 3px 0 rgba(255, 255, 255, 0.4), inset 0 -4px 0 var(--green-edge), 0 5px 0 var(--ink-soft);
  transform: rotate(-8deg);
}
@keyframes fx-charge { 0%, 100% { transform: translate(0, 0); } 25% { transform: translate(-3px, 1px); } 75% { transform: translate(3px, -1px); } }
.is-reduced .fx-flip.is-charging .fx-card { animation: none; }

/* ---------- achievement ---------- */
.fx-ach {
  position: relative; width: min(340px, 100%); padding: 92px var(--s-5) var(--s-5); margin-top: 84px;
  display: flex; flex-direction: column; align-items: center; gap: var(--s-3);
  border-radius: var(--r-lg); border: 3px solid var(--ink);
  background: var(--grad-panel);
  box-shadow: var(--bevel), var(--shadow-pop);
}
.fx-ach__badgewrap {
  position: absolute; left: 50%; top: -84px; width: 160px; height: 160px; margin-left: -80px;
  display: grid; place-items: center;
}
.fx-ach__badge {
  position: relative; width: 140px; height: 140px; display: grid; place-items: center; font-size: 84px; line-height: 0;
  border-radius: 50%; border: 4px solid var(--ink);
  background: radial-gradient(circle at 50% 38%, #ffe680 0%, var(--yellow) 45%, var(--yellow-lo) 100%);
  box-shadow: inset 0 0 0 7px rgba(255, 255, 255, 0.35), inset 0 -8px 0 rgba(166, 89, 8, 0.45), 0 6px 0 var(--ink-soft);
}
.fx-ach__badge .ic { filter: drop-shadow(0 4px 0 rgba(0, 0, 0, 0.25)); }
.fx-title--ach { font-size: clamp(28px, 8vw, 36px); }
.fx-ach .fx-ribbon__face { min-width: 0; }
.fx-ach .fx-ribbon__text { font-size: 18px; }

/* ---------- streak ---------- */
.fx-flame-wrap { position: relative; display: flex; flex-direction: column; align-items: center; }
.fx-flame { position: relative; width: 170px; height: 170px; display: grid; place-items: center; }
.fx-flame__icon { position: relative; font-size: 170px; line-height: 0; filter: drop-shadow(0 6px 0 var(--ink-soft)); }
.fx-flame.is-lit .fx-flame__icon { animation: fx-flicker 0.5s ease-in-out infinite alternate; transform-origin: 50% 90%; }
.is-reduced .fx-flame .fx-flame__icon { animation: none; }
.fx-streak__num {
  margin-top: -64px; position: relative; font-size: var(--fs-mega); line-height: 0.9;
  text-shadow: -4px -4px 0 var(--ink), 4px -4px 0 var(--ink), -4px 4px 0 var(--ink), 4px 4px 0 var(--ink), 0 8px 0 var(--ink);
}
@keyframes fx-flicker { from { transform: scale(1, 1) rotate(-2deg); } to { transform: scale(1.04, 1.08) rotate(2deg); } }

/* ---------- flawless ---------- */
.fx-flawless-wrap { position: relative; display: grid; place-items: center; padding: var(--s-5) 0; }
.fx-flawless {
  position: relative; display: inline-flex; align-items: center; gap: 10px;
  padding: 12px 22px 16px; overflow: hidden;
  background: linear-gradient(180deg, #ffe066 0%, var(--yellow) 45%, var(--yellow-lo) 100%);
  border: 4px solid var(--ink); border-radius: 14px;
  box-shadow: inset 0 4px 0 rgba(255, 255, 255, 0.5), inset 0 -6px 0 rgba(166, 89, 8, 0.5), 0 7px 0 var(--ink-soft);
  transform: rotate(-6deg);
}
.fx-flawless__text {
  display: block; font-size: clamp(40px, 12vw, 58px); line-height: 1;
  text-shadow: -2px -2px 0 var(--ink), 2px -2px 0 var(--ink), -2px 2px 0 var(--ink), 2px 2px 0 var(--ink), 0 5px 0 var(--ink);
}
.fx-flawless__star { font-size: 36px; }
.fx-flawless::after {
  content: ''; position: absolute; top: -20%; bottom: -20%; width: 26%; left: -40%;
  background: rgba(255, 255, 255, 0.6);
  transform: skewX(-20deg); opacity: 0;
}
.fx-flawless.is-shine::after { animation: fx-shine 0.9s ease-in-out 0.1s 2 both; }
.is-reduced .fx-flawless.is-shine::after { animation: none; }
@keyframes fx-shine { 0% { left: -40%; opacity: 1; } 100% { left: 120%; opacity: 1; } }

/* ---------- challenger (red vs blue split) ---------- */
.fx-split { position: absolute; inset: 0; z-index: 1; }
.fx-split--a {
  background:
    repeating-linear-gradient(-30deg, transparent 0 22px, rgba(0, 0, 0, 0.08) 22px 30px),
    linear-gradient(180deg, var(--red-btn), var(--red-btn-lo));
  clip-path: polygon(0 0, 100% 0, 100% 38%, 0 62%);
  animation: fx-split-a 380ms var(--ease-out) both;
}
.fx-split--b {
  background:
    repeating-linear-gradient(-30deg, transparent 0 22px, rgba(0, 0, 0, 0.08) 22px 30px),
    linear-gradient(180deg, var(--blue-btn), var(--blue-btn-lo));
  clip-path: polygon(0 62%, 100% 38%, 100% 100%, 0 100%);
  animation: fx-split-b 380ms var(--ease-out) both;
}
.fx-split__seam {
  position: absolute; left: -10%; right: -10%; top: 50%; height: 14px; margin-top: -7px; z-index: 2;
  background: #fff; border-top: 4px solid var(--ink); border-bottom: 4px solid var(--ink);
  transform: rotate(-22deg) scaleX(0);
  animation: fx-seam 500ms 300ms var(--ease-out) both;
}
.fx-challenger__text {
  position: relative; z-index: 3; width: 100%; padding: 0 var(--s-4);
  display: flex; flex-direction: column; align-items: center; gap: var(--s-2); text-align: center;
  transform: rotate(-10deg);
  animation: fx-challenger-text 460ms 300ms var(--ease-pop) both;
}
.fx-challenger__kicker {
  padding: 4px 14px 6px; border-radius: 8px; font-size: var(--fs-lg); text-shadow: var(--ts-outline-sm);
  background: linear-gradient(180deg, #ffe066, var(--yellow) 50%, var(--yellow-lo));
  border: 3px solid var(--ink); box-shadow: 0 4px 0 var(--ink-soft);
}
.fx-challenger__main {
  font-size: clamp(34px, 11vw, 54px); line-height: 0.98;
  text-shadow: -3px -3px 0 var(--ink), 3px -3px 0 var(--ink), -3px 3px 0 var(--ink), 3px 3px 0 var(--ink), 0 7px 0 var(--ink);
}
.fx-challenger .fx-cine__dim { background: var(--ink); }
.is-reduced .fx-split--a, .is-reduced .fx-split--b, .is-reduced .fx-challenger__text, .is-reduced .fx-split__seam { animation: fx-fade-in 200ms both; }
.is-reduced .fx-split__seam { transform: rotate(-22deg); }
@keyframes fx-split-a { from { transform: translateX(-100%); } to { transform: none; } }
@keyframes fx-split-b { from { transform: translateX(100%); } to { transform: none; } }
@keyframes fx-seam { to { transform: rotate(-22deg) scaleX(1); } }
@keyframes fx-challenger-text { from { transform: rotate(-10deg) scale(2.4); opacity: 0; } to { transform: rotate(-10deg) scale(1); opacity: 1; } }

/* ---------- GT reward panel ---------- */
.fx-reward {
  position: relative; width: min(340px, 100%); padding: 0 var(--s-4) var(--s-5); margin-top: 22px; border-radius: var(--r-lg);
  display: flex; flex-direction: column; align-items: center; gap: var(--s-3);
  background: var(--grad-panel);
  border: 3px solid var(--ink);
  box-shadow: var(--bevel), var(--shadow-pop);
  animation: fx-panel-in 360ms var(--ease-pop) both;
}
.fx-reward > .fx-ribbon { margin-top: -24px; }
.fx-reward > .fx-ribbon .fx-ribbon__text { font-size: 22px; }
.fx-reward__total { display: flex; align-items: center; justify-content: center; gap: 10px; padding: var(--s-2) 0 0; }
.fx-reward__coin { font-size: 60px; line-height: 0; filter: drop-shadow(0 4px 0 var(--ink-soft)); }
.fx-reward__amount {
  display: inline-block; font-size: var(--fs-3xl); line-height: 1; font-variant-numeric: tabular-nums;
  color: var(--yellow);
  text-shadow: -2.5px -2.5px 0 var(--ink), 2.5px -2.5px 0 var(--ink), -2.5px 2.5px 0 var(--ink), 2.5px 2.5px 0 var(--ink), 0 6px 0 var(--ink);
}
.fx-reward__lines {
  width: 100%; display: flex; flex-direction: column; gap: 2px;
  border-radius: var(--r-md); padding: 6px 4px;
  background: rgba(13, 24, 56, 0.35); border: 2px solid var(--ink); box-shadow: inset 0 3px 0 rgba(0, 0, 0, 0.2);
}
.fx-reward__lines:empty { display: none; }
.fx-reward__line {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--s-2);
  padding: 6px 10px;
  font-weight: 800; color: var(--text); font-size: var(--fs-md); text-align: left;
  animation: fx-line-in 280ms var(--ease-out) both;
}
.fx-reward__line + .fx-reward__line { border-top: 2px solid rgba(13, 24, 56, 0.35); }
.fx-reward__line b {
  font-family: var(--font-display); font-weight: 400; font-size: var(--fs-lg); color: var(--yellow);
  text-shadow: var(--ts-outline-sm); white-space: nowrap;
}
.fx-reward__xp {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 16px 6px 8px; border-radius: var(--r-pill);
  font-size: var(--fs-lg); text-shadow: var(--ts-outline-sm);
  background: linear-gradient(180deg, #d79bff, var(--violet) 50%, #8a3dd1);
  border: 3px solid var(--ink);
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.35), 0 4px 0 var(--ink-soft);
}
.fx-reward__xp .ic { font-size: 28px; }
.is-reduced .fx-reward, .is-reduced .fx-reward__line { animation: fx-fade-in 200ms both; }
@keyframes fx-panel-in { from { transform: scale(0.6) translateY(40px); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes fx-line-in { from { transform: translateX(-30px); opacity: 0; } to { transform: none; opacity: 1; } }

/* ---------- shared keyframes ---------- */
@keyframes fx-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes fx-fade-out { from { opacity: 1; } to { opacity: 0; } }
@keyframes fx-fade-up { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes fx-fade-inout { 0% { opacity: 0; } 20%, 70% { opacity: 1; } 100% { opacity: 0; } }
@keyframes fx-spin { to { transform: rotate(360deg); } }
@keyframes fx-blink { 0%, 100% { opacity: 0.5; } 50% { opacity: 1; } }
@keyframes fx-throb { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.1); } }
@keyframes fx-shadow-bob { 0%, 100%, 55% { transform: scaleX(1); opacity: 1; } 35% { transform: scaleX(0.7); opacity: 0.6; } }

html.reduce-motion .fx-rays, html.reduce-motion .fx-crate__box, html.reduce-motion .fx-crate__shadow,
html.reduce-motion .fx-lootcard__rays, html.reduce-motion .fx-flame__icon, html.reduce-motion .fx-lootcard__inner { animation: none !important; }
@media (prefers-reduced-motion: reduce) {
  .fx-rays, .fx-crate__box, .fx-crate__shadow, .fx-lootcard__rays, .fx-flame__icon, .fx-lootcard__inner { animation: none !important; }
}
