/* BattleBot Arena v2 — base tokens, chrome, shared components.
   Broadcast-combat look: carbon fiber, brushed steel, angled cuts,
   red/amber accents. Self-contained: system fonts, pure CSS. */

:root {
  --steel-950: #07090c;
  --steel-900: #0b0d11;
  --steel-800: #12151b;
  --steel-700: #1a1f27;
  --steel-600: #262d38;
  --steel-500: #39424f;
  --line: rgba(255, 255, 255, 0.13);
  --line-strong: rgba(255, 255, 255, 0.28);

  --red: #e8362a;
  --red-hot: #ff5d47;
  --red-deep: #8f1710;
  --amber: #ffb92e;
  --yellow: #ffd23d;
  --white: #f4f6f8;
  --muted: #93a0b1;

  --font-display: Impact, "Arial Black", "Franklin Gothic Bold", "Helvetica Neue", sans-serif;
  --font-ui: "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
  --skew: -8deg;

  --cut: 14px;
  --carbon:
    repeating-linear-gradient(45deg, rgba(255, 255, 255, 0.024) 0 2px, transparent 2px 5px),
    repeating-linear-gradient(-45deg, rgba(255, 255, 255, 0.024) 0 2px, transparent 2px 5px);
  --hazard: repeating-linear-gradient(
    -45deg,
    var(--yellow) 0 14px,
    #14161a 14px 28px
  );
}

* {
  box-sizing: border-box;
}

/* The [hidden] attribute always wins, even over display:flex components. */
[hidden] {
  display: none !important;
}

html,
body {
  width: 100%;
  height: 100%;
  margin: 0;
  overflow: hidden;
  font-family: var(--font-ui);
  color: var(--white);
  background: var(--steel-950);
  -webkit-font-smoothing: antialiased;
}

button,
input,
select {
  font: inherit;
  color: inherit;
}

img {
  max-width: 100%;
  display: block;
}

/* The game canvas sits behind every screen; integrator owns its context. */
#scene {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  display: block;
  z-index: 0;
  background: #0a0c0f;
  touch-action: none;
}

#app {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 100%;
}

/* ------------------------------------------------------------------ screens */

.screen {
  position: fixed;
  inset: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(14px);
  transition:
    opacity 0.3s ease,
    transform 0.3s ease,
    visibility 0s linear 0.3s;
}

.screen.is-active {
  opacity: 1;
  visibility: visible;
  transform: none;
  pointer-events: auto;
  transition:
    opacity 0.3s ease,
    transform 0.3s ease;
}

/* Match screen is a passthrough HUD — the canvas keeps pointer input. */
.screen-match,
.screen-match.is-active {
  pointer-events: none;
}

/* Dark broadcast backdrop over the canvas for menu screens. */
.screen-backdrop {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(1100px 640px at 50% -12%, rgba(232, 54, 42, 0.17), transparent 62%),
    radial-gradient(900px 560px at 82% 108%, rgba(255, 185, 46, 0.08), transparent 60%),
    var(--carbon),
    linear-gradient(180deg, #10141a 0%, #090b0e 68%, #060709 100%);
}

.screen-backdrop::after {
  /* faint scanlines */
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    0deg,
    rgba(255, 255, 255, 0.016) 0 1px,
    transparent 1px 4px
  );
  pointer-events: none;
}

/* ------------------------------------------------------------------ buttons */

.btn {
  --btn-bg: linear-gradient(180deg, var(--steel-600), var(--steel-700) 55%, var(--steel-800));
  --btn-edge: var(--line-strong);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 12px 30px;
  border: 1px solid var(--btn-edge);
  background: var(--btn-bg);
  color: var(--white);
  font-family: var(--font-display);
  font-size: 1.05rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  cursor: pointer;
  clip-path: polygon(10px 0, 100% 0, calc(100% - 10px) 100%, 0 100%);
  transform: skewX(var(--skew));
  transition:
    filter 0.15s ease,
    transform 0.15s ease,
    box-shadow 0.15s ease;
}

.btn > span {
  display: inline-block;
  transform: skewX(calc(var(--skew) * -1));
}

.btn:hover:not(:disabled) {
  filter: brightness(1.22);
  box-shadow: 0 0 22px rgba(255, 255, 255, 0.12);
}

.btn:active:not(:disabled) {
  transform: skewX(var(--skew)) translateY(1px);
}

.btn:disabled {
  opacity: 0.38;
  cursor: not-allowed;
}

.btn:focus-visible {
  outline: 2px solid var(--amber);
  outline-offset: 3px;
}

