/* Battleground — retro arcade, mobile-first.
   Contrast ratios (checked against WCAG AA, 4.5:1 text / 3:1 UI):
   text on bg 17.4, text on panel 15.0, muted on panel 8.7,
   accent on panel 11.4, error on panel 8.1, cyan on panel 10.4,
   fight button text (ink) on red 6.2, on hover yellow 13.2, red "VS" on panel 5.4.
   The dark red shadows are decorative only. */

:root {
  --bg: #0d0d26;
  --panel: #1a1a46;
  --text: #f4f4ff;
  --muted: #b9b9e6;
  --accent: #ffd23f;
  --cyan: #3de0ff;
  --red: #ff5a5a;
  --red-dark: #b32d2d;
  --error: #ff9a9a;
  --ink: #0d0d26;
  --energy-high: #5be37d;

  --font: "Press Start 2P", "Courier New", ui-monospace, monospace;
  --gutter: 16px;
  --border: 4px;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  background-color: var(--bg);
  /* subtle pixel grid */
  background-image:
    linear-gradient(rgba(61, 224, 255, 0.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(61, 224, 255, 0.05) 1px, transparent 1px);
  background-size: 24px 24px;
  color: var(--text);
  font-family: var(--font);
  font-size: 0.75rem;
  line-height: 1.8;
}

/* Decorative CRT scanlines. Never needed for legibility. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0.18) 0,
    rgba(0, 0, 0, 0.18) 1px,
    transparent 1px,
    transparent 3px
  );
  z-index: 10;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.noscript {
  margin: 0;
  padding: 16px;
  background: var(--panel);
  border: var(--border) solid var(--red);
  color: var(--text);
}

/* Layout */
.screen {
  width: 100%;
  max-width: 960px;
  margin: 0 auto;
  padding: 32px var(--gutter) 24px;
  display: flex;
  flex-direction: column;
  gap: 32px;
}

/* Masthead */
.masthead {
  text-align: center;
}

.title {
  margin: 0;
  font-size: clamp(1.25rem, 7vw, 2.75rem);
  line-height: 1.3;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text);
  text-shadow: 3px 3px 0 var(--red-dark);
  overflow-wrap: anywhere;
}

.title-accent {
  color: var(--accent);
}

.tagline {
  margin: 16px 0 0;
  color: var(--cyan);
  text-transform: uppercase;
}

/* Panel */
.panel {
  background: var(--panel);
  border: var(--border) solid var(--cyan);
  box-shadow: 6px 6px 0 var(--red-dark);
  padding: 24px 16px;
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.fighters {
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
  display: grid;
  gap: 16px;
  grid-template-columns: 1fr;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}

.label {
  color: var(--accent);
  text-transform: uppercase;
}

.input {
  width: 100%;
  min-height: 52px;
  padding: 12px;
  background: var(--bg);
  color: var(--text);
  border: var(--border) solid var(--cyan);
  border-radius: 0;
  font-family: var(--font);
  font-size: 1rem; /* 16px minimum stops iOS zooming on focus */
  line-height: 1.4;
}

.input::placeholder {
  color: var(--muted);
  opacity: 1;
  /* Smaller than the typed text so the "e.g." examples fit on narrow phones */
  font-size: 0.75rem;
}

/* The example disappears as soon as the field is focused, so it can't be
   mistaken for a real value. The visible label still names the field. */
.input:focus::placeholder {
  color: transparent;
}

.input:focus-visible {
  outline: 4px solid var(--accent);
  outline-offset: 2px;
  border-color: var(--accent);
}

/* Fighter combobox: text input + arrow button + dropdown of saved fighters */
.combo {
  position: relative;
}

.combo .input {
  padding-right: 56px; /* room for the arrow button */
}

/* Saved-fighter marker: thumbnail inside the field, plus a hint underneath */
.combo-thumb {
  position: absolute;
  top: 8px;
  left: 8px;
  width: 36px;
  height: 36px;
  border: 2px solid var(--accent);
  image-rendering: pixelated;
  pointer-events: none;
}

.combo[data-saved="true"] .input {
  padding-left: 56px; /* room for the thumbnail */
}

.field-hint {
  margin: 0;
  color: var(--cyan);
  font-size: 0.625rem;
  line-height: 1.8;
  text-transform: uppercase;
  overflow-wrap: anywhere;
}

.combo-toggle {
  position: absolute;
  top: 4px;
  right: 4px;
  bottom: 4px;
  width: 44px;
  padding: 0;
  background: transparent;
  border: 0;
  border-radius: 0;
  cursor: pointer;
}

/* Arrow drawn with borders, so it doesn't depend on a font glyph */
.combo-toggle::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  margin: -3px 0 0 -7px;
  border-left: 7px solid transparent;
  border-right: 7px solid transparent;
  border-top: 8px solid var(--cyan);
}

