/* P2.5 — camada 2/5 do antigo rebirth.css (partição sequencial;
   a ordem de carga preserva a cascata por construção).
   Conteúdo: v55 fases 1-4: foundation visual, combat juice, living world, grimório/bazaar, signature identity. */

/* =========================================================================
   v55 — Foundation Visual: Dark Fantasy Tático Premium / Arcane Industrial
   ========================================================================= */

:root {
    --rb-iron-dark: #1a1612;
    --rb-iron-mid: #2c2620;
    --rb-iron-edge: #4a3f33;
    --rb-iron-rim-light: rgba(255, 255, 255, 0.14);
    --rb-iron-rim-dark: rgba(0, 0, 0, 0.7);
    --rb-gold-aged: #c89a3a;
    --rb-gold-aged-deep: #8a5e1c;
    --rb-gold-aged-shadow: #4c2f0c;
    --rb-arcane-blue: rgba(95, 175, 235, 0.85);
    --rb-arcane-blue-deep: rgba(45, 95, 170, 0.6);
    --rb-profane-red: rgba(225, 80, 70, 0.85);
    --rb-profane-red-deep: rgba(140, 30, 25, 0.6);
}

/* --- 1. MEDALHÃO 3D — #next-turn-button ---------------------------------
   Disco de ferro fundido pesado. Inclina suavemente seguindo o cursor
   (JS atualiza --rb-tilt-x / --rb-tilt-y). Quando o jogador entra em
   dead-end (renderer aplica .is-cta-pulse), o medalhão gira 180° em Y
   revelando o lado dourado envelhecido e ativa o glow arcano.
   ------------------------------------------------------------------------ */

#next-turn-button.rb-button-secondary,
#play-button.rb-button-primary {
    position: relative;
    min-width: 180px;
    height: 64px;
    padding: 0 28px;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: #f4e8d2;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    cursor: pointer;
    overflow: visible;
    transform-style: preserve-3d;
    perspective: 900px;
    transition: transform 220ms cubic-bezier(0.2, 0.7, 0.2, 1);
    z-index: 0;
}

#next-turn-button.rb-button-secondary > *,
#play-button.rb-button-primary > * {
    /* o conteúdo precisa sair do plano dos pseudo-elementos */
    position: relative;
    z-index: 2;
    transform: translateZ(8px);
}

#next-turn-button.rb-button-secondary::before,
#play-button.rb-button-primary::before {
    /* face frontal: ferro fundido escuro com runas sutis e luz superior */
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background:
        radial-gradient(circle at 32% 22%, rgba(255, 240, 210, 0.22), transparent 38%),
        radial-gradient(circle at 70% 80%, rgba(0, 0, 0, 0.55), transparent 55%),
        linear-gradient(140deg, var(--rb-iron-mid) 0%, var(--rb-iron-dark) 55%, #0a0806 100%);
    box-shadow:
        inset 0 2px 2px var(--rb-iron-rim-light),
        inset 0 -3px 6px var(--rb-iron-rim-dark),
        inset 0 0 0 1.5px rgba(70, 58, 46, 0.85),
        0 8px 18px rgba(0, 0, 0, 0.55),
        0 2px 4px rgba(0, 0, 0, 0.5);
    backface-visibility: hidden;
    transition: box-shadow 220ms ease;
}

#next-turn-button.rb-button-secondary::after,
#play-button.rb-button-primary::after {
    /* face traseira: ouro envelhecido — só aparece com o flip */
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background:
        radial-gradient(circle at 32% 22%, rgba(255, 245, 200, 0.42), transparent 45%),
        radial-gradient(circle at 65% 78%, rgba(70, 35, 10, 0.55), transparent 60%),
        linear-gradient(135deg, var(--rb-gold-aged) 0%, var(--rb-gold-aged-deep) 55%, var(--rb-gold-aged-shadow) 100%);
    box-shadow:
        inset 0 2px 2px rgba(255, 245, 210, 0.4),
        inset 0 -3px 6px rgba(40, 22, 6, 0.65),
        inset 0 0 0 1.5px rgba(180, 130, 50, 0.95),
        0 0 22px rgba(244, 200, 90, 0.55),
        0 10px 22px rgba(0, 0, 0, 0.55);
    transform: rotateY(180deg);
    backface-visibility: hidden;
    opacity: 0.95;
}

/* Inclinação 3D seguindo o mouse — JS popula --rb-tilt-x/--rb-tilt-y. */
#next-turn-button.rb-button-secondary,
#play-button.rb-button-primary {
    transform:
        perspective(800px)
        rotateX(var(--rb-tilt-x, 0deg))
        rotateY(calc(var(--rb-tilt-y, 0deg) + var(--rb-flip, 0deg)));
}

#next-turn-button.rb-button-secondary:hover:not(:disabled),
#play-button.rb-button-primary:hover:not(:disabled) {
    transform:
        perspective(800px)
        rotateX(var(--rb-tilt-x, 0deg))
        rotateY(calc(var(--rb-tilt-y, 0deg) + var(--rb-flip, 0deg)))
        translateZ(4px);
}

#next-turn-button.rb-button-secondary:active:not(:disabled),
#play-button.rb-button-primary:active:not(:disabled) {
    transform:
        perspective(800px)
        rotateX(calc(var(--rb-tilt-x, 0deg) * 0.4))
        rotateY(calc(var(--rb-tilt-y, 0deg) * 0.4 + var(--rb-flip, 0deg)))
        translateZ(-2px);
}

/* DEAD-END: flip + pulso arcano contínuo. Sobrescreve o keyframe
   rb-cta-pulse (legado v54) por algo mais alto-contraste. */
#next-turn-button.is-cta-pulse:not(:disabled) {
    --rb-flip: 180deg;
    animation: rb-arcane-medallion-pulse 1.8s ease-in-out infinite;
}

#next-turn-button.is-cta-pulse:not(:disabled)::after {
    animation: rb-arcane-glow 1.8s ease-in-out infinite;
}

@keyframes rb-arcane-medallion-pulse {
    0%, 100% {
        transform:
            perspective(800px)
            rotateX(var(--rb-tilt-x, 0deg))
            rotateY(calc(var(--rb-tilt-y, 0deg) + 180deg))
            translateZ(0);
    }
    50% {
        transform:
            perspective(800px)
            rotateX(var(--rb-tilt-x, 0deg))
            rotateY(calc(var(--rb-tilt-y, 0deg) + 180deg))
            translateZ(6px);
    }
}

@keyframes rb-arcane-glow {
    0%, 100% {
        box-shadow:
            inset 0 2px 2px rgba(255, 245, 210, 0.4),
            inset 0 -3px 6px rgba(40, 22, 6, 0.65),
            inset 0 0 0 1.5px rgba(180, 130, 50, 0.95),
            0 0 18px rgba(244, 200, 90, 0.5),
            0 10px 22px rgba(0, 0, 0, 0.55);
    }
    50% {
        box-shadow:
            inset 0 2px 2px rgba(255, 245, 210, 0.5),
            inset 0 -3px 6px rgba(40, 22, 6, 0.65),
            inset 0 0 0 1.5px rgba(220, 160, 60, 1),
            0 0 38px 8px rgba(244, 200, 90, 0.85),
            0 0 60px rgba(180, 110, 30, 0.45),
            0 10px 22px rgba(0, 0, 0, 0.55);
    }
}

#next-turn-button.rb-button-secondary:disabled,
#play-button.rb-button-primary:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

/* --- 2. CARTAS COMO ENTIDADES VIVAS -------------------------------------
   Sombras volumétricas profundas; frame metálico varia por raridade.
   Hover: elevação, escala, sombra projetada expandida, vizinhos desfocam
   via :has() (CSS puro, sem JS extra).
   ------------------------------------------------------------------------ */

.rb-hand .rb-mini-card.rb-tcg-card {
    transform-origin: center bottom;
    transition:
        transform 260ms cubic-bezier(0.2, 0.7, 0.2, 1),
        box-shadow 260ms ease,
        opacity 240ms ease;
    box-shadow:
        0 2px 4px rgba(0, 0, 0, 0.5),
        0 8px 16px rgba(0, 0, 0, 0.5),
        0 16px 28px rgba(0, 0, 0, 0.35),
        inset 0 1px 0 rgba(255, 255, 255, 0.08),
        inset 0 -1px 0 rgba(0, 0, 0, 0.4);
    position: relative;
}

.rb-hand .rb-mini-card.rb-tcg-card.is-rarity-common {
    border: 2px solid transparent;
    border-image: linear-gradient(140deg, #6a5848 0%, #3a3128 50%, #1f1a14 100%) 1;
}

.rb-hand .rb-mini-card.rb-tcg-card.is-rarity-uncommon {
    border: 2px solid transparent;
    border-image: linear-gradient(140deg, #9bb4c8 0%, #4e6878 50%, #243240 100%) 1;
    box-shadow:
        0 2px 4px rgba(0, 0, 0, 0.5),
        0 8px 18px rgba(80, 140, 210, 0.25),
        0 16px 30px rgba(0, 0, 0, 0.4),
        inset 0 1px 0 rgba(180, 220, 245, 0.2),
        inset 0 -1px 0 rgba(0, 0, 0, 0.4);
}

.rb-hand .rb-mini-card.rb-tcg-card:hover:not(:disabled):not(.is-locked),
.rb-hand .rb-mini-card.rb-tcg-card:focus-visible:not(:disabled):not(.is-locked) {
    transform: translateY(-20px) scale(1.08);
    box-shadow:
        0 10px 18px rgba(0, 0, 0, 0.6),
        0 26px 44px rgba(0, 0, 0, 0.65),
        0 40px 64px rgba(244, 180, 80, 0.2),
        inset 0 1px 0 rgba(255, 255, 255, 0.16),
        inset 0 -1px 0 rgba(0, 0, 0, 0.4);
    z-index: 5;
}

/* Vizinhos perdem foco durante o hover — opacidade + scale down. Optamos
   por não usar blur via CSS filter (perf-budget do projeto bane esses
   tokens em tests/rebirth/test_rebirth_frontend_contract.py). O efeito
   cinemático fica via foco-vs-recesso: a carta hover fica protagonista,
   as outras recuam levemente. Pure CSS via :has() — browsers sem :has()
   simplesmente não aplicam a regra, sem regressão. */
#player-hand:has(.rb-mini-card.rb-tcg-card:hover:not(:disabled):not(.is-locked)) .rb-mini-card.rb-tcg-card:not(:hover),
#player-hand:has(.rb-mini-card.rb-tcg-card:focus-visible:not(:disabled):not(.is-locked)) .rb-mini-card.rb-tcg-card:not(:focus-visible) {
    opacity: 0.45;
    transform: scale(0.94) translateY(2px);
}

/* Brasão metálico esculpido nas estatísticas (ATK / GRD). Aplica em
   cards de hand E de campo. Usa clip-path em forma de escudo. */
.rb-card-stat.is-atk,
.rb-card-stat.is-grd {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 30px;
    height: 30px;
    padding: 0 8px;
    background:
        radial-gradient(circle at 30% 25%, rgba(255, 255, 255, 0.18), transparent 50%),
        linear-gradient(140deg, var(--rb-iron-edge) 0%, var(--rb-iron-mid) 60%, var(--rb-iron-dark) 100%);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.18),
        inset 0 -1px 1px rgba(0, 0, 0, 0.55),
        0 2px 3px rgba(0, 0, 0, 0.5);
    clip-path: polygon(0 0, 100% 0, 100% 75%, 50% 100%, 0 75%);
    color: #f6e5c4;
    font-weight: 900;
    text-shadow: 0 1px 1px rgba(0, 0, 0, 0.7);
}

