/* ============================================================
   Living Portraits — CSS Animation System
   Makes character portraits on The Veil feel alive through
   ambient breathing, event-driven reactions, and sustained
   visual state driven by HP/conditions.

   Architecture:
     Layer 1 (idle)     → .portrait-card__image transform/opacity
     Layer 2 (state)    → card + pseudo-element filters/overlays
     Layer 3 (reaction) → card-level animation via JS class toggle

   All animated properties are GPU-composited:
   transform, opacity, filter only — no layout thrash.
   ============================================================ */

/* --- Animatable custom properties -------------------------------- */

@property --rw-lp-idle-speed {
    syntax: '<number>';
    initial-value: 1;
    inherits: true;
}

@property --rw-lp-breath-intensity {
    syntax: '<number>';
    initial-value: 1;
    inherits: true;
}

@property --rw-hp-pct {
    syntax: '<number>';
    initial-value: 1;
    inherits: true;
}

/* =================================================================
   SECTION 1 — AMBIENT IDLE
   Every portrait breathes. Always on, never distracting.
   ================================================================= */

/* --- Breathing: subtle scaleY oscillation anchored at bottom --- */
@keyframes rw-lp-breathe {
    0%, 100% {
        transform: scaleY(1) translateY(0);
    }
    50% {
        transform: scaleY(1.008) translateY(-0.3%);
    }
}

/* --- Drift: very slow horizontal parallax within frame --- */
@keyframes rw-lp-ambient-drift {
    0%, 100% {
        transform: translateX(0);
    }
    33% {
        transform: translateX(0.4%);
    }
    66% {
        transform: translateX(-0.4%);
    }
}

/* --- Vignette flicker: simulates firelight on the portrait --- */
@keyframes rw-lp-vignette-flicker {
    0%, 100% {
        opacity: 0.25;
        background-position: 50% 82%;
    }
    35% {
        opacity: 0.38;
        background-position: 48% 80%;
    }
    65% {
        opacity: 0.28;
        background-position: 52% 83%;
    }
}

/* --- Apply idle to all portrait images --- */
.portrait-card__image {
    transform-origin: center bottom;
    animation:
        rw-lp-breathe calc(6s / var(--rw-lp-idle-speed, 1)) ease-in-out infinite,
        rw-lp-ambient-drift calc(12s / var(--rw-lp-idle-speed, 1)) ease-in-out infinite;
    animation-delay:
        var(--rw-lp-stagger, 0s),
        calc(var(--rw-lp-stagger, 0s) + 2s);
    will-change: transform;
}

/* --- Ambient vignette overlay (::before on image-wrap) --- */
.portrait-card__image-wrap::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    background: radial-gradient(ellipse at 50% 82%, transparent 35%, rgba(0, 0, 0, 0.45) 100%);
    animation: rw-lp-vignette-flicker 8s ease-in-out infinite;
    animation-delay: calc(var(--rw-lp-stagger, 0s) + 1.2s);
    will-change: opacity;
}

/* --- Reaction overlay surface (::after on image-wrap) ---
   Idle state: transparent. Reactions and states write to this. */
.portrait-card__image-wrap::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 3;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.4s ease;
}


/* =================================================================
   SECTION 2 — CLASS-SPECIFIC IDLE FLAVOR
   Each class gets a unique ambient treatment layered onto
   the base breathing. Applied via existing class selectors.
   ================================================================= */

/* --- Warlock: faint eldritch purple glow --- */
@keyframes rw-lp-warlock-pulse {
    0%, 100% { opacity: 0; }
    50%      { opacity: 0.12; }
}

.portrait-card--class-warlock .portrait-card__image-wrap::after {
    background: radial-gradient(ellipse at 50% 60%, rgba(106, 58, 106, 0.5) 0%, transparent 70%);
    mix-blend-mode: screen;
    animation: rw-lp-warlock-pulse 5s ease-in-out infinite;
    animation-delay: var(--rw-lp-stagger, 0s);
}

