/* css/styles.css — Warzone Wheel: dark casino theme */

:root {
  --accent-color: #d4af37;
  --primary-color: #3a3f33;
  --secondary-color: #6b7264;
  --bg-black: #0a0a0c;
  --panel-black: #121214;
  --text-light: #f1efe7;
  --text-dim: #9a9a94;
  --transition-fast: 250ms ease;
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html, body {
  height: 100%;
  overflow: hidden;
  background: var(--bg-black);
  color: var(--text-light);
  font-family: 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
  -webkit-tap-highlight-color: transparent;
  /* none (not pan-y) now that horizontal swipes are a real gesture (category
     switching) — pan-y would let the browser treat a horizontal drag as its
     own back/forward navigation swipe instead of handing it to our touchend
     handler. */
  touch-action: none;
}

#app {
  position: relative;
  width: 100%;
  height: 100%;
  min-height: 100dvh;
  overflow: hidden;
}

/* ---------- Header / map badge ---------- */

#header {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 18px 16px 10px;
  text-align: center;
  pointer-events: none;
}

.map-badge {
  font-size: clamp(28px, 7vw, 44px);
  font-weight: 800;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--text-light);
  text-shadow: 0 0 18px color-mix(in srgb, var(--accent-color) 70%, transparent), 0 2px 4px #000;
  transition: color var(--transition-fast);
}

.map-badge .dash {
  color: var(--accent-color);
  margin: 0 8px;
}

#mapMode {
  color: var(--accent-color);
  font-weight: 600;
}

.hint {
  font-size: 11px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--text-dim);
  opacity: 0.8;
}

/* ---------- Map screen ---------- */

.map-screen {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transform: scale(0.97);
}

.map-screen.map-enter {
  animation: mapFadeIn var(--transition-fast) forwards;
}

@keyframes mapFadeIn {
  from { opacity: 0; transform: scale(0.97); }
  to   { opacity: 1; transform: scale(1); }
}

.background-layer {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  transition: background var(--transition-fast);
}

.bg-watermark {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: clamp(48px, 16vw, 160px);
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 4px;
  color: rgba(255, 255, 255, 0.06);
  white-space: nowrap;
  pointer-events: none;
  user-select: none;
}

.bg-pattern {
  position: absolute;
  inset: 0;
  pointer-events: none;
  mix-blend-mode: overlay;
}

.bg-pattern svg {
  display: block;
}

/* ---------- Wheel ---------- */

.wheel-container {
  position: relative;
  z-index: 5;
  transition: transform 550ms cubic-bezier(0.2, 0.8, 0.2, 1), opacity 400ms ease;
  /* IMPORTANT: the wheel is vertically centered in the FULL viewport height
     (mapScreen fills #app), not in the band between the header and the
     swipe-hint — so the binding constraint is 2x whichever of those two
     reserved zones is larger, not their sum. #header (now-larger map name +
     hint + the large top toggle) is ~205px tall; .swipe-hint reserves ~190px
     from the bottom (its fixed 100px offset + its own ~90px height, now a
     "Swipe" label plus a 3-chevron blinker stack). Both are fixed-px-based
     specifically so they don't scale with vh and throw this math off (a
     %-based swipe-hint offset previously caused it to visually overlap the
     wheel on tall viewports). 440px total is 2x ~205px plus a safety margin.
     Now that the category toggle lives in the header (not a side rail) and
     the old chevron buttons are gone entirely, nothing is anchored to the
     left/right edges either, so the 100vw/calc term only needs a small edge
     margin. */
  width: min(97vw, calc(100vh - 440px), calc(100vw - 24px), 1200px);
  aspect-ratio: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
  filter: drop-shadow(0 0 26px rgba(0, 0, 0, 0.55));
}

.wheel-svg {
  width: 100%;
  height: 100%;
  overflow: visible;
  filter: drop-shadow(0 0 24px color-mix(in srgb, var(--accent-color) 45%, transparent));
}

.wheel-group {
  transform-box: fill-box;
  transform-origin: 50% 50%;
  will-change: transform;
}

.wheel-wedge {
  transition: filter var(--transition-fast);
}

.wheel-label {
  fill: #fdfaf0;
  font-weight: 700;
  paint-order: stroke;
  stroke: #000;
  stroke-width: 2.5px;
  stroke-linejoin: round;
  pointer-events: none;
  user-select: none;
}

.wheel-hub-bg {
  fill: var(--panel-black);
  stroke: var(--accent-color);
  stroke-width: 3;
}

.wheel-pointer {
  fill: var(--accent-color);
  stroke: #000;
  stroke-width: 1.5;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.6));
}