.rb-card-stat.is-atk {
    background:
        radial-gradient(circle at 30% 25%, rgba(255, 220, 180, 0.28), transparent 50%),
        linear-gradient(140deg, #5a3a26 0%, #38211a 60%, #1f120c 100%);
}

.rb-card-stat.is-grd {
    background:
        radial-gradient(circle at 30% 25%, rgba(200, 220, 240, 0.28), transparent 50%),
        linear-gradient(140deg, #3a4858 0%, #1f2a36 60%, #0f1820 100%);
}

/* --- 3. SLOTS COMO ALTARES DE PEDRA --------------------------------------
   Slots vazios afundados na mesa (inset shadow agressivo). Runa circular
   central inerte por padrão; acende em azul espectral pro jogador, em
   vermelho profano pro alvo do bot quando o slot vira target válido.
   ------------------------------------------------------------------------ */

.rb-field-slots .rb-field-slot-empty {
    position: relative;
    overflow: hidden;
    border: 1px solid rgba(60, 50, 40, 0.6);
    background:
        radial-gradient(ellipse at 50% 50%, rgba(0, 0, 0, 0.55) 0%, rgba(0, 0, 0, 0.2) 60%, transparent 100%),
        linear-gradient(180deg, #16120e 0%, #0a0806 100%);
    box-shadow:
        inset 0 6px 14px rgba(0, 0, 0, 0.85),
        inset 0 -3px 6px rgba(0, 0, 0, 0.6),
        inset 0 0 0 1px rgba(80, 65, 50, 0.35),
        0 1px 0 rgba(255, 255, 255, 0.04);
    transition: box-shadow 280ms ease, background 280ms ease;
}

.rb-field-slots .rb-field-slot-empty::before {
    /* Runa circular central — inerte por padrão */
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 78px;
    height: 78px;
    border-radius: 50%;
    transform: translate(-50%, -50%);
    background:
        radial-gradient(circle, transparent 30%, rgba(180, 150, 90, 0.18) 38%, rgba(180, 150, 90, 0.04) 55%, transparent 70%);
    opacity: 0.5;
    transition: opacity 360ms ease, background 360ms ease, transform 360ms ease;
    pointer-events: none;
}

.rb-field-slots .rb-field-slot-empty::after {
    /* halo externo que cresce quando a runa é ativada */
    content: '';
    position: absolute;
    inset: 4px;
    border-radius: inherit;
    box-shadow: inset 0 0 0 0 transparent;
    transition: box-shadow 360ms ease;
    pointer-events: none;
}

/* K10 (DoC re-color): runa DOURADA quando o slot é target de invocação.
   Antes era azul espectral (cyberpunk). Agora bronze envelhecido
   alinhado à paleta Duel of Champions. */
#player-battlefield .rb-field-slot-empty.is-summon-target {
    border-color: rgba(232, 212, 164, 0.62);
    background:
        radial-gradient(ellipse at 50% 50%, rgba(196, 160, 80, 0.28) 0%, rgba(120, 84, 30, 0.12) 60%, transparent 100%),
        linear-gradient(180deg, #28190c 0%, #0c0805 100%);
    box-shadow:
        inset 0 6px 14px rgba(0, 0, 0, 0.85),
        inset 0 -3px 6px rgba(0, 0, 0, 0.6),
        inset 0 0 22px rgba(196, 160, 80, 0.32),
        0 0 16px rgba(196, 160, 80, 0.24);
}

#player-battlefield .rb-field-slot-empty.is-summon-target::before {
    /* Mantém o L-bracket ornamental — vai ser amarelo dourado. */
    border-color: var(--rb-gold-2);
}

#player-battlefield .rb-field-slot-empty.is-summon-target::after {
    border-color: var(--rb-gold-2);
}

/* Bot: runa vermelha profana quando o slot é alvo de ataque direto OU
   quando o jogador está em modo "escolher alvo" e o slot do bot está
   destacado. */
#bot-battlefield .rb-field-slot-empty[data-direct-attack="true"],
.rb-game-board.is-choosing-attack #bot-battlefield .rb-field-slot-empty {
    border-color: rgba(225, 80, 70, 0.55);
    background:
        radial-gradient(ellipse at 50% 50%, rgba(140, 30, 25, 0.28) 0%, rgba(70, 15, 12, 0.12) 60%, transparent 100%),
        linear-gradient(180deg, #16120e 0%, #0a0806 100%);
    box-shadow:
        inset 0 6px 14px rgba(0, 0, 0, 0.85),
        inset 0 -3px 6px rgba(0, 0, 0, 0.6),
        inset 0 0 22px rgba(225, 80, 70, 0.32),
        0 0 12px rgba(225, 80, 70, 0.2);
    color: rgba(255, 220, 215, 0.92);
}

#bot-battlefield .rb-field-slot-empty[data-direct-attack="true"]::before,
.rb-game-board.is-choosing-attack #bot-battlefield .rb-field-slot-empty::before {
    opacity: 1;
    background:
        radial-gradient(circle, transparent 28%, var(--rb-profane-red) 36%, var(--rb-profane-red-deep) 55%, transparent 72%);
    animation: rb-altar-rune-red 1.8s ease-in-out infinite;
}

#bot-battlefield .rb-field-slot-empty[data-direct-attack="true"]::after,
.rb-game-board.is-choosing-attack #bot-battlefield .rb-field-slot-empty::after {
    box-shadow: inset 0 0 0 2px rgba(225, 80, 70, 0.55);
}

@keyframes rb-altar-rune-blue {
    0%, 100% {
        opacity: 0.65;
        transform: translate(-50%, -50%) scale(0.92);
    }
    50% {
        opacity: 1;
        transform: translate(-50%, -50%) scale(1.06);
    }
}

@keyframes rb-altar-rune-red {
    0%, 100% {
        opacity: 0.65;
        transform: translate(-50%, -50%) scale(0.92);
    }
    50% {
        opacity: 1;
        transform: translate(-50%, -50%) scale(1.08);
    }
}

/* --- 4. COMBAT IMPACT — spark burst no atacante + hit flash no defensor -
   Aproveita o pipeline existente em RebirthCombatMotion.play():
     attacker → .is-attack-primed → .is-attack-lunging → defender
     ganha .is-taking-hit.
   O lunging existente só fazia translate3d + glow dourado. Adicionamos:
     • spark burst (raios saindo do centro do atacante) via ::after
     • flash branco visceral no defensor — anima alpha intensa que
       evapora; sente-se o impacto sem precisar de partículas pesadas.
   Todas as animações usam transform/opacity (compositing-friendly),
   nada de CSS filter (perf-budget do projeto bane esses tokens).
   ------------------------------------------------------------------------ */

.rb-field-card.is-attack-lunging {
    /* relativa porque vai abrigar pseudo-element do spark */
    position: relative;
}

.rb-field-card.is-attack-lunging::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 140px;
    height: 140px;
    border-radius: 50%;
    pointer-events: none;
    transform: translate(-50%, -50%) scale(0.2);
    background:
        radial-gradient(circle, rgba(255, 245, 200, 0.95) 0%, rgba(255, 200, 90, 0.5) 22%, rgba(255, 120, 40, 0.2) 40%, transparent 65%),
        conic-gradient(from 0deg,
            rgba(255, 245, 200, 0.85) 0deg, transparent 18deg,
            rgba(255, 245, 200, 0.85) 60deg, transparent 78deg,
            rgba(255, 245, 200, 0.85) 120deg, transparent 138deg,
            rgba(255, 245, 200, 0.85) 180deg, transparent 198deg,
            rgba(255, 245, 200, 0.85) 240deg, transparent 258deg,
            rgba(255, 245, 200, 0.85) 300deg, transparent 318deg,
            rgba(255, 245, 200, 0.85) 360deg);
    opacity: 0;
    z-index: 6;
    animation: rb-spark-burst 360ms cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
}

@keyframes rb-spark-burst {
    0% {
        transform: translate(-50%, -50%) scale(0.2) rotate(0deg);
        opacity: 0;
    }
    20% {
        transform: translate(-50%, -50%) scale(0.6) rotate(40deg);
        opacity: 1;
    }
    55% {
        transform: translate(-50%, -50%) scale(1.05) rotate(110deg);
        opacity: 0.85;
    }
    100% {
        transform: translate(-50%, -50%) scale(1.55) rotate(160deg);
        opacity: 0;
    }
}

/* Hit flash visceral: o keyframe rb-target-hit existente faz o shake.
   Sobrepomos um pseudo-element ::before que pisca branco intenso e some.
   Garante position: relative no host. */
.rb-field-card.is-taking-hit,
.rb-bot-card.is-taking-hit {
    position: relative;
}

.rb-field-card.is-taking-hit::before,
.rb-bot-card.is-taking-hit::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    background:
        radial-gradient(circle at 50% 50%, rgba(255, 255, 255, 0.95) 0%, rgba(255, 220, 150, 0.55) 38%, transparent 72%);
    mix-blend-mode: screen;
    opacity: 0;
    z-index: 6;
    animation: rb-hit-flash 260ms ease-out forwards;
}

@keyframes rb-hit-flash {
    0% {
        opacity: 0;
        transform: scale(0.7);
    }
    25% {
        opacity: 1;
        transform: scale(1.05);
    }
    100% {
        opacity: 0;
        transform: scale(1.18);
    }
}

/* =========================================================================
   v55 FASE 2 — Combat Juice: hit pause, screen shake contextual, shield
   shatter, death dissolve em brasa. O JS injeta as classes/elementos no
   pipeline RebirthCombatMotion.play(); o CSS define a aparência.
   ========================================================================= */

/* --- SCREEN SHAKE contextual (.vfx-screen-shake / .vfx-screen-shake-heavy)
   Aplicado no .rb-game-viewport pelo triggerScreenShake().
   • normal (3px só horizontal): para dano leve em HP
   • heavy (5px X+Y): para trade mútuo (clash) e dano pesado
   Removido do DOM após 160-180ms.
   ------------------------------------------------------------------------ */

@keyframes rb-vfx-shake-normal {
    0%, 100% { transform: translate3d(0, 0, 0); }
    18% { transform: translate3d(-3px, 0, 0); }
    36% { transform: translate3d(3px, 0, 0); }
    54% { transform: translate3d(-2px, 0, 0); }
    72% { transform: translate3d(2px, 0, 0); }
    88% { transform: translate3d(-1px, 0, 0); }
}

@keyframes rb-vfx-shake-heavy {
    0%, 100% { transform: translate3d(0, 0, 0); }
    12% { transform: translate3d(-5px, 3px, 0); }
    24% { transform: translate3d(5px, -3px, 0); }
    36% { transform: translate3d(-5px, -3px, 0); }
    48% { transform: translate3d(5px, 3px, 0); }
    60% { transform: translate3d(-3px, 5px, 0); }
    72% { transform: translate3d(3px, -2px, 0); }
    86% { transform: translate3d(-2px, 1px, 0); }
}