/* --- Druid: drifting leaf particles (simulated via gradient dots) --- */
@keyframes rw-lp-druid-drift {
    from { background-position: 20% -10%, 60% -30%, 85% -20%; }
    to   { background-position: 30% 110%, 50% 130%, 75% 120%; }
}

.portrait-card--class-druid .portrait-card__image-wrap::after {
    background-image:
        radial-gradient(2px 3px at center, rgba(74, 140, 92, 0.6) 50%, transparent 50%),
        radial-gradient(3px 2px at center, rgba(100, 160, 80, 0.5) 50%, transparent 50%),
        radial-gradient(2px 2px at center, rgba(60, 120, 70, 0.4) 50%, transparent 50%);
    background-size: 30% 30%, 25% 25%, 35% 35%;
    background-repeat: no-repeat;
    mix-blend-mode: screen;
    opacity: 1;
    animation: rw-lp-druid-drift 15s linear infinite;
    animation-delay: var(--rw-lp-stagger, 0s);
}

/* --- Paladin / Cleric: diagonal golden/silver shimmer --- */
@keyframes rw-lp-divine-shimmer {
    0%   { background-position: -100% 0; }
    100% { background-position: 200% 0; }
}

.portrait-card--class-paladin .portrait-card__image-wrap::after,
.portrait-card--class-cleric .portrait-card__image-wrap::after {
    background: linear-gradient(
        120deg,
        transparent 30%,
        rgba(212, 168, 64, 0.1) 45%,
        rgba(220, 210, 180, 0.15) 50%,
        rgba(212, 168, 64, 0.1) 55%,
        transparent 70%
    );
    background-size: 200% 100%;
    mix-blend-mode: screen;
    opacity: 1;
    animation: rw-lp-divine-shimmer 6s ease-in-out infinite;
    animation-delay: var(--rw-lp-stagger, 0s);
}

/* --- Barbarian: faint reddish heat distortion overlay --- */
@keyframes rw-lp-barb-heat {
    0%, 100% { opacity: 0; }
    50%      { opacity: 0.06; }
}

.portrait-card--class-barbarian .portrait-card__image-wrap::after {
    background: radial-gradient(ellipse at 50% 70%, rgba(184, 58, 26, 0.4) 0%, transparent 60%);
    mix-blend-mode: multiply;
    animation: rw-lp-barb-heat 4s ease-in-out infinite;
    animation-delay: var(--rw-lp-stagger, 0s);
}

/* --- Rogue: deeper, more dramatic vignette --- */
.portrait-card--class-rogue .portrait-card__image-wrap::before {
    background: radial-gradient(ellipse at 50% 75%, transparent 25%, rgba(0, 0, 0, 0.55) 100%);
}

/* --- Wizard: faint arcane blue shimmer --- */
@keyframes rw-lp-wizard-shimmer {
    0%, 100% { opacity: 0; }
    50%      { opacity: 0.08; }
}

.portrait-card--class-wizard .portrait-card__image-wrap::after {
    background: radial-gradient(ellipse at 50% 40%, rgba(74, 106, 154, 0.4) 0%, transparent 60%);
    mix-blend-mode: screen;
    animation: rw-lp-wizard-shimmer 7s ease-in-out infinite;
    animation-delay: var(--rw-lp-stagger, 0s);
}

/* --- Ranger: subtle nature light dapple --- */
@keyframes rw-lp-ranger-dapple {
    0%, 100% { opacity: 0.04; background-position: 40% 30%; }
    50%      { opacity: 0.09; background-position: 55% 45%; }
}

.portrait-card--class-ranger .portrait-card__image-wrap::after {
    background: radial-gradient(circle at 45% 35%, rgba(106, 122, 80, 0.5) 0%, transparent 40%);
    mix-blend-mode: screen;
    animation: rw-lp-ranger-dapple 9s ease-in-out infinite;
    animation-delay: var(--rw-lp-stagger, 0s);
}

