body.duel-playing .card-movement-ghost {
    position: fixed;
    z-index: 9998;
    pointer-events: none;
    will-change: transform, opacity, filter;
}

body.duel-playing .generic-zone-card-ghost.zone-card-miniature {
    display: block;
    padding: 0;
    overflow: hidden;
    border-radius: 7px;
    text-align: initial;
    box-shadow: 0 0 0 2px rgba(251, 191, 36, .7), 0 16px 34px rgba(0, 0, 0, .52);
}

body.duel-playing .zone-card-miniature--hidden {
    display: grid;
    place-items: center;
    background:
        repeating-linear-gradient(135deg, rgba(250, 204, 21, .12) 0 6px, transparent 6px 12px),
        linear-gradient(145deg, #1e293b, #090f1f 58%, #172554);
    border: 2px solid rgba(253, 230, 138, .78);
}

body.duel-playing .zone-card-miniature__back {
    display: grid;
    place-items: center;
    width: 58%;
    aspect-ratio: 1;
    border: 1px solid rgba(254, 240, 138, .68);
    border-radius: 50%;
    color: #fef3c7;
    font-size: 1rem;
    font-weight: 900;
    text-shadow: 0 0 12px rgba(250, 204, 21, .65);
}

body.duel-playing .fx-abyss-vortex {
    position: fixed;
    z-index: 9997;
    display: block;
    border-radius: 50%;
    pointer-events: none;
    background:
        radial-gradient(circle, #000 0 18%, rgba(2, 6, 23, .98) 27%, transparent 31%),
        conic-gradient(from 12deg, rgba(2, 6, 23, .08), rgba(99, 102, 241, .9), rgba(15, 23, 42, .22), rgba(168, 85, 247, .82), rgba(2, 6, 23, .08));
    box-shadow: 0 0 16px rgba(15, 23, 42, .95), 0 0 34px rgba(99, 102, 241, .7), inset 0 0 20px #000;
    animation: fxAbyssVortexOpen .24s ease-out both, fxAbyssVortexSpin .78s linear .24s infinite;
    will-change: transform, opacity, filter;
}

body.duel-playing .fx-abyss-vortex::before,
body.duel-playing .fx-abyss-vortex::after {
    content: "";
    position: absolute;
    border-radius: 50%;
    pointer-events: none;
}

body.duel-playing .fx-abyss-vortex::before {
    inset: 9%;
    border: 2px solid rgba(196, 181, 253, .72);
    border-left-color: transparent;
    border-bottom-color: rgba(129, 140, 248, .22);
}

body.duel-playing .fx-abyss-vortex::after {
    inset: 33%;
    background: #000;
    box-shadow: 0 0 13px 7px rgba(0, 0, 0, .94);
}

body.duel-playing .fx-abyss-vortex.is-closing {
    animation: fxAbyssVortexClose .26s ease-in both;
}

body.duel-playing .card-movement-ghost::before,
body.duel-playing .card-movement-ghost::after {
    content: "";
    position: absolute;
    inset: -3px;
    border-radius: 6px;
    pointer-events: none;
    opacity: 0;
}

body.duel-playing .fx-card-shatter,
body.duel-playing .fx-card-shatter__fragment,
body.duel-playing .fx-ability-clash {
    pointer-events: none;
}

body.duel-playing .fx-card-shatter {
    --fx-shatter-duration: 1.08s;
    overflow: visible;
    background: transparent;
    border: 0;
    box-shadow: none;
}

body.duel-playing .fx-card-shatter::before {
    content: "";
    position: absolute;
    inset: -3px;
    z-index: 8;
    border-radius: 6px;
    background:
        linear-gradient(72deg, transparent 46%, rgba(255, 244, 229, .96) 47% 49%, transparent 50%),
        linear-gradient(112deg, transparent 53%, rgba(248, 113, 113, .92) 54% 56%, transparent 57%);
    filter: drop-shadow(0 0 7px rgba(239, 68, 68, .72));
    animation: fxShatterCracks var(--fx-shatter-duration) ease-out both;
    pointer-events: none;
}

body.duel-playing .fx-card-shatter__fragment {
    position: absolute !important;
    inset: 0 !important;
    width: 100% !important;
    height: 100% !important;
    max-width: none !important;
    margin: 0 !important;
    transform-origin: center;
    animation: fxShatterFragment var(--fx-shatter-duration) cubic-bezier(.2, .78, .28, 1) both !important;
    will-change: transform, opacity, filter;
}

body.duel-playing .fx-card-shatter--destroyed-combat {
    --fx-shatter-duration: 1.28s;
}

body.duel-playing .fx-card-shatter--destroyed-combat .fx-card-shatter__fragment {
    filter: contrast(1.08);
}

body.duel-playing .fx-card-shatter--revived-to-abyss {
    --fx-shatter-duration: 1.16s;
}

body.duel-playing .fx-card-shatter--revived-to-abyss .fx-card-shatter__fragment {
    filter: sepia(.25) brightness(.9);
}

body.duel-playing .fx-card-shatter--revived-to-abyss::before {
    background:
        linear-gradient(72deg, transparent 46%, rgba(254, 240, 138, .98) 47% 49%, transparent 50%),
        linear-gradient(112deg, transparent 53%, rgba(148, 163, 184, .9) 54% 56%, transparent 57%);
    filter: drop-shadow(0 0 8px rgba(250, 204, 21, .68));
}

body.duel-playing .fx-card-shatter--sacrificed .fx-card-shatter__fragment {
    animation: fxSacrificeFragment .76s cubic-bezier(.42, 0, .32, 1) both !important;
}

body.duel-playing .fx-card-shatter--sacrificed::before {
    background:
        linear-gradient(72deg, transparent 46%, rgba(226, 232, 240, .94) 47% 49%, transparent 50%),
        linear-gradient(112deg, transparent 53%, rgba(148, 163, 184, .86) 54% 56%, transparent 57%);
    filter: drop-shadow(0 0 6px rgba(100, 116, 139, .74));
    animation: fxSacrificeCracks .76s ease-out both;
}

body.duel-playing .fx-card-shatter__fragment--1 { --fx-shatter-x: -20px; --fx-shatter-y: -18px; --fx-shatter-r: -8deg; clip-path: polygon(0 0, 58% 0, 48% 35%, 0 30%); }
body.duel-playing .fx-card-shatter__fragment--2 { --fx-shatter-x: 22px; --fx-shatter-y: -20px; --fx-shatter-r: 9deg; clip-path: polygon(58% 0, 100% 0, 100% 34%, 48% 35%); }
body.duel-playing .fx-card-shatter__fragment--3 { --fx-shatter-x: -26px; --fx-shatter-y: 0; --fx-shatter-r: -12deg; clip-path: polygon(0 30%, 48% 35%, 55% 67%, 0 61%); }
body.duel-playing .fx-card-shatter__fragment--4 { --fx-shatter-x: 27px; --fx-shatter-y: 2px; --fx-shatter-r: 11deg; clip-path: polygon(48% 35%, 100% 34%, 100% 66%, 55% 67%); }
body.duel-playing .fx-card-shatter__fragment--5 { --fx-shatter-x: -18px; --fx-shatter-y: 26px; --fx-shatter-r: -9deg; clip-path: polygon(0 61%, 55% 67%, 48% 100%, 0 100%); }
body.duel-playing .fx-card-shatter__fragment--6 { --fx-shatter-x: 21px; --fx-shatter-y: 27px; --fx-shatter-r: 8deg; clip-path: polygon(55% 67%, 100% 66%, 100% 100%, 48% 100%); }

body.duel-playing .fx-card-movement-source {
    animation: fxMovementSourcePulse .54s ease-out both;
}

body.duel-playing .fx-card-movement--to-cemetery,
body.duel-playing .fx-card-movement--discarded {
    animation: fxToCemetery .62s ease-in-out both;
    filter: saturate(.72);
}

body.duel-playing .fx-card-movement--to-abyss,
body.duel-playing .fx-card-movement--revived-to-abyss {
    animation: fxToAbyss .92s cubic-bezier(.42, 0, .76, .34) both;
    box-shadow: 0 0 0 2px rgba(148, 163, 184, .62), 0 0 32px rgba(3, 7, 18, .92);
}

body.duel-playing .fx-card-movement--revived-to-abyss::before {
    opacity: 1;
    inset: 12%;
    border: 2px solid rgba(250, 204, 21, .9);
    border-radius: 50%;
    box-shadow: 0 0 18px rgba(250, 204, 21, .62);
    animation: fxReviveSeal .65s ease-out both;
}

body.duel-playing .fx-card-movement--to-hand,
body.duel-playing .fx-card-movement--to-deck,
body.duel-playing .fx-card-movement--to-limbo,
body.duel-playing .fx-card-movement--generic {
    animation: fxZoneTravel .62s ease-in-out both;
}

body.duel-playing .fx-card-movement--enter-field,
body.duel-playing .fx-card-movement--from-deck,
body.duel-playing .fx-card-movement--revive,
body.duel-playing .fx-card-movement--return-field,
body.duel-playing .fx-card-movement--released {
    animation: fxEnterFieldTravel .46s cubic-bezier(.22, .78, .24, 1) both;
}

body.duel-playing .fx-enter-field {
    animation: fxEnterFieldMaterialize .46s ease-out both;
}

body.duel-playing .fx-enter-field--revive {
    box-shadow: 0 0 0 3px rgba(250, 204, 21, .82), 0 0 32px rgba(234, 179, 8, .48), 0 18px 44px rgba(0, 0, 0, .48) !important;
}

body.duel-playing .fx-enter-field--return {
    box-shadow: 0 0 0 3px rgba(56, 189, 248, .78), 0 0 30px rgba(14, 165, 233, .42), 0 18px 44px rgba(0, 0, 0, .48) !important;
}

body.duel-playing .fx-enter-field--released {
    animation-name: fxReleasedMaterialize;
    box-shadow: 0 0 0 3px rgba(52, 211, 153, .86), 0 0 34px rgba(16, 185, 129, .48), 0 18px 44px rgba(0, 0, 0, .48) !important;
}

body.duel-playing .fx-card-movement-destination {
    animation: fxMovementDestinationPulse .22s ease-out both;
}

body.duel-playing .card-captured-ghost {
    animation-duration: .62s;
    filter: saturate(.78) brightness(.92);
}

body.duel-playing .card-captor-impact {
    animation-duration: .5s;
}

body.duel-playing .fx-ability-clash {
    z-index: 9998;
    animation-duration: .58s !important;
    animation-fill-mode: both !important;
}

body.duel-playing .fx-ability-clash--source {
    animation-name: fxAbilityClashSource !important;
    animation-timing-function: cubic-bezier(.2, .82, .25, 1) !important;
}

body.duel-playing .fx-ability-clash--target {
    animation-name: fxAbilityClashTarget !important;
    animation-timing-function: ease-out !important;
}

body.duel-playing .fx-ability-clash--source.fx-ability-clash--target-wins {
    animation-name: fxAbilityClashSourceLoses !important;
}

body.duel-playing .fx-ability-clash--source.fx-ability-clash--tie {
    animation-name: fxAbilityClashSourceTie !important;
}

body.duel-playing .fx-ability-clash--target.fx-ability-clash--source-wins {
    animation-name: fxAbilityClashTargetLoses !important;
}

body.duel-playing .fx-ability-clash--target.fx-ability-clash--tie {
    animation-name: fxAbilityClashTargetTie !important;
}

@keyframes fxShatterFragment {
    0%, 24% { transform: translate(0, 0) rotate(0) scale(1); opacity: 1; filter: brightness(1); }
    34% { transform: translate(0, 0) rotate(0) scale(1.035); opacity: 1; filter: brightness(1.5) saturate(.7); }
    48% { transform: translate(calc(var(--fx-shatter-x) * .18), calc(var(--fx-shatter-y) * .18)) rotate(calc(var(--fx-shatter-r) * .18)) scale(.98); opacity: .94; filter: brightness(.72) saturate(.48); }
    72% { transform: translate(calc(var(--card-zone-move-mid-x, 0px) + var(--fx-shatter-x)), calc(var(--card-zone-move-mid-y, 0px) + var(--fx-shatter-y))) rotate(var(--fx-shatter-r)) scale(.72); opacity: .7; filter: brightness(.48) saturate(.34); }
    100% { transform: translate(calc(var(--card-zone-move-x, 0px) + var(--fx-shatter-x)), calc(var(--card-zone-move-y, 0px) + var(--fx-shatter-y))) rotate(calc(var(--fx-shatter-r) * 1.6)) scale(.34); opacity: 0; filter: brightness(.2) saturate(.16); }
}

@keyframes fxShatterCracks {
    0%, 23% { transform: scale(.72); opacity: 0; }
    34%, 52% { transform: scale(1.02); opacity: 1; }
    100% { transform: scale(1.16); opacity: 0; }
}

@keyframes fxSacrificeFragment {
    0% { transform: translate(0, 0) rotate(0) scale(1); opacity: 1; filter: grayscale(0) brightness(1); }
    30% { transform: translate(0, 0) rotate(0) scale(1); opacity: 1; filter: grayscale(1) brightness(.9); }
    48% { transform: translate(0, 0) rotate(0) scale(1); opacity: 1; filter: grayscale(1) brightness(.78); }
    62% { transform: translate(calc(var(--fx-shatter-x) * .12), calc(var(--fx-shatter-y) * .12)) rotate(calc(var(--fx-shatter-r) * .12)) scale(.98); opacity: .92; filter: grayscale(1) brightness(.65); }
    78% { transform: translate(calc(var(--card-zone-move-mid-x, 0px) + var(--fx-shatter-x)), calc(var(--card-zone-move-mid-y, 0px) + var(--fx-shatter-y))) rotate(var(--fx-shatter-r)) scale(.68); opacity: .66; filter: grayscale(1) brightness(.48); }
    100% { transform: translate(calc(var(--card-zone-move-x, 0px) + var(--fx-shatter-x)), calc(var(--card-zone-move-y, 0px) + var(--fx-shatter-y))) rotate(calc(var(--fx-shatter-r) * 1.45)) scale(.32); opacity: 0; filter: grayscale(1) brightness(.22); }
}

@keyframes fxSacrificeCracks {
    0%, 48% { transform: scale(.84); opacity: 0; }
    58%, 70% { transform: scale(1.02); opacity: .9; }
    100% { transform: scale(1.14); opacity: 0; }
}

@keyframes fxAbilityClashSource {
    0% { transform: translate(0, 0) scale(1); filter: brightness(1); }
    52% { transform: translate(var(--ability-clash-x), var(--ability-clash-y)) scale(1.055); filter: brightness(1.42); }
    68% { transform: translate(calc(var(--ability-clash-x) * .88), calc(var(--ability-clash-y) * .88)) scale(1.02); filter: brightness(1.18); }
    100% { transform: translate(0, 0) scale(1); filter: brightness(1); }
}

@keyframes fxAbilityClashSourceLoses {
    0% { transform: translate(0, 0) scale(1); filter: brightness(1); }
    52% { transform: translate(var(--ability-clash-x), var(--ability-clash-y)) scale(1.055); filter: brightness(1.42); }
    72% { transform: translate(calc(var(--ability-clash-x) * .72 - 7px), calc(var(--ability-clash-y) * .72 + 3px)) rotate(-2deg) scale(.94); filter: brightness(.72); }
    100% { transform: translate(0, 0) scale(.98); filter: brightness(.86); }
}

@keyframes fxAbilityClashSourceTie {
    0% { transform: translate(0, 0) scale(1); filter: brightness(1); }
    52% { transform: translate(var(--ability-clash-x), var(--ability-clash-y)) scale(1.055); filter: brightness(1.42); }
    66% { transform: translate(calc(var(--ability-clash-x) * .84 - 4px), calc(var(--ability-clash-y) * .84 + 2px)) rotate(-1.5deg); }
    78% { transform: translate(calc(var(--ability-clash-x) * .86 + 4px), calc(var(--ability-clash-y) * .86 - 2px)) rotate(1.5deg); }
    100% { transform: translate(0, 0) scale(.98); filter: brightness(.88); }
}

@keyframes fxAbilityClashTarget {
    0%, 45% { transform: translate(0, 0) scale(1); filter: brightness(1); }
    58% { transform: translate(2px, -1px) scale(1.025); filter: brightness(1.3); }
    100% { transform: translate(0, 0) scale(1); filter: brightness(1); }
}

@keyframes fxAbilityClashTargetLoses {
    0%, 45% { transform: translate(0, 0) scale(1); filter: brightness(1); }
    58% { transform: translate(7px, -2px) rotate(1.5deg) scale(.96); filter: brightness(1.55) saturate(.72); }
    72% { transform: translate(-5px, 2px) rotate(-1deg) scale(.98); filter: brightness(.72); }
    100% { transform: translate(0, 0) scale(.98); filter: brightness(.88); }
}

@keyframes fxAbilityClashTargetTie {
    0%, 45% { transform: translate(0, 0) scale(1); filter: brightness(1); }
    58% { transform: translate(5px, -2px) rotate(1deg) scale(.97); filter: brightness(1.45) saturate(.78); }
    70% { transform: translate(-4px, 2px) rotate(-1deg); }
    82% { transform: translate(3px, -1px) rotate(.7deg); }
    100% { transform: translate(0, 0) scale(.98); filter: brightness(.88); }
}

@keyframes fxMovementSourcePulse {
    0%, 100% { filter: brightness(1); }
    35% { filter: brightness(1.35); box-shadow: 0 0 0 3px rgba(45, 212, 191, .8), 0 0 28px rgba(14, 116, 144, .46); }
}

@keyframes fxToCemetery {
    0% { transform: translate(0, 0) rotate(var(--card-zone-stack-r, 0deg)) scale(1); opacity: 1; filter: saturate(1); }
    100% { transform: translate(var(--card-zone-move-x, 0), var(--card-zone-move-y, 42px)) rotate(0deg) scale(.72); opacity: 0; filter: saturate(0); }
}

@keyframes fxToAbyss {
    0% { transform: translate(0, 0) rotate(var(--card-zone-stack-r, 0deg)) scale(1); opacity: 1; filter: brightness(1); }
    48% { opacity: .9; filter: brightness(.78) saturate(.75); }
    78% { opacity: .62; filter: brightness(.42) saturate(.45) blur(.5px); }
    100% { transform: translate(var(--card-zone-move-x, 0), var(--card-zone-move-y, 24px)) rotate(34deg) scale(.03); opacity: 0; filter: brightness(.08) blur(3px); }
}

@keyframes fxReviveSeal {
    0% { transform: rotate(0) scale(.65); opacity: 0; }
    30% { opacity: 1; }
    100% { transform: rotate(90deg) scale(1.18); opacity: 0; }
}

@keyframes fxZoneTravel {
    0% { transform: translate(0, 0) rotate(var(--card-zone-stack-r, 0deg)) scale(.9); opacity: .96; }
    62% { opacity: 1; }
    100% { transform: translate(var(--card-zone-move-x, 0), var(--card-zone-move-y, 0)) rotate(0deg) scale(.68); opacity: 0; }
}

@keyframes fxAbyssVortexOpen {
    0% { opacity: 0; transform: scale(.28); filter: blur(5px); }
    100% { opacity: 1; transform: scale(1); filter: blur(0); }
}

@keyframes fxAbyssVortexSpin {
    to { transform: rotate(360deg); }
}

@keyframes fxAbyssVortexClose {
    0% { opacity: 1; transform: rotate(0) scale(1); }
    100% { opacity: 0; transform: rotate(80deg) scale(.16); filter: blur(4px); }
}

@keyframes fxEnterFieldTravel {
    0% { transform: translate(0, 0) scale(.72); opacity: .2; filter: brightness(.75); }
    70% { opacity: .86; }
    100% { transform: translate(var(--card-zone-move-x, 0), var(--card-zone-move-y, 0)) scale(.94); opacity: 0; filter: brightness(1.3); }
}

@keyframes fxEnterFieldMaterialize {
    0% { opacity: .25; filter: brightness(1.7) saturate(.6); }
    45% { opacity: 1; filter: brightness(1.35) saturate(1.08); }
    100% { opacity: 1; filter: brightness(1) saturate(1); }
}

@keyframes fxReleasedMaterialize {
    0% { opacity: .2; filter: brightness(1.7) saturate(.65); }
    38% { opacity: 1; filter: brightness(1.42) saturate(1.12); }
    100% { opacity: 1; filter: brightness(1) saturate(1); }
}

@keyframes fxMovementDestinationPulse {
    0% { filter: brightness(1); }
    45% { filter: brightness(1.32); }
    100% { filter: brightness(1); }
}

body.duel-playing .fx-heavy-entry-impact {
    transform-origin: center bottom;
    animation: fxHeavyEntryImpact .72s cubic-bezier(.18, .84, .24, 1) both !important;
    will-change: transform, filter, box-shadow;
}

body.duel-playing .fx-heavy-entry-bounce {
    transform-origin: center bottom;
    animation: fxHeavyFieldBounce .64s cubic-bezier(.2, .78, .24, 1) var(--fx-heavy-entry-delay, 0ms) both !important;
    will-change: transform, filter;
}

@keyframes fxHeavyEntryImpact {
    0% { transform: translateY(-9px) scale(1.055); filter: brightness(1.34); }
    24% { transform: translateY(4px) scale(.975); filter: brightness(1.62); box-shadow: 0 0 0 3px rgba(250, 204, 21, .72), 0 18px 38px rgba(0, 0, 0, .48); }
    48% { transform: translateY(-3px) scale(1.018); filter: brightness(1.18); }
    70% { transform: translateY(1px) scale(.995); filter: brightness(1.06); }
    100% { transform: translateY(0) scale(1); filter: brightness(1); }
}

@keyframes fxHeavyFieldBounce {
    0%, 12% { transform: translate(0, 0) rotate(0) scale(1); filter: brightness(1); }
    34% { transform: translate(var(--fx-heavy-entry-x, 0), var(--fx-heavy-entry-y, -9px)) rotate(var(--fx-heavy-entry-r, 0deg)) scale(1.018); filter: brightness(1.14); }
    55% { transform: translate(0, 3px) rotate(0) scale(.992); filter: brightness(.96); }
    73% { transform: translate(0, -3px) rotate(0) scale(1.006); filter: brightness(1.04); }
    100% { transform: translate(0, 0) rotate(0) scale(1); filter: brightness(1); }
}

@media (prefers-reduced-motion: reduce) {
    body.duel-playing .card-movement-ghost,
    body.duel-playing .card-movement-ghost::before,
    body.duel-playing .card-movement-ghost::after,
    body.duel-playing .fx-card-movement-source,
    body.duel-playing .fx-card-movement-destination,
    body.duel-playing .fx-enter-field,
    body.duel-playing .fx-heavy-entry-impact,
    body.duel-playing .fx-heavy-entry-bounce,
    body.duel-playing .fx-abyss-vortex,
    body.duel-playing .card-captured-ghost,
    body.duel-playing .card-captor-impact,
    body.duel-playing .fx-ability-clash {
        animation: fxMovementReduced .1s ease-out both !important;
    }

    body.duel-playing .fx-card-shatter__fragment,
    body.duel-playing .fx-card-shatter::before {
        animation: fxShatterReduced .12s ease-out both !important;
    }
}

@keyframes fxMovementReduced {
    0% { opacity: .62; filter: brightness(1.25); }
    100% { opacity: 1; filter: brightness(1); }
}

@keyframes fxShatterReduced {
    0% { opacity: .8; filter: grayscale(.35) brightness(1.2); }
    100% { opacity: 0; filter: grayscale(1) brightness(.72); }
}
