/* Holographic card styling.
   Two CSS variables drive the per-card palette:
     --type-1: primary type color
     --type-2: secondary type color (= primary for mono-type)
*/

.card {
  position: relative;
  width: 160px;
  aspect-ratio: 5 / 7;
  border-radius: 14px;
  background: linear-gradient(150deg, var(--type-1, #888), var(--type-2, #444));
  padding: 4px;
  cursor: pointer;
  transition:
    transform 0.22s cubic-bezier(0.2, 0.9, 0.3, 1.4),
    filter 0.22s ease,
    box-shadow 0.22s ease;
  box-shadow:
    0 6px 14px rgba(0, 0, 0, 0.4),
    0 0 0 1px rgba(255, 255, 255, 0.04) inset;
  user-select: none;
  flex-shrink: 0;
  color: #fff;
  font-family: "Inter", system-ui, sans-serif;
}

.card .card-inner {
  position: relative;
  height: 100%;
  border-radius: 11px;
  background: #15192a;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* Animated holographic sheen — diagonal gradient sweeping over the card.
   `background-position` is the animated property, per spec. */
.card .card-sheen {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    115deg,
    transparent 30%,
    rgba(255, 255, 255, 0.12) 45%,
    rgba(255, 255, 255, 0.28) 50%,
    rgba(255, 255, 255, 0.12) 55%,
    transparent 70%
  );
  background-size: 300% 300%;
  background-position: 0% 0%;
  animation: holoSheen 4.5s linear infinite;
  mix-blend-mode: screen;
}

@keyframes holoSheen {
  0%   { background-position: -150% 100%; }
  100% { background-position: 200% -50%; }
}

.card:hover {
  transform: translateY(-12px) rotateX(8deg);
  filter: brightness(1.08);
  box-shadow:
    0 18px 30px rgba(0, 0, 0, 0.55),
    0 0 24px var(--type-1, #888),
    0 0 0 1px rgba(255, 255, 255, 0.1) inset;
  z-index: 5;
}

.card.unplayable {
  filter: grayscale(0.6) brightness(0.65);
  cursor: not-allowed;
}
.card.unplayable:hover {
  transform: none;
  filter: grayscale(0.6) brightness(0.65);
  box-shadow: 0 6px 14px rgba(0, 0, 0, 0.4);
}

/* Field-card state badges. Summoning sickness shows a sleeping zzz; spent
   (already attacked this turn) shows a clear "✓ ACTED" pill + dims the
   card. Pills sit clearly ABOVE the card, extending off the top edge so
   they read from across the board. */
.card.summoning::after {
  content: "💤 sleeping";
  position: absolute;
  top: -24px;
  left: 50%;
  transform: translateX(-50%);
  background: linear-gradient(145deg, #2a3658, #15192a);
  border: 1.5px solid rgba(180, 200, 255, 0.5);
  border-radius: 12px;
  padding: 4px 10px;
  font-size: 9px;
  letter-spacing: 1px;
  text-transform: uppercase;
  font-family: var(--font-display);
  color: #d4e0ff;
  white-space: nowrap;
  z-index: 10;
  box-shadow: 0 3px 8px rgba(0,0,0,0.5), 0 0 14px rgba(140, 180, 255, 0.3);
  pointer-events: none;
}
/* Guardians and sleepers can occupy the same card — offset the sleep pill
   down a tick so it doesn't overlap the shield. */
.card .card-guardian + .card-status,
.card.summoning .card-guardian + ::after { /* unused fallback */ }
.card.summoning .card-guardian {
  top: -34px; /* push the shield further up when there's a sleep pill */
}
.card.spent {
  filter: saturate(0.55) brightness(0.85);
}
.card.spent::after {
  content: "✓ ACTED";
  position: absolute;
  top: -16px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.78);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 10px;
  padding: 2px 8px;
  font-size: 8px;
  letter-spacing: 1px;
  font-family: var(--font-display);
  color: #aaa;
  white-space: nowrap;
  z-index: 3;
}

/* Critical-hit gold flash for the defender card. */
@keyframes critFlash {
  0%, 100% { box-shadow: 0 6px 14px rgba(0,0,0,0.4); }
  50%      { box-shadow: 0 0 30px #f7d02c, 0 0 60px #ee8130; }
}
.card.crit-flash { animation: critFlash 0.55s ease; }

/* AI summons a creature — brief celebratory glow around the new card. */
@keyframes aiSummon {
  0%   { transform: scale(0.5) translateY(-30px); opacity: 0; box-shadow: 0 0 0 0 rgba(255,255,255,0.6); }
  60%  { transform: scale(1.1); opacity: 1; box-shadow: 0 0 24px 4px rgba(255,255,255,0.5); }
  100% { transform: scale(1); opacity: 1; box-shadow: 0 6px 14px rgba(0,0,0,0.4); }
}
.card.ai-just-summoned { animation: aiSummon 0.7s cubic-bezier(0.2, 0.9, 0.3, 1.4); }

/* Level-up badge — small star pip in the top-left corner of evolved cards. */
.card .card-level {
  position: absolute;
  top: -10px;
  left: -8px;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #fff7c2, #f7d02c, #ee8130);
  color: #1a0a00;
  font-family: var(--font-display);
  font-size: 9px;
  display: grid;
  place-items: center;
  box-shadow: 0 0 12px rgba(247, 208, 44, 0.7), 0 2px 4px rgba(0, 0, 0, 0.5);
  z-index: 4;
  pointer-events: none;
  animation: levelPulse 2.4s ease-in-out infinite;
}
@keyframes levelPulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.12); }
}

/* Level-up flash when a card KOs an enemy and grows. */
@keyframes levelUp {
  0%   { transform: scale(1); box-shadow: 0 0 0 0 #f7d02c; }
  40%  { transform: scale(1.18); box-shadow: 0 0 35px 8px #f7d02c, 0 0 60px 12px #ee8130; }
  100% { transform: scale(1); box-shadow: 0 6px 14px rgba(0,0,0,0.4); }
}
.card.leveled-up { animation: levelUp 0.85s ease-out; }

/* Sacrifice prompt — pulsing red outline on your own field cards while
   choosing one to discard so the new hand card can take its slot. */
@keyframes sacrificePulse {
  0%, 100% { box-shadow: 0 6px 14px rgba(0,0,0,0.4), 0 0 0 0 rgba(255, 92, 99, 0.6); }
  50%      { box-shadow: 0 6px 14px rgba(0,0,0,0.4), 0 0 22px 4px rgba(255, 92, 99, 0.7); }
}
.card.sacrifice-target {
  animation: sacrificePulse 0.9s ease-in-out infinite;
  cursor: crosshair;
}

/* Drag-to-attack — visuals while dragging a player attacker. */
.card.being-dragged {
  opacity: 0.55;
  cursor: grabbing;
}
body.dragging-attack .ai-field .field-slot,
body.dragging-attack .champion-block.ai {
  outline: 2px dashed rgba(255, 92, 99, 0.45);
  outline-offset: 4px;
  border-radius: 14px;
  cursor: crosshair;
}
.drop-hover {
  background: rgba(255, 92, 99, 0.18) !important;
  box-shadow: 0 0 22px rgba(255, 92, 99, 0.55) inset;
}

/* Guardian badge — perched at the TOP-CENTER of the card and lifted high
   enough to clearly extend off the card's top edge. Sits above all other
   layers (z-10) so it never gets clipped by neighbouring cards. */
.card .card-guardian {
  position: absolute;
  top: -22px;
  left: 50%;
  transform: translateX(-50%);
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: radial-gradient(circle at 30% 30%, #e5edff, #4a6fc4 60%, #1f3982);
  color: #0a1430;
  font-size: 20px;
  display: grid;
  place-items: center;
  box-shadow:
    0 0 18px rgba(120, 165, 255, 0.95),
    0 0 36px rgba(120, 165, 255, 0.5),
    0 3px 6px rgba(0,0,0,0.6),
    inset 0 0 4px rgba(255,255,255,0.7);
  z-index: 10;
  pointer-events: none;
  animation: guardianPulse 1.8s ease-in-out infinite;
}
@keyframes guardianPulse {
  0%, 100% {
    transform: translateX(-50%) scale(1);
    box-shadow: 0 0 18px rgba(120, 165, 255, 0.95), 0 0 36px rgba(120, 165, 255, 0.5), 0 3px 6px rgba(0,0,0,0.6), inset 0 0 4px rgba(255,255,255,0.7);
  }
  50% {
    transform: translateX(-50%) scale(1.15);
    box-shadow: 0 0 26px rgba(120, 165, 255, 1), 0 0 52px rgba(120, 165, 255, 0.65), 0 3px 6px rgba(0,0,0,0.6), inset 0 0 4px rgba(255,255,255,0.8);
  }
}
/* When a Guardian is on the field, give it a defensive aura ring as a
   sibling element (not ::after — that conflicts with the .card.spent /
   .card.summoning pseudo badges). The ring is BRIGHT BLUE so it pops on
   any background and never tries to grey/mute the card it surrounds. */
.card .guardian-ring {
  position: absolute;
  inset: -7px;
  border-radius: 14px;
  border: 2px solid rgba(120, 165, 255, 0.65);
  box-shadow:
    0 0 22px rgba(120, 165, 255, 0.55),
    0 0 44px rgba(120, 165, 255, 0.25),
    inset 0 0 12px rgba(120, 165, 255, 0.25);
  pointer-events: none;
  z-index: 0; /* sit BEHIND the card-inner content so the art stays vibrant */
  animation: guardianRing 2.4s ease-in-out infinite;
}
@keyframes guardianRing {
  0%, 100% { opacity: 0.75; transform: scale(1); }
  50%      { opacity: 1;    transform: scale(1.04); }
}
/* Extra "ready to defend" cue: a small floating tag below the badge so the
   "must hit me first" rule reads without any tutorial. */
.card .guardian-tag {
  position: absolute;
  top: 18px; right: -4px;
  background: rgba(20, 28, 60, 0.92);
  color: #c2d4ff;
  border: 1px solid rgba(120,165,255,0.7);
  border-radius: 999px;
  padding: 2px 7px;
  font-size: 8px;
  letter-spacing: 1.2px;
  font-family: var(--font-display);
  z-index: 4;
  white-space: nowrap;
  box-shadow: 0 2px 6px rgba(0,0,0,0.4);
  pointer-events: none;
}

/* Legendary holo: a single sheen band that slides across the card.
   We translate a fixed-size pseudo-element with `transform` so the
   compositor can run the whole animation on the GPU — animating
   `background-position` instead would force a paint every frame and
   stutters badly on mobile.  No `mix-blend-mode` either — same reason. */
.card[data-card-rare="legendary"] .card-inner,
.card[data-card-rare="mythical"] .card-inner {
  position: relative;
  overflow: hidden;
}
.card[data-card-rare="legendary"] .card-inner::before,
.card[data-card-rare="mythical"] .card-inner::before {
  content: "";
  position: absolute;
  top: 0;
  /* The sheen band itself: ~60% of card width, positioned just off-screen
     to the left so it can slide all the way across. */
  left: -70%;
  width: 60%;
  height: 100%;
  background: linear-gradient(115deg,
    transparent 0%,
    rgba(255, 180, 200, 0.32) 30%,
    rgba(220, 240, 255, 0.45) 50%,
    rgba(255, 240, 180, 0.32) 70%,
    transparent 100%);
  pointer-events: none;
  z-index: 2;
  will-change: transform;
  transform: translate3d(0, 0, 0); /* promote to its own layer */
  animation: legendaryHoloSlide 3.8s linear infinite;
}
@keyframes legendaryHoloSlide {
  0%   { transform: translate3d(0, 0, 0); }
  100% { transform: translate3d(280%, 0, 0); }
}

/* Slow the band down on mobile (where the paint cost still exists for the
   compositor's transform layer) and on every device that asks for reduced
   motion. Visually it still glints; just less often. */
@media (max-width: 768px), (hover: none) and (pointer: coarse) {
  .card[data-card-rare="legendary"] .card-inner::before,
  .card[data-card-rare="mythical"] .card-inner::before {
    animation-duration: 6.5s;
  }
}
@media (prefers-reduced-motion: reduce) {
  .card[data-card-rare="legendary"] .card-inner::before,
  .card[data-card-rare="mythical"] .card-inner::before {
    animation: none;
    opacity: 0.35;
  }
}
.card[data-card-rare="mythical"] {
  border-color: #ffb3ff !important;
  box-shadow: 0 0 20px rgba(255, 179, 255, 0.35) !important;
}
.card[data-card-rare="legendary"] {
  border-color: #ffd166 !important;
  box-shadow: 0 0 18px rgba(255, 209, 102, 0.28) !important;
}

/* Shiny tier — additional rainbow shimmer behind the holo sheen so shiny
   cards are immediately recognisable. */
.card.shiny-1 .card-sheen,
.card.shiny-2 .card-sheen,
.card.shiny-3 .card-sheen {
  background:
    linear-gradient(115deg, transparent 28%, rgba(255,180,255,0.18) 44%, rgba(255,250,180,0.34) 50%, rgba(180,255,230,0.18) 56%, transparent 72%),
    linear-gradient(115deg, transparent 30%, rgba(255,255,255,0.16) 50%, transparent 70%);
}
.card.shiny-2 { box-shadow: 0 6px 14px rgba(0,0,0,0.4), 0 0 18px rgba(247,208,44,0.45); }
.card.shiny-3 { box-shadow: 0 6px 14px rgba(0,0,0,0.4), 0 0 28px rgba(247,208,44,0.65); }

@keyframes rarityShine {
  0%, 100% { opacity: 0.35; transform: scale(0.95); }
  50%      { opacity: 1;    transform: scale(1.05); }
}
.card .card-rarity {
  animation: rarityShine 1.8s ease-in-out infinite;
}

/* Legendary / mythical aura — pulsing glow behind the card while it's on
   the field (any instance, including hand-rendered ones get the rarity
   tag, but only field cards get the big aura because the field-slot
   wrapper sets up positioning). */
@keyframes legendaryAura {
  0%, 100% { box-shadow: 0 6px 14px rgba(0,0,0,0.4), 0 0 18px rgba(247, 208, 44, 0.45); }
  50%      { box-shadow: 0 6px 14px rgba(0,0,0,0.4), 0 0 34px rgba(247, 208, 44, 0.95), 0 0 60px rgba(238, 129, 48, 0.4); }
}
@keyframes mythicalAura {
  0%   { box-shadow: 0 6px 14px rgba(0,0,0,0.4), 0 0 28px rgba(255, 145, 200, 0.6); }
  33%  { box-shadow: 0 6px 14px rgba(0,0,0,0.4), 0 0 28px rgba(167, 240, 255, 0.65); }
  66%  { box-shadow: 0 6px 14px rgba(0,0,0,0.4), 0 0 28px rgba(217, 192, 255, 0.65); }
  100% { box-shadow: 0 6px 14px rgba(0,0,0,0.4), 0 0 28px rgba(255, 145, 200, 0.6); }
}
.field-slot .card .card-rarity:not(.mythical) ~ .card-art,
.field-slot .card.has-legendary { /* placeholder */ }
/* Apply auras at the card root via classes for ease of selection: */
.card.is-legendary { animation: legendaryAura 2.4s ease-in-out infinite; }
.card.is-mythical  { animation: mythicalAura 3s linear infinite; }

.card.selected {
  outline: 2px solid #fff;
  outline-offset: 4px;
  box-shadow:
    0 0 24px var(--type-1, #fff),
    0 0 60px var(--type-1, #fff);
}

.card.ko {
  transition: filter 0.7s ease, transform 0.7s ease, opacity 0.7s ease;
  filter: grayscale(1) brightness(0.4);
  transform: scale(0.6) rotate(-12deg);
  opacity: 0;
}

/* Header: cost, hp, types */
.card-header {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 8px 4px;
  z-index: 2;
}

.cost-gem {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: radial-gradient(circle at 30% 30%, #fff8, var(--type-1, #888));
  display: grid;
  place-items: center;
  font-weight: 700;
  font-size: 13px;
  box-shadow:
    inset 0 0 6px rgba(255, 255, 255, 0.5),
    0 0 8px var(--type-1, #888);
}

.card-hp {
  font-family: var(--font-display);
  font-size: 11px;
  letter-spacing: 1px;
}
.card-hp-max {
  opacity: 0.55;
  font-size: 9px;
}

.card-types {
  display: flex;
  gap: 3px;
}
.type-badge {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 11px;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.18) inset;
}

/* Art */
.card-art {
  flex: 1;
  display: grid;
  place-items: center;
  padding: 4px;
  background: radial-gradient(
    circle at 50% 40%,
    rgba(255, 255, 255, 0.12),
    rgba(0, 0, 0, 0.5)
  );
  position: relative;
}
.card-art img {
  max-width: 100%;
  max-height: 100%;
  filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.6));
}

/* Footer */
.card-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 4px 8px 8px;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.6), transparent);
}
.card-name {
  font-weight: 700;
  font-size: 13px;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.7);
  text-transform: capitalize;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100px;
}
.card-attack {
  font-family: var(--font-display);
  font-size: 11px;
}

/* Rarity badge — was a strip just above the footer, which crowded the
 * card name on smaller cards. Now a compact pill centered just under
 * the header so it sits IN the art area (not over the name) and reads
 * at a glance. Width auto-fits the text instead of left-anchoring. */
.card-rarity {
  position: absolute;
  top: 38px;
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--font-display);
  font-size: 7px;
  color: gold;
  text-shadow: 0 0 4px gold, 0 0 8px gold;
  letter-spacing: 1.5px;
  background: rgba(0, 0, 0, 0.55);
  padding: 3px 8px;
  border-radius: 999px;
  border: 1px solid rgba(255, 215, 0, 0.55);
  white-space: nowrap;
  pointer-events: none;
  z-index: 2;
}
.card-rarity.mythical {
  color: #ff90c8;
  text-shadow: 0 0 4px #ff90c8, 0 0 8px #ff90c8;
  border-color: rgba(255, 144, 200, 0.6);
}