.vfx-screen-shake {
    animation: rb-vfx-shake-normal 160ms ease-in-out both;
    will-change: transform;
}

.vfx-screen-shake.vfx-screen-shake-heavy {
    animation: rb-vfx-shake-heavy 180ms cubic-bezier(0.4, 0, 0.6, 1) both;
}

/* --- SHIELD SHATTER (.vfx-shield-shatter)
   Container spawned pelo JS dentro do node do alvo quando perde guard
   mas sobrevive. 6 fragmentos geométricos (b.vfx-shield-shatter__shard)
   explodem do centro pra fora em ângulos uniformes, com fade-out.
   ------------------------------------------------------------------------ */

.vfx-shield-shatter {
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 7;
    /* container só pra alinhar; toda animação fica nos shards */
}

.vfx-shield-shatter__shard {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 14px;
    height: 22px;
    margin: -11px 0 0 -7px;
    background:
        linear-gradient(140deg, rgba(180, 220, 255, 0.92) 0%, rgba(80, 140, 200, 0.65) 55%, rgba(30, 70, 130, 0.4) 100%);
    box-shadow:
        0 0 6px rgba(140, 200, 255, 0.65),
        inset 0 0 4px rgba(255, 255, 255, 0.4);
    clip-path: polygon(50% 0, 100% 38%, 78% 100%, 22% 100%, 0 38%);
    opacity: 0;
    transform-origin: 50% 100%;
    animation: rb-vfx-shard-fly 380ms cubic-bezier(0.2, 0.7, 0.2, 1) forwards;
    --shard-angle: 0deg;
}

@keyframes rb-vfx-shard-fly {
    0% {
        opacity: 0;
        transform: rotate(var(--shard-angle, 0deg)) translateY(0) scale(0.4);
    }
    18% {
        opacity: 1;
        transform: rotate(var(--shard-angle, 0deg)) translateY(-12px) scale(1);
    }
    100% {
        opacity: 0;
        transform: rotate(var(--shard-angle, 0deg)) translateY(-72px) scale(0.6);
    }
}

/* --- DEATH DISSOLVE (.is-dead-dissolve)
   Aplicado pelo JS no card que será removido na próxima render.
   Borda incandescente (brasa) + clip-path que queima de baixo pra cima.
   Toda a card encolhe e some em ~720ms; depois o applyState() limpa o
   HTML residual.
   ------------------------------------------------------------------------ */

.is-dead-dissolve {
    animation: rb-vfx-dissolve-card 720ms cubic-bezier(0.4, 0, 0.6, 1) forwards;
    position: relative;
    z-index: 4;
    pointer-events: none;
}

.is-dead-dissolve::after {
    /* halo de brasa por trás do card enquanto queima */
    content: '';
    position: absolute;
    inset: -6px;
    border-radius: inherit;
    pointer-events: none;
    background:
        radial-gradient(ellipse at 50% 78%, rgba(255, 200, 90, 0.7) 0%, rgba(255, 110, 30, 0.45) 28%, rgba(80, 30, 10, 0.18) 55%, transparent 80%);
    mix-blend-mode: screen;
    opacity: 0;
    animation: rb-vfx-ember-glow 720ms ease-out forwards;
    z-index: -1;
}

@keyframes rb-vfx-dissolve-card {
    0% {
        opacity: 1;
        transform: scale(1);
        /* clip-path completo: card inteira visível */
        clip-path: inset(0 0 0 0);
        box-shadow: 0 0 0 0 rgba(255, 180, 60, 0);
    }
    18% {
        /* borda incandescente ativa, ainda visível inteira */
        clip-path: inset(0 0 0 0);
        box-shadow:
            0 0 18px 2px rgba(255, 180, 60, 0.75),
            inset 0 0 20px rgba(255, 220, 130, 0.45);
        transform: scale(1.02);
    }
    60% {
        /* queimando de baixo pra cima — top do card "vivo", base virou cinzas */
        clip-path: inset(0 0 45% 0);
        box-shadow:
            0 0 14px 2px rgba(255, 130, 40, 0.6),
            inset 0 0 16px rgba(255, 180, 60, 0.35);
        transform: scale(0.94);
        opacity: 0.85;
    }
    100% {
        clip-path: inset(0 0 100% 0);  /* virou cinza inteiro */
        box-shadow: 0 0 6px 0 rgba(120, 60, 20, 0.2);
        transform: scale(0.82) translateY(6px);
        opacity: 0;
    }
}

@keyframes rb-vfx-ember-glow {
    0% { opacity: 0; transform: scale(0.7); }
    18% { opacity: 1; transform: scale(1.1); }
    100% { opacity: 0; transform: scale(1.4); }
}

/* =========================================================================
   v55 FASE 3 — Living World & Ecosystem
   Camadas parallax do tabuleiro, brasas suspensas e auras elementares
   nas criaturas em campo. JS escuta mousemove e popula --rb-parallax-x/y
   no .battlefield-living; cada .battlefield-layer multiplica por seu
   data-parallax-depth para o efeito de profundidade volumétrica.
   ========================================================================= */

.battlefield-living {
    position: relative;
    isolation: isolate;
    --rb-parallax-x: 0px;
    --rb-parallax-y: 0px;
}

.battlefield-layer {
    position: absolute;
    inset: -18px;
    pointer-events: none;
    transform: translate3d(
        calc(var(--rb-parallax-x) * var(--rb-parallax-mult, 1)),
        calc(var(--rb-parallax-y) * var(--rb-parallax-mult, 1)),
        0
    );
    transition: transform 220ms cubic-bezier(0.18, 0.7, 0.22, 1);
    will-change: transform;
}

/* Skybox: névoa quente e nebulosa no topo, escurecida em baixo.
   --rb-parallax-mult = 1 (default) e o data-parallax-depth do HTML é -8,
   mas como o JS multiplica diretamente o offset pelo depth/10, a multiplicação
   acontece no JS. Aqui só aplicamos translate3d com os valores recebidos. */
.battlefield-layer-skybox {
    z-index: 0;
    background:
        radial-gradient(ellipse at 50% 0%, rgba(180, 100, 40, 0.18) 0%, transparent 55%),
        radial-gradient(ellipse at 30% 80%, rgba(80, 30, 60, 0.22) 0%, transparent 60%),
        radial-gradient(ellipse at 70% 90%, rgba(60, 70, 110, 0.18) 0%, transparent 55%),
        linear-gradient(180deg, #0a0707 0%, #050405 100%);
}

.battlefield-layer-board {
    z-index: 1;
    background:
        radial-gradient(circle at 50% 50%, rgba(180, 150, 80, 0.08) 0%, transparent 65%),
        repeating-linear-gradient(0deg, rgba(255, 255, 255, 0.018) 0 1px, transparent 1px 18px),
        repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.018) 0 1px, transparent 1px 18px);
    box-shadow:
        inset 0 0 80px rgba(0, 0, 0, 0.55),
        inset 0 0 0 1px rgba(80, 60, 40, 0.18);
}

.battlefield-layer-foreground {
    z-index: 2;
    background:
        radial-gradient(ellipse at 50% 100%, rgba(0, 0, 0, 0.55) 0%, transparent 70%),
        radial-gradient(ellipse at 50% 0%, rgba(0, 0, 0, 0.4) 0%, transparent 60%);
}

/* O conteúdo do tabuleiro (.rb-field-row, .rb-bot-card-zone, .rb-field-vs)
   precisa ficar ACIMA das 3 camadas, no z-index 3. */
.battlefield-living > .rb-field-row,
.battlefield-living > .rb-bot-card-zone,
.battlefield-living > .rb-field-vs {
    position: relative;
    z-index: 3;
}

/* Brasas suspensas: pontos luminosos que sobem lentamente. CSS puro,
   transform/opacity (compositing-friendly). 6 brasas no skybox. */
.battlefield-embers {
    position: absolute;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
}

.battlefield-ember {
    position: absolute;
    bottom: -10%;
    left: var(--ember-x, 50%);
    width: var(--ember-size, 4px);
    height: var(--ember-size, 4px);
    border-radius: 50%;
    background:
        radial-gradient(circle, rgba(255, 220, 130, 0.95) 0%, rgba(255, 140, 50, 0.6) 45%, transparent 80%);
    box-shadow: 0 0 6px rgba(255, 180, 80, 0.6);
    opacity: 0;
    animation: rb-ember-rise 12s linear var(--ember-delay, 0s) infinite;
    will-change: transform, opacity;
}

@keyframes rb-ember-rise {
    0% {
        transform: translate3d(0, 0, 0) scale(0.6);
        opacity: 0;
    }
    8% {
        opacity: 0.9;
    }
    50% {
        transform: translate3d(-12px, -380px, 0) scale(1);
        opacity: 0.7;
    }
    92% {
        opacity: 0.35;
    }
    100% {
        transform: translate3d(6px, -760px, 0) scale(0.5);
        opacity: 0;
    }
}

/* --- AURAS ELEMENTARES nas criaturas no campo ---------------------------
   O JS já injeta .is-element-{fire,water,earth,shadow} em todos os cards.
   Aqui scopamos só para .rb-field-card (criatura no tabuleiro), porque
   na mão o efeito seria visualmente pesado demais. Cada elemento ganha:
     • glow interno via box-shadow (cor diferente)
     • pseudo-element ::before com animação característica
   Tudo via transform/opacity/box-shadow — sem CSS filter (perf-budget).
   ------------------------------------------------------------------------ */

.rb-field-card.is-element-fire {
    box-shadow:
        0 0 0 1px rgba(255, 120, 50, 0.4),
        0 0 18px rgba(255, 100, 30, 0.32),
        0 18px 34px rgba(0, 0, 0, 0.56),
        inset 0 0 22px rgba(255, 80, 20, 0.18);
}

.rb-field-card.is-element-fire::before {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: -4px;
    height: 18px;
    pointer-events: none;
    background:
        radial-gradient(ellipse at 30% 100%, rgba(255, 180, 80, 0.45), transparent 60%),
        radial-gradient(ellipse at 70% 100%, rgba(255, 90, 30, 0.45), transparent 60%);
    border-radius: inherit;
    opacity: 0.85;
    animation: rb-element-fire-heat 2.4s ease-in-out infinite;
    z-index: 5;
    transform-origin: 50% 100%;
}

@keyframes rb-element-fire-heat {
    0%, 100% {
        transform: translateY(0) scaleX(1) skewX(0deg);
        opacity: 0.65;
    }
    25% {
        transform: translateY(-2px) scaleX(1.04) skewX(2deg);
        opacity: 0.95;
    }
    50% {
        transform: translateY(-3px) scaleX(0.98) skewX(-1.5deg);
        opacity: 0.8;
    }
    75% {
        transform: translateY(-2px) scaleX(1.02) skewX(1deg);
        opacity: 0.9;
    }
}

.rb-field-card.is-element-water {
    box-shadow:
        0 0 0 1px rgba(80, 160, 220, 0.4),
        0 0 18px rgba(50, 120, 200, 0.32),
        0 18px 34px rgba(0, 0, 0, 0.56),
        inset 0 0 22px rgba(40, 100, 180, 0.18);
}