.combo-toggle[aria-expanded="true"]::after {
  border-top: 0;
  border-bottom: 8px solid var(--cyan);
}

.combo-toggle:hover::after {
  border-top-color: var(--accent);
}

.combo-toggle[aria-expanded="true"]:hover::after {
  border-bottom-color: var(--accent);
}

.combo-toggle:focus-visible {
  outline: 4px solid var(--accent);
  outline-offset: -4px;
}

.combo-list {
  position: absolute;
  z-index: 5;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  max-height: 260px;
  overflow-y: auto;
  margin: 0;
  padding: 0;
  list-style: none;
  background: var(--bg);
  border: var(--border) solid var(--accent);
  box-shadow: 4px 4px 0 var(--red-dark);
}

.combo-option {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 48px;
  padding: 8px 12px;
  cursor: pointer;
  overflow-wrap: anywhere;
}

.combo-option span {
  min-width: 0;
}

.combo-option img {
  flex: none;
  width: 32px;
  height: 32px;
  border: 2px solid var(--cyan);
  image-rendering: pixelated;
}

.combo-option:hover,
.combo-option[aria-selected="true"] {
  background: var(--accent);
  color: var(--ink);
}

.field-error {
  margin: 0;
  min-height: 0;
  color: var(--error);
}

.field-error:empty {
  display: none;
}

/* Marker so errors don't rely on colour alone */
.field-error::before {
  content: "! ";
}

.input[aria-invalid="true"] {
  border-color: var(--red);
}

.vs {
  justify-self: center;
  color: var(--red);
  font-size: 1.5rem;
  text-shadow: 3px 3px 0 var(--ink);
  line-height: 1;
}

/* Fight button */
.fight-button {
  width: 100%;
  min-height: 60px;
  padding: 16px;
  background: var(--red);
  color: var(--ink);
  border: var(--border) solid var(--text);
  border-radius: 0;
  box-shadow: 0 6px 0 var(--red-dark);
  font-family: var(--font);
  font-size: 1.25rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  cursor: pointer;
  transition: transform 0.08s ease, box-shadow 0.08s ease;
}

.fight-button:hover {
  background: var(--accent);
}

.fight-button:active {
  transform: translateY(6px);
  box-shadow: 0 0 0 var(--red-dark);
}

.fight-button:focus-visible {
  outline: 4px solid var(--accent);
  outline-offset: 4px;
}

/* Let long button labels break instead of overflowing when text is enlarged */
.fight-button,
.secondary-button,
.save-button,
.remove-button {
  overflow-wrap: anywhere;
}

/* Secondary button: outlined, used for BattleDex navigation */
.secondary-button {
  width: 100%;
  min-height: 52px;
  padding: 12px 16px;
  background: transparent;
  color: var(--cyan);
  border: var(--border) solid var(--cyan);
  border-radius: 0;
  font-family: var(--font);
  font-size: 0.875rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  cursor: pointer;
}

.secondary-button:hover {
  background: var(--cyan);
  color: var(--ink);
}

.secondary-button:focus-visible {
  outline: 4px solid var(--accent);
  outline-offset: 4px;
}

/* BattleDex view */
.dex-title {
  margin: 0;
  color: var(--accent);
  font-size: clamp(1.25rem, 7vw, 1.75rem);
  line-height: 1.4;
  text-transform: uppercase;
  overflow-wrap: anywhere;
}

.dex-title:focus {
  outline: none;
}

.dex-note,
.dex-empty {
  margin: 0;
  line-height: 2;
}

.dex-note {
  color: var(--error);
}

.dex-empty {
  color: var(--muted);
}

.dex-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr));
  gap: 16px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.dex-list:empty {
  display: none;
}

.dex-item {
  display: flex;
  flex-wrap: wrap; /* the info block drops below the portrait when text is enlarged */
  align-items: center;
  gap: 16px;
  min-width: 0;
  padding: 12px;
  background: var(--bg);
  border: 2px solid var(--cyan);
}

.dex-item img {
  display: block;
  flex: none;
  width: 96px;
  height: 96px;
  border: var(--border) solid var(--cyan);
  image-rendering: pixelated;
}

.dex-item-info {
  display: flex;
  flex: 1 1 0;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
  min-width: min-content;
}

.dex-item-name {
  margin: 0;
  overflow-wrap: anywhere;
}