.launch-btn {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 19%;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  border: 3px solid var(--accent-color);
  /* Falls back to this dark radial if a map ever has no image (app.js only
     sets an inline background-image when map.backgroundImage is present). */
  background: radial-gradient(circle at 35% 30%, #2a2a2a, #050505 75%);
  background-size: cover;
  background-position: center;
  color: var(--accent-color);
  cursor: pointer;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 0 18px color-mix(in srgb, var(--accent-color) 55%, transparent), inset 0 0 10px rgba(0, 0, 0, 0.6);
  transition: transform 120ms ease, box-shadow 120ms ease;
}

.launch-label {
  font-weight: 900;
  font-size: clamp(10px, 2.4vw, 16px);
  letter-spacing: 1.5px;
  color: var(--text-light);
  text-shadow: 0 0 10px rgba(0, 0, 0, 0.9), 0 2px 3px rgba(0, 0, 0, 0.9);
  pointer-events: none;
  user-select: none;
}

.launch-btn:hover:not(:disabled) {
  transform: translate(-50%, -50%) scale(1.05);
  box-shadow: 0 0 26px color-mix(in srgb, var(--accent-color) 75%, transparent), inset 0 0 10px rgba(0, 0, 0, 0.6);
}

.launch-btn:active:not(:disabled) {
  transform: translate(-50%, -50%) scale(0.96);
}

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

/* ---------- Result (screen-reader only) ---------- */

/* The visible result is the reveal card below; this stays in the DOM purely
   so assistive tech still gets an announced "Landing Zone: X" via its
   aria-live="polite" attribute on the element itself (see index.html). */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ---------- Wheel shrink (on spin result) ---------- */

.wheel-container.shrunk {
  transform: scale(0.4) translateY(-20%);
  opacity: 0.5;
  pointer-events: none;
}

/* ---------- Reveal overlay (POI card + Spin Again) ---------- */

.reveal-overlay {
  position: absolute;
  inset: 0;
  z-index: 18;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 380ms ease;
}

.reveal-overlay.visible {
  opacity: 1;
  pointer-events: auto;
}

.reveal-card {
  position: relative;
  width: min(88vw, 420px);
  aspect-ratio: 2 / 3;
  max-height: 82vh;
  border-radius: 18px;
  overflow: hidden;
  border: 3px solid var(--accent-color);
  background: #0a0a0c;
  box-shadow: 0 0 40px rgba(0, 0, 0, 0.6), 0 0 26px color-mix(in srgb, var(--accent-color) 40%, transparent);
  transform: scale(0.9);
  transition: transform 380ms cubic-bezier(0.2, 0.8, 0.2, 1.15);
}

.reveal-overlay.visible .reveal-card {
  transform: scale(1);
}

.reveal-card-content {
  position: relative;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 24px;
}

.reveal-eyebrow {
  font-size: clamp(10px, 2.6vw, 13px);
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--accent-color);
  font-weight: 700;
  margin-bottom: 10px;
}

.reveal-poi-name {
  font-size: clamp(28px, 8vw, 46px);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--text-light);
  text-shadow: 0 3px 0 #000, 0 0 24px color-mix(in srgb, var(--accent-color) 45%, transparent);
  word-break: break-word;
}

.reveal-rule {
  width: 56px;
  height: 3px;
  background: var(--accent-color);
  margin: 18px 0;
}

.reveal-sub {
  font-size: clamp(12px, 3vw, 14px);
  color: var(--text-dim);
  letter-spacing: 0.5px;
  margin-bottom: 48px;
}

.spin-again-btn {
  appearance: none;
  border: none;
  border-radius: 6px;
  padding: 14px 34px;
  background: var(--accent-color);
  color: #1a1500;
  font-weight: 800;
  font-size: clamp(13px, 3.4vw, 16px);
  letter-spacing: 2px;
  text-transform: uppercase;
  cursor: pointer;
  box-shadow: 0 4px 0 color-mix(in srgb, var(--accent-color) 55%, black);
  transition: transform 120ms ease, box-shadow 120ms ease;
}

.spin-again-btn:hover {
  transform: translateY(-2px);
}

.spin-again-btn:active {
  transform: translateY(1px);
  box-shadow: 0 2px 0 color-mix(in srgb, var(--accent-color) 55%, black);
}

/* ---------- Category toggle (Big Map / Small Map) ---------- */

/* Lives inside #header now (third flex child, stacked below the hint text)
   instead of pinned to the left edge — sits at the top of the screen,
   centered, side-by-side. #header sets pointer-events:none so its own text
   can be clicked through, so this needs pointer-events:auto to stay
   clickable. Sized ~75% larger again on top of the earlier 50% bump, so the
   button text now reads at roughly the same scale as the header's map name.
   Base rule below is MOBILE sizing, shrunk to 75% of that desktop-parity
   size per user feedback that it read too large on phones; the 720px+
   media query below restores the original (pre-shrink) numbers for desktop. */
.category-toggle {
  position: relative;
  pointer-events: auto;
  margin-top: 10.5px;
  display: flex;
  flex-direction: row;
  border: 3.75px solid var(--accent-color);
  border-radius: 19.5px;
  overflow: hidden;
  background: rgba(10, 10, 12, 0.75);
  box-shadow: 0 0 16px color-mix(in srgb, var(--accent-color) 35%, transparent);
  opacity: 1;
  transition: opacity 250ms ease;
}

/* Hidden while the reveal card is up (see app.js) — it's a distraction once
   a result is showing, and the Spin Again button / a map switch both bring
   it back via hideReveal(). */
