/* 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); }
.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; }
  .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; }
}