.remove-button {
  min-height: 44px;
  padding: 10px 16px;
  background: transparent;
  color: var(--red);
  border: 3px solid var(--red);
  border-radius: 0;
  font-family: var(--font);
  font-size: 0.75rem;
  text-transform: uppercase;
  cursor: pointer;
}

.remove-button:hover,
.remove-button[data-armed="true"] {
  background: var(--red);
  color: var(--ink);
}

.remove-button:focus-visible {
  outline: 4px solid var(--accent);
  outline-offset: 3px;
}

/* Views are switched with the `hidden` attribute; this beats the display
   values set on .panel, .result etc. */
[hidden] {
  display: none !important;
}

/* Loading view */
.loading {
  text-align: center;
  padding: 24px 0;
}

.loading:focus {
  outline: none;
}

.loading-text {
  margin: 0;
  /* "FIGHT!" is 6 characters wide, so tying the size to the viewport keeps it
     on screen even when the user enlarges their text. */
  font-size: min(14vw, 4.5rem);
  line-height: 1.2;
  color: var(--red);
  text-shadow: 4px 4px 0 var(--red-dark);
  animation: blink 0.8s steps(1, end) infinite;
}

.loading-sub {
  margin: 16px 0 0;
  /* Room for three lines, so the layout doesn't jump as the phrases change. */
  min-height: 5.5em;
  line-height: 1.8;
  color: var(--cyan);
  text-transform: uppercase;
}

@keyframes blink {
  50% {
    color: var(--accent);
  }
}

.fight-error {
  margin: 0;
  padding: 16px;
  background: var(--panel);
  border: var(--border) solid var(--red);
  color: var(--error);
}

.fight-error::before {
  content: "! ";
}

/* Winner's card */
.result {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.winner-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 24px;
  padding: 24px 16px;
  background: var(--panel);
  border: var(--border) solid var(--accent);
  box-shadow: 6px 6px 0 var(--red-dark);
  text-align: center;
  animation: card-slam 0.5s steps(5, end) both;
}

.winner-heading {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  max-width: 100%;
  margin: 0;
  line-height: 1.4;
  text-transform: uppercase;
  overflow-wrap: anywhere;
}

.winner-heading:focus {
  outline: none;
}

.winner-banner {
  color: var(--red);
  font-size: clamp(1.25rem, 8vw, 2rem);
  text-shadow: 3px 3px 0 var(--ink);
  animation: pop 0.4s steps(4, end) 0.4s both;
}

.winner-name {
  color: var(--accent);
  font-size: clamp(1rem, 6vw, 1.5rem);
}

.winner-portrait {
  width: 100%;
  max-width: 240px;
  animation: pop 0.4s steps(4, end) 0.6s both;
}

.winner-portrait img,
.defeated-portrait img {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  background: var(--bg);
  image-rendering: pixelated;
}

.winner-portrait img {
  border: var(--border) solid var(--accent);
  box-shadow: 6px 6px 0 var(--red-dark);
}

/* Save to BattleDex */
.fighter-actions {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
}

.winner-actions {
  align-items: center;
  animation: pop 0.4s steps(4, end) 0.6s both;
}

.save-button {
  min-height: 44px;
  padding: 10px 16px;
  background: transparent;
  color: var(--accent);
  border: 3px solid var(--accent);
  border-radius: 0;
  font-family: var(--font);
  font-size: 0.75rem;
  text-transform: uppercase;
  cursor: pointer;
}

.save-button:hover {
  background: var(--accent);
  color: var(--ink);
}

.save-button:focus-visible {
  outline: 4px solid var(--cyan);
  outline-offset: 3px;
}

.save-button[aria-disabled="true"],
.save-button[aria-disabled="true"]:hover {
  background: transparent;
  color: var(--muted);
  border-color: var(--muted);
  cursor: default;
}

.save-note {
  overflow-wrap: anywhere;
  margin: 0;
  color: var(--muted);
  font-size: 0.625rem;
  text-transform: uppercase;
}

.save-message {
  margin: 0;
  color: var(--cyan);
  overflow-wrap: anywhere;
}

.save-message:empty {
  display: none;
}

.save-message[data-error="true"] {
  color: var(--error);
}

.save-message[data-error="true"]::before {
  content: "! ";
}

/* Energy bars. Segmented, stepped, fighting-game style. The number is always
   shown as text, so colour is only an extra cue. */
.energy {
  width: 100%;
  padding: 16px;
  background: var(--bg);
  border: 2px solid var(--muted);
  text-align: left;
  animation: rise 0.5s steps(5, end) 0.8s both;
}