/* --- Bard: warm golden ambient glow --- */
@keyframes rw-lp-bard-glow {
    0%, 100% { opacity: 0.03; }
    50%      { opacity: 0.1; }
}

.portrait-card--class-bard .portrait-card__image-wrap::after {
    background: radial-gradient(ellipse at 50% 65%, rgba(196, 160, 64, 0.35) 0%, transparent 55%);
    mix-blend-mode: screen;
    animation: rw-lp-bard-glow 5s ease-in-out infinite;
    animation-delay: var(--rw-lp-stagger, 0s);
}

/* --- Monk: serene centered calm (gentle light pulse) --- */
@keyframes rw-lp-monk-calm {
    0%, 100% { opacity: 0; }
    50%      { opacity: 0.06; }
}

.portrait-card--class-monk .portrait-card__image-wrap::after {
    background: radial-gradient(circle at 50% 50%, rgba(160, 128, 96, 0.3) 0%, transparent 50%);
    mix-blend-mode: screen;
    animation: rw-lp-monk-calm 8s ease-in-out infinite;
    animation-delay: var(--rw-lp-stagger, 0s);
}


/* =================================================================
   SECTION 3 — SUSTAINED VISUAL STATES
   Persistent CSS classes driven by Blazor class binding.
   Compose with idle + reactions. Use transitions, not animations,
   for smooth state changes.
   ================================================================= */

/* --- Bloodied (25–50% HP) --- */
.rw-lp-state-bloodied {
    --rw-lp-idle-speed: 1.3;
}

.rw-lp-state-bloodied .portrait-card__image {
    filter: saturate(0.85);
    transition: filter 0.6s ease;
}

.rw-lp-state-bloodied .portrait-card__image-wrap::before {
    background:
        radial-gradient(ellipse at 50% 82%, transparent 35%, rgba(0, 0, 0, 0.45) 100%),
        linear-gradient(to top, rgba(140, 30, 20, 0.08), transparent 60%);
}

/* --- Critical (<25% HP) --- */
.rw-lp-state-critical {
    --rw-lp-idle-speed: 1.6;
}

.rw-lp-state-critical .portrait-card__image {
    filter: saturate(0.7) brightness(0.9);
    transition: filter 0.6s ease;
}

.rw-lp-state-critical .portrait-card__image-wrap::before {
    background:
        radial-gradient(ellipse at 50% 82%, transparent 25%, rgba(140, 30, 20, 0.2) 100%),
        linear-gradient(to top, rgba(140, 30, 20, 0.15), transparent 50%);
}

/* Crack overlay at low opacity for critical state */
.rw-lp-state-critical .portrait-card__image-wrap::after {
    background:
        linear-gradient(47deg, transparent 44%, rgba(80, 20, 10, 0.15) 45%, transparent 46%),
        linear-gradient(133deg, transparent 52%, rgba(80, 20, 10, 0.12) 53%, transparent 54%),
        linear-gradient(78deg, transparent 38%, rgba(80, 20, 10, 0.1) 39%, transparent 40%);
    opacity: 1 !important;
    animation: none !important;
}

/* --- Dead --- */
.rw-lp-state-dead {
    --rw-lp-idle-speed: 0;
}

.rw-lp-state-dead .portrait-card__image {
    filter: grayscale(0.9) brightness(0.35);
    transform: scale(0.96) rotate(-2deg);
    animation-play-state: paused;
    transition: filter 1s ease, transform 1s ease;
}

.rw-lp-state-dead .portrait-card__image-wrap::before {
    opacity: 0.6;
    background: rgba(0, 0, 0, 0.4);
    animation-play-state: paused;
}

.rw-lp-state-dead .portrait-card__image-wrap::after {
    background:
        linear-gradient(35deg, transparent 30%, rgba(60, 10, 5, 0.25) 31%, transparent 32%),
        linear-gradient(145deg, transparent 45%, rgba(60, 10, 5, 0.2) 46%, transparent 47%),
        linear-gradient(80deg, transparent 55%, rgba(60, 10, 5, 0.18) 56%, transparent 57%),
        linear-gradient(110deg, transparent 20%, rgba(60, 10, 5, 0.15) 21%, transparent 22%);
    opacity: 1 !important;
    animation: none !important;
}

