/* Say It! — tiny word game. Side-view vertical climber, CSS-only. */

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

/* Locale-appropriate quotes for any element using open-quote/close-quote. */
:root            { quotes: "\201C" "\201D"; }          /* English "…" */
:root:lang(fr)   { quotes: "\00AB\00A0" "\00A0\00BB"; } /* French « … » */

html, body {
  height: 100%;
  height: 100dvh; /* tracks the dynamic viewport on mobile (address bar etc.) */
  width: 100%;
  margin: 0;
  overflow: hidden;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  color: #1f2937;
}

/* Desktop gets a dark letterbox around the portrait play area so the game
   reads as a phone-shaped window regardless of monitor size. On actual phones
   (viewport ≤ 620), min() collapses to 100vw and the bars disappear.

   Background echoes the in-game scene muted and darker: deep-sky navy at top
   fading into earth-brown at the bottom — "the wider world" framing the
   playfield. Simple enough to stay out of the way, but not a flat slab. */
body {
  background:
    linear-gradient(to bottom,
      #0c1b33 0%,
      #152338 45%,
      #2a1a0e 100%);
  display: flex;
  justify-content: center;
  align-items: stretch;
}

/* ---------- Game: portrait playfield ---------- */
.game {
  position: relative;
  width: min(100vw, 620px);
  height: 100vh;
  height: 100dvh; /* follow visible viewport so mobile browser chrome doesn't clip the bottom */
  overflow: hidden;
  /* Subtle shadow lifts the playfield out of the letterbox on desktop. */
  box-shadow: 0 0 40px rgba(0, 0, 0, 0.55);
}

/* ---------- HUD cluster (pause + altitude + score) ---------- */
/* position: fixed so the cluster anchors to the viewport — on desktop that
   parks it in the dark letterbox (outside the 620px playfield); on mobile
   the frame fills the viewport and it sits at the game's top-right. */
.hud-cluster {
  position: fixed;
  top: 20px;
  right: 20px;
  display: flex;
  align-items: center;
  gap: 12px;
  z-index: 15;
}

/* ---------- Pause button (rounded square, inside .hud-cluster) ---------- */
.pause-btn {
  width: 44px;
  height: 44px;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: rgba(42, 24, 16, 0.82);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 2px solid rgba(217, 119, 6, 0.6);
  border-radius: 14px;
  color: #fde68a;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.35);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease, background 0.15s;
}
.pause-btn.active {
  opacity: 1;
  pointer-events: auto;
}
.pause-btn:hover { background: rgba(42, 24, 16, 0.98); }

.score-badge {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 18px;
  background: rgba(42, 24, 16, 0.82);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 2px solid rgba(217, 119, 6, 0.6);
  border-radius: 14px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.35);
  color: #fde68a;
  font-weight: 700;
  font-size: 18px;
}
.score-icon { font-size: 18px; }

/* ---------- Altitude badge (flex sibling inside .hud-cluster) ---------- */
.altitude-badge {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 10px 16px;
  background: rgba(42, 24, 16, 0.82);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 2px solid rgba(217, 119, 6, 0.6);
  border-radius: 14px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.35);
  color: #fde68a;
  font-weight: 700;
  font-size: 16px;
  font-variant-numeric: tabular-nums;
  opacity: 0;
  transition: opacity 0.2s ease;
  pointer-events: none;
}
.altitude-badge.active { opacity: 1; }
.altitude-icon { font-size: 14px; opacity: 0.85; }
.altitude-unit { opacity: 0.7; font-size: 14px; }

/* Freeze the countdown ring CSS animation while paused. */
.game.paused .timer-fill { animation-play-state: paused; }