.energy-title {
  margin: 0 0 16px;
  color: var(--muted);
  font-size: 0.75rem;
  text-transform: uppercase;
}

.energy-list {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.energy-name {
  display: block;
  margin-bottom: 8px;
  overflow-wrap: anywhere;
  font-size: 0.75rem;
  text-transform: uppercase;
}

.energy-meter {
  display: flex;
  align-items: center;
  gap: 12px;
}

.energy-bar {
  position: relative;
  flex: 1;
  min-width: 0;
  height: 24px;
  background: var(--panel);
  border: 3px solid var(--text);
  overflow: hidden;
}

.energy-fill {
  --energy: 100%;
  width: var(--energy);
  height: 100%;
  /* The final colour is set here, not by the animation, so it is right even
     with reduced motion (no animation) on. */
  background: var(--energy-end, var(--energy-high));
  animation:
    energy-drain 1.4s steps(20, end) 1.4s both,
    energy-tint 1.4s steps(4, end) 1.4s both;
}

.energy-fill[data-level="mid"] {
  --energy-end: var(--accent);
}

.energy-fill[data-level="low"] {
  --energy-end: var(--red);
}

/* Chunky segments over the fill, like the bars in fighting games. */
.energy-bar::after {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(90deg, transparent 0 calc(10% - 2px), var(--panel) calc(10% - 2px) 10%);
  pointer-events: none;
}

.energy-value {
  flex: none;
  min-width: 5ch;
  text-align: right;
  font-size: 0.75rem;
}

@keyframes energy-drain {
  from {
    width: 100%;
  }
}

@keyframes energy-tint {
  from {
    background-color: var(--energy-high);
  }
  to {
    background-color: var(--energy-end, var(--energy-high));
  }
}

.winner-reasoning {
  width: 100%;
  padding: 16px;
  background: var(--bg);
  border: 2px solid var(--cyan);
  text-align: left;
  animation: rise 0.5s steps(5, end) 1s both;
}

.reasoning-title {
  margin: 0 0 12px;
  color: var(--cyan);
  font-size: 0.75rem;
  text-transform: uppercase;
}

.reasoning-text {
  margin: 0;
  line-height: 2;
  overflow-wrap: anywhere;
}

.defeated {
  display: flex;
  align-items: center;
  gap: 16px;
  width: 100%;
  text-align: left;
  animation: rise 0.5s steps(5, end) 1.3s both;
}

.defeated-portrait {
  flex: none;
  width: 96px;
}

.defeated-portrait img {
  border: var(--border) solid var(--muted);
}

.defeated-portrait img {
  filter: grayscale(1);
}

.defeated-info {
  min-width: 0;
}

.defeated-label {
  overflow-wrap: anywhere;
  margin: 0 0 8px;
  color: var(--muted);
  font-size: 0.625rem;
  text-transform: uppercase;
}

.defeated-name {
  margin: 0;
  overflow-wrap: anywhere;
}

@keyframes card-slam {
  0% {
    opacity: 0;
    transform: translateY(-32px) scale(1.15);
  }
  100% {
    opacity: 1;
    transform: none;
  }
}

@keyframes pop {
  0% {
    opacity: 0;
    transform: scale(0.2);
  }
  100% {
    opacity: 1;
    transform: none;
  }
}

@keyframes rise {
  0% {
    opacity: 0;
    transform: translateY(16px);
  }
  100% {
    opacity: 1;
    transform: none;
  }
}

@keyframes fade-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* Footer */
.footer {
  text-align: center;
  color: var(--muted);
  text-transform: uppercase;
  font-size: 0.625rem;
}

.footer p {
  margin: 0;
}

/* Tablet and up: fighters side by side */
@media (min-width: 640px) {
  .screen {
    padding: 48px 24px 32px;
    gap: 40px;
  }

  .panel {
    padding: 32px;
    gap: 32px;
  }

  .fighters {
    grid-template-columns: 1fr auto 1fr;
    align-items: start;
    gap: 24px;
  }

  .vs {
    align-self: center;
    font-size: 2rem;
    /* line up with the inputs rather than the labels */
    margin-top: 32px;
  }

  .fight-button,
  .secondary-button {
    max-width: 360px;
    align-self: center;
  }
}

@media (min-width: 960px) {
  body {
    font-size: 0.875rem;
  }
}

/* Honour reduced motion preference: no movement, just a simple fade for the card */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition: none !important;
    animation: none !important;
  }

  .winner-card,
  .winner-banner,
  .winner-portrait,
  .winner-actions,
  .energy,
  .winner-reasoning,
  .defeated {
    animation: fade-in 0.4s linear both !important;
  }
}