/* Suppress reactions on dead portraits (except revive) */
.rw-lp-state-dead.rw-lp-react-hit,
.rw-lp-state-dead.rw-lp-react-crit,
.rw-lp-state-dead.rw-lp-react-heal,
.rw-lp-state-dead.rw-lp-react-turn,
.rw-lp-state-dead.rw-lp-react-loot,
.rw-lp-state-dead.rw-lp-react-cast,
.rw-lp-state-dead.rw-lp-react-combat-ready {
    animation: none !important;
}

/* --- Down / Unconscious --- */
.rw-lp-state-down {
    --rw-lp-idle-speed: 0.4;
}

.rw-lp-state-down .portrait-card__image {
    filter: grayscale(0.5) brightness(0.5);
    transform: translateY(3px);
    transition: filter 0.8s ease, transform 0.8s ease;
}

/* Suppress HP sheen on down/dead — red fades out as grayscale fades in */
.rw-lp-state-down .portrait-card__hp-sheen,
.rw-lp-state-dead .portrait-card__hp-sheen {
    opacity: 0 !important;
    transition: opacity 1s ease;
}

/* --- Temp HP active: shield shimmer --- */
@keyframes rw-lp-temphp-shimmer {
    0%, 100% { opacity: 0.06; }
    50%      { opacity: 0.15; }
}

.rw-lp-state-temphp::before {
    box-shadow: inset 0 0 12px rgba(100, 160, 220, 0.2);
}

.rw-lp-state-temphp .portrait-card__image-wrap::after {
    background: linear-gradient(
        180deg,
        rgba(100, 160, 220, 0.08) 0%,
        rgba(140, 180, 230, 0.12) 50%,
        rgba(100, 160, 220, 0.06) 100%
    );
    mix-blend-mode: screen;
    opacity: 1;
    animation: rw-lp-temphp-shimmer 3s ease-in-out infinite !important;
}

/* --- Raging --- */
@keyframes rw-lp-rage-heat {
    0%, 100% { opacity: 0.08; }
    50%      { opacity: 0.2; }
}

.rw-lp-state-raging {
    --rw-lp-idle-speed: 2.0;
    --rw-lp-breath-intensity: 2.0;
    border-color: #b83a1a !important;
}

.rw-lp-state-raging .portrait-card__image {
    filter: saturate(1.3) contrast(1.1);
    transition: filter 0.4s ease;
}

.rw-lp-state-raging .portrait-card__image-wrap::before {
    background:
        radial-gradient(ellipse at 50% 100%, rgba(184, 58, 26, 0.3) 0%, transparent 60%),
        radial-gradient(ellipse at 50% 82%, transparent 25%, rgba(100, 20, 10, 0.3) 100%);
}

.rw-lp-state-raging .portrait-card__image-wrap::after {
    background: radial-gradient(ellipse at 50% 80%, rgba(184, 58, 26, 0.3) 0%, transparent 50%);
    mix-blend-mode: multiply;
    animation: rw-lp-rage-heat 1.5s ease-in-out infinite !important;
    opacity: 1;
}

/* --- Poisoned --- */
@keyframes rw-lp-poison-wobble {
    0%, 100% { transform: rotate(0deg); }
    25%      { transform: rotate(0.3deg); }
    75%      { transform: rotate(-0.3deg); }
}

.rw-lp-state-poisoned .portrait-card__image {
    filter: hue-rotate(15deg) saturate(0.8);
    animation:
        rw-lp-breathe calc(6s / var(--rw-lp-idle-speed, 1)) ease-in-out infinite,
        rw-lp-ambient-drift calc(12s / var(--rw-lp-idle-speed, 1)) ease-in-out infinite,
        rw-lp-poison-wobble 2s ease-in-out infinite;
    transition: filter 0.4s ease;
}