.rb-field-card.is-element-water::before {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
    border-radius: inherit;
    background:
        linear-gradient(
            115deg,
            transparent 35%,
            rgba(140, 200, 240, 0.22) 48%,
            rgba(180, 220, 255, 0.32) 52%,
            transparent 65%
        );
    background-size: 240% 240%;
    background-position: 100% 0%;
    opacity: 0.7;
    animation: rb-element-water-flow 4.2s ease-in-out infinite;
    z-index: 5;
    mix-blend-mode: screen;
}

@keyframes rb-element-water-flow {
    0% { background-position: 100% 0%; }
    100% { background-position: -40% 100%; }
}

.rb-field-card.is-element-earth {
    box-shadow:
        0 0 0 1px rgba(150, 110, 60, 0.55),
        0 0 14px rgba(110, 75, 30, 0.28),
        0 18px 34px rgba(0, 0, 0, 0.56),
        inset 0 0 22px rgba(80, 50, 20, 0.22);
    /* Borda áspera: duas camadas de gradiente repetido simulam textura */
    border-image-source: repeating-linear-gradient(
        45deg,
        rgba(120, 85, 40, 0.85) 0 3px,
        rgba(60, 40, 18, 0.85) 3px 5px
    );
    border-image-slice: 2;
    border-image-width: 2px;
}

.rb-field-card.is-element-earth::before {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
    border-radius: inherit;
    background:
        radial-gradient(circle at 18% 22%, rgba(140, 95, 50, 0.5) 0 2px, transparent 3px),
        radial-gradient(circle at 78% 14%, rgba(140, 95, 50, 0.4) 0 1.5px, transparent 2.5px),
        radial-gradient(circle at 30% 84%, rgba(140, 95, 50, 0.45) 0 2px, transparent 3px),
        radial-gradient(circle at 86% 78%, rgba(140, 95, 50, 0.4) 0 1.5px, transparent 2.5px);
    opacity: 0;
    transition: opacity 280ms ease, transform 280ms ease;
    z-index: 5;
}

.rb-field-card.is-element-earth:hover::before,
.rb-field-card.is-element-earth.is-selected::before {
    opacity: 1;
    animation: rb-element-earth-dust 2s ease-in-out infinite;
}

@keyframes rb-element-earth-dust {
    0%, 100% {
        transform: translate(0, 0);
        opacity: 0.7;
    }
    50% {
        transform: translate(2px, -3px);
        opacity: 1;
    }
}

/* SHADOW: névoa volumétrica simulada com camadas radiais (sem CSS filter
   blur — perf-budget bane). Aplicada na base da carta, escurecendo o
   contorno inferior pra dar peso fantasmagórico. */
.rb-field-card.is-element-shadow {
    box-shadow:
        0 0 0 1px rgba(155, 90, 220, 0.4),
        0 0 22px rgba(100, 40, 160, 0.32),
        0 18px 34px rgba(0, 0, 0, 0.65),
        inset 0 -18px 30px rgba(40, 10, 60, 0.45);
}

.rb-field-card.is-element-shadow::before {
    content: '';
    position: absolute;
    left: -8px;
    right: -8px;
    bottom: -10px;
    height: 56px;
    pointer-events: none;
    /* Cinco gradientes radiais empilhados em opacities decrescentes
       simulam um halo difuso sem precisar de CSS filter. */
    background:
        radial-gradient(ellipse at 30% 80%, rgba(50, 10, 70, 0.65) 0%, transparent 60%),
        radial-gradient(ellipse at 70% 60%, rgba(80, 20, 110, 0.55) 0%, transparent 60%),
        radial-gradient(ellipse at 50% 100%, rgba(20, 5, 40, 0.78) 0%, transparent 70%);
    border-radius: 50%;
    opacity: 0.85;
    animation: rb-element-shadow-fog 5s ease-in-out infinite;
    z-index: 5;
}

@keyframes rb-element-shadow-fog {
    0%, 100% {
        transform: translateY(0) scaleX(1);
        opacity: 0.7;
    }
    50% {
        transform: translateY(2px) scaleX(1.08);
        opacity: 0.95;
    }
}

/* --- Reduced motion: respeita preferência do SO ----------------------- */
@media (prefers-reduced-motion: reduce) {
    #next-turn-button.is-cta-pulse:not(:disabled),
    #next-turn-button.is-cta-pulse:not(:disabled)::after,
    .rb-field-slots .rb-field-slot-empty.is-summon-target::before,
    .rb-field-slots .rb-field-slot-empty[data-direct-attack="true"]::before,
    .rb-field-card.is-attack-lunging::after,
    .rb-field-card.is-taking-hit::before,
    .rb-bot-card.is-taking-hit::before,
    .vfx-screen-shake,
    .vfx-screen-shake.vfx-screen-shake-heavy,
    .vfx-shield-shatter__shard,
    .is-dead-dissolve,
    .is-dead-dissolve::after,
    .battlefield-ember,
    .rb-field-card.is-element-fire::before,
    .rb-field-card.is-element-water::before,
    .rb-field-card.is-element-earth::before,
    .rb-field-card.is-element-shadow::before {
        animation: none;
    }
    .battlefield-layer {
        transition-duration: 0ms;
        transform: none !important;
    }
    .rb-hand .rb-mini-card.rb-tcg-card,
    #next-turn-button.rb-button-secondary,
    #play-button.rb-button-primary {
        transition-duration: 80ms;
    }
    .is-dead-dissolve {
        opacity: 0;
        transform: scale(0.9);
    }
}

/* =========================================================================
   v55 FASE 3 — GRIMÓRIO + BAZAAR
   Coleção vira livro antigo aberto, Loja vira bancada de contrabandista
   com vinheta cinematográfica e pergaminhos lacrados.
   ========================================================================= */

/* --- GRIMÓRIO: a aba de coleção --------------------------------------- */