/* Pause overlay — dims the scene, shows an icon + label. Click to resume. */
.pause-overlay {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 19;  /* above HUD (15), below start/end overlays (20) */
  cursor: pointer;
}
.pause-overlay[hidden] { display: none; }
.pause-panel {
  text-align: center;
  color: #fde68a;
  user-select: none;
}
.pause-icon {
  font-size: 80px;
  line-height: 1;
  margin-bottom: 12px;
  filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.3));
}
.pause-label {
  font-size: 32px;
  font-weight: 800;
  letter-spacing: 2px;
  text-transform: uppercase;
  text-shadow: 0 2px 0 #7c2d12;
}
.pause-hint {
  font-size: 13px;
  opacity: 0.7;
  margin-top: 12px;
  letter-spacing: 0.5px;
}
/* ---------- Floating "+N" points indicator ---------- */
.points-float {
  position: absolute;
  transform: translate(-50%, -50%);
  font-weight: 800;
  pointer-events: none;
  z-index: 8;
  text-shadow: 0 3px 0 rgba(0, 0, 0, 0.45);
  animation: points-pop 1.2s cubic-bezier(0.2, 0.8, 0.3, 1) forwards;
  user-select: none;
}
.points-float.fast { color: #bbf7d0; font-size: 52px; }
.points-float.med  { color: #fde68a; font-size: 44px; }
.points-float.slow { color: #fecaca; font-size: 36px; }
@keyframes points-pop {
  0%   { transform: translate(-50%, -50%)  scale(0.5); opacity: 0; }
  20%  { transform: translate(-50%, -100%) scale(1.25); opacity: 1; }
  65%  { transform: translate(-50%, -150%) scale(1.1); opacity: 1; }
  100% { transform: translate(-50%, -220%) scale(0.9); opacity: 0; }
}

/* ---------- Menu (restart): quarter-circle anchored to top-left ---------- */
/* position: fixed — lives in the viewport's top-left corner so it sits in
   the letterbox on desktop while staying at the playfield corner on mobile. */
.menu-btn {
  position: fixed;
  top: 0;
  left: 0;
  width: 56px;
  height: 56px;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Box-center (28,28) sits near the arc because the visible pie skews toward
     the top-left corner. Shifting the flex-center inward with bottom+right
     padding puts the icon closer to the pie's optical center. */
  padding: 0 12px 12px 0;
  background: rgba(42, 24, 16, 0.88);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 2px solid rgba(217, 119, 6, 0.6);
  border-top: none;
  border-left: none;
  border-radius: 0 0 100% 0;
  color: #fde68a;
  font-size: 22px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  /* Clip the hit area to match the visible quarter-pie so clicks in the
     transparent corner don't register. */
  clip-path: circle(100% at 0 0);
  transition: background 0.15s;
  z-index: 16;
}
.menu-btn:hover {
  background: rgba(42, 24, 16, 0.98);
}
/* Rotate only the icon on hover — the quarter-pie stays anchored so its
   clip-path doesn't drift out from under the cursor. SVG has a precise
   center so rotation pivots in place (unlike text glyphs, which sit on the
   baseline and swing). */
.menu-icon {
  display: block;
  width: 16px;
  height: 16px;
  transition: transform 0.3s ease;
}
.menu-btn:hover .menu-icon,
.menu-btn:focus-visible .menu-icon {
  transform: rotate(-180deg);
}

/* Hover-revealed "Restart" label, sitting to the RIGHT of the quarter-pie.
   Also fixed so it tracks the menu-btn into the letterbox on desktop. */
.menu-label {
  position: fixed;
  top: 14px;
  left: 64px;
  padding: 6px 14px;
  background: rgba(42, 24, 16, 0.9);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 2px solid rgba(217, 119, 6, 0.6);
  border-radius: 999px;
  color: #fde68a;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.3px;
  white-space: nowrap;
  opacity: 0;
  transform: translateX(-8px);
  transition: opacity 0.2s ease, transform 0.2s ease;
  pointer-events: none;
  z-index: 18;
}
.menu-btn:hover ~ .menu-label,
.menu-btn:focus-visible ~ .menu-label {
  opacity: 1;
  transform: translateX(0);
}

/* ---------- Hint (top-center) — countdown → prompt → word reveal ---------- */
.hint {
  position: absolute;
  top: 20px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  padding: 14px 26px 14px 18px;
  background: rgba(42, 24, 16, 0.82);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 2px solid rgba(217, 119, 6, 0.6);
  border-radius: 14px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.35);
  pointer-events: none;
  z-index: 15;
  opacity: 0;
  transition: opacity 0.25s ease;
}
.hint.counting,
.hint.revealed { opacity: 1; }

/* Countdown ring — sits to the LEFT of the prompt, collapses on reveal */
.hint-timer {
  position: relative;
  width: 44px;
  height: 44px;
  flex: 0 0 auto;
  opacity: 0;
  max-width: 0;
  margin-right: 0;
  overflow: hidden;
  transition:
    opacity 0.2s ease,
    max-width 0.2s ease,
    margin-right 0.2s ease;
}
.hint.counting .hint-timer {
  opacity: 1;
  max-width: 44px;
  margin-right: 12px;
}
.timer-ring {
  display: block;
  width: 44px;
  height: 44px;
}
.timer-track {
  fill: none;
  stroke: rgba(255, 255, 255, 0.18);
  stroke-width: 2.5;
}
.timer-fill {
  fill: none;
  stroke: #fbbf24;
  stroke-width: 2.5;
  stroke-linecap: round;
  transform: rotate(-90deg);
  transform-origin: 22px 22px;
  /* circumference = 2·π·r where r=19 → ~119.38 */
  stroke-dasharray: 119.38;
  stroke-dashoffset: 0;
}
.hint.counting .timer-fill {
  animation: hint-countdown var(--reveal-duration, 3000ms) linear forwards;
}
@keyframes hint-countdown {
  to { stroke-dashoffset: 119.38; }
}
.timer-number {
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  transform: translateY(-50%);
  text-align: center;
  font-size: 18px;
  font-weight: 800;
  color: #fde68a;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.hint-content {
  text-align: center;
}

.hint-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 2px;
  color: #fbbf24;
  opacity: 0;
  max-height: 0;
  overflow: hidden;
  transition: opacity 0.25s ease, max-height 0.25s ease;
}
.hint.revealed .hint-label {
  opacity: 0.9;
  max-height: 20px;
  margin-bottom: 6px;
}

.hint-text {
  font-size: 20px;
  font-weight: 600;
  letter-spacing: 1px;
  color: #fde68a;
  text-shadow: 0 2px 0 #7c2d12;
  line-height: 1.2;
  transition: font-size 0.25s ease, letter-spacing 0.25s ease;
}
.hint.revealed .hint-text {
  font-size: 28px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 2px;
}
.hint.revealed .hint-text::before { content: open-quote; }
.hint.revealed .hint-text::after  { content: close-quote; }

/* ---------- Scene: side-view vertical climber ---------- */
.scene {
  position: absolute;
  inset: 0;
  overflow: hidden;
  /* Sky gradient: deeper blue high up fading to warm near the horizon.
     The warm band sits just above the ground strip so the horizon reads
     as sunset-lit. */
  background: linear-gradient(to bottom,
    #38bdf8 0%,
    #7dd3fc 45%,
    #bae6fd 75%,
    #fef3c7 100%);
}

/* Soft vignette at the edges */
.scene::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  box-shadow: inset 0 0 120px rgba(0, 0, 0, 0.18);
  z-index: 10;
}

/* Parallax cloud layer: sibling of .world, scrolled at a fraction of the
   camera speed. DOM order (before .world) keeps it behind platforms and the
   goat without needing an explicit z-index. */
.clouds {
  position: absolute;
  inset: 0;
  pointer-events: none;
  will-change: transform;
}
.cloud {
  position: absolute;
  line-height: 1;
  user-select: none;
  filter: blur(0.5px);
  transform: translateX(-50%);
  /* Horizontal drift. Each cloud gets a randomized --drift-duration and
     --drift-delay via inline styles from JS so the layer looks alive instead
     of metronomically synced. alternate = oscillate both directions. Using
     longhand animation properties because var() inside the `animation:`
     shorthand is parsed inconsistently across browsers. */
  animation-name: cloud-drift;
  animation-duration: var(--drift-duration, 24s);
  animation-delay: var(--drift-delay, 0s);
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
  animation-direction: alternate;
}
@keyframes cloud-drift {
  from { transform: translateX(calc(-50% - 55px)); }
  to   { transform: translateX(calc(-50% + 65px)); }
}

/* World: every gameplay element lives here. The camera is a CSS transform
   on this node — translateY(positive) pushes the world DOWN on screen,
   which visually is "we climbed higher." */
.world {
  position: absolute;
  inset: 0;
  will-change: transform;
}

/* Ground: the goat's starting surface. Grass cap on top, earth underneath.
   The top 56px (worldY 0 → 56) is grass; below that, the element extends
   ~400px down so it fills the viewport's bottom area with brown soil at
   game start. As the camera rises, the whole block scrolls off as one. */
.ground {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -400px;        /* extends into worldY = -400 */
  height: 456px;         /* top at worldY = 56 (goat's starting perch) */
  /* Grass in the top 56px, then the soil column underneath. Stops are
     pixel-absolute so the transition lines up precisely with the goat's
     perch. */
  background:
    linear-gradient(to bottom,
      #86efac   0px,
      #4ade80  30px,
      #166534  54px,     /* dark grass edge — just above the dirt boundary */
      #92400e  56px,     /* dirt starts here */
      #7c2d12 140px,     /* richer brown */
      #5a1e0b 260px,     /* deeper earth */
      #3f1608 456px);    /* near-black soil at the bottom */
  border-top: 4px solid #14532d;
  border-radius: 8px 8px 0 0;
  pointer-events: none;
  z-index: 1;  /* behind platforms and player */
}
/* Grass blades: restricted to the top 56px via background-size + no-repeat.
   Pseudo-element layered on top of the main dirt gradient so the blade
   pattern doesn't bleed into the soil. */
.ground::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 56px;
  background: repeating-linear-gradient(90deg,
    rgba(0, 0, 0, 0) 0 5px,
    rgba(22, 101, 52, 0.3) 5px 6px,
    rgba(0, 0, 0, 0) 6px 11px);
  pointer-events: none;
}

/* Platform: floating wooden shelf with a grass cap. `bottom` and `left`
   are set inline by JS per-platform; the rest is static. */
.platform {
  position: absolute;
  transform: translateX(-50%);
  width: 150px;
  height: 26px;
  background:
    linear-gradient(to bottom,
      #86efac 0% 8px,
      #4ade80 8px 14px,
      #92400e 14px 20px,
      #78350f 20px 100%);
  border-radius: 10px;
  box-shadow: 0 8px 12px rgba(0, 0, 0, 0.3);
  z-index: 3;
}
/* Edge-connected variants: platform sits flush against the left or right
   side of the playfield. Three-corner radius suggests it's jutting out
   from a wall rather than floating free. */
.platform.edge-left {
  left: 0;
  right: auto;
  transform: none;
  border-radius: 0 12px 12px 0;
}
.platform.edge-right {
  left: auto;
  right: 0;
  transform: none;
  border-radius: 12px 0 0 12px;
}

/* Emoji sits on the top edge of its platform */
.platform-emoji {
  position: absolute;
  left: 50%;
  bottom: 100%;
  transform: translate(-50%, 8px);
  font-size: 54px;
  filter: drop-shadow(0 4px 4px rgba(0, 0, 0, 0.3));
  user-select: none;
  pointer-events: none;
  line-height: 1;
}
.platform-emoji.eaten {
  animation: emoji-eaten 0.4s ease-out forwards;
}
@keyframes emoji-eaten {
  0%   { transform: translate(-50%, 8px)   scale(1);    opacity: 1; }
  45%  { transform: translate(-50%, -30px) scale(1.35); opacity: 1; }
  100% { transform: translate(-50%, -60px) scale(0);    opacity: 0; }
}

/* Reused by the "correct!" flash on a platform emoji (was .object.flash). */
.platform-emoji.flash {
  animation: emoji-pop 0.5s ease-out 2;
}
@keyframes emoji-pop {
  0%, 100% { transform: translate(-50%, 8px) scale(1); }
  50%      { transform: translate(-50%, 4px) scale(1.35); }
}

/* Player character. Lives inside .world so it scrolls with the camera.
   `bottom` and `left` are set inline by JS; transitions make the hop feel
   springy without real physics. */
.player {
  --size: 64px;
  position: absolute;
  font-size: var(--size);
  transform: translateX(-50%);
  filter: drop-shadow(0 5px 5px rgba(0, 0, 0, 0.45));
  user-select: none;
  line-height: 1;
  z-index: 5;
  /* Horizontal side-to-side travel still tweens via CSS; vertical motion is
     driven by a Web Animations API keyframe in jumpGoatTo so it can arc
     (briefly overshoot the destination before landing). */
  transition: left 280ms cubic-bezier(0.34, 1.45, 0.64, 1);
}
.player.falling {
  transition: bottom 500ms ease-in, transform 500ms ease-in;
  transform: translateX(-50%) rotate(30deg);
}

/* ---------- Feedback toast (only visible when correct/wrong) ---------- */
.feedback {
  position: absolute;
  bottom: 150px;
  left: 50%;
  transform: translateX(-50%);
  padding: 0;
  font-size: 15px;
  color: #fff;
  background: transparent;
  border-radius: 8px;
  text-align: center;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
  z-index: 15;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s;
}
.feedback.correct,
.feedback.wrong {
  padding: 6px 18px;
  opacity: 1;
}
.feedback.correct { color: #bbf7d0; background: rgba(22, 101, 52, 0.8); }
.feedback.wrong   { color: #fecaca; background: rgba(153, 27, 27, 0.8); }

/* ---------- Controls (floating bottom-center) ---------- */
/* Raised off the viewport edge so the "Listening…" label can sit UNDER the
   mic and the feedback toast can sit cleanly ABOVE it. */
.controls {
  position: absolute;
  bottom: 64px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 12px;
  z-index: 15;
}

/* Dev panel — hidden by default, appears next to the mic when toggled */
.dev-panel {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-radius: 14px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3);
}
.dev-panel[hidden] { display: none; }

.mic-btn {
  position: relative;
  width: 68px;
  height: 68px;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 2px solid #e5e7eb;
  border-radius: 50%;
  background: #f3f4f6;
  font-size: 36px;
  line-height: 1;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, transform 0.05s;
  overflow: visible;
}
.mic-btn .mic-emoji {
  display: block;
  transition: filter 0.15s, opacity 0.15s;
}
.mic-btn:hover:not(:disabled) { background: #fde68a; border-color: #d97706; }
.mic-btn:active:not(:disabled) { transform: scale(0.95); }
.mic-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.mic-btn.unsupported { display: none; }

/* LISTENING — green means "working", not the alarming red */
.mic-btn.listening {
  background: #dcfce7;
  border-color: #22c55e;
  animation: mic-pulse 1.1s ease-in-out infinite;
}
@keyframes mic-pulse {
  0%   { box-shadow: 0 0 0 0   rgba(34, 197, 94, 0.55); }
  70%  { box-shadow: 0 0 0 16px rgba(34, 197, 94, 0); }
  100% { box-shadow: 0 0 0 0   rgba(34, 197, 94, 0); }
}

/* MUTED — gray with a bold diagonal slash across the mic */
.mic-btn.muted {
  background: #e5e7eb;
  border-color: #9ca3af;
}
.mic-btn.muted .mic-emoji {
  filter: grayscale(1);
  opacity: 0.55;
}
.mic-btn.muted::before {
  content: "";
  position: absolute;
  top: 50%;
  /* Span the full button width so the slash, after 45° rotation, reaches
     edge-to-edge across the circle's diameter. */
  left: 0;
  right: 0;
  height: 4px;
  border-radius: 2px;
  background: #ef4444;
  transform: translateY(-50%) rotate(-45deg);
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.9);
}

/* Status label — floats UNDER the button so the feedback toast above stays
   readable when recognition reports what it heard. */
.mic-status {
  position: absolute;
  top: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.7);
  color: white;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.3px;
  white-space: nowrap;
  max-width: 280px;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease, background 0.15s ease;
}
.mic-btn.listening .mic-status {
  opacity: 1;
  background: #16a34a;
}
.mic-btn.muted .mic-status {
  opacity: 1;
  background: #4b5563;
}
.dev-panel input {
  width: 220px;
  padding: 10px 12px;
  border: 2px solid #e5e7eb;
  border-radius: 10px;
  font-size: 15px;
  outline: none;
  transition: border-color 0.15s, background 0.15s;
}
.dev-panel input:focus { border-color: #d97706; }
.dev-panel input.correct { border-color: #4ade80; background: #ecfdf5; }
.dev-panel input.wrong   { border-color: #f87171; background: #fef2f2; animation: shake 0.35s; }

@keyframes shake {
  0%, 100% { transform: translateX(0); }
  20%      { transform: translateX(-8px); }
  40%      { transform: translateX(8px); }
  60%      { transform: translateX(-5px); }
  80%      { transform: translateX(5px); }
}

.dev-panel button {
  padding: 12px 22px;
  border: none;
  border-radius: 10px;
  background: #d97706;
  color: white;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.5px;
  cursor: pointer;
  transition: background 0.15s, transform 0.05s;
}
.dev-panel button:hover:not(:disabled) { background: #b45309; }
.dev-panel button:active:not(:disabled) { transform: translateY(1px); }
.dev-panel button:disabled { opacity: 0.4; cursor: not-allowed; }

/* ---------- Overlays (start / end) ---------- */
.overlay {
  position: absolute;
  inset: 0;
  background: rgba(15, 23, 42, 0.6);
  backdrop-filter: blur(3px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 20;
}
.overlay.hidden { display: none; }

.panel {
  /* Warm off-white — game-y, not clinical */
  background: #fffbeb;
  padding: 36px 28px 28px;
  border-radius: 22px;
  text-align: center;
  /* Scope to the playfield width on desktop (400px frame) while leaving a
     small gutter so the panel doesn't kiss the edges. */
  width: min(560px, calc(100% - 24px));
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.4);
}
.panel h1 {
  font-size: 32px;
  margin-bottom: 10px;
  color: #1f2937;
  line-height: 1.2;
  letter-spacing: -0.3px;
}

/* End screen title has more swagger — bigger, bolder, with a playful
   text-shadow to suggest the bold-stroke feel of arcade game-over screens. */
#end-overlay .panel h1 {
  font-size: 40px;
  font-weight: 900;
  letter-spacing: -0.5px;
  color: #92400e;
  text-shadow: 0 3px 0 #fcd34d;
  margin-bottom: 6px;
}
.panel .tag {
  color: #6b7280;
  margin-bottom: 40px;
  font-size: 19px;
  line-height: 1.5;
}

/* Mascot — goat peeking above the headline */
.panel-mascot {
  font-size: 72px;
  line-height: 1;
  margin-top: -20px;
  margin-bottom: 10px;
  filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.15));
}

/* Block label — tiny uppercase heading shared by each section */
.panel .block-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 1.6px;
  color: #9ca3af;
  margin-bottom: 12px;
  font-weight: 700;
}

.panel .mic-note {
  font-size: 12px;
  color: #92400e;
  background: #fef3c7;
  padding: 8px 12px;
  border-radius: 8px;
  margin-bottom: 20px;
}
/* Hide the mic-note when it carries no message (supported browsers) */
.panel .mic-note:empty { display: none; }

/* Language choice block — margin matches the play block's internal rhythm */
.lang-choice {
  margin-bottom: 40px;
}
/* End-screen footer variant: de-emphasized, tighter, smaller flag pills.
   Sits under the Play Again hero so it doesn't compete with the main CTA. */
.lang-choice.lang-footer {
  margin-top: 24px;
  margin-bottom: 0;
}
.lang-choice.lang-footer .block-label {
  font-size: 10px;
  margin-bottom: 8px;
  opacity: 0.7;
}
.lang-choice.lang-footer .lang-btn {
  padding: 5px 12px;
  font-size: 12px;
}

/* Language picker — visible, clickable flag pills
   (.panel prefix needed so these rules beat .panel button specificity) */
.lang-picker {
  display: flex;
  justify-content: center;
  gap: 12px;
  flex-wrap: wrap;
}
.panel .lang-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  border: 2px solid #e5e7eb;
  border-radius: 999px;
  background: white;
  color: #374151;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.5px;
  cursor: pointer;
  transition: color 0.15s, background 0.15s, border-color 0.15s, transform 0.05s;
}
.panel .lang-btn:hover {
  background: #fffbeb;
  border-color: #fcd34d;
  color: #374151;
}
.panel .lang-btn:active { transform: scale(0.97); }
.panel .lang-btn.active {
  /* Softer selected state so the flag buttons don't fight the primary CTA. */
  background: #fef3c7;
  border-color: #fbbf24;
  color: #78350f;
}
.panel .big-score {
  font-size: 56px;
  font-weight: 800;
  color: #d97706;
  line-height: 1.1;
  margin: 4px 0 20px;
}

/* End-screen: three-column stats. Each stat in an outlined card (warm amber
   border, transparent background) so it reads as a "stat" not a button. */
.stats-row {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 10px;
  margin: 4px 0 32px;
  text-align: center;
}
.stat {
  border: 1.5px solid rgba(217, 119, 6, 0.35);
  border-radius: 12px;
  padding: 14px 8px 12px;
  background: transparent;
}
.stat-label {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 1.4px;
  color: #a16207;
  font-weight: 700;
  margin-bottom: 6px;
}
.stat-value {
  font-size: 26px;
  font-weight: 800;
  color: #78350f;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.stat-unit {
  font-size: 14px;
  font-weight: 600;
  opacity: 0.55;
  margin-left: 1px;
}

/* High score under the current score, Flappy-Bird style. */
.best-score {
  font-size: 13px;
  color: #92400e;
  opacity: 0.7;
  margin: -24px 0 32px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.best-score[hidden] { display: none; }
.best-score-label {
  text-transform: uppercase;
  letter-spacing: 1.2px;
  font-weight: 700;
  margin-right: 6px;
}
.best-score.new-best {
  opacity: 1;
  color: #d97706;
  font-weight: 700;
  animation: best-pulse 1.4s ease-in-out infinite;
}
@keyframes best-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.06); }
}
.panel button {
  padding: 22px 52px;
  font-size: 24px;
  font-weight: 700;
  background: #d97706;
  color: white;
  border: none;
  border-radius: 12px;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, transform 0.05s;
}
.panel button:active { transform: scale(0.98); }
.panel button:hover { background: #b45309; }

/* Hero Play Again — big green pill, the unmistakable primary action. Sits
   below the share row so the eye terminates on "play again" after naturally
   scanning score → stats → share → replay. */
.panel .replay-hero {
  display: block;
  width: 100%;
  margin-top: 18px;
  padding: 20px 28px;
  font-size: 22px;
  font-weight: 800;
  letter-spacing: 0.3px;
  color: #064e3b;
  background: #4ade80;
  border: none;
  border-radius: 14px;
  box-shadow: 0 4px 0 #16a34a;
  cursor: pointer;
  transition: transform 0.05s, background 0.15s, box-shadow 0.1s;
}
.panel .replay-hero:hover   { background: #86efac; }
.panel .replay-hero:active  { transform: translateY(2px); box-shadow: 0 2px 0 #16a34a; }

/* Mode switch — text link under the green button. Stays unobtrusive but
   discoverable so "Play again" doesn't feel like a forced mode choice. */
.panel .mode-switch-link {
  display: block;
  margin: 12px auto 0;
  padding: 4px 12px;
  background: transparent;
  color: #6b7280;
  border: none;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  text-decoration: underline;
  text-decoration-color: #9ca3af;
  text-underline-offset: 3px;
  transition: color 0.15s, text-decoration-color 0.15s;
}
.panel .mode-switch-link:hover {
  color: #d97706;
  text-decoration-color: #d97706;
}

/* End-screen share row — big pill buttons so the share action reads as a
   real CTA, not an afterthought. Two equal-weight buttons; X gets the brand
   dark fill, Copy link is a strong outline. */
.share-row {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin-top: 20px;
}
.panel .share-btn {
  flex: 1;
  min-width: 0;
  padding: 14px 18px;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.3px;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s, transform 0.05s;
}
.panel .share-btn:active { transform: scale(0.97); }
.panel .share-btn.share-x {
  background: #0f172a;
  color: #fff;
  border: 2px solid #0f172a;
}
.panel .share-btn.share-x:hover {
  background: #1e293b;
  border-color: #1e293b;
}
.panel .share-btn.share-copy {
  background: #fff;
  color: #1f2937;
  border: 2px solid #1f2937;
}
.panel .share-btn.share-copy:hover {
  background: #f3f4f6;
  color: #0f172a;
  border-color: #0f172a;
}
.panel .share-btn.copied {
  background: #dcfce7 !important;
  color: #166534 !important;
  border-color: #16a34a !important;
}

/* Stack the two start buttons; promote the primary, de-emphasize the secondary */
.start-buttons {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}
.panel button.secondary {
  background: transparent;
  color: #6b7280;
  padding: 6px 14px;
  font-size: 13px;
  font-weight: 500;
  /* Permanent underline so it reads as a clickable link on touch devices too. */
  text-decoration: underline;
  text-decoration-color: #9ca3af;
  text-underline-offset: 3px;
}
.panel button.secondary:hover {
  background: transparent;
  color: #d97706;
  text-decoration-color: #d97706;
}

/* Type mode — hide the voice UI so keyboard users aren't confused */
.game.mode-type .mic-btn { display: none; }

/* ---------- Author signature (bottom-right) ---------- */
/* Fixed so it lives in the desktop letterbox; sits above gameplay on mobile.
   Subtle glass chip with a hover amber accent on the handle. */
.signature {
  position: fixed;
  bottom: 0;
  right: 0;
  padding: 6px 14px;
  font-size: 13px;
  line-height: 1.2;
  color: #d4d4d8;
  background: rgba(255, 255, 255, 0.05);
  border-top: 1px solid rgba(255, 255, 255, 0.10);
  border-left: 1px solid rgba(255, 255, 255, 0.10);
  border-top-left-radius: 12px;
  text-decoration: none;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  transition: background 0.2s ease, backdrop-filter 0.2s ease;
  /* Above the start/end overlay (z-index 20) so the link stays clickable on the end screen. */
  z-index: 30;
}
.signature:hover {
  background: rgba(255, 255, 255, 0.15);
  backdrop-filter: blur(24px);
  -webkit-backdrop-filter: blur(24px);
}
.signature span { color: inherit; transition: color 0.2s ease; }
.signature:hover span { color: #fbbf24; }

/* ---------- Small screens ---------- */
@media (max-width: 500px) {
  .player         { --size: 48px; }
  .platform       { width: 118px; height: 22px; }
  .platform-emoji { font-size: 42px; }
  /* Move altitude + score to the bottom corners (altitude left, score right)
     so the top-right is free for the pause button alone. Prevents the
     three-pill cluster from getting clipped on narrow phones. */
  .hud-cluster {
    top: auto;
    bottom: 20px;
    left: 20px;
    right: 20px;
    justify-content: space-between;
  }
  .pause-btn {
    position: fixed;
    top: 20px;
    right: 20px;
    z-index: 16;
  }
  /* Lift the mic / typing input above the bottom HUD badges (altitude + score
     sit at bottom:20). Default bottom:64 leaves almost no gap and the typing
     input visually overlaps the badges. */
  .controls {
    bottom: 80px;
  }
  /* Hide the signature during active gameplay on mobile. Its bottom-right
     corner overlaps the centered mic / typing input and the score badge.
     It re-appears whenever a start/end overlay is up, which is where the
     credit actually matters. */
  .signature { display: none; }
  body:has(.overlay:not(.hidden)) .signature { display: block; }
}