.rw-lp-state-poisoned .portrait-card__image-wrap::before {
    background:
        radial-gradient(ellipse at 50% 82%, transparent 35%, rgba(0, 0, 0, 0.45) 100%),
        linear-gradient(to top, rgba(40, 120, 50, 0.1), transparent 50%);
}

/* --- Frightened --- */
@keyframes rw-lp-tremble {
    0%, 100% { transform: translateX(0); }
    25%      { transform: translateX(-0.5px); }
    75%      { transform: translateX(0.5px); }
}

.rw-lp-state-frightened {
    --rw-lp-idle-speed: 1.8;
}

.rw-lp-state-frightened .portrait-card__image {
    filter: saturate(0.7) brightness(0.9);
    transition: filter 0.4s ease;
}

.rw-lp-state-frightened .portrait-card {
    animation: rw-lp-tremble 0.15s linear infinite;
}

/* --- Blessed / Buffed --- */
@keyframes rw-lp-blessed-sparkle {
    0%   { background-position: 20% 80%, 70% 20%, 40% 50%, 80% 70%; opacity: 0.06; }
    50%  { background-position: 25% 70%, 65% 30%, 45% 40%, 75% 60%; opacity: 0.18; }
    100% { background-position: 30% 60%, 60% 40%, 50% 30%, 70% 50%; opacity: 0.06; }
}

.rw-lp-state-blessed {
    box-shadow:
        var(--rw-shadow),
        0 0 10px rgba(196, 160, 64, 0.15),
        0 0 20px rgba(196, 160, 64, 0.06);
}

.rw-lp-state-blessed .portrait-card__image-wrap::after {
    background-image:
        radial-gradient(1.5px 1.5px at 20% 80%, rgba(218, 184, 85, 0.8) 50%, transparent 50%),
        radial-gradient(1px 1px at 70% 20%, rgba(218, 184, 85, 0.6) 50%, transparent 50%),
        radial-gradient(2px 2px at 40% 50%, rgba(218, 184, 85, 0.7) 50%, transparent 50%),
        radial-gradient(1px 1px at 80% 70%, rgba(218, 184, 85, 0.5) 50%, transparent 50%);
    background-size: 100% 100%;
    mix-blend-mode: screen;
    opacity: 1;
    animation: rw-lp-blessed-sparkle 3s ease-in-out infinite !important;
}

/* --- Cursed / Hexed --- */
@keyframes rw-lp-curse-pulse {
    0%, 100% {
        box-shadow: inset 0 0 8px rgba(90, 50, 120, 0.15), inset 0 0 3px rgba(40, 120, 50, 0.1);
    }
    50% {
        box-shadow: inset 0 0 16px rgba(90, 50, 120, 0.3), inset 0 0 6px rgba(40, 120, 50, 0.2);
    }
}

.rw-lp-state-cursed {
    animation: rw-lp-curse-pulse 2.5s ease-in-out infinite;
}

.rw-lp-state-cursed .portrait-card__image {
    filter: hue-rotate(-10deg) saturate(0.85);
    transition: filter 0.4s ease;
}

/* --- Concentrating (enhanced beyond existing aura) --- */
@keyframes rw-lp-conc-orbit {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}

.rw-lp-state-concentrating .portrait-card__image-wrap::after {
    background: conic-gradient(
        from 0deg,
        transparent 0deg,
        rgba(72, 176, 192, 0.08) 30deg,
        transparent 60deg,
        transparent 120deg,
        rgba(72, 176, 192, 0.06) 150deg,
        transparent 180deg,
        transparent 240deg,
        rgba(72, 176, 192, 0.07) 270deg,
        transparent 300deg,
        transparent 360deg
    );
    opacity: 1;
    animation: rw-lp-conc-orbit 12s linear infinite !important;
    border-radius: 50%;
    inset: -10%;
}


/* =================================================================
   SECTION 4 — ONE-SHOT REACTIONS
   Triggered by JS (add class → animationend → remove class).
   Applied to the .portrait-card element so they compose with
   image-level idle animations without conflict.
   ================================================================= */