.category-toggle.hidden {
  opacity: 0;
  pointer-events: none;
}

.category-toggle-btn {
  appearance: none;
  border: none;
  background: transparent;
  color: var(--text-dim);
  font-weight: 800;
  font-size: 19.5px;
  letter-spacing: 2px;
  text-transform: uppercase;
  padding: 19.5px 24px;
  cursor: pointer;
  white-space: nowrap;
  transition: background 150ms ease, color 150ms ease;
}

.category-toggle-btn + .category-toggle-btn {
  border-left: 1.5px solid color-mix(in srgb, var(--accent-color) 40%, transparent);
}

.category-toggle-btn.active {
  background: var(--accent-color);
  color: #0a0a0c;
}

.category-toggle-btn:hover:not(.active) {
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-light);
}

/* ---------- Swipe-down hint ---------- */

/* Replaces the old up/down chevron buttons as the visual cue for vertical
   map switching. The whole block breathes gently (opacity + scale) so it
   reads as a hint rather than static UI chrome, and below the "Swipe" text
   sits a stack of 3 chevrons (smallest on top, largest on bottom, gapped so
   they don't touch) that blink in sequence top-to-bottom like a turn-signal
   "blinker" — reinforcing the downward swipe direction on top of the shape
   alone. Sits above the result banner's position so the two never overlap
   once a spin result is shown.
   Text is sized to match the header's map-name scale and then 25% bigger on
   top of that (clamp bounds and vw factor are the header's map-badge values
   * 1.25). Uses --text-light (not --text-dim) plus a heavy dual drop-shadow
   — a dark contact shadow for contrast against light/busy photo
   backgrounds, and an accent-colored glow for contrast against dark
   backgrounds — so it reads clearly over every map's background art, not
   just the darker ones. filter:drop-shadow (not text-shadow) is used
   specifically because it also applies to the SVG chevrons, not just the
   text. */
.swipe-hint {
  position: absolute;
  left: 50%;
  /* Fixed px, not %, on purpose: a %-based offset compounds with its own
     height as viewport height grows, which silently ate into the wheel's
     vertical budget below (the wheel is centered in the FULL viewport
     height, not in the band between header and hint, so both reserved
     zones need to be a roughly fixed size, not scale with vh). */
  bottom: 100px;
  transform: translateX(-50%);
  z-index: 12;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  color: var(--text-light);
  font-size: clamp(25px, 6.25vw, 37.5px);
  font-weight: 900;
  letter-spacing: 2px;
  text-transform: uppercase;
  pointer-events: none;
  user-select: none;
  filter:
    drop-shadow(0 2px 4px rgba(0, 0, 0, 0.9))
    drop-shadow(0 0 12px color-mix(in srgb, var(--accent-color) 65%, transparent));
  animation: swipeHintPulse 1.8s ease-in-out infinite;
}

.chevron {
  display: block;
  opacity: 0.3;
  animation: chevronBlink 1.4s ease-in-out infinite;
}

.chevron-sm { width: 15px; height: 8px; }
.chevron-md { width: 21px; height: 11px; }
.chevron-lg { width: 27px; height: 14px; }

.chevron-md { animation-delay: 0.18s; }
.chevron-lg { animation-delay: 0.36s; }

@keyframes chevronBlink {
  0%, 55%, 100% { opacity: 0.25; }
  20% { opacity: 1; }
}

@keyframes swipeHintPulse {
  0%, 100% { opacity: 0.35; transform: translateX(-50%) scale(0.92); }
  50% { opacity: 1; transform: translateX(-50%) scale(1.05); }
}

/* ---------- Responsive ---------- */

@media (min-width: 720px) {
  .wheel-container {
    width: min(84vw, calc(100vh - 440px), calc(100vw - 60px), 1200px);
  }
  /* Desktop toggle kept at its original (pre-mobile-75%-shrink) size — the
     75% reduction below is mobile-only. */
  .category-toggle {
    margin-top: 14px;
    border: 5px solid var(--accent-color);
    border-radius: 26px;
  }
  .category-toggle-btn {
    font-size: 32px;
    padding: 32px 37px;
  }
  .category-toggle-btn + .category-toggle-btn {
    border-left: 2px solid color-mix(in srgb, var(--accent-color) 40%, transparent);
  }
}

@media (max-height: 560px) {
  #header {
    padding: 10px 16px 4px;
  }
  .map-badge {
    font-size: 22px;
  }
  .hint {
    display: none;
  }
  .category-toggle-btn {
    font-size: 13.5px;
    padding: 10.5px 13.5px;
  }
  .swipe-hint {
    font-size: 18px;
    bottom: 40px;
  }
  .chevron-sm { width: 11px; height: 6px; }
  .chevron-md { width: 15px; height: 8px; }
  .chevron-lg { width: 19px; height: 10px; }
  .wheel-container {
    width: min(97vw, calc(100vh - 230px), calc(100vw - 24px), 1200px);
  }
  .reveal-card {
    aspect-ratio: auto;
    height: 82vh;
    width: min(88vw, 340px);
  }
  .reveal-sub {
    margin-bottom: 24px;
  }
}