.btn-primary {
  --btn-bg: linear-gradient(180deg, var(--red-hot), var(--red) 48%, var(--red-deep));
  --btn-edge: rgba(255, 130, 110, 0.6);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.45);
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.4),
    0 10px 28px rgba(232, 54, 42, 0.32);
}

.btn-primary:hover:not(:disabled) {
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.4),
    0 10px 36px rgba(255, 93, 71, 0.55);
}

.btn-xl {
  padding: 18px 52px;
  font-size: 1.7rem;
  letter-spacing: 0.12em;
}

.btn-sm {
  padding: 8px 18px;
  font-size: 0.85rem;
}

.btn-toggle.is-on {
  --btn-bg: linear-gradient(180deg, #55c46a, #2e9245 55%, #1d6330);
  --btn-edge: rgba(120, 255, 150, 0.45);
}

/* ---------------------------------------------------------------- kickers */

.kicker {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-family: var(--font-display);
  font-size: 0.82rem;
  letter-spacing: 0.42em;
  text-transform: uppercase;
  color: var(--amber);
}

.kicker::before,
.kicker::after {
  content: "";
  width: 42px;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--amber));
}

.kicker::after {
  background: linear-gradient(90deg, var(--amber), transparent);
}

/* ------------------------------------------------------------------- panel */

.panel-cut {
  position: relative;
  border: 1px solid var(--line);
  background:
    var(--carbon),
    linear-gradient(180deg, rgba(38, 45, 56, 0.92), rgba(14, 17, 22, 0.95));
  clip-path: polygon(
    var(--cut) 0,
    100% 0,
    100% calc(100% - var(--cut)),
    calc(100% - var(--cut)) 100%,
    0 100%,
    0 var(--cut)
  );
}

.hazard-strip {
  height: 10px;
  background: var(--hazard);
  opacity: 0.85;
}

/* ------------------------------------------------------------------- modal */

.modal {
  position: fixed;
  inset: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(4, 5, 7, 0.72);
  backdrop-filter: blur(3px);
  opacity: 0;
  transition: opacity 0.2s ease;
}

.modal.is-open {
  opacity: 1;
}

.modal-panel {
  width: min(440px, calc(100vw - 48px));
  padding: 0 0 20px;
  transform: translateY(10px);
  transition: transform 0.2s ease;
}

.modal.is-open .modal-panel {
  transform: none;
}

.modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 22px 12px;
  border-bottom: 1px solid var(--line);
}

.modal-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.4rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  transform: skewX(var(--skew));
}

.modal-body {
  padding: 8px 22px 4px;
}

.setting-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 11px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.setting-row:last-child {
  border-bottom: 0;
}