/* --- Take Damage (hit) — Enhanced with vertical impact + scale punch --- */
@keyframes rw-lp-hit-kf {
    0%, 100% { transform: translateX(0) translateY(0) scale(1); filter: brightness(1); }
    10%      { transform: translateX(-7px) translateY(2px) scale(1.02); filter: brightness(1.4); box-shadow: inset 0 0 24px rgba(184, 58, 26, 0.5); }
    25%      { transform: translateX(6px) translateY(-1px) scale(1.01); }
    40%      { transform: translateX(-5px) translateY(0) scale(1); }
    55%      { transform: translateX(3px); filter: brightness(1); box-shadow: inset 0 0 0 transparent; }
    70%      { transform: translateX(-2px); }
    85%      { transform: translateX(1px); }
}

.rw-lp-react-hit {
    animation: rw-lp-hit-kf 0.4s ease-out !important;
}

/* Image-level flash on hit — brief brightness/saturation punch */
.rw-lp-react-hit .portrait-card__image {
    filter: brightness(1.3) saturate(1.2);
    transition: filter 0.15s ease-out;
}

/* --- Critical Hit --- */
@keyframes rw-lp-crit-kf {
    0%       { transform: translateX(0) scale(1); filter: brightness(1); }
    8%       { transform: translateX(-8px) scale(1.04); filter: brightness(1.5) saturate(1.3); box-shadow: inset 0 0 30px rgba(180, 40, 30, 0.6); }
    18%      { transform: translateX(8px) scale(1.03); }
    28%      { transform: translateX(-6px) scale(1.02); }
    40%      { transform: translateX(5px) scale(1.01); filter: brightness(1.1); box-shadow: inset 0 0 15px rgba(180, 40, 30, 0.3); }
    55%      { transform: translateX(-3px); }
    70%      { transform: translateX(2px); filter: brightness(1); box-shadow: inset 0 0 0 transparent; }
    100%     { transform: translateX(0) scale(1); }
}

@keyframes rw-lp-crit-splatter {
    0%       { opacity: 0; }
    15%      { opacity: 0.5; }
    100%     { opacity: 0; }
}

.rw-lp-react-crit {
    animation: rw-lp-crit-kf 0.6s ease-out !important;
}

.rw-lp-react-crit .portrait-card__image-wrap::after {
    background: radial-gradient(ellipse at 30% 20%, rgba(160, 20, 10, 0.4) 0%, transparent 35%),
                radial-gradient(ellipse at 75% 30%, rgba(140, 15, 5, 0.3) 0%, transparent 30%),
                radial-gradient(ellipse at 50% 85%, rgba(120, 10, 5, 0.35) 0%, transparent 40%) !important;
    mix-blend-mode: multiply;
    animation: rw-lp-crit-splatter 0.6s ease-out forwards !important;
}

/* --- Healed --- */
@keyframes rw-lp-heal-kf {
    0%   { transform: scale(1); filter: brightness(1); }
    30%  { transform: scale(1.02); filter: brightness(1.15); }
    100% { transform: scale(1); filter: brightness(1); }
}

@keyframes rw-lp-heal-sweep {
    0%   { opacity: 0; background-position: 50% 120%; }
    30%  { opacity: 0.4; background-position: 50% 50%; }
    100% { opacity: 0; background-position: 50% -20%; }
}

.rw-lp-react-heal {
    animation: rw-lp-heal-kf 0.8s ease-out !important;
}

.rw-lp-react-heal .portrait-card__image-wrap::after {
    background: linear-gradient(
        to top,
        rgba(80, 176, 104, 0.3) 0%,
        rgba(218, 184, 85, 0.2) 50%,
        transparent 100%
    ) !important;
    background-size: 100% 200%;
    mix-blend-mode: soft-light;
    animation: rw-lp-heal-sweep 0.8s ease-out forwards !important;
}