.card-status {
  position: absolute;
  bottom: 38px;
  right: 6px;
  font-family: var(--font-display);
  font-size: 7px;
  padding: 2px 4px;
  border-radius: 4px;
  letter-spacing: 1px;
}
.card-status.status-burn      { background: #EE8130; color: #fff; }
.card-status.status-bleed     { background: #b3122b; color: #fff; }
.card-status.status-stun  { background: #F7D02C; color: #222; }
.card-status.status-sleep     { background: #735797; color: #fff; }
.card-status.status-curse     { background: #4a3b66; color: #fff; }

/* Floating status pictogram above the card so it's readable at a glance. */
.card .status-icon {
  position: absolute;
  top: -18px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 22px;
  filter: drop-shadow(0 2px 4px rgba(0,0,0,0.7));
  pointer-events: none;
  z-index: 2;
}
@keyframes zzzFloat {
  0%   { transform: translate(-50%, 0)    rotate(-5deg); opacity: 0.85; }
  50%  { transform: translate(-50%, -6px) rotate(5deg);  opacity: 1; }
  100% { transform: translate(-50%, 0)    rotate(-5deg); opacity: 0.85; }
}
.card .status-icon.kind-sleep { animation: zzzFloat 1.6s ease-in-out infinite; }
@keyframes burnFlicker {
  0%, 100% { transform: translate(-50%, 0)    scale(1);    filter: drop-shadow(0 0 4px #ff6622) hue-rotate(0deg); }
  50%      { transform: translate(-50%, -3px) scale(1.18); filter: drop-shadow(0 0 8px #ff9c44) hue-rotate(8deg); }
}
.card .status-icon.kind-burn  { animation: burnFlicker 0.55s ease-in-out infinite; }
.card .status-icon.kind-bleed { animation: burnFlicker 0.7s ease-in-out infinite; }
@keyframes sparkBuzz {
  0%, 100% { transform: translate(-50%, 0)   scale(1); }
  25%      { transform: translate(-52%, -2px) scale(1.1); }
  50%      { transform: translate(-48%, 0)    scale(1.05); }
  75%      { transform: translate(-52%, -2px) scale(1.12); }
}
.card .status-icon.kind-stun { animation: sparkBuzz 0.3s linear infinite; }

/* Compact: smaller cards for the field */
.card.compact {
  width: 110px;
}
.card.compact .card-name { font-size: 11px; max-width: 70px; }
.card.compact .card-hp { font-size: 9px; }
.card.compact .cost-gem { width: 22px; height: 22px; font-size: 11px; }

/* Card Mastery badge — small gold stars.
 * Mirrored to the TOP-RIGHT corner so it doesn't crowd the
 * creature name in the footer's lower-left. .card-level sits in the
 * top-left corner; mastery now sits in the top-right.
 * L3 gets a glow ring (signals the +1 ATK active state). */
.card .card-mastery {
  position: absolute;
  top: -10px;
  right: -8px;
  background: rgba(0,0,0,0.78);
  color: #ffd166;
  border: 1px solid rgba(255,209,102,0.7);
  border-radius: 999px;
  padding: 2px 7px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 1.5px;
  z-index: 5;
  text-shadow: 0 0 4px #ffd166aa;
  pointer-events: none;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5);
}
.card[data-card-mastery="3"] .card-mastery,
.card .card-mastery:has-text("★★★") {
  /* CSS can't match text directly so we fall back to a length check via
     attribute selectors when JS sets data-card-mastery (future work).
     For now the 3-star variant just shows the brighter shadow because
     of the longer text. */
}

/* =========================================================================
 * Spell cards — visually distinct from creature. Gradient background,
 * big centered glyph (no sprite), description text below the name.
 * Shares the same outer .card frame so hover / drag / selected styles
 * Just Work without extra rules.
 * ====================================================================== */
.card.spell-card .card-inner {
  background: linear-gradient(155deg,
    color-mix(in srgb, var(--type-1) 70%, #0c1422 30%) 0%,
    color-mix(in srgb, var(--type-1) 25%, #0a0f1c 75%) 100%);
  border: 1px solid color-mix(in srgb, var(--type-1) 80%, #fff 20%);
  box-shadow:
    inset 0 0 18px color-mix(in srgb, var(--type-1) 40%, transparent),
    0 4px 14px rgba(0, 0, 0, 0.5);
}
.card.spell-card .spell-tag {
  position: absolute;
  top: 6px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 1.5px;
  padding: 2px 8px;
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  text-shadow: 0 0 4px rgba(255, 255, 255, 0.3);
}
.card.spell-card .spell-art {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 1;
  min-height: 0;
  background: radial-gradient(circle at 50% 45%,
    color-mix(in srgb, var(--type-1) 35%, transparent) 0%,
    transparent 65%);
}
.card.spell-card .spell-glyph {
  font-size: clamp(40px, 10vw, 70px);
  line-height: 1;
  filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.6))
          drop-shadow(0 0 12px color-mix(in srgb, var(--type-1) 70%, transparent));
  animation: spellGlyphFloat 3.6s ease-in-out infinite;
}
.card.spell-card .spell-footer {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 5px 7px 7px;
}
.card.spell-card .spell-desc {
  font-size: 9px;
  line-height: 1.25;
  color: rgba(255, 255, 255, 0.85);
  opacity: 0.9;
  font-style: italic;
}
.card.spell-card.compact .spell-desc { display: none; }
.card.spell-card.compact .spell-glyph { font-size: clamp(28px, 7vw, 44px); }

@keyframes spellGlyphFloat {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  50%      { transform: translateY(-3px) rotate(-2deg); }
}

/* Rarity-coloured border accent so players can spot rare spells fast.
 * Uses outer ring vs the existing legendary star treatment for
 * creature (we don't want spells competing visually with the
 * legendary glow that announces a Mewtwo). */
.card.spell-card.rarity-uncommon { box-shadow: 0 0 0 1px #6ee7b755, inset 0 0 18px color-mix(in srgb, var(--type-1) 40%, transparent), 0 4px 14px rgba(0,0,0,.5); }
.card.spell-card.rarity-rare     { box-shadow: 0 0 0 2px #60a5fa88, inset 0 0 18px color-mix(in srgb, var(--type-1) 40%, transparent), 0 4px 14px rgba(0,0,0,.5); }
.card.spell-card.rarity-epic     { box-shadow: 0 0 0 2px #c084fc99, inset 0 0 22px color-mix(in srgb, var(--type-1) 50%, transparent), 0 4px 16px rgba(0,0,0,.6); }
.card.spell-card.rarity-legendary { box-shadow: 0 0 0 2px #f59e0bcc, inset 0 0 24px color-mix(in srgb, var(--type-1) 55%, transparent), 0 4px 18px rgba(245,158,11,.4); }

/* Frozen status — frostbite overlay on a card with status.kind=freeze. */
.card .card-status.status-freeze,
.card .status-icon.kind-freeze { color: #93c5fd; text-shadow: 0 0 6px #60a5faaa; }
.field-slot .card[data-frozen] .card-art,
.field-slot .card .card-status.status-freeze ~ .card-art {
  filter: brightness(0.85) hue-rotate(180deg) saturate(0.85);
}

/* --- Species evolution flash (slice 9) -------------------------------
 * Fires when a creature transforms into its next evolution form
 * mid-match (Charmander → Charmeleon). A bigger, more dramatic
 * version of the existing level-up bump.
 */
.card.evolving {
  animation: speciesEvolve 1.4s ease-out;
  position: relative;
  z-index: 10;
}
@keyframes speciesEvolve {
  0%   { transform: scale(1);    filter: brightness(1) drop-shadow(0 0 0 transparent); }
  25%  { transform: scale(1.15) rotate(-3deg);
         filter: brightness(2.5) drop-shadow(0 0 18px #fff) drop-shadow(0 0 28px #fbbf24); }
  50%  { transform: scale(0.95) rotate(2deg);
         filter: brightness(3) drop-shadow(0 0 28px #fff) drop-shadow(0 0 40px #fbbf24); }
  75%  { transform: scale(1.1);
         filter: brightness(1.8) drop-shadow(0 0 18px #fbbf24); }
  100% { transform: scale(1);    filter: brightness(1) drop-shadow(0 0 0 transparent); }
}

/* ===== Fantasy skin — gilt TCG card frame ===== */
.card {
  box-shadow: 0 6px 14px rgba(0, 0, 0, 0.5), 0 0 0 1px var(--gold-dim, #8a6f34) inset;
}
.card .card-inner { border: 1px solid rgba(201, 162, 78, 0.30); }
.card .card-name { font-family: var(--font-display); color: #f3e4b0; letter-spacing: 0.5px; }

/* ===== Field cards: creature name as a banner pinned to the bottom edge ===== */
.field-slot .card .card-footer {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 4;
  padding: 5px 6px 4px;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.9), rgba(0, 0, 0, 0.45) 70%, transparent);
}
.field-slot .card .card-name {
  max-width: 78%;
  font-size: 11px;
}

/* Spell/item card art — generated image fills the art slot; the glyph behind
   it shows only if the image is missing (onerror removes the img). */
.spell-art { position: relative; }
.spell-art .spell-art-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: inherit;
}