.setting-label {
  font-size: 0.86rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

.setting-hint {
  display: block;
  margin-top: 2px;
  font-size: 0.72rem;
  font-weight: 400;
  letter-spacing: 0.05em;
  text-transform: none;
  color: rgba(147, 160, 177, 0.7);
}

.switch-btn {
  min-width: 74px;
  padding: 7px 14px;
  border: 1px solid var(--line-strong);
  background: linear-gradient(180deg, var(--steel-600), var(--steel-800));
  color: var(--muted);
  font-family: var(--font-display);
  font-size: 0.85rem;
  letter-spacing: 0.14em;
  cursor: pointer;
  clip-path: polygon(7px 0, 100% 0, calc(100% - 7px) 100%, 0 100%);
  transition: filter 0.15s ease;
}

.switch-btn:hover {
  filter: brightness(1.25);
}

.switch-btn.is-on {
  background: linear-gradient(180deg, #58c96d, #237a38);
  border-color: rgba(130, 255, 160, 0.5);
  color: #eafff0;
}

.select {
  padding: 8px 12px;
  border: 1px solid var(--line-strong);
  background: linear-gradient(180deg, var(--steel-600), var(--steel-800));
  color: var(--white);
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: 0.85rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
}

.select:focus-visible,
.switch-btn:focus-visible {
  outline: 2px solid var(--amber);
  outline-offset: 2px;
}

/* -------------------------------------------------------------- scrollbars */

::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

::-webkit-scrollbar-track {
  background: var(--steel-900);
}

::-webkit-scrollbar-thumb {
  background: var(--steel-500);
  border: 2px solid var(--steel-900);
}

/* --------------------------------------------------------- reduced motion */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ------------------------------------------------- controller focus ring
   Applied by src/ui/gamepadNav.js alongside a real element.focus(), so pad,
   keyboard and mouse all agree on "where you are". Uses an INSET outline
   because every panel here is clip-path'd (an outer ring would be clipped
   away) and because outline never competes with the box-shadow that draws
   the YOU / RIVAL selection rings or the .btn-primary glow. */

@keyframes navFocusPulse {
  0%,
  100% {
    outline-color: var(--amber);
  }
  50% {
    outline-color: #fff8e2;
  }
}

.btn.is-nav-focus:not(:disabled),
.bot-card.is-nav-focus,
.pod-plate.is-nav-focus,
.switch-btn.is-nav-focus,
.select.is-nav-focus,
.difficulty-buttons button.is-nav-focus,
.is-nav-focus {
  outline: 4px solid var(--amber);
  outline-offset: -4px;
  animation: navFocusPulse 1.1s ease-in-out infinite;
}

/* Extra lift so the ring reads on dark carbon without touching box-shadow. */
.btn.is-nav-focus:not(:disabled),
.switch-btn.is-nav-focus,
.difficulty-buttons button.is-nav-focus {
  filter: brightness(1.22);
}

.bot-card.is-nav-focus {
  transform: translateY(-3px);
  border-color: var(--line-strong);
}

.pod-plate.is-nav-focus {
  border-color: var(--line-strong);
}

.select.is-nav-focus {
  outline-offset: -2px;
}

@media (prefers-reduced-motion: reduce) {
  .is-nav-focus {
    outline-color: var(--amber);
  }
}

/* Duo mode (two pads on bot select): each pad drives its own cursor, so the
   two rings must be told apart at a glance. COLOUR is the only thing that
   separates them — P1 red, P2 yellow, matching the YOU / RIVAL slot colours —
   and both are dashed. P1 used to be solid, which read as a different KIND of
   indicator rather than as the same indicator belonging to someone else. Both
   override the shared amber ring. Kept to outline + box-shadow: ::before and
   ::after are already spoken for by the bot-card accent blade and the
   YOU/RIVAL flag. */
/* Every rule here is written twice, once with :focus-visible. Cursor 0 is the
   only one that owns real DOM focus (see ui/gamepadNav.js), so P1's element is
   always :focus-visible too — and the generic focus ring in screens.css has the
   same specificity and lands later in the cascade. Without the doubled
   selectors P1 wears the shared amber ring and never its own, which is exactly
   how the two players' cursors came to look like different things. */
.is-nav-focus.is-nav-p1,
.is-nav-focus.is-nav-p1:focus-visible,
.is-nav-focus.is-nav-p2,
.is-nav-focus.is-nav-p2:focus-visible,
.is-nav-focus.is-nav-p3,
.is-nav-focus.is-nav-p3:focus-visible,
.is-nav-focus.is-nav-p4,
.is-nav-focus.is-nav-p4:focus-visible {
  animation: none;
  outline-offset: -4px;
}

.is-nav-focus.is-nav-p1,
.is-nav-focus.is-nav-p1:focus-visible {
  outline: 4px dashed var(--red-hot);
}

.is-nav-focus.is-nav-p2,
.is-nav-focus.is-nav-p2:focus-visible {
  outline: 4px dashed var(--yellow);
}

.is-nav-focus.is-nav-p3,
.is-nav-focus.is-nav-p3:focus-visible {
  outline: 4px dashed #a45cf0;
}

.is-nav-focus.is-nav-p4,
.is-nav-focus.is-nav-p4:focus-visible {
  outline: 4px dashed #4bd6a0;
}

/* Two cursors on the same element: nest the rings so neither disappears. The
   outline is the LOWER-numbered player's and the inset ring is the other's, so
   with three or four players a shared card still names both of them. Only the
   pairs are enumerated — three cursors on one card is a rare enough moment that
   showing two of them is honest enough, and the card's own P-flags say the
   rest. */
.is-nav-focus.is-nav-p1.is-nav-p2,
.is-nav-focus.is-nav-p1.is-nav-p2:focus-visible {
  outline: 4px dashed var(--red-hot);
  box-shadow: inset 0 0 0 9px rgba(11, 13, 17, 0.9), inset 0 0 0 13px var(--yellow);
}

.is-nav-focus.is-nav-p1.is-nav-p3,
.is-nav-focus.is-nav-p1.is-nav-p3:focus-visible {
  outline: 4px dashed var(--red-hot);
  box-shadow: inset 0 0 0 9px rgba(11, 13, 17, 0.9), inset 0 0 0 13px #a45cf0;
}

.is-nav-focus.is-nav-p1.is-nav-p4,
.is-nav-focus.is-nav-p1.is-nav-p4:focus-visible {
  outline: 4px dashed var(--red-hot);
  box-shadow: inset 0 0 0 9px rgba(11, 13, 17, 0.9), inset 0 0 0 13px #4bd6a0;
}

.is-nav-focus.is-nav-p2.is-nav-p3,
.is-nav-focus.is-nav-p2.is-nav-p3:focus-visible {
  outline: 4px dashed var(--yellow);
  box-shadow: inset 0 0 0 9px rgba(11, 13, 17, 0.9), inset 0 0 0 13px #a45cf0;
}

.is-nav-focus.is-nav-p2.is-nav-p4,
.is-nav-focus.is-nav-p2.is-nav-p4:focus-visible {
  outline: 4px dashed var(--yellow);
  box-shadow: inset 0 0 0 9px rgba(11, 13, 17, 0.9), inset 0 0 0 13px #4bd6a0;
}

.is-nav-focus.is-nav-p3.is-nav-p4,
.is-nav-focus.is-nav-p3.is-nav-p4:focus-visible {
  outline: 4px dashed #a45cf0;
  box-shadow: inset 0 0 0 9px rgba(11, 13, 17, 0.9), inset 0 0 0 13px #4bd6a0;
}

/* ============================================================ LOADERS
   Two users: the boot gate baked into index.html, and the shared asset
   overlay driven by src/ui/loader.js. Both share this markup/skin. */

.loader-overlay {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background:
    radial-gradient(ellipse at 50% 40%, rgba(26, 31, 39, 0.85), rgba(7, 9, 12, 0.96) 70%),
    var(--steel-950);
  opacity: 0;
  transition: opacity 0.28s ease;
}

.loader-overlay.is-open {
  opacity: 1;
}

.loader-panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  width: min(420px, 100%);
  padding: 30px 34px 26px;
  border: 1px solid var(--line);
  background:
    var(--carbon),
    linear-gradient(180deg, rgba(32, 38, 47, 0.92), rgba(12, 14, 18, 0.95));
  clip-path: polygon(
    var(--cut) 0,
    100% 0,
    100% calc(100% - var(--cut)),
    calc(100% - var(--cut)) 100%,
    0 100%,
    0 var(--cut)
  );
  text-align: center;
}