/* --- Level Up --- */
@keyframes rw-lp-levelup-kf {
    0%   { transform: scale(1); filter: brightness(1); }
    15%  { transform: scale(1.08); filter: brightness(1.3) saturate(1.2); }
    40%  { transform: scale(1.03); filter: brightness(1.15); }
    100% { transform: scale(1); filter: brightness(1); }
}

@keyframes rw-lp-levelup-burst {
    0%   { opacity: 0; transform: scale(0.5); }
    20%  { opacity: 0.6; transform: scale(1); }
    100% { opacity: 0; transform: scale(1.5); }
}

.rw-lp-react-levelup {
    animation: rw-lp-levelup-kf 1.5s cubic-bezier(0.23, 1, 0.32, 1) !important;
    box-shadow:
        0 0 40px rgba(218, 184, 85, 0.6),
        0 0 80px rgba(218, 184, 85, 0.2) !important;
}

.rw-lp-react-levelup .portrait-card__image-wrap::after {
    background: radial-gradient(circle at 50% 50%, rgba(218, 184, 85, 0.5) 0%, transparent 60%) !important;
    animation: rw-lp-levelup-burst 1.5s ease-out forwards !important;
}

/* --- Death --- */
@keyframes rw-lp-death-kf {
    0%   { filter: brightness(1) grayscale(0); transform: scale(1) rotate(0deg); }
    30%  { filter: brightness(0.6) grayscale(0.5); }
    100% { filter: brightness(0.35) grayscale(0.9); transform: scale(0.96) rotate(-2deg); }
}

.rw-lp-react-death {
    animation: rw-lp-death-kf 1.2s ease-in forwards !important;
}

/* --- Revived (nat20) --- */
@keyframes rw-lp-revived-kf {
    0%   { filter: brightness(2) grayscale(0.9); transform: scale(1); }
    20%  { filter: brightness(1.6) grayscale(0.4); }
    50%  { transform: scale(1.06); filter: brightness(1.2) grayscale(0); }
    100% { transform: scale(1); filter: brightness(1) grayscale(0); }
}

@keyframes rw-lp-revived-bloom {
    0%   { opacity: 0.7; box-shadow: 0 0 30px rgba(218, 184, 85, 0.6); }
    100% { opacity: 0; box-shadow: 0 0 0 rgba(218, 184, 85, 0); }
}

.rw-lp-react-revived {
    animation: rw-lp-revived-kf 1.0s ease-out forwards !important;
}

.rw-lp-react-revived::after {
    animation: rw-lp-revived-bloom 1.0s ease-out forwards !important;
}

/* Revive overrides dead state */
.rw-lp-state-dead.rw-lp-react-revived {
    animation: rw-lp-revived-kf 1.0s ease-out forwards !important;
}

.rw-lp-state-dead.rw-lp-react-revived .portrait-card__image {
    animation-play-state: running !important;
}

/* --- Death Save Success --- */
@keyframes rw-lp-ds-success-kf {
    0%, 100% { box-shadow: 0 0 0 rgba(196, 160, 64, 0); }
    40%      { box-shadow: 0 0 14px rgba(196, 160, 64, 0.5); }
}

.rw-lp-react-ds-success {
    animation: rw-lp-ds-success-kf 0.5s ease-out !important;
}

/* --- Death Save Failure --- */
@keyframes rw-lp-ds-fail-kf {
    0%       { filter: brightness(1); transform: translateY(0); }
    30%      { filter: brightness(0.7); box-shadow: inset 0 0 10px rgba(184, 58, 26, 0.4); }
    100%     { filter: brightness(1); transform: translateY(2px); box-shadow: inset 0 0 0 transparent; }
}

.rw-lp-react-ds-fail {
    animation: rw-lp-ds-fail-kf 0.5s ease-out forwards !important;
}

