/* Battle Visualiser — animated combat replay */

.bv-arena {
  position: relative;
  width: 100%;
  max-width: 720px;
  height: 380px;
  margin: 0.75rem auto;
  background: transparent;
  border: 2px solid var(--border-dark);
  border-radius: 6px;
  overflow: hidden;
  user-select: none;
}

/* Water background texture — desaturated so ships pop */
.bv-water {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  opacity: 0.12;
  background-repeat: repeat;
  background-size: 256px;
  pointer-events: none;
  filter: saturate(0) brightness(0.7);
}
/* With a shore the water runs to the beach: attackers at sea, the harbour mouth, the docked ships in the harbour */
.bv-has-shore .bv-water {
  right: 28%;
  border-right: 2px solid rgba(139, 115, 70, 0.4);
}

/* Shore area — ground texture behind defences */
.bv-shore-ground {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  width: 28%;
  background-repeat: repeat;
  background-size: 128px;
  opacity: 0.15;
  filter: saturate(0) brightness(0.6);
  pointer-events: none;
  border-left: 2px solid rgba(139, 115, 70, 0.4);
}

/* Defence units positioned on the shore strip */
/* Defences (Rob, Sep 17: the ships were drawn on land behind the fortress). Left to right: the attackers at
   sea, the walls and the chain at the harbour mouth in the water, the docked ships inside the harbour, then
   the guns and the works on the shore behind them. Damage order is unchanged (walls, guns, works, ships) */
.bv-defences {
  position: absolute;
  left: 0;
  right: 0;
  top: 32px;
  bottom: 36px;
  z-index: 5;
  pointer-events: none;
}
.bv-defence-col {
  position: absolute;
  top: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  min-width: 0;
}
.bv-defence-col[data-col="0"] { left: 41%; width: 9%; }
.bv-defence-col[data-col="1"] { left: 73%; width: 13%; }
.bv-defence-col[data-col="2"] { left: 87%; width: 13%; }
.bv-defences .bv-unit {
  position: relative;
  pointer-events: auto;
}

/* Round counter */
.bv-round {
  position: absolute;
  top: 8px;
  left: 50%;
  transform: translateX(-50%);
  font-family: 'Cinzel', serif;
  font-size: 0.85rem;
  font-weight: 700;
  color: #e8dcc4;
  text-shadow: 0 1px 3px rgba(0,0,0,0.8);
  z-index: 10;
  letter-spacing: 0.05em;
}

/* Fleet containers — positioned zones for overlapping ships */
.bv-fleet {
  position: absolute;
  top: 32px;
  bottom: 36px;
  width: 42%;
  pointer-events: none;
  /* Units stack by depth inside the fleet; the fleet itself sits under every overlay, so a big fleet never climbs over the dialogue */
  z-index: 3;
  isolation: isolate;
}
.bv-fleet-left { left: 0; }
.bv-fleet-right { right: 0; }
/* With a shore, the docked ships sit in the harbour: inside the wall, in front of the shore guns */
.bv-arena.bv-has-shore .bv-fleet-left { width: 40%; }
.bv-arena.bv-has-shore .bv-fleet-right { right: 28%; width: 21%; }

/* Individual unit — absolutely positioned within fleet zone */
.bv-unit {
  position: absolute;
  display: flex;
  align-items: center;
  gap: 3px;
  pointer-events: auto;
  transition: opacity 0.6s ease;
}
.bv-fleet-left .bv-unit { flex-direction: row; }
.bv-fleet-right .bv-unit { flex-direction: row-reverse; }

/* Ship/defence image — size set inline via JS based on ship class */
.bv-unit-img {
  object-fit: contain;
  flex-shrink: 0;
}

/* Unit info (name + hull bar) — sits beside the ship */
.bv-unit-info {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 50px;
}
.bv-unit-name {
  font-size: 0.5rem;
  color: #c8b890;
  white-space: nowrap;
  text-shadow: 0 1px 2px rgba(0,0,0,0.9);
  font-family: Georgia, serif;
}