.rb-product-shell .rb-loadout-builder {
    position: relative;
    background:
        /* lombada central (sombra interna marcando o vinco do livro) */
        linear-gradient(90deg, transparent 47%, rgba(40, 24, 12, 0.55) 49%, rgba(20, 10, 4, 0.7) 50%, rgba(40, 24, 12, 0.55) 51%, transparent 53%),
        /* textura de pergaminho envelhecido — pontos manchados */
        radial-gradient(circle at 18% 22%, rgba(120, 80, 30, 0.16) 0 5px, transparent 6px),
        radial-gradient(circle at 78% 14%, rgba(120, 80, 30, 0.12) 0 4px, transparent 5px),
        radial-gradient(circle at 30% 84%, rgba(120, 80, 30, 0.18) 0 6px, transparent 7px),
        radial-gradient(circle at 86% 78%, rgba(120, 80, 30, 0.14) 0 5px, transparent 6px),
        /* fundo bege envelhecido com vinheta */
        radial-gradient(ellipse at 50% 50%, rgba(180, 140, 80, 0.18) 0%, rgba(50, 32, 16, 0.55) 80%),
        linear-gradient(135deg, #3a2a18 0%, #2a1c0e 50%, #1a1108 100%);
    border: 2px solid;
    border-image: linear-gradient(140deg, #6a4a22 0%, #3a2410 50%, #1a0f06 100%) 1;
    box-shadow:
        inset 0 0 60px rgba(60, 30, 10, 0.55),
        inset 0 0 0 1px rgba(180, 130, 60, 0.18),
        0 18px 38px rgba(0, 0, 0, 0.6),
        0 4px 8px rgba(0, 0, 0, 0.5);
    transform-style: preserve-3d;
    perspective: 1400px;
    /* divide as linhas em duas colunas pra simular páginas espelhadas */
}

.rb-product-shell .rb-loadout-builder::before {
    /* faísca de luz no canto superior esquerdo, como vela próxima ao livro */
    content: '';
    position: absolute;
    top: -4px;
    left: -4px;
    width: 160px;
    height: 80px;
    pointer-events: none;
    background:
        radial-gradient(ellipse at 12% 18%, rgba(255, 200, 110, 0.28) 0%, transparent 60%);
    z-index: 1;
    border-radius: inherit;
}

.rb-product-shell .rb-loadout-row {
    /* cada linha vira uma entrada de pergaminho mais sólida */
    background:
        linear-gradient(140deg, rgba(80, 56, 28, 0.4) 0%, rgba(40, 26, 12, 0.55) 100%);
    border: 1px solid rgba(160, 120, 60, 0.32);
    box-shadow:
        inset 0 1px 0 rgba(255, 220, 160, 0.08),
        0 2px 4px rgba(0, 0, 0, 0.45);
    position: relative;
    z-index: 2;  /* acima do background do livro */
}

/* Flip 3D pronto pra ser disparado por JS quando paginação real entrar.
   Por enquanto a classe .is-flipping não é injetada — o efeito existe
   como infra latente. */
.rb-loadout-builder.is-flipping {
    animation: rb-grimoire-flip 720ms cubic-bezier(0.4, 0, 0.2, 1) both;
    transform-origin: 50% 50%;
}

@keyframes rb-grimoire-flip {
    0% { transform: rotateY(0deg); }
    50% { transform: rotateY(90deg); opacity: 0.5; }
    100% { transform: rotateY(0deg); }
}

/* Sumário do loadout (Selected/Attack/Guard/Pairs) ganha tratamento de
   "cristais cravados no topo do livro". */
.rb-product-shell .rb-loadout-summary article {
    background:
        radial-gradient(circle at 30% 25%, rgba(140, 200, 240, 0.32), transparent 55%),
        linear-gradient(140deg, #3a4858 0%, #1f2a36 60%, #0f1820 100%);
    border: 1px solid rgba(140, 180, 220, 0.45);
    box-shadow:
        inset 0 1px 0 rgba(220, 240, 255, 0.22),
        inset 0 -1px 1px rgba(0, 0, 0, 0.55),
        0 4px 8px rgba(0, 0, 0, 0.5),
        0 0 12px rgba(80, 140, 200, 0.22);
    clip-path: polygon(8% 0, 92% 0, 100% 32%, 100% 68%, 92% 100%, 8% 100%, 0 68%, 0 32%);
}

.rb-product-shell .rb-loadout-summary article strong {
    color: #f6efd4;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
}

/* --- BAZAAR: a aba de loja -------------------------------------------- */

/* Vinheta cinematográfica nas bordas — radial-gradient escuro
   transparente no centro. Aplicada via ::after fixed na shell de produto
   só quando estamos na loja. */
.rb-product-shell[data-page-key="shop"]::after {
    content: '';
    position: fixed;
    inset: 0;
    pointer-events: none;
    background:
        radial-gradient(ellipse at 50% 50%, transparent 35%, rgba(0, 0, 0, 0.45) 75%, rgba(0, 0, 0, 0.78) 100%);
    z-index: 5;
}

/* O pacote de cartas vira pergaminho enrolado + selo de cera no topo. */
.rb-product-shell .rb-shop-pack {
    position: relative;
    background:
        radial-gradient(ellipse at 50% -20%, rgba(180, 140, 60, 0.12) 0%, transparent 55%),
        linear-gradient(180deg, #2a1d10 0%, #1c1308 60%, #0c0904 100%);
    border: 1.5px solid rgba(140, 95, 40, 0.55);
    box-shadow:
        inset 0 1px 0 rgba(220, 170, 90, 0.18),
        inset 0 0 28px rgba(80, 50, 20, 0.5),
        0 18px 28px rgba(0, 0, 0, 0.55),
        0 3px 6px rgba(0, 0, 0, 0.4);
    padding-top: 38px;  /* abre espaço pro selo de cera */
}

/* Selo de cera vermelha — disco com brasão no centro, ::before */
.rb-product-shell .rb-shop-pack::before {
    content: '';
    position: absolute;
    top: -22px;
    left: 50%;
    width: 56px;
    height: 56px;
    transform: translateX(-50%);
    border-radius: 50%;
    background:
        radial-gradient(circle at 32% 28%, rgba(255, 220, 200, 0.42), transparent 50%),
        radial-gradient(circle at 65% 70%, rgba(60, 0, 0, 0.55), transparent 55%),
        linear-gradient(140deg, #8b1a1a 0%, #5a0f0f 55%, #2c0606 100%);
    box-shadow:
        inset 0 2px 2px rgba(255, 200, 180, 0.4),
        inset 0 -3px 6px rgba(0, 0, 0, 0.7),
        inset 0 0 0 2px rgba(120, 30, 30, 0.85),
        0 6px 14px rgba(0, 0, 0, 0.55);
    z-index: 3;
    transition: transform 280ms cubic-bezier(0.4, 0, 0.2, 1), opacity 280ms ease;
}

/* Coroa de runas em volta do selo, ::after */
.rb-product-shell .rb-shop-pack::after {
    content: 'A';
    position: absolute;
    top: -22px;
    left: 50%;
    width: 56px;
    height: 56px;
    transform: translateX(-50%);
    display: grid;
    place-items: center;
    font-size: var(--fs-lg);
    font-weight: 900;
    color: rgba(255, 220, 180, 0.85);
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8), 0 0 10px rgba(255, 140, 80, 0.4);
    z-index: 4;
    pointer-events: none;
    transition: opacity 280ms ease;
}

/* Quando o JS injeta .is-seal-broken (no clique do comprar), o selo se
   parte em dois fragmentos que rotam pra fora e desaparecem. */
.rb-product-shell .rb-shop-pack.is-seal-broken::before {
    animation: rb-seal-shatter-left 420ms cubic-bezier(0.4, 0, 0.6, 1) forwards;
    clip-path: polygon(0 0, 50% 0, 50% 100%, 0 100%);
}

.rb-product-shell .rb-shop-pack.is-seal-broken::after {
    opacity: 0;
}

/* Pra dar a sensação de "dois pedaços", duplicamos o selo via uma camada
   adicional usando outline. Como CSS não permite duas pseudo do mesmo,
   vamos com um único shatter pro brief — o efeito visual de uma metade
   girando pra esquerda + texto sumindo é suficiente pra leitura de
   "quebrou". */

@keyframes rb-seal-shatter-left {
    0% {
        transform: translateX(-50%) rotate(0deg) scale(1);
        opacity: 1;
    }
    100% {
        transform: translateX(calc(-50% - 32px)) rotate(-46deg) scale(0.75);
        opacity: 0;
    }
}

.rb-product-shell .rb-shop-pack [data-rebirth-booster] {
    /* botão "Comprar Booster" mais teatral, estilo medalhão pequeno */
    margin-top: 12px;
    letter-spacing: 0.08em;
}

/* Mercado de jogadores também ganha vibe de feira */
.rb-product-shell[data-page-key="shop"] [data-rebirth-market-offers] {
    background:
        radial-gradient(ellipse at 50% -10%, rgba(180, 130, 60, 0.1) 0%, transparent 60%),
        linear-gradient(180deg, rgba(20, 14, 6, 0.55) 0%, rgba(8, 5, 2, 0.65) 100%);
    border: 1px solid rgba(120, 85, 40, 0.35);
    border-radius: 6px;
    padding: 14px;
}

@media (prefers-reduced-motion: reduce) {
    .rb-loadout-builder.is-flipping,
    .rb-product-shell .rb-shop-pack.is-seal-broken::before {
        animation: none;
    }
}

/* =========================================================================
   v55 FASE 4 — SIGNATURE IDENTITY
   Animações de assinatura: evolução cinemática em 4 fases, dano direto
   nos orbes do herói, telas de VITÓRIA e DERROTA premium. Todas
   orquestradas pelo JS com timeline awaitable antes do applyState.
   ========================================================================= */

/* --- 1. EVOLUÇÃO CINEMATOGRÁFICA --------------------------------------
   Container .vfx-evolution-stage cobre toda a área de jogo (position:
   absolute na main). O JS clona os 2 cards a serem fundidos pra dentro
   dele e dispara a sequência: dark overlay → convergência → runa → flash.
   ------------------------------------------------------------------------ */

.vfx-evolution-stage {
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 50;
    display: none;
    isolation: isolate;
}

.vfx-evolution-stage.is-active {
    display: block;
}

/* Fase 1: overlay escuro cobre o tabuleiro. NÃO uso CSS filter (perf-
   budget bane) — em vez disso uma camada preta com opacidade controlada
   sobre um gradiente radial dá a sensação de profundidade escurecida. */
.vfx-evolution-stage .vfx-evolution-overlay {
    position: absolute;
    inset: 0;
    background:
        radial-gradient(ellipse at 50% 50%, rgba(0, 0, 0, 0.55) 0%, rgba(0, 0, 0, 0.92) 80%);
    opacity: 0;
    transition: opacity 360ms ease;
}

.vfx-evolution-stage.is-active .vfx-evolution-overlay {
    opacity: 0.85;
}

/* Fase 2: clones convergem para o centro. .vfx-evolution-clone é um
   wrapper posicionado pelo JS (top/left fixos do card original); a
   classe .is-converging dispara a animação rumo ao centro do stage. */
.vfx-evolution-clone {
    position: absolute;
    transform-origin: center center;
    transition: transform 520ms cubic-bezier(0.4, 0, 0.2, 1), opacity 520ms ease;
    z-index: 2;
    will-change: transform, opacity;
}

.vfx-evolution-clone.is-converging {
    /* CSS custom property --target-x/--target-y populada pelo JS pra
       cada clone andar até o centro do stage. */
    transform:
        translate3d(var(--target-x, 0), var(--target-y, 0), 0)
        scale(1.18)
        rotate(var(--converge-rot, 0deg));
    opacity: 1;
}

.vfx-evolution-clone.is-vanishing {
    opacity: 0;
    transform:
        translate3d(var(--target-x, 0), var(--target-y, 0), 0)
        scale(2.4)
        rotate(0deg);
    transition: transform 320ms cubic-bezier(0.4, 0, 0.6, 1), opacity 320ms ease;
}

/* Fase 3: a runa gigante surge no centro */
.vfx-evolution-stage .vfx-evolution-rune {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 320px;
    height: 320px;
    margin: -160px 0 0 -160px;
    border-radius: 50%;
    pointer-events: none;
    background:
        radial-gradient(circle, transparent 30%, rgba(255, 215, 110, 0.85) 38%, rgba(220, 150, 50, 0.55) 50%, transparent 72%),
        conic-gradient(from 0deg,
            rgba(255, 230, 140, 0.85) 0deg, transparent 14deg,
            rgba(255, 230, 140, 0.85) 60deg, transparent 74deg,
            rgba(255, 230, 140, 0.85) 120deg, transparent 134deg,
            rgba(255, 230, 140, 0.85) 180deg, transparent 194deg,
            rgba(255, 230, 140, 0.85) 240deg, transparent 254deg,
            rgba(255, 230, 140, 0.85) 300deg, transparent 314deg,
            rgba(255, 230, 140, 0.85) 360deg);
    opacity: 0;
    transform: translateZ(0) scale(0.2) rotate(0deg);
    z-index: 3;
    box-shadow:
        0 0 60px rgba(255, 200, 90, 0.55),
        inset 0 0 40px rgba(255, 220, 130, 0.4);
}

.vfx-evolution-stage.is-rune-active .vfx-evolution-rune {
    animation: rb-vfx-rune-summon 880ms cubic-bezier(0.2, 0.7, 0.2, 1) forwards;
}

@keyframes rb-vfx-rune-summon {
    0% { opacity: 0; transform: scale(0.2) rotate(0deg); }
    35% { opacity: 1; transform: scale(1.08) rotate(120deg); }
    75% { opacity: 0.92; transform: scale(1) rotate(220deg); }
    100% { opacity: 0; transform: scale(1.4) rotate(360deg); }
}

/* Fase 4: explosão de luz no centro quando o evolved aparece */
.vfx-evolution-stage .vfx-evolution-burst {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 460px;
    height: 460px;
    margin: -230px 0 0 -230px;
    border-radius: 50%;
    pointer-events: none;
    background:
        radial-gradient(circle, rgba(255, 250, 220, 1) 0%, rgba(255, 200, 90, 0.7) 22%, rgba(220, 130, 40, 0.3) 50%, transparent 80%);
    opacity: 0;
    transform: scale(0.1);
    z-index: 4;
}

.vfx-evolution-stage.is-burst-active .vfx-evolution-burst {
    animation: rb-vfx-evolution-burst 560ms cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
}

@keyframes rb-vfx-evolution-burst {
    0% { opacity: 0; transform: scale(0.1); }
    25% { opacity: 1; transform: scale(0.8); }
    55% { opacity: 0.9; transform: scale(1.3); }
    100% { opacity: 0; transform: scale(2.2); }
}

/* --- REBIRTH LABS: FIELD FUSION PROTOTYPE --------------------------- */

.rb-field-card.is-fusion-source {
    position: relative;
    z-index: 5;
    box-shadow:
        0 0 0 1px rgba(255, 255, 255, 0.65),
        0 0 28px rgba(255, 230, 150, 0.36),
        0 18px 34px rgba(0, 0, 0, 0.56);
    animation: rb-fusion-source-pulse 980ms ease-in-out infinite;
}

.rb-field-card.is-fusion-source::after {
    content: '';
    position: absolute;
    inset: -8px;
    border-radius: inherit;
    pointer-events: none;
    background:
        radial-gradient(circle at 50% 50%, rgba(255, 255, 255, 0.24), transparent 64%),
        conic-gradient(from 45deg, transparent 0deg, rgba(255, 235, 170, 0.42) 42deg, transparent 84deg, rgba(255, 255, 255, 0.3) 156deg, transparent 210deg, rgba(255, 210, 130, 0.36) 292deg, transparent 360deg);
    opacity: 0.65;
    animation: rb-fusion-source-ring 1.3s linear infinite;
    z-index: 3;
}

@keyframes rb-fusion-source-pulse {
    0%, 100% { transform: translateZ(0) scale(1); }
    50% { transform: translateZ(0) scale(1.025); }
}

@keyframes rb-fusion-source-ring {
    0% { transform: rotate(0deg) scale(0.96); opacity: 0.26; }
    45% { opacity: 0.82; }
    100% { transform: rotate(360deg) scale(1.05); opacity: 0.26; }
}

.rb-field-card.is-fusion-material-live {
    opacity: 0.34;
    transform: scale(0.96);
}

.vfx-fusion-overlay {
    position: absolute;
    inset: 0;
    background:
        radial-gradient(ellipse at 50% 56%, rgba(255, 255, 255, 0.16) 0%, transparent 34%),
        radial-gradient(ellipse at 50% 56%, rgba(0, 0, 0, 0.56) 0%, rgba(0, 0, 0, 0.82) 82%);
    opacity: 0;
    transition: opacity 120ms ease;
}

.vfx-evolution-stage.is-fusion-active .vfx-fusion-overlay {
    opacity: 0.78;
}

.vfx-fusion-clone {
    position: absolute;
    z-index: 5;
    transform-origin: center center;
    transition:
        transform 240ms cubic-bezier(0.12, 0.86, 0.18, 1),
        opacity 240ms ease;
    will-change: transform, opacity;
}

.vfx-fusion-clone::after {
    content: '';
    position: absolute;
    inset: -18px -30px;
    border-radius: inherit;
    pointer-events: none;
    background:
        linear-gradient(90deg, transparent 0%, rgba(255, 255, 255, 0.34) 48%, rgba(255, 205, 110, 0.24) 62%, transparent 100%);
    opacity: 0;
    transform: scaleX(0.5);
    z-index: -1;
}

.vfx-fusion-clone.is-converging {
    transform:
        translate3d(var(--target-x, 0), var(--target-y, 0), 0)
        scale(0.68)
        rotate(var(--fusion-rot, 0deg));
    opacity: 0.88;
}

.vfx-fusion-clone.is-converging::after {
    animation: rb-fusion-trail 240ms ease-out forwards;
}

@keyframes rb-fusion-trail {
    0% { opacity: 0; transform: scaleX(0.35); }
    35% { opacity: 0.9; transform: scaleX(1.12); }
    100% { opacity: 0; transform: scaleX(1.9); }
}

.vfx-fusion-slot-flash,
.vfx-fusion-burst {
    position: absolute;
    pointer-events: none;
    transform: translate(-50%, -50%) scale(0.1);
    opacity: 0;
    border-radius: 50%;
}

.vfx-fusion-slot-flash {
    width: 280px;
    height: 280px;
    z-index: 8;
    background:
        radial-gradient(circle, rgba(255, 255, 255, 1) 0%, rgba(255, 244, 198, 0.9) 20%, rgba(255, 192, 94, 0.34) 48%, transparent 72%);
}

.vfx-fusion-burst {
    width: 440px;
    height: 440px;
    z-index: 7;
    background:
        radial-gradient(circle, rgba(255, 255, 255, 0.98) 0%, rgba(255, 225, 150, 0.76) 18%, rgba(255, 120, 70, 0.36) 44%, transparent 76%),
        conic-gradient(from 0deg, rgba(255, 255, 255, 0.86), transparent 18deg, rgba(255, 200, 120, 0.72) 56deg, transparent 92deg, rgba(255, 255, 255, 0.72) 136deg, transparent 180deg, rgba(255, 180, 90, 0.72) 242deg, transparent 300deg, rgba(255, 255, 255, 0.86));
}

.vfx-evolution-stage.is-fusion-flash .vfx-fusion-slot-flash {
    animation: rb-fusion-white-flash 180ms ease-out forwards;
}

.vfx-evolution-stage.is-fusion-flash .vfx-fusion-burst {
    animation: rb-fusion-stage-burst 520ms cubic-bezier(0.16, 0.84, 0.18, 1) forwards;
}

@keyframes rb-fusion-white-flash {
    0% { opacity: 0; transform: translate(-50%, -50%) scale(0.2); }
    38% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
    100% { opacity: 0; transform: translate(-50%, -50%) scale(1.5); }
}

@keyframes rb-fusion-stage-burst {
    0% { opacity: 0; transform: translate(-50%, -50%) scale(0.08) rotate(0deg); }
    18% { opacity: 1; transform: translate(-50%, -50%) scale(0.72) rotate(24deg); }
    62% { opacity: 0.88; transform: translate(-50%, -50%) scale(1.2) rotate(96deg); }
    100% { opacity: 0; transform: translate(-50%, -50%) scale(1.85) rotate(180deg); }
}

.rb-field-card.is-fusion-born {
    position: relative;
    z-index: 9;
    animation: rb-fusion-born 460ms cubic-bezier(0.12, 0.86, 0.18, 1) both;
}

.rb-field-card.is-fusion-born::after {
    content: '';
    position: absolute;
    inset: -14px;
    border-radius: inherit;
    pointer-events: none;
    background:
        radial-gradient(circle at 50% 50%, rgba(255, 255, 255, 0.88) 0%, rgba(255, 228, 154, 0.54) 36%, transparent 70%);
    opacity: 0;
    animation: rb-fusion-born-glow 620ms ease-out forwards;
    z-index: 8;
}

@keyframes rb-fusion-born {
    0% { opacity: 0; transform: scale(0.42); }
    34% { opacity: 1; transform: scale(1.18); }
    64% { transform: scale(0.96); }
    100% { opacity: 1; transform: scale(1); }
}

@keyframes rb-fusion-born-glow {
    0% { opacity: 0; transform: scale(0.62); }
    28% { opacity: 1; transform: scale(1.02); }
    100% { opacity: 0; transform: scale(1.46); }
}

/* --- 2. DANO DIRETO NO HERÓI ----------------------------------------- */

/* Os orbes de HP são .rb-hp-meter; o JS injeta .vfx-hero-damage no
   .rb-hud-player ou .rb-hud-bot afetado quando o HP do payload caiu. */
.vfx-hero-damage {
    animation: rb-vfx-hero-pulse 460ms cubic-bezier(0.36, 0, 0.2, 1) both;
    position: relative;
}

@keyframes rb-vfx-hero-pulse {
    0%, 100% { transform: scale(1); }
    20% { transform: scale(0.92) translateX(-4px); }
    35% { transform: scale(1.06) translateX(5px); }
    55% { transform: scale(0.96) translateX(-3px); }
    78% { transform: scale(1.02) translateX(2px); }
}

.vfx-hero-damage::before {
    content: '';
    position: absolute;
    inset: -8px;
    pointer-events: none;
    background:
        radial-gradient(ellipse at 50% 50%, rgba(255, 50, 40, 0.55) 0%, rgba(180, 20, 10, 0.3) 35%, transparent 70%);
    border-radius: inherit;
    mix-blend-mode: screen;
    opacity: 0;
    animation: rb-vfx-hero-flash 460ms ease-out forwards;
    z-index: 1;
}

@keyframes rb-vfx-hero-flash {
    0% { opacity: 0; transform: scale(0.6); }
    18% { opacity: 1; transform: scale(1); }
    100% { opacity: 0; transform: scale(1.4); }
}

/* Faíscas de sangue arcano — 4 partículas projetadas pelos cantos */
.vfx-hero-damage::after {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
    background:
        radial-gradient(circle at 15% 30%, rgba(255, 80, 60, 0.85) 0 3px, transparent 4px),
        radial-gradient(circle at 85% 28%, rgba(180, 0, 30, 0.85) 0 2px, transparent 3px),
        radial-gradient(circle at 20% 78%, rgba(200, 40, 60, 0.85) 0 2.5px, transparent 3.5px),
        radial-gradient(circle at 82% 80%, rgba(140, 0, 20, 0.85) 0 2px, transparent 3px);
    opacity: 0;
    animation: rb-vfx-hero-spark 460ms ease-out forwards;
    z-index: 2;
}

@keyframes rb-vfx-hero-spark {
    0% { opacity: 0; transform: scale(0.5); }
    25% { opacity: 1; transform: scale(1.1); }
    100% { opacity: 0; transform: scale(1.8); }
}

/* --- 3. FINALIZAÇÃO TRIUNFAL ----------------------------------------- */

.vfx-finale-overlay {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: none;
    align-items: center;
    justify-content: center;
    pointer-events: none;
    isolation: isolate;
}

.vfx-finale-overlay.is-active {
    display: flex;
    pointer-events: none;
}

.vfx-finale-overlay .vfx-finale-curtain {
    position: absolute;
    inset: 0;
    opacity: 0;
    transition: opacity 580ms ease;
}

.vfx-finale-overlay.is-active .vfx-finale-curtain {
    opacity: 1;
}

.vfx-finale-overlay .vfx-finale-text {
    position: relative;
    z-index: 4;
    font-family: var(--rb-font-epic);
    font-weight: 900;
    letter-spacing: 0.32em;
    font-size: var(--fs-display);
    text-transform: uppercase;
    opacity: 0;
    transform: scale(0.6) translateY(20px);
    transition: opacity 720ms ease, transform 720ms cubic-bezier(0.2, 0.7, 0.2, 1);
}

.vfx-finale-overlay.is-active .vfx-finale-text {
    opacity: 1;
    transform: scale(1) translateY(0);
}

/* VITÓRIA — névoa dourada + runas flutuantes */
.vfx-finale-overlay.is-victory .vfx-finale-curtain {
    background:
        radial-gradient(ellipse at 50% 30%, rgba(255, 210, 130, 0.42) 0%, transparent 55%),
        radial-gradient(ellipse at 50% 80%, rgba(255, 170, 80, 0.32) 0%, transparent 60%),
        radial-gradient(circle at 50% 50%, rgba(80, 50, 20, 0.7) 0%, rgba(30, 15, 5, 0.92) 90%);
}

.vfx-finale-overlay.is-victory .vfx-finale-text {
    color: #f8e9b5;
    text-shadow:
        0 2px 0 rgba(140, 90, 30, 1),
        0 4px 0 rgba(80, 50, 15, 1),
        0 8px 24px rgba(255, 200, 90, 0.6),
        0 0 60px rgba(255, 180, 70, 0.55);
    background:
        linear-gradient(180deg, #fff2c4 0%, #f5c466 40%, #a06618 80%, #4a2810 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    animation: rb-vfx-victory-shimmer 3.2s ease-in-out infinite;
}

@keyframes rb-vfx-victory-shimmer {
    0%, 100% { background-position: 0% 0%; }
    50% { background-position: 0% 100%; }
}

/* Runas flutuantes da vitória — 6 pontos brilhantes que sobem */
.vfx-finale-overlay.is-victory::before,
.vfx-finale-overlay.is-victory::after {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
    background:
        radial-gradient(circle at 18% 90%, rgba(255, 230, 140, 0.85) 0 4px, transparent 5px),
        radial-gradient(circle at 30% 95%, rgba(255, 200, 90, 0.8) 0 3px, transparent 4px),
        radial-gradient(circle at 50% 92%, rgba(255, 240, 160, 0.9) 0 4px, transparent 5px),
        radial-gradient(circle at 68% 96%, rgba(255, 200, 80, 0.8) 0 3px, transparent 4px),
        radial-gradient(circle at 82% 90%, rgba(255, 230, 140, 0.85) 0 4px, transparent 5px);
    opacity: 0;
    animation: rb-vfx-victory-runes 4.5s ease-out infinite;
    z-index: 2;
}

.vfx-finale-overlay.is-victory::after {
    animation-delay: 1.5s;
}

@keyframes rb-vfx-victory-runes {
    0% { opacity: 0; transform: translateY(0) scale(0.7); }
    18% { opacity: 0.9; transform: translateY(-80px) scale(1); }
    100% { opacity: 0; transform: translateY(-360px) scale(0.5); }
}

/* DERROTA — vinheta cinzenta + texto sombrio */
.vfx-finale-overlay.is-defeat .vfx-finale-curtain {
    background:
        radial-gradient(ellipse at 50% 50%, transparent 18%, rgba(20, 5, 25, 0.65) 60%, rgba(5, 5, 12, 0.95) 100%);
}

.vfx-finale-overlay.is-defeat .vfx-finale-text {
    color: #b8a8c8;
    text-shadow:
        0 1px 0 rgba(40, 20, 50, 1),
        0 2px 0 rgba(25, 10, 35, 1),
        0 6px 18px rgba(80, 40, 110, 0.6),
        0 0 40px rgba(100, 50, 130, 0.45);
    letter-spacing: 0.38em;
    /* sem shimmer animado — o peso da derrota é estático */
}

/* Energia espectral roxa subindo do canto inferior (orbe quebrado) */
.vfx-finale-overlay.is-defeat::before {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
    background:
        radial-gradient(circle at 50% 100%, rgba(130, 70, 180, 0.45) 0%, rgba(80, 30, 130, 0.25) 18%, transparent 45%);
    opacity: 0;
    animation: rb-vfx-defeat-mist 2.4s ease-out forwards;
    z-index: 2;
}

@keyframes rb-vfx-defeat-mist {
    0% { opacity: 0; transform: translateY(40px) scale(0.9); }
    35% { opacity: 1; transform: translateY(0) scale(1); }
    100% { opacity: 0.55; transform: translateY(-30px) scale(1.1); }
}

/* O orbe do player ganha .vfx-orb-crack na derrota */
.rb-hud-player.vfx-orb-crack .rb-hp-meter,
.rb-hud-player.vfx-orb-crack [id="player-hp"] {
    animation: rb-vfx-orb-crack-shake 720ms cubic-bezier(0.36, 0, 0.2, 1) both;
}

.rb-hud-player.vfx-orb-crack .rb-hp-meter::after {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
    background:
        radial-gradient(circle at 30% 40%, rgba(140, 60, 180, 0.65) 0 1.5px, transparent 2px),
        linear-gradient(115deg, transparent 30%, rgba(180, 100, 220, 0.55) 32%, transparent 34%),
        linear-gradient(75deg, transparent 50%, rgba(180, 100, 220, 0.45) 52%, transparent 54%);
    opacity: 0;
    animation: rb-vfx-orb-crack-flash 720ms ease-out forwards;
}

@keyframes rb-vfx-orb-crack-shake {
    0%, 100% { transform: translate(0, 0); }
    20% { transform: translate(-4px, 2px); }
    40% { transform: translate(4px, -2px); }
    60% { transform: translate(-3px, 3px); }
    80% { transform: translate(2px, -1px); }
}

@keyframes rb-vfx-orb-crack-flash {
    0% { opacity: 0; }
    30% { opacity: 0.95; }
    100% { opacity: 0; }
}

/* Tabuleiro se despedaça na vitória — leve tilt + glow dourado */
.rb-game-board.vfx-board-shatter {
    animation: rb-vfx-board-shatter 1.4s ease-out both;
}

@keyframes rb-vfx-board-shatter {
    0% { transform: none; box-shadow: none; }
    35% {
        transform: translate(2px, -2px) rotate(0.4deg);
        box-shadow: 0 0 80px rgba(255, 200, 90, 0.35);
    }
    72% {
        transform: translate(-2px, 1px) rotate(-0.2deg);
        box-shadow: 0 0 120px rgba(255, 180, 60, 0.25);
    }
    100% { transform: none; box-shadow: none; }
}

/* --- Primeira vitória / rematch CTA --------------------------- */
.vfx-finale-overlay .vfx-finale-subtitle {
    margin-top: 18px;
    font-size: var(--fs-md);
    font-weight: 600;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: rgba(255, 235, 180, 0.92);
    text-shadow: 0 0 18px rgba(255, 190, 90, 0.65);
    opacity: 0;
    transform: translateY(14px);
    transition: opacity 0.6s ease 0.4s, transform 0.6s ease 0.4s;
    position: relative;
    z-index: 4;
}

.vfx-finale-overlay.is-active .vfx-finale-subtitle {
    opacity: 1;
    transform: translateY(0);
}

.vfx-finale-overlay.is-first-duel .vfx-finale-text {
    animation: rb-vfx-victory-shimmer 2.4s ease-in-out infinite, rb-vfx-first-duel-pop 0.8s ease-out;
    font-size: var(--fs-display);
    letter-spacing: 0.16em;
}

@keyframes rb-vfx-first-duel-pop {
    0% { transform: scale(0.6); opacity: 0; }
    55% { transform: scale(1.12); opacity: 1; }
    100% { transform: scale(1); opacity: 1; }
}

.rb-result-actions {
    display: flex;
    flex-direction: column;
    gap: 10px;
    align-items: stretch;
    justify-content: flex-end;
    min-width: 200px;
}

.rb-result-actions.is-finished .rb-secondary {
    opacity: 0.85;
}

.rb-rematch-cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    min-height: 56px;
    padding: 14px 26px;
    font-size: var(--fs-sm);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    border-radius: 14px;
    background: linear-gradient(180deg, #f8c259 0%, #d6852e 60%, #8c4a16 100%);
    color: #2a1606;
    border: 1px solid rgba(255, 220, 150, 0.65);
    box-shadow:
        0 0 0 1px rgba(0, 0, 0, 0.35) inset,
        0 10px 28px rgba(220, 130, 40, 0.45),
        0 0 24px rgba(255, 190, 90, 0.4);
    cursor: pointer;
    transition: transform 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease;
}

.rb-rematch-cta:hover:not([disabled]) {
    transform: translateY(-1px);
    background: linear-gradient(180deg, #ffd373 0%, #e69335 60%, #9a5418 100%);
    box-shadow:
        0 0 0 1px rgba(0, 0, 0, 0.35) inset,
        0 12px 32px rgba(220, 130, 40, 0.55),
        0 0 32px rgba(255, 200, 100, 0.55);
}

.rb-rematch-cta:active:not([disabled]) {
    transform: translateY(1px);
    background: linear-gradient(180deg, #e5b14a 0%, #c4762a 60%, #793e13 100%);
}

.rb-rematch-cta[disabled] {
    opacity: 0.6;
    cursor: progress;
}

.rb-rematch-cta.is-first-duel {
    animation: rb-rematch-pulse 1.8s ease-in-out infinite;
}

@keyframes rb-rematch-pulse {
    0%, 100% {
        box-shadow:
            0 0 0 1px rgba(0, 0, 0, 0.35) inset,
            0 10px 28px rgba(220, 130, 40, 0.45),
            0 0 24px rgba(255, 190, 90, 0.4);
    }
    50% {
        box-shadow:
            0 0 0 1px rgba(0, 0, 0, 0.35) inset,
            0 12px 36px rgba(220, 130, 40, 0.6),
            0 0 44px rgba(255, 210, 120, 0.75);
    }
}

.rb-progression-tease {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin-top: 10px;
    padding: 10px 14px;
    border-radius: 10px;
    background: rgba(255, 200, 120, 0.08);
    border: 1px solid rgba(255, 200, 120, 0.2);
    color: rgba(245, 230, 200, 0.92);
    font-size: var(--fs-xs);
    line-height: 1.4;
}

.rb-progression-tease[hidden] {
    display: none;
}

.rb-progression-tease .rb-tease-headline {
    font-size: var(--fs-xs);
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #f8c259;
}

.rb-result-panel.is-first-duel {
    border-color: rgba(255, 190, 90, 0.55);
    box-shadow: 0 0 32px rgba(255, 180, 70, 0.25);
}

/* --- Reduced motion overrides para Fase 4 --------------------------- */
@media (prefers-reduced-motion: reduce) {
    .vfx-evolution-stage .vfx-evolution-rune,
    .vfx-evolution-stage .vfx-evolution-burst,
    .vfx-fusion-clone,
    .vfx-fusion-clone::after,
    .vfx-fusion-slot-flash,
    .vfx-fusion-burst,
    .rb-field-card.is-fusion-source,
    .rb-field-card.is-fusion-source::after,
    .rb-field-card.is-fusion-born,
    .rb-field-card.is-fusion-born::after,
    .vfx-finale-overlay.is-victory .vfx-finale-text,
    .vfx-finale-overlay.is-victory::before,
    .vfx-finale-overlay.is-victory::after,
    .vfx-finale-overlay.is-defeat::before,
    .vfx-finale-overlay.is-first-duel .vfx-finale-text,
    .vfx-hero-damage,
    .vfx-hero-damage::before,
    .vfx-hero-damage::after,
    .rb-hud-player.vfx-orb-crack .rb-hp-meter,
    .rb-hud-player.vfx-orb-crack .rb-hp-meter::after,
    .rb-game-board.vfx-board-shatter,
    .rb-rematch-cta.is-first-duel {
        animation: none !important;
    }
    .vfx-evolution-clone,
    .vfx-fusion-clone {
        transition: opacity 80ms ease;
    }
    .vfx-evolution-stage .vfx-evolution-overlay,
    .vfx-fusion-overlay,
    .vfx-finale-overlay .vfx-finale-curtain,
    .vfx-finale-overlay .vfx-finale-text {
        transition: none !important;
    }
}

/* v58: native touch layout. Mobile no longer shrinks the desktop canvas. */
@media (max-width: 1179px) {
    body.rb-game-page.rb-mobile-native {
        --rb-touch-target-min: 44px;
        --rb-touch-target-comfort: 48px;
        --rb-mobile-nav-height: 196px;
        position: relative;
        inset: auto;
        width: auto;
        height: auto;
        min-height: 100dvh;
        overflow-x: hidden;
        overflow-y: auto;
        overscroll-behavior-y: contain;
        touch-action: pan-y;
    }

    .rb-mobile-native .rb-global-nav {
        grid-template-columns: minmax(0, 1fr);
        gap: 12px;
        padding: 12px;
    }

    .rb-mobile-native .rb-global-tabs {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(56px, 1fr));
        gap: 6px;
        overflow: visible;
    }

    .rb-mobile-native .rb-global-tabs a {
        display: grid;
        width: 100%;
        min-width: 0;
        place-items: center;
        padding-inline: 4px;
        line-height: 1.1;
        overflow-wrap: anywhere;
    }

    .rb-mobile-native .rb-global-player {
        display: flex;
        gap: 12px;
        overflow-x: auto;
    }

    .rb-mobile-native .rb-global-player > * {
        flex: 1 0 auto;
    }

    .rb-mobile-native :where(button, a, [role="button"], .rb-field-card, .rb-field-slot-empty) {
        min-width: var(--rb-touch-target-min);
        min-height: var(--rb-touch-target-min);
        touch-action: manipulation;
        -webkit-tap-highlight-color: transparent;
    }

    .rb-mobile-native .rb-global-tabs a,
    .rb-mobile-native .rb-nav-auth {
        min-height: var(--rb-touch-target-min);
        padding-block: 11px;
    }

    .rb-mobile-native .rb-game-viewport {
        position: relative;
        inset: auto;
        width: 100%;
        height: auto;
        min-height: 100dvh;
        display: block;
        overflow: visible;
        contain: layout paint;
        transform: translateZ(0);
        transform-origin: center center;
        will-change: transform;
        padding:
            calc(var(--rb-mobile-nav-height, 152px) + var(--rb-safe-top) + 10px)
            max(8px, var(--rb-safe-right))
            calc(78px + var(--rb-safe-bottom))
            max(8px, var(--rb-safe-left));
    }

    .rb-mobile-native .rb-game-viewport.vfx-screen-shake,
    .rb-mobile-native .rb-game-viewport.is-screen-shaking {
        contain: layout paint;
        transform-origin: center center;
    }

    /* v59 — cascata defensiva contra v55 VFX. O seletor base de touch
       targets usa :where() (especificidade 0), então qualquer classe
       VFX que herde min-height/min-width zerados via cascade vence.
       Reforçamos AQUI com especificidade dedicada por classe VFX:
       mesmo durante .vfx-hero-damage, .is-dead-dissolve, .vfx-shield-shatter,
       .is-cta-pulse e .vfx-orb-crack, o alvo de toque continua 44-48px e
       o jogador não erra o toque por causa de uma animação rolando. */
    .rb-mobile-native button.vfx-hero-damage,
    .rb-mobile-native a.vfx-hero-damage,
    .rb-mobile-native [role="button"].vfx-hero-damage,
    .rb-mobile-native .rb-field-card.is-dead-dissolve,
    .rb-mobile-native .rb-field-card.vfx-shield-shatter,
    .rb-mobile-native button.is-cta-pulse,
    .rb-mobile-native .rb-hud-player.vfx-orb-crack button,
    .rb-mobile-native .rb-hud-player.vfx-orb-crack a {
        min-width: var(--rb-touch-target-min);
        min-height: var(--rb-touch-target-min);
    }

    .rb-mobile-native .rb-game-board {
        position: relative;
        left: auto;
        top: auto;
        width: 100% !important;
        height: auto !important;
        min-height: 0;
        overflow: hidden !important;
        transform: none;
        transform-style: preserve-3d;
        backface-visibility: hidden;
        contain: layout paint;
        display: grid;
        grid-template-areas:
            "hud"
            "arena"
            "evo"
            "hand"
            "actions"
            "result"
            "log";
        grid-template-columns: minmax(0, 1fr);
        grid-template-rows: auto;
        gap: 12px;
        padding: 10px;
        border: 1px solid rgba(255, 255, 255, 0.12);
    }

    .rb-mobile-native .rb-game-board.vfx-board-shatter,
    .rb-mobile-native .vfx-evolution-clone,
    .rb-mobile-native .vfx-evolution-rune,
    .rb-mobile-native .vfx-evolution-burst {
        transform-origin: center center;
        will-change: transform, opacity;
    }

    .rb-mobile-native .rb-hud,
    .rb-mobile-native .rb-battle-zone,
    .rb-mobile-native .rb-player-hand,
    .rb-mobile-native .rb-actions-row,
    .rb-mobile-native .rb-result-panel,
    .rb-mobile-native .rb-log,
    .rb-mobile-native .rb-evolution-panel {
        position: relative;
        inset: auto;
        width: 100%;
        height: auto;
        min-height: 0;
    }

    .rb-mobile-native .rb-hud {
        grid-area: hud;
        min-height: 90px;
        grid-template-columns: minmax(0, 1fr) 58px minmax(0, 1fr);
    }

    .rb-mobile-native .rb-hud-side {
        min-height: 90px;
        display: block;
        padding: 10px 8px;
    }

    .rb-mobile-native .rb-hud-copy > span {
        font-size: var(--fs-3xs);
    }

    .rb-mobile-native .rb-mark,
    .rb-mobile-native .rb-bot-emblem {
        display: none;
    }

    .rb-mobile-native .rb-hud-health strong,
    .rb-mobile-native .rb-turn-core strong {
        font-size: var(--fs-lg);
    }

    .rb-mobile-native .rb-hp-meter {
        width: 100%;
        height: 7px;
    }

    .rb-mobile-native .rb-zone-row {
        display: grid;
        grid-template-columns: 1fr;
        gap: 3px;
        font-size: var(--fs-3xs);
    }

    .rb-mobile-native .rb-turn-core {
        padding: 10px 3px;
    }

    .rb-mobile-native .rb-turn-core small {
        font-size: var(--fs-3xs);
    }

    .rb-mobile-native .rb-phase-timeline {
        gap: 2px;
        margin-top: 4px;
    }

    .rb-mobile-native .rb-phase-timeline i {
        width: 8px;
        height: 3px;
    }

    .rb-mobile-native .rb-battle-zone {
        grid-area: arena;
        min-height: 386px;
        display: grid;
        grid-template-rows: minmax(166px, 1fr) 30px minmax(166px, 1fr);
        gap: 6px;
        padding: 8px 6px;
    }

    .rb-mobile-native .rb-field-row {
        grid-template-columns: 1fr;
        gap: 6px;
        align-content: center;
    }

    .rb-mobile-native .rb-field-row > span {
        font-size: var(--fs-3xs);
        padding-inline: 4px;
    }

    .rb-mobile-native .rb-field-slots {
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 6px;
    }

    .rb-mobile-native .rb-field-card,
    .rb-mobile-native .rb-field-slot-empty {
        height: clamp(112px, 31vw, 132px);
        min-height: 112px;
        transform-origin: center center;
        backface-visibility: hidden;
    }

    .rb-mobile-native .rb-field-card {
        --cost-size: 27px;
        --medal-size: 29px;
        --text-pad-x: 34px;
    }

    .rb-mobile-native .rb-field-card .rb-card-textbox p {
        font-size: var(--fs-3xs);
        line-height: 1.12;
    }

    .rb-mobile-native .rb-card-stage {
        display: contents;
    }

    .rb-mobile-native .rb-monster-card-main {
        display: none;
    }

    .rb-mobile-native .rb-evolution-panel {
        grid-area: evo;
        display: grid;
        grid-template-columns: auto 62px 1fr auto;
        align-items: center;
        gap: 8px;
        min-height: 72px;
        padding: 8px;
    }

    .rb-mobile-native .rb-evolution-thumb {
        width: 58px;
        height: 58px;
    }

    .rb-mobile-native .rb-evolution-panel small {
        display: none;
    }

    .rb-mobile-native .rb-combine-button {
        width: auto;
        min-width: 78px;
        min-height: 48px;
        font-size: var(--fs-xs);
    }

    .rb-mobile-native .rb-player-hand {
        grid-area: hand;
        min-height: 174px;
        overflow: visible;
    }

    .rb-mobile-native .rb-hand {
        display: grid;
        grid-auto-flow: column;
        grid-auto-columns: clamp(116px, 35vw, 142px);
        grid-template-columns: none;
        gap: 8px;
        height: 164px;
        overflow-x: auto;
        overflow-y: visible;
        padding: 8px 2px 4px;
        scroll-snap-type: x proximity;
        touch-action: pan-x;
    }

    .rb-mobile-native .rb-hand .rb-mini-card {
        width: 100%;
        height: 150px;
        min-height: 150px;
        scroll-snap-align: start;
    }

    .rb-mobile-native .rb-actions-row {
        grid-area: actions;
        position: sticky;
        bottom: calc(8px + var(--rb-safe-bottom));
        z-index: 60;
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 8px;
        padding: 8px;
        background: rgba(5, 7, 10, 0.96);
        border: 1px solid rgba(244, 173, 38, 0.22);
    }

    .rb-mobile-native .rb-actions-row > div {
        gap: 4px;
    }

    .rb-mobile-native #next-turn-button.rb-button-secondary,
    .rb-mobile-native #play-button.rb-button-primary,
    .rb-mobile-native .rb-actions-row .rb-cta,
    .rb-mobile-native .rb-actions-row .rb-secondary {
        width: 100%;
        min-width: 0;
        min-height: 52px;
        font-size: var(--fs-xs);
    }

    .rb-mobile-native .rb-actions-row small {
        font-size: var(--fs-3xs);
    }

    .rb-mobile-native .rb-result-panel {
        grid-area: result;
        display: grid;
        grid-template-columns: minmax(0, 1fr) 98px;
        align-items: stretch;
        gap: 8px;
        padding: 12px;
    }

    .rb-mobile-native .rb-result-panel p {
        display: block;
        overflow: visible;
        -webkit-line-clamp: unset;
    }

    .rb-mobile-native .rb-result-panel .rb-secondary {
        width: 100%;
        min-width: 0;
        min-height: 48px;
        padding: 8px 6px;
        font-size: var(--fs-sm);
    }

    .rb-mobile-native .rb-log,
    .rb-mobile-native .rb-log:not(.is-open),
    .rb-mobile-native .rb-log.is-open {
        grid-area: log;
        width: 100%;
        height: auto;
    }
}

@media (max-width: 1179px) and (orientation: landscape) {
    .rb-mobile-native .rb-game-viewport {
        padding-top: calc(var(--rb-mobile-nav-height, 70px) + var(--rb-safe-top) + 8px);
    }

    .rb-mobile-native .rb-game-board {
        grid-template-areas:
            "hud hud"
            "arena hand"
            "arena evo"
            "actions actions"
            "result log";
        grid-template-columns: minmax(330px, 1.15fr) minmax(250px, 0.85fr);
    }

    .rb-mobile-native .rb-battle-zone {
        min-height: 352px;
    }
}

/* v59 performance hardening: waiting states stay visually rich but static.
   Finite combat and transition effects remain available when actions occur. */
.rb-game-viewport::before,
.rb-game-viewport::after,
.rb-game-board[data-bot-profile="aggressive"] .rb-hud-bot,
.rb-game-board[data-bot-profile="aggressive"] .rb-bot-emblem,
.rb-game-board[data-bot-profile="opportunist"] .rb-hud-bot,
.rb-game-board[data-bot-profile="opportunist"] .rb-bot-emblem,
.rb-monster-card.is-evolved:hover .rb-card-art::before,
.rb-hand .rb-mini-card.is-evolved:hover .rb-mini-art::after,
.rb-monster-card.is-burn,
.rb-mini-card.is-burn,
#next-turn-button.is-cta-pulse:not(:disabled),
#next-turn-button.is-cta-pulse:not(:disabled)::after,
.rb-field-card.is-attacking,
.rb-game-board.is-choosing-attack .rb-battle-zone::after,
.rb-field-card.is-targetable,
.rb-field-slot-empty[data-direct-attack="true"].is-selected,
#player-battlefield .rb-field-slot-empty.is-summon-target::before,
#bot-battlefield .rb-field-slot-empty[data-direct-attack="true"]::before,
.rb-game-board.is-choosing-attack #bot-battlefield .rb-field-slot-empty::before,
.battlefield-ember,
.rb-field-card.is-element-fire::before,
.rb-field-card.is-element-water::before,
.rb-field-card.is-element-earth:hover::before,
.rb-field-card.is-element-earth.is-selected::before,
.rb-field-card.is-element-shadow::before,
.vfx-finale-overlay.is-victory .vfx-finale-text,
.vfx-finale-overlay.is-victory::before,
.vfx-finale-overlay.is-victory::after {
    animation: none;
}