/* --- Concentration Broken --- */
@keyframes rw-lp-conc-break-kf {
    0%   { box-shadow: 0 0 12px rgba(72, 176, 192, 0.5); }
    40%  { box-shadow: 0 0 20px rgba(72, 176, 192, 0.3), 0 0 6px rgba(72, 176, 192, 0.6); }
    100% { box-shadow: 0 0 0 rgba(72, 176, 192, 0); }
}

@keyframes rw-lp-conc-break-shatter {
    0%   { opacity: 0.6; clip-path: inset(0); }
    100% { opacity: 0; clip-path: inset(-20% -20% -20% -20%); transform: scale(1.3); }
}

.rw-lp-react-conc-break {
    animation: rw-lp-conc-break-kf 0.6s ease-out !important;
}

.rw-lp-react-conc-break .portrait-card__image-wrap::after {
    background: radial-gradient(circle at 50% 50%, rgba(72, 176, 192, 0.3) 0%, transparent 50%) !important;
    animation: rw-lp-conc-break-shatter 0.6s ease-out forwards !important;
}

/* --- Turn Start --- */
@keyframes rw-lp-turn-kf {
    0%   { transform: scale(1); }
    30%  { transform: scale(1.03); }
    100% { transform: scale(1); }
}

@keyframes rw-lp-turn-spotlight {
    0%   { opacity: 0; background-position: -100% 0; }
    30%  { opacity: 0.3; }
    100% { opacity: 0; background-position: 200% 0; }
}

.rw-lp-react-turn {
    animation: rw-lp-turn-kf 0.6s ease-out !important;
}

.rw-lp-react-turn .portrait-card__image-wrap::before {
    background: linear-gradient(
        90deg,
        transparent 30%,
        rgba(196, 160, 64, 0.25) 50%,
        transparent 70%
    ) !important;
    background-size: 200% 100%;
    animation: rw-lp-turn-spotlight 0.6s ease-out forwards !important;
}

/* --- Combat Starts (all portraits) --- */
@keyframes rw-lp-combat-ready-kf {
    0%   { transform: scale(1) translateY(0); }
    40%  { transform: scale(1.02) translateY(-2px); border-color: var(--rw-gold); }
    100% { transform: scale(1) translateY(0); }
}

.rw-lp-react-combat-ready {
    animation: rw-lp-combat-ready-kf 0.5s ease-out !important;
}

/* --- Loot Earned --- */
@keyframes rw-lp-loot-sparkle {
    0%   {
        opacity: 0;
        background-position: 15% 85%, 55% 15%, 80% 60%, 30% 40%, 65% 80%;
    }
    30%  { opacity: 0.7; }
    100% {
        opacity: 0;
        background-position: 10% 70%, 50% 5%, 85% 45%, 25% 25%, 70% 65%;
    }
}

.rw-lp-react-loot .portrait-card__image-wrap::after {
    background-image:
        radial-gradient(2px 2px at 15% 85%, rgba(218, 184, 85, 0.9) 50%, transparent 50%),
        radial-gradient(1.5px 1.5px at 55% 15%, rgba(218, 184, 85, 0.8) 50%, transparent 50%),
        radial-gradient(2px 2px at 80% 60%, rgba(218, 184, 85, 0.7) 50%, transparent 50%),
        radial-gradient(1px 1px at 30% 40%, rgba(218, 184, 85, 0.9) 50%, transparent 50%),
        radial-gradient(1.5px 1.5px at 65% 80%, rgba(218, 184, 85, 0.6) 50%, transparent 50%) !important;
    background-size: 100% 100%;
    mix-blend-mode: screen;
    animation: rw-lp-loot-sparkle 0.8s ease-out forwards !important;
}

/* --- Spell Cast --- */
@keyframes rw-lp-cast-kf {
    0%   { box-shadow: 0 0 0 0 rgba(72, 176, 192, 0.5); }
    40%  { box-shadow: 0 0 20px 6px rgba(72, 176, 192, 0.3); }
    100% { box-shadow: 0 0 0 12px rgba(72, 176, 192, 0); }
}

.rw-lp-react-cast {
    animation: rw-lp-cast-kf 0.6s ease-out !important;
}