/* Hull bar */
.bv-hull-bar {
  width: 50px;
  height: 4px;
  background: rgba(0,0,0,0.5);
  border-radius: 2px;
  overflow: hidden;
  border: 1px solid rgba(200,180,140,0.2);
}
.bv-hull-fill {
  height: 100%;
  background: #4a9e4a;
  border-radius: 1px;
  transition: width 0.5s ease;
}
.bv-hull-fill.hull-mid { background: #c9a227; }
.bv-hull-fill.hull-low { background: #c06030; }
.bv-hull-fill.hull-crit { background: #b04040; }

/* Stacked unit badge */
.bv-stack-badge {
  position: absolute;
  top: -2px;
  left: -2px;
  background: rgba(0,0,0,0.75);
  color: #e8dcc4;
  font-size: 0.55rem;
  font-weight: 700;
  padding: 0 3px;
  border-radius: 2px;
  border: 1px solid rgba(200,180,140,0.3);
  z-index: 2;
  font-family: Georgia, serif;
}
.bv-fleet-right .bv-stack-badge {
  left: auto;
  right: -2px;
}

/* Combat nudge — per-unit with random delay via inline animation-delay */
.bv-unit.bv-firing {
  animation: bv-nudge-right 0.35s ease;
}
.bv-fleet-right .bv-unit.bv-firing {
  animation: bv-nudge-left 0.35s ease;
}
/* Emplacements do not sail at the enemy: a gun kicks back on its carriage and settles */
.bv-unit[data-is-defence].bv-firing {
  animation: bv-recoil 0.3s ease-out;
}
@keyframes bv-recoil {
  0% { transform: translateX(0); }
  25% { transform: translateX(5px) scale(1.03); }
  100% { transform: translateX(0); }
}
@keyframes bv-nudge-right {
  0%, 100% { transform: translateX(0); }
  40% { transform: translateX(10px); }
}
@keyframes bv-nudge-left {
  0%, 100% { transform: translateX(0); }
  40% { transform: translateX(-10px); }
}

/* Sinking animation — individual ships */
.bv-unit.bv-sinking {
  animation: bv-sink 1.2s ease forwards;
  pointer-events: none;
}
@keyframes bv-sink {
  0% { opacity: 1; }
  30% { transform: translateY(6px) rotate(5deg); opacity: 0.8; }
  70% { transform: translateY(18px) rotate(12deg); opacity: 0.3; }
  100% { transform: translateY(35px) rotate(18deg); opacity: 0; }
}
.bv-fleet-right .bv-unit.bv-sinking {
  animation: bv-sink-right 1.2s ease forwards;
}
@keyframes bv-sink-right {
  0% { opacity: 1; }
  30% { transform: translateY(6px) rotate(-5deg); opacity: 0.8; }
  70% { transform: translateY(18px) rotate(-12deg); opacity: 0.3; }
  100% { transform: translateY(35px) rotate(-18deg); opacity: 0; }
}

/* Floating damage numbers */
.bv-dmg {
  position: absolute;
  font-family: 'Cinzel', serif;
  font-weight: 700;
  pointer-events: none;
  z-index: 20;
  animation: bv-float-up 1.4s ease-out forwards;
  text-shadow: 0 1px 2px rgba(0,0,0,0.6), 0 0 4px rgba(255,255,255,0.3);
  white-space: nowrap;
}
.bv-dmg-hit {
  color: #e84040;
  font-size: 0.85rem;
}
.bv-dmg-crit {
  color: #ffd700;
  font-size: 1.1rem;
}
.bv-dmg-miss {
  color: #8888cc;
  font-size: 0.7rem;
  font-style: italic;
}
.bv-dmg-heal {
  color: #5aee5a;
  font-size: 0.8rem;
}
.bv-dmg-dot {
  color: #ff8c40;
  font-size: 0.75rem;
}
@keyframes bv-float-up {
  0% { transform: translateY(0); opacity: 1; }
  70% { opacity: 1; }
  100% { transform: translateY(-35px); opacity: 0; }
}

/* VFX sprites (smoke, blast, impact) */
.bv-vfx {
  position: absolute;
  pointer-events: none;
  z-index: 15;
}
.bv-smoke {
  opacity: 0.7;
  animation: bv-smoke-rise 1.6s ease-out forwards;
}
@keyframes bv-smoke-rise {
  0% { transform: scale(0.6) translateY(0); opacity: 0.7; }
  40% { transform: scale(1.3) translateY(-12px); opacity: 0.5; }
  100% { transform: scale(2.0) translateY(-35px); opacity: 0; }
}
.bv-blast {
  animation: bv-blast-flash 0.35s ease-out forwards;
}
@keyframes bv-blast-flash {
  0% { transform: scale(0.3); opacity: 1; }
  50% { transform: scale(1.2); opacity: 0.8; }
  100% { transform: scale(0.8); opacity: 0; }
}
.bv-impact {
  animation: bv-impact-burst 0.5s ease-out forwards;
}
@keyframes bv-impact-burst {
  0% { transform: scale(0.4); opacity: 1; }
  30% { transform: scale(1.1); opacity: 0.9; }
  100% { transform: scale(0.6); opacity: 0; }
}

/* Ring effect VFX — distinct from cannon impacts */
.bv-ring-vfx {
  position: absolute;
  pointer-events: none;
  z-index: 15;
  object-fit: contain;
}
.bv-ring-surge {
  animation: bv-surge-rise 1.4s ease-out forwards;
}
@keyframes bv-surge-rise {
  0% { transform: translateY(8px) scale(0.5); opacity: 0; }
  20% { transform: translateY(-4px) scale(1.1); opacity: 0.9; }
  50% { transform: translateY(-14px) scale(1.0); opacity: 0.7; }
  100% { transform: translateY(-28px) scale(0.8); opacity: 0; }
}
.bv-ring-splash {
  animation: bv-ring-expand 0.8s ease-out forwards;
}
@keyframes bv-ring-expand {
  0% { transform: scale(0.3); opacity: 1; }
  40% { transform: scale(1.4); opacity: 0.8; }
  100% { transform: scale(1.8); opacity: 0; }
}
.bv-ring-devour {
  animation: bv-devour-pull 1.2s ease-in-out forwards;
}
@keyframes bv-devour-pull {
  0% { transform: translateX(0) scale(0.6); opacity: 0; }
  30% { transform: translateX(-10px) scale(1.0); opacity: 0.9; }
  70% { transform: translateX(-20px) scale(0.9); opacity: 0.6; }
  100% { transform: translateX(-30px) scale(0.7); opacity: 0; }
}

/* Cannonball projectile */
.bv-cannonball {
  position: absolute;
  width: 6px;
  height: 6px;
  background: #2a2018;
  border-radius: 50%;
  box-shadow: 0 1px 2px rgba(0,0,0,0.4);
  opacity: 0.45;
  pointer-events: none;
  z-index: 16;
}

/* Trigger effect text */
.bv-trigger {
  position: absolute;
  font-size: 0.6rem;
  font-family: Georgia, serif;
  font-style: italic;
  pointer-events: none;
  z-index: 20;
  text-shadow: 0 1px 3px rgba(0,0,0,0.9);
  white-space: nowrap;
  animation: bv-trigger-pop 1.8s ease-out forwards;
}
.bv-trigger-buff { color: #4a9e4a; }
.bv-trigger-debuff { color: #e06050; }
.bv-trigger-special { color: #7b68ee; }
.bv-trigger-heal { color: #5aee5a; }
@keyframes bv-trigger-pop {
  0% { transform: translateY(0) scale(0.8); opacity: 0; }
  15% { transform: translateY(-4px) scale(1.1); opacity: 1; }
  70% { opacity: 1; }
  100% { transform: translateY(-24px); opacity: 0; }
}

/* Controls bar — hidden inside chest modal (auto-plays), visible on test page */
.bv-controls {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  padding: 0.4rem;
  background: rgba(0,0,0,0.4);
  border-top: 1px solid rgba(200,180,140,0.15);
  z-index: 25;
}
.chest-modal .bv-controls { display: none; }
.bv-btn {
  background: none;
  border: 1px solid rgba(200,180,140,0.3);
  color: #c8b890;
  font-family: Georgia, serif;
  font-size: 0.7rem;
  padding: 3px 10px;
  border-radius: 3px;
  cursor: pointer;
  transition: background 0.2s, border-color 0.2s;
}
.bv-btn:hover {
  background: rgba(200,180,140,0.15);
  border-color: rgba(200,180,140,0.5);
}
.bv-btn:disabled {
  opacity: 0.4;
  cursor: default;
}
.bv-speed {
  color: #a09070;
  font-size: 0.65rem;
  font-family: Georgia, serif;
}

/* Watch Battle button on combat reports */
.bv-watch-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  background: var(--navy);
  color: #c8b890;
  border: 1px solid var(--border-dark);
  padding: 0.25rem 0.6rem;
  border-radius: 4px;
  font-family: Georgia, serif;
  font-size: 0.75rem;
  cursor: pointer;
  transition: background 0.2s, border-color 0.2s;
  margin-top: 0.4rem;
}
.bv-watch-btn:hover {
  background: #243a4a;
  border-color: rgba(200,180,140,0.5);
}
.bv-watch-btn svg {
  width: 14px;
  height: 14px;
}
/* Copy replay link: icon only, link swaps to a check once copied */
.combat-report-actions { display: inline-flex; gap: 0.35rem; align-items: center; }
.bv-share-btn { padding: 0.25rem 0.45rem; position: relative; }
.bv-share-btn .bv-share-done, .bv-share-btn.bv-share-copied .bv-share-link { display: none; }
.bv-share-btn.bv-share-copied .bv-share-done { display: block; color: #8fd18f; }
.bv-share-btn.bv-share-copied { border-color: #8fd18f; }

/* Floating loot after victory */
.bv-loot-item {
  position: absolute;
  display: flex;
  align-items: center;
  gap: 4px;
  pointer-events: none;
  z-index: 28;
  animation: bv-loot-rise 2.5s ease-out forwards;
  white-space: nowrap;
}
.bv-loot-icon {
  width: 24px;
  height: 24px;
  object-fit: contain;
  filter: drop-shadow(0 1px 3px rgba(0,0,0,0.8));
}
.bv-loot-text {
  font-family: 'Cinzel', serif;
  font-weight: 700;
  font-size: 0.8rem;
  color: #ffd700;
  text-shadow: 0 1px 4px rgba(0,0,0,0.9), 0 0 8px rgba(0,0,0,0.5);
}
.bv-loot-capture .bv-loot-text { color: #7b68ee; }
.bv-loot-drop .bv-loot-text { color: #5aee5a; }
@keyframes bv-loot-rise {
  0% { transform: translateY(0) scale(0.7); opacity: 0; }
  15% { transform: translateY(-8px) scale(1.05); opacity: 1; }
  75% { opacity: 1; }
  100% { transform: translateY(-50px); opacity: 0; }
}

/* Battle dialogue — uses same style as Harbourmaster/boss dialogue */
.bv-dialogue {
  position: absolute;
  bottom: 40px;
  z-index: 28;
  animation: bv-dialogue-in 0.3s ease-out forwards;
  max-width: 60%;
}
/* Dialogue text takes the parchment panel's colour wherever the arena is hosted, the public page body is light on dark */
.bv-dialogue .hm-dialog { color: var(--text); text-align: left; } /* the replay modal's card centres text; dialogue reads left like the inline report */
.bv-dialogue-left { left: 8px; }
.bv-dialogue-right { right: 8px; }
@keyframes bv-dialogue-in {
  0% { transform: translateY(10px); opacity: 0; }
  100% { transform: translateY(0); opacity: 1; }
}
.bv-dialogue.bv-dialogue-out {
  animation: bv-dialogue-out 0.3s ease-in forwards;
}
@keyframes bv-dialogue-out {
  0% { opacity: 1; }
  100% { transform: translateY(10px); opacity: 0; }
}

/* Outcome banner */
.bv-outcome {
  position: absolute;
  top: 45%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0);
  font-family: 'Pirata One', cursive;
  font-size: 2rem;
  z-index: 30;
  text-shadow: 0 2px 8px rgba(0,0,0,0.9);
  animation: bv-outcome-pop 0.6s ease forwards;
  letter-spacing: 0.05em;
}
.bv-outcome-victory { color: #ffd700; }
.bv-outcome-defeat { color: #e84040; }
@keyframes bv-outcome-pop {
  0% { transform: translate(-50%, -50%) scale(0); opacity: 0; }
  60% { transform: translate(-50%, -50%) scale(1.15); opacity: 1; }
  100% { transform: translate(-50%, -50%) scale(1); opacity: 1; }
}

/* Widen the chest modal when visualiser is inside */
.chest-modal:has(.bv-container) {
  max-width: 780px;
  align-items: stretch;
}
.bv-container {
  width: 100%;
}
/* Dim the modal backdrop when battle is playing */
.chest-modal-overlay {
  transition: background 0.8s ease;
}
.chest-modal-overlay.bv-cinematic {
  background: rgba(0, 0, 0, 0.7);
}
/* Cinematic: the card disappears and the arena floats over the scene on its own */
.chest-modal-overlay.bv-cinematic .chest-modal,
.chest-modal-overlay.bv-cinematic .chest-modal:has(.bv-container) {
  background: none;
  border-color: transparent;
  box-shadow: none;
  padding: 0;
  max-width: 780px;
}
.chest-modal-overlay.bv-cinematic .chest-modal-title { display: none; }
.chest-modal-overlay.bv-cinematic .bv-arena {
  border: 2px solid var(--accent);
  border-radius: 4px;
  background: rgba(8, 12, 18, 0.62);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.75), 0 0 0 4px rgba(139, 106, 46, 0.35), 0 6px 18px rgba(0, 0, 0, 0.5);
}
.chest-modal-overlay.bv-cinematic .bv-arena::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 6px;
  pointer-events: none;
  z-index: 1;
  background: radial-gradient(ellipse at center, rgba(0,0,0,0) 55%, rgba(0,0,0,0.55) 100%);
}
.chest-modal-overlay.bv-cinematic .bv-has-shore .bv-water { border-right: none; }
.chest-modal-overlay.bv-cinematic .bv-shore-ground { border-left: none; }
.chest-modal-overlay.bv-cinematic .bv-container { margin: 0 !important; }
.chest-modal-overlay.bv-cinematic .bv-water { opacity: 0.18; }
.chest-modal-overlay.bv-cinematic .bv-shore-ground { opacity: 0.35; }
/* Skip: appears a few seconds into the fight */
.bv-skip {
  position: absolute;
  top: 8px;
  right: 10px;
  z-index: 30;
  font-family: 'Cinzel', serif;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  color: #e8dcc4;
  background: rgba(0, 0, 0, 0.45);
  border: 1px solid rgba(232, 220, 196, 0.35);
  border-radius: 3px;
  padding: 0.25rem 0.6rem;
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s ease;
}
.bv-skip.bv-skip-visible { opacity: 1; pointer-events: auto; }
.bv-skip:hover { background: rgba(0, 0, 0, 0.7); border-color: #e8dcc4; }
/* Letterbox bars */
.chest-modal-overlay.bv-cinematic::before,
.chest-modal-overlay.bv-cinematic::after {
  content: '';
  position: fixed;
  left: 0;
  right: 0;
  height: 7vh;
  background: #000;
  z-index: 2;
  pointer-events: none;
}
.chest-modal-overlay.bv-cinematic::before { top: 0; }
.chest-modal-overlay.bv-cinematic::after { bottom: 0; }
/* Scene painting behind the modal: where the fight happened. Fades in with the cinematic dim. */
.bv-scene-bg {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.8s ease;
  filter: saturate(0.85) brightness(0.7);
}
.chest-modal-overlay.bv-cinematic .bv-scene-bg { opacity: 1; }
.chest-modal-overlay.bv-night .bv-scene-bg { filter: saturate(0.5) brightness(0.3) sepia(0.2) hue-rotate(190deg); }
.chest-modal-overlay > *:not(.bv-scene-bg) { position: relative; }

/* Per-player fleet bands (multi-player battles) */
.bv-player-band {
  position: absolute;
  background: rgba(200,180,140,0.06);
  border-top: 1px solid rgba(200,180,140,0.12);
  border-bottom: 1px solid rgba(200,180,140,0.08);
  pointer-events: none;
}
.bv-player-label {
  position: absolute;
  display: flex;
  align-items: center;
  gap: 4px;
  z-index: 8;
  pointer-events: none;
  overflow: hidden;
}
.bv-player-label .bv-player-name { overflow: hidden; text-overflow: ellipsis; }
.bv-player-portrait {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 1px solid rgba(200,180,140,0.5);
  object-fit: cover;
}
.bv-player-name {
  font-size: 0.55rem;
  color: #e8dcc4;
  font-family: 'Cinzel', serif;
  font-weight: 700;
  text-shadow: 0 1px 3px rgba(0,0,0,0.9);
  white-space: nowrap;
  letter-spacing: 0.03em;
}

/* Screen shake on crits */
.bv-arena.bv-shake-light {
  animation: bv-shake-light 0.25s ease;
}
.bv-arena.bv-shake-heavy {
  animation: bv-shake-heavy 0.4s ease;
}
@keyframes bv-shake-light {
  0%, 100% { transform: translate(0); }
  25% { transform: translate(-2px, 1px); }
  75% { transform: translate(2px, -1px); }
}
@keyframes bv-shake-heavy {
  0%, 100% { transform: translate(0); }
  20% { transform: translate(-4px, 3px); }
  40% { transform: translate(3px, -2px); }
  60% { transform: translate(-3px, 2px); }
  80% { transform: translate(4px, -3px); }
}

/* Burn/DoT fire effect */
.bv-unit.bv-burning .bv-unit-img {
  animation: bv-burn-flicker 0.6s ease-in-out infinite alternate;
}
@keyframes bv-burn-flicker {
  0% { filter: brightness(1.2) sepia(0.3) saturate(1.8) hue-rotate(-10deg); }
  100% { filter: brightness(1.5) sepia(0.5) saturate(2.2) hue-rotate(-5deg); }
}

/* Responsive — smaller on mobile */
@media (max-width: 600px) {
  .bv-arena { height: 300px; }
  /* Dialogue panels take the full width of the arena on phones; at 60% every line wrapped (Rob, Sep 21) */
  .bv-dialogue { max-width: none; left: 6px; right: 6px; bottom: 30px; }
  .bv-dialogue .hm-dialog { font-size: 0.8rem; }
  /* The cinematic modal fills the phone: no card padding, arena edge to edge */
  .chest-modal-overlay.bv-cinematic { padding: 0; }
  .chest-modal-overlay.bv-cinematic .chest-modal { width: 100%; max-width: none; margin: 0; }
  .chest-modal-overlay.bv-cinematic .bv-arena { margin: 0; border-radius: 0; border-left: none; border-right: none; }
  .bv-unit-img { width: 40px; height: 40px; }
  .bv-unit[data-is-defence] .bv-unit-img { width: 32px; height: 32px; }
  .bv-hull-bar { width: 40px; height: 3px; }
  .bv-unit-name { font-size: 0.45rem; }
  .bv-dmg-hit { font-size: 0.7rem; }
  .bv-dmg-crit { font-size: 0.9rem; }
  .bv-round { font-size: 0.75rem; }
  .bv-outcome { font-size: 1.5rem; }
}

/* A captain's fight in a cave (Oct 8, caverns.js): a dark floor in place of the sea, figures standing on it, a
   lunge in place of a broadside, and a fall in place of a sinking */
.bv-arena.bv-arena-cave, .chest-modal-overlay.bv-cinematic .bv-arena.bv-arena-cave { background: radial-gradient(ellipse at 50% 35%, #3a2e22 0%, #1d1712 70%, #120e0a 100%); }
/* With the cave painted behind, the arena lets it through */
.chest-modal-overlay.bv-cinematic:has(.bv-scene-bg) .bv-arena.bv-arena-cave { background: linear-gradient(180deg, rgba(18, 14, 10, 0.2) 0%, rgba(18, 14, 10, 0.05) 60%, rgba(18, 14, 10, 0.45) 100%); }
.bv-cave-floor { position: absolute; left: 0; right: 0; bottom: 0; height: 28%; background: linear-gradient(180deg, rgba(40, 32, 24, 0) 0%, rgba(40, 32, 24, 0.65) 100%); pointer-events: none; }
.bv-arena-cave .bv-unit-img { object-fit: contain; filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.6)); }
.bv-arena-cave .bv-unit.bv-unit-portrait .bv-unit-img { border: 3px solid #8b6914; border-radius: 6px; background: #1d1712; }
.bv-unit.bv-falling { animation: bv-fall 0.9s ease forwards; pointer-events: none; }
@keyframes bv-fall {
  0% { opacity: 1; }
  40% { transform: translateY(4px) rotate(-6deg); opacity: 0.85; }
  100% { transform: translateY(26px) rotate(-80deg); opacity: 0; }
}
.bv-fleet-right .bv-unit.bv-falling { animation-name: bv-fall-right; }
@keyframes bv-fall-right {
  0% { opacity: 1; }
  40% { transform: translateY(4px) rotate(6deg); opacity: 0.85; }
  100% { transform: translateY(26px) rotate(80deg); opacity: 0; }
}

/* HP bars (Oct 8): under each figure in a captain's fight, draining round by round */
.bv-unit .bv-hp { position: absolute; left: 50%; bottom: -12px; transform: translateX(-50%); width: 80px; max-width: 100%; height: 9px; background: rgba(0, 0, 0, 0.65); border: 1px solid rgba(212, 160, 23, 0.7); border-radius: 3px; overflow: hidden; pointer-events: none; z-index: 3; }
.bv-unit .bv-hp-fill { height: 100%; background: linear-gradient(180deg, #5fbf4a, #2f8a2a); transition: width 0.5s ease; }
.bv-unit .bv-hp-fill.bv-hp-low { background: linear-gradient(180deg, #e0563a, #9a2a1a); }
.bv-unit .bv-hp-num { position: absolute; inset: 0; font: bold 8px/9px Georgia, serif; color: #fff; text-align: center; text-shadow: 0 0 2px #000; }
.bv-unit.bv-falling .bv-hp, .bv-unit.bv-sinking .bv-hp { display: none; }
/* A den gets the wider side of a cave arena: one captain needs little room, three beasts need a lot */
.bv-arena-cave .bv-fleet-left { width: 32%; }
.bv-arena-cave .bv-fleet-right { width: 60%; }

/* The ability bar (Oct 8): a delve class's abilities along the foot of a captain's fight. Never pressed: each lights
   up as it fires; the always-on ones sit lit and quiet */
.bv-ability-bar { position: absolute; left: 50%; bottom: 6px; transform: translateX(-50%); display: flex; gap: 4px; align-items: center; z-index: 6; pointer-events: auto; }
.bv-ability-class { font: bold 0.8rem Georgia, serif; color: #e8d9b0; margin-right: 4px; text-shadow: 0 1px 2px #000; }
.bv-ability { font: 0.68rem Georgia, serif; color: #e8d9b0; padding: 2px 7px; border: 1px solid rgba(212, 160, 23, 0.55); border-radius: 4px; background: rgba(20, 16, 12, 0.75); }
.bv-ability-passive { border-style: dashed; opacity: 0.75; }
.bv-ability-fire { animation: bv-ability-fire 0.9s ease-out; }
@keyframes bv-ability-fire { 0% { background: #d4a017; color: #1d1712; box-shadow: 0 0 14px rgba(212, 160, 23, 0.9); transform: scale(1.15); } 100% { background: rgba(20, 16, 12, 0.75); color: #e8d9b0; box-shadow: none; transform: scale(1); } }
.bv-unit.bv-heal-glow .bv-unit-img { animation: bv-heal-glow 0.8s ease-out; }
@keyframes bv-heal-glow { 0% { filter: drop-shadow(0 0 0 rgba(95, 191, 74, 0)); } 40% { filter: drop-shadow(0 0 12px rgba(95, 191, 74, 0.95)); } 100% { filter: drop-shadow(0 0 0 rgba(95, 191, 74, 0)); } }

/* Delve ability effects (Oct 8): heals in green, guards as a blue aura that lasts their rounds, Whirl as a slash across
   the den, the always-on abilities as gold words over the figure */
.bv-dmg-heal { color: #6fe05a; font-size: 0.95rem; }
.bv-dmg-big { font-size: 1.35rem; }
.bv-dmg-guard { color: #8fc4ff; font-size: 0.8rem; }
.bv-dmg-ability { color: #f2c94c; font-size: 0.9rem; letter-spacing: 0.04em; }
.bv-unit.bv-heal-burst .bv-unit-img { animation: bv-heal-burst 1s ease-out; }
@keyframes bv-heal-burst { 0% { filter: drop-shadow(0 0 0 rgba(95, 191, 74, 0)) brightness(1); } 30% { filter: drop-shadow(0 0 22px rgba(120, 230, 90, 1)) brightness(1.35); } 100% { filter: drop-shadow(0 0 0 rgba(95, 191, 74, 0)) brightness(1); } }
.bv-unit.bv-guarded .bv-unit-img { filter: drop-shadow(0 0 6px rgba(120, 180, 255, 0.95)) drop-shadow(0 0 14px rgba(80, 140, 230, 0.6)) !important; }
.bv-whirl { position: absolute; top: 18%; right: 4%; width: 58%; height: 64%; border-radius: 50%; border-top: 6px solid rgba(255, 245, 220, 0.9); border-right: 3px solid rgba(255, 245, 220, 0.4); pointer-events: none; z-index: 7; animation: bv-whirl 0.55s ease-out forwards; filter: drop-shadow(0 0 8px rgba(255, 230, 160, 0.9)); }
@keyframes bv-whirl { 0% { transform: rotate(-70deg) scale(0.7); opacity: 0; } 30% { opacity: 1; } 100% { transform: rotate(110deg) scale(1.05); opacity: 0; } }
.bv-arena-cave.bv-cave-party .bv-fleet-left { width: 46%; }
.bv-arena-cave.bv-cave-party .bv-fleet-right { width: 50%; }

/* An Ultimate Delve Weapon's ability on the bar: the same slot, edged in gold */
.bv-ability-weapon { border-color: #f2c94c; color: #f7e3a0; }
/* A delve captain's class icon, just left of their HP bar */
.bv-unit .bv-hp-class { position: absolute; left: calc(50% - 40px - 19px); bottom: -16px; width: 17px; height: 17px; object-fit: contain; pointer-events: none; z-index: 3; filter: drop-shadow(0 1px 1px #000); }

/* Taunt (Oct 8): the Bruiser flares red as he shouts; a taunted beast wears a red mark until it wears off */
.bv-unit.bv-taunting .bv-unit-img { animation: bv-taunting 0.9s ease-out; }
@keyframes bv-taunting { 0% { filter: drop-shadow(0 0 4px rgba(230, 70, 40, 1)) drop-shadow(0 0 18px rgba(230, 70, 40, 0.8)); transform: scale(1.08); } 100% { filter: none; transform: scale(1); } }
.bv-unit.bv-taunted .bv-unit-img { filter: drop-shadow(0 0 5px rgba(220, 60, 40, 0.9)) !important; }
.bv-unit.bv-taunted::after { content: '!'; position: absolute; top: -14px; left: 50%; transform: translateX(-50%); width: 18px; height: 18px; line-height: 18px; text-align: center; border-radius: 50%; background: #b8321e; color: #fff3d6; font: bold 13px Georgia, serif; box-shadow: 0 0 8px rgba(220, 60, 40, 0.9); z-index: 7; pointer-events: none; }

/* Ability tooltips on the bar */
.bv-ability { cursor: help; }
.bv-ability-tip { position: absolute; z-index: 9; max-width: 240px; padding: 7px 10px; border: 1px solid rgba(212, 160, 23, 0.7); border-radius: 5px; background: rgba(20, 16, 12, 0.95); color: #e8d9b0; box-shadow: 0 4px 14px rgba(0, 0, 0, 0.6); opacity: 0; pointer-events: none; transition: opacity 0.12s; }
.bv-ability-tip-on { opacity: 1; }
.bv-ability-tip-name { font: bold 0.8rem 'Cinzel', serif; color: #f2c94c; }
.bv-ability-tip-kind { font: italic 0.66rem Georgia, serif; opacity: 0.75; margin: 1px 0 4px; }
.bv-ability-tip-text { font: 0.74rem/1.35 Georgia, serif; }
.bv-unit.bv-riposte .bv-unit-img { filter: drop-shadow(0 0 4px rgba(242, 201, 76, 0.95)) drop-shadow(0 0 10px rgba(212, 160, 23, 0.6)); }

/* Icon slots (Oct 8): the bar shows each ability's icon; a missing icon falls back to its name */
.bv-ability:not(.bv-ability-text) { padding: 2px; width: 36px; height: 36px; box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; }
.bv-ability-icon { width: 30px; height: 30px; display: block; pointer-events: none; }
.bv-ability-passive .bv-ability-icon { opacity: 0.8; }

/* Loot from a falling beast (Oct 8): pops out in an arc beside it and stays on the cave floor */
.bv-drop { position: absolute; width: 30px; height: 30px; z-index: 8; pointer-events: auto; cursor: help; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  animation: bv-drop-pop 0.7s cubic-bezier(0.2, 0.8, 0.3, 1) forwards, bv-drop-bob 2.4s ease-in-out 0.7s infinite; --glow: rgba(232, 217, 176, 0.75); filter: drop-shadow(0 0 5px var(--glow)); }
.bv-drop img { width: 28px; height: 28px; display: block; }
.bv-drop-uncommon { --glow: rgba(129, 199, 132, 0.9); }
.bv-drop-rare { --glow: rgba(100, 160, 240, 0.95); }
.bv-drop-epic { --glow: rgba(190, 110, 240, 0.95); }
.bv-drop-legendary { --glow: rgba(242, 170, 60, 1); }
.bv-drop-text { width: auto; height: auto; padding: 1px 6px; border-radius: 4px; background: rgba(20, 16, 12, 0.85); color: #e8d9b0; font: 0.62rem Georgia, serif; white-space: nowrap; }
.bv-drop-qty { position: absolute; right: -6px; bottom: -4px; font: bold 0.62rem Georgia, serif; color: #fff3d6; background: rgba(20, 16, 12, 0.85); border-radius: 6px; padding: 0 3px; }
@keyframes bv-drop-pop {
  0% { transform: translate(0, 0) scale(0.3); opacity: 0; }
  45% { transform: translate(calc(var(--dx) * 0.55), calc(var(--dy) - 46px)) scale(1.1); opacity: 1; }
  100% { transform: translate(var(--dx), var(--dy)) scale(1); opacity: 1; }
}
@keyframes bv-drop-bob { 0%, 100% { translate: 0 0; } 50% { translate: 0 -3px; } }

/* The drop's name floating up off it */
.bv-drop-label { position: absolute; z-index: 9; transform: translateX(-50%); white-space: nowrap; pointer-events: none; font: bold 0.78rem Georgia, serif; color: #e8d9b0; text-shadow: 0 1px 2px #000, 0 0 6px rgba(0, 0, 0, 0.8); animation: bv-drop-label 2.6s ease-out forwards; }
.bv-drop-label-uncommon { color: #9be39f; }
.bv-drop-label-rare { color: #8fc0ff; }
.bv-drop-label-epic { color: #d39bff; }
.bv-drop-label-legendary { color: #ffc067; }
@keyframes bv-drop-label { 0% { opacity: 0; margin-top: 6px; } 15% { opacity: 1; margin-top: 0; } 75% { opacity: 1; margin-top: -26px; } 100% { opacity: 0; margin-top: -36px; } }

/* The zoomed-out battle (Oct 11): a sprite is a squadron, with its count on it */
.bv-zoom-note { position: absolute; left: 10px; top: 8px; z-index: 50; font-size: 11px; line-height: 1; padding: 3px 6px; border-radius: 3px; background: rgba(0,0,0,0.55); color: #f0e8d4; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; pointer-events: none; }

/* A defence blown apart (Oct 11): a jolt, a flash of white, then it darkens and crumbles in place */
.bv-unit.bv-destroyed { animation: bv-destroy 1.1s ease-out forwards; }
@keyframes bv-destroy {
  0% { transform: translate(0, 0) scale(1); filter: brightness(2.2); opacity: 1; }
  12% { transform: translate(-3px, 2px) scale(1.06); filter: brightness(2.6); }
  24% { transform: translate(3px, -2px) scale(1.02); filter: brightness(1.2) sepia(0.4); }
  60% { transform: translate(0, 4px) scale(0.92); filter: brightness(0.5) sepia(0.6); opacity: 0.8; }
  100% { transform: translate(0, 10px) scale(0.75); filter: brightness(0.2); opacity: 0; }
}

/* A defence doomed this round (Oct 11): alight where it stands until the round's losses fall. The flame sprite lays over
   it; without the sprite the glow alone marks it */
.bv-unit.bv-doomed .bv-unit-img { filter: brightness(1.35) sepia(0.45) saturate(1.9) hue-rotate(-8deg); animation: bv-burn-flicker 0.4s ease-in-out infinite alternate; }
.bv-flame { position: absolute; left: 12%; bottom: 38%; width: 76%; height: 95%; object-fit: contain; object-position: bottom; pointer-events: none; transform-origin: 50% 100%; animation: bv-flame-lick 0.36s ease-in-out infinite alternate; }
.bv-flame[style*="scaleX(-1)"] { animation-name: bv-flame-lick-flipped; }
@keyframes bv-flame-lick { 0% { transform: scaleY(0.82) scaleX(1.06); opacity: 0.88; } 100% { transform: scaleY(1.18) scaleX(0.94); opacity: 1; } }
@keyframes bv-flame-lick-flipped { 0% { transform: scaleX(-1.06) scaleY(0.82); opacity: 0.88; } 100% { transform: scaleX(-0.94) scaleY(1.18); opacity: 1; } }
.bv-burst { position: absolute; left: -20%; bottom: 10%; width: 140%; height: 140%; object-fit: contain; object-position: bottom; pointer-events: none; transform-origin: 50% 100%; animation: bv-burst 0.9s ease-out forwards; }
@keyframes bv-burst { 0% { transform: scale(0.3); opacity: 0; } 18% { transform: scale(1.05); opacity: 1; } 100% { transform: scale(1.3) translateY(-12%); opacity: 0; } }