/* Saw-blade spinner: matches the title gear rather than a generic ring. */
.loader-spinner {
  width: 46px;
  height: 46px;
  border: 4px solid rgba(255, 255, 255, 0.14);
  border-top-color: var(--amber);
  border-right-color: var(--red);
  border-radius: 50%;
  animation: loaderSpin 0.9s linear infinite;
}

@keyframes loaderSpin {
  to {
    transform: rotate(360deg);
  }
}

.loader-title {
  font-family: var(--font-display);
  font-size: 1.4rem;
  letter-spacing: 0.16em;
  color: var(--white);
}

.loader-detail {
  min-height: 1.1em;
  font-family: var(--font-ui);
  font-size: 0.82rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

.loader-bar {
  position: relative;
  display: block;
  width: 100%;
  height: 10px;
  overflow: hidden;
  border: 1px solid var(--line);
  background: rgba(0, 0, 0, 0.5);
}

.loader-bar > i {
  display: block;
  width: 100%;
  height: 100%;
  transform: scaleX(0);
  transform-origin: left center;
  background: linear-gradient(90deg, var(--red), var(--amber), var(--yellow));
  transition: transform 0.2s ease-out;
}

/* Unknown total (no content-length on the response): sweep instead of fill. */
.loader-bar-indeterminate > i {
  width: 38%;
  transform: none;
  animation: loaderSweep 1.15s ease-in-out infinite;
}

@keyframes loaderSweep {
  0% {
    margin-left: -38%;
  }
  100% {
    margin-left: 100%;
  }
}

.loader-pct {
  min-height: 1em;
  font-family: var(--font-display);
  font-size: 0.9rem;
  letter-spacing: 0.18em;
  color: var(--amber);
}

@media (prefers-reduced-motion: reduce) {
  .loader-spinner {
    animation-duration: 2.4s;
  }
  .loader-bar-indeterminate > i {
    animation-duration: 3s;
  }
}

/* Per-image placeholder shimmer. The roster photos are ~2MB each, so a card
   would otherwise sit as an empty black box until its image lands. */
.is-img-loading {
  position: relative;
}

.is-img-loading::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(
    100deg,
    rgba(255, 255, 255, 0.03) 30%,
    rgba(255, 255, 255, 0.11) 50%,
    rgba(255, 255, 255, 0.03) 70%
  );
  background-size: 240% 100%;
  animation: imgShimmer 1.3s ease-in-out infinite;
}

.is-img-loading img {
  opacity: 0;
}

@keyframes imgShimmer {
  0% {
    background-position: 130% 0;
  }
  100% {
    background-position: -130% 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .is-img-loading::before {
    animation: none;
  }
}
