:root {
  --bg1: #2d1b4e;
  --bg2: #1b3a5e;
  --card: #ffffff;
  --ink: #241a38;
  --accent: #ff7a59;
  --accent2: #24c6a0;
  --gold: #ffc93c;
  --radius: 20px;
}
* { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }
[hidden] { display: none !important; }
html, body { height: 100%; }
body {
  font-family: "Nunito", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  color: var(--ink);
  background: radial-gradient(1000px 700px at 20% -10%, #4a2d7a 0%, transparent 55%),
              radial-gradient(900px 700px at 110% 20%, #14577e 0%, transparent 50%),
              linear-gradient(160deg, var(--bg1), var(--bg2));
  background-attachment: fixed;
  min-height: 100vh;
  display: flex; flex-direction: column; align-items: center;
  padding: 20px 14px;
  user-select: none;
}

/* ---------- menu ---------- */
#menu { width: 100%; max-width: 1020px; display: flex; flex-direction: column; align-items: center; gap: 20px; }
.menu-head { text-align: center; color: #fff; margin-top: 8px; }
.menu-head h1 { font-weight: 1000; font-size: clamp(2.2rem, 6vw, 3.4rem); letter-spacing: -0.02em; text-shadow: 0 4px 0 rgba(0,0,0,0.25); }
.tagline { color: #e8def5; font-weight: 600; font-size: 1.05rem; margin-top: 4px; }
.level-grid { width: 100%; display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 16px; }
.level-card {
  display: flex; flex-direction: column; gap: 10px; align-items: stretch; text-align: left;
  background: var(--card); border: none; border-radius: var(--radius); padding: 12px 12px 14px;
  cursor: pointer; box-shadow: 0 12px 30px -12px rgba(0,0,0,0.5);
  transition: transform 0.12s ease, box-shadow 0.12s ease;
  font-family: inherit;
}
.level-card:hover { transform: translateY(-3px) scale(1.01); box-shadow: 0 18px 36px -12px rgba(0,0,0,0.55); }
.level-thumb { display: block; border-radius: 12px; overflow: hidden; aspect-ratio: 4 / 3; background: #eee; }
.level-thumb svg { width: 100%; height: 100%; display: block; }
.level-name { font-weight: 800; font-size: 1.12rem; color: var(--ink); }
.badge { align-self: flex-start; font-size: 0.72rem; font-weight: 800; letter-spacing: 0.06em; padding: 4px 10px; border-radius: 999px; color: #fff; }
.badge--easy { background: var(--accent2); }
.badge--medium { background: #f5a623; }
.badge--hard { background: #e0475b; }
.badge--very-hard { background: #6b2d8e; }
.menu-foot { color: #cabfe0; font-weight: 600; font-size: 0.9rem; text-align: center; }

/* ---------- game ---------- */
#game { width: 100%; max-width: none; display: flex; flex-direction: column; gap: 14px; flex: 1; min-height: 0; }
.hud {
  /* One place to scale the bar. The vars are scoped to .hud on purpose: the
     menu's #muteBtn also uses .hud-btn but sits outside, so it keeps 44px and
     never moves. Each clamp prefers min(vw, vh) so the bar only grows when the
     viewport is wide AND tall; short landscape windows, where the pictures are
     height-limited, keep their chrome small. Vertical padding and the column
     gap stay fixed: pure height, no legibility payoff. */
  --hud-btn: clamp(44px, min(2.1vw, 4.2vh), 52px);
  --hud-btn-fs: clamp(1.3rem, min(1vw, 2vh), 1.55rem);
  --hud-gap: clamp(10px, 0.7vw, 20px);
  display: flex; flex-direction: column; gap: 9px;
  background: rgba(255,255,255,0.1); border: 1px solid rgba(255,255,255,0.18);
  border-radius: clamp(16px, 0.9vw, 22px); padding: 10px clamp(14px, 1vw, 26px); color: #fff;
}
/* three zones: back + title | found dots | score, hint, zoom, mute, timer.
   minmax(0,1fr) auto 1fr keeps the dots dead-centre while there is slack; when
   there is not, the title ellipsis gives ground first and the right-hand
   controls are never allowed to squeeze. */
.hud-row { display: grid; grid-template-columns: minmax(0, 1fr) auto 1fr; align-items: center; gap: var(--hud-gap); }
.hud-zone { display: flex; align-items: center; gap: var(--hud-gap); min-width: 0; }
.hud-zone > * { flex: 0 0 auto; } /* keeps buttons from shrinking under 44px */
.hud-zone--left { justify-content: flex-start; }
.hud-zone--right { justify-content: flex-end; }

/* Classic Photo Hunt segmented timer bar */
.timerbar {
  display: flex; gap: clamp(3px, 0.18vw, 6px); height: clamp(14px, min(0.85vw, 1.7vh), 22px);
  align-items: stretch; background: rgba(0,0,0,0.35); border-radius: 999px;
  padding: clamp(3px, 0.16vw, 5px);
}
.tick { flex: 1; border-radius: clamp(2px, 0.12vw, 4px); background: rgba(255,255,255,0.10); transition: background 0.2s ease; }
.tick--green { background: #35d07f; box-shadow: 0 0 6px rgba(53,208,127,0.5); }
.tick--yellow { background: #ffd23c; box-shadow: 0 0 6px rgba(255,210,60,0.5); }
.tick--orange { background: #ff9838; box-shadow: 0 0 6px rgba(255,152,56,0.5); }
.tick--red { background: #ff4d5e; box-shadow: 0 0 7px rgba(255,77,94,0.7); animation: tickpulse 0.7s infinite; }
.tick--lost { background: #ff4d5e; animation: tickfade 0.5s forwards; }

/* marathon fine bar: ~200 vertical lines in a red-to-green positional
   gradient (inline hsl per line); the run burns green, yellow, orange, red */
/* the gap grows with the bar so 200 lines keep reading as LINES on a wide
   screen instead of squat blobs (11.6x8 with a 1px gap becomes 9.4x13.6) */
.timerbar--fine { gap: clamp(1px, 0.14vw, 3px); padding: clamp(3px, 0.16vw, 5px) clamp(4px, 0.2vw, 6px); }
.timerbar--fine .fline { flex: 1; min-width: 1px; border-radius: 1px; transition: opacity 0.2s ease; }
.fline--off { opacity: 0.09; }
.fline--lost { animation: tickpulse 0.25s 2; }
.timerbar--danger .fline:not(.fline--off) { animation: tickpulse 0.7s infinite; }
@keyframes tickpulse { 0%,100% { opacity: 1; } 50% { opacity: 0.45; } }
@keyframes tickfade { 0% { opacity: 1; } 100% { opacity: 0.08; background: rgba(255,255,255,0.10); } }
.hud-btn {
  background: rgba(255,255,255,0.16); color: #fff; border: none; border-radius: 12px;
  font-size: var(--hud-btn-fs, 1.3rem); font-weight: 800;
  width: var(--hud-btn, 44px); height: var(--hud-btn, 44px); cursor: pointer; font-family: inherit;
}
/* Hover only where hovering is real, so a tapped button on a tablet does not
   stay lit. Two guards matter: an exhausted hint must not light up, and an
   active zoom must stay gold (plain .hud-btn:hover outranks .hud-btn--active). */
@media (hover: hover) {
  .hud-btn:hover:not(:disabled):not(.hud-btn--active) { background: rgba(255,255,255,0.28); }
  .hud-btn--active:hover { background: #ffd968; }
}
.hud-btn:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.hud-title { font-weight: 800; font-size: clamp(1.05rem, min(0.72vw, 1.5vh), 1.4rem); color: #f0e9ff;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hud-zone .hud-title { flex: 1 1 auto; min-width: 0; } /* two-class: order-independent */
/* centre zone: the primary progress cue. Pinned to button height so it aligns
   optically with the controls and costs zero extra HUD height. */
.dots {
  display: flex; align-items: center; justify-content: center; gap: clamp(7px, 0.45vw, 12px);
  height: var(--hud-btn, 44px); padding: 0 clamp(12px, 0.7vw, 20px);
  background: rgba(0,0,0,0.18); border: 1px solid rgba(255,255,255,0.1); border-radius: 999px;
}
.dot { flex: 0 0 auto;
  width: clamp(16px, min(0.86vw, 1.75vh), 24px); height: clamp(16px, min(0.86vw, 1.75vh), 24px);
  border-radius: 50%; background: rgba(255,255,255,0.22);
  border: clamp(2px, 0.11vw, 3px) solid rgba(255,255,255,0.4); }
.dot--found { background: var(--gold); border-color: var(--gold); box-shadow: 0 0 12px rgba(255,201,60,0.75); }
.dot--hint { background: transparent; border: clamp(2px, 0.11vw, 3px) dashed var(--gold); box-shadow: 0 0 10px rgba(255,201,60,0.4); }
.timer { font-weight: 1000; font-size: clamp(1.5rem, min(1.15vw, 2.3vh), 2rem); font-variant-numeric: tabular-nums;
  min-width: clamp(74px, 4vw, 104px); text-align: right; }
/* two-class so it wins on specificity, not source order: this rule sat above
   .timer and silently lost its size and width for the whole of Marathon. */
.timer.timer--speed { color: #7be0b8; font-size: clamp(1.05rem, min(0.8vw, 1.6vh), 1.35rem);
  min-width: clamp(50px, 2.7vw, 72px); }
.timer--low { color: #ff8896; animation: pulse 1s infinite; }
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.5; } }

/* fill the available viewport: images grow to the largest 4:3 that fits both
   half-width and the leftover height, so they use the whole screen, not a cap */
.playfield { display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr; gap: 14px; flex: 1; min-height: 0; align-content: stretch; }
.img-frame {
  min-width: 0; min-height: 0; display: flex; align-items: center; justify-content: center;
  background: #fff; border-radius: var(--radius); padding: 8px;
  cursor: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="34" height="34" viewBox="0 0 34 34"><circle cx="13" cy="13" r="9" fill="rgba(255,255,255,0.25)" stroke="%23241a38" stroke-width="3"/><line x1="20" y1="20" x2="30" y2="30" stroke="%23241a38" stroke-width="5" stroke-linecap="round"/><line x1="13" y1="9" x2="13" y2="17" stroke="%23ff7a59" stroke-width="2.5" stroke-linecap="round"/><line x1="9" y1="13" x2="17" y2="13" stroke="%23ff7a59" stroke-width="2.5" stroke-linecap="round"/></svg>') 13 13, crosshair;
  box-shadow: 0 12px 30px -12px rgba(0,0,0,0.5);
}
.img-frame svg { width: auto; height: auto; max-width: 100%; max-height: 100%; aspect-ratio: 4 / 3; display: block; border-radius: 12px; }
.shake { animation: shake 0.3s; }
@keyframes shake { 0%,100% { transform: translateX(0); } 25% { transform: translateX(-6px); } 75% { transform: translateX(6px); } }

/* Colorblind-safe by shape: found = solid ring + check, hint = dashed,
   missed = dotted. Colors differ too but are never the only cue. */
.mark { fill: none; stroke-width: 6; animation: pop 0.35s ease-out; transform-box: fill-box; transform-origin: center; }
.mark--found { stroke: #17b890; }
.mark--hint { stroke: #ffb703; stroke-dasharray: 12 8; }
.mark--missed { stroke: #8a93a6; stroke-dasharray: 2 8; stroke-linecap: round; }
.mark-check {
  fill: #17b890; font-size: 34px; font-weight: 800; font-family: "Nunito", sans-serif;
  paint-order: stroke; stroke: #ffffff; stroke-width: 5; text-anchor: middle;
}
@keyframes pop { 0% { transform: scale(1.6); opacity: 0; } 100% { transform: scale(1); opacity: 1; } }
.penalty-float {
  fill: #e0475b; font-size: 40px; font-weight: 800; font-family: "Nunito", sans-serif;
  paint-order: stroke; stroke: #fff; stroke-width: 6; text-anchor: middle;
  animation: rise 0.9s ease-out forwards;
}
@keyframes rise { 0% { opacity: 1; } 100% { opacity: 0; transform: translateY(-40px); } }

/* menu groups, stars, thumbnails */
.group-head {
  grid-column: 1 / -1; display: flex; align-items: baseline; justify-content: space-between;
  color: #fff; padding: 10px 6px 0;
}
.group-name { font-weight: 900; font-size: 1.15rem; letter-spacing: 0.01em; }
.group-stars { color: var(--gold); font-weight: 800; font-size: 0.95rem; }
.level-stars { display: block; font-size: 0.85rem; line-height: 1.2; }
.star { color: #cfc9dd; }
.star--on { color: #f5a623; text-shadow: 0 0 6px rgba(245,166,35,0.5); }
.thumb-ph { display: block; width: 100%; height: 100%; }
.thumb-ph--easy { background: linear-gradient(135deg, #7be0b8, #35b98c); }
.thumb-ph--medium { background: linear-gradient(135deg, #ffd98a, #f5a623); }
.thumb-ph--hard { background: linear-gradient(135deg, #ff9aa8, #e0475b); }
.thumb-ph--very-hard { background: linear-gradient(135deg, #c39ae8, #6b2d8e); }
.menu-head { position: relative; width: 100%; }
.menu-mute { position: absolute; right: 0; top: 6px; }
.mode-row { display: flex; gap: 12px; justify-content: center; margin-top: 16px; }
.mode-row .marathon-btn { font-size: 1.1rem; background: linear-gradient(135deg, #ff7a59, #e0475b); }
.mode-row .daily-btn { font-size: 1.1rem; background: linear-gradient(135deg, #24c6a0, #14808a); }
.btn:disabled { opacity: 0.55; cursor: default; transform: none; box-shadow: 0 6px 0 rgba(0,0,0,0.15); }
.marathon-best { color: var(--gold); font-weight: 800; font-size: 0.95rem; margin-top: 8px; }
.relax-toggle {
  margin-top: 10px; font-family: inherit; font-weight: 800; font-size: 0.9rem;
  color: #cdeee4; background: rgba(255,255,255,0.1); border: 1px solid rgba(255,255,255,0.25);
  border-radius: 999px; padding: 7px 16px; cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.relax-toggle:hover { background: rgba(255,255,255,0.18); }
.relax-toggle--on { background: var(--accent2); color: #fff; border-color: var(--accent2); }
.toast {
  position: fixed; inset: 0; z-index: 9; display: grid; place-items: center;
  background: rgba(20, 12, 40, 0.45); pointer-events: none;
  font-size: clamp(1.6rem, 4vw, 2.6rem); font-weight: 1000; color: #fff;
  text-shadow: 0 4px 0 rgba(0,0,0,0.35);
  animation: pop 0.3s ease-out;
}

/* hud extras */
.hud-btn--wide { width: auto; padding: 0 clamp(12px, 0.7vw, 20px); font-size: clamp(0.95rem, min(0.6vw, 1.2vh), 1.15rem); }
.hud-btn--active { background: var(--gold); color: #241a38; }
.hud-btn:disabled { opacity: 0.4; cursor: default; }
.scorebox { font-weight: 900; font-size: clamp(1.05rem, min(0.78vw, 1.6vh), 1.35rem); color: var(--gold);
  min-width: clamp(44px, 2.4vw, 64px); text-align: right; font-variant-numeric: tabular-nums; }
.streakbox {
  background: var(--accent2); color: #fff; font-weight: 900;
  font-size: clamp(0.8rem, min(0.55vw, 1.15vh), 1rem);
  border-radius: 999px; padding: clamp(3px, 0.2vw, 5px) clamp(9px, 0.55vw, 14px);
  animation: pop 0.25s ease-out;
}
.paused-note { text-align: center; color: #ffd98a; font-weight: 800; }
.img-frame { overflow: hidden; }
.img-frame svg { transition: transform 0.25s ease; }
/* stars are the hero of a win: big, and they land one at a time so three
   stars feel earned rather than simply displayed */
.result-stars { font-size: clamp(2.2rem, min(2.9vw, 5.8vh), 3.6rem); letter-spacing: clamp(6px, 0.5vw, 12px); margin: 6px 0 2px; }
.result-stars .star { display: inline-block; }
.result-stars .star--on { animation: starpop 0.5s ease-out both; }
.result-stars .star--on:nth-child(1) { animation-delay: 0.10s; }
.result-stars .star--on:nth-child(2) { animation-delay: 0.28s; }
.result-stars .star--on:nth-child(3) { animation-delay: 0.46s; }
@keyframes starpop {
  0% { transform: scale(0.2) rotate(-25deg); opacity: 0; }
  65% { transform: scale(1.25) rotate(6deg); opacity: 1; }
  100% { transform: scale(1) rotate(0deg); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .result-stars .star--on, .result-badge, .overlay, .overlay-card { animation: none; }
}

/* portrait: stack the two images, each full-width and width-driven; let the
   page scroll if the pair is taller than the viewport */
@media (max-aspect-ratio: 1/1), (max-width: 700px) {
  #game { min-height: auto; }
  .playfield { grid-template-columns: 1fr; grid-template-rows: auto auto; min-height: 0; }
  .img-frame svg { width: 100%; height: auto; max-width: 100%; max-height: none; aspect-ratio: auto; }
  body { padding: 12px 10px; }
}

/* narrow: the three zones fold into two rows - back plus controls on top, the
   found dots on their own centred row so the progress cue stays large. Portrait
   is a scrolling layout (images are width-driven here), so the extra row costs
   scroll, never picture. Width-based, not aspect-based, so a narrow desktop
   window is caught too and 768px tablets are deliberately spared. */
@media (max-width: 700px) {
  .hud { --hud-gap: 8px; padding: 8px 10px; border-radius: 14px; }
  .hud-row { grid-template-columns: auto minmax(0, 1fr); grid-template-rows: auto auto; row-gap: 8px; }
  .hud-zone--left { grid-column: 1; grid-row: 1; }
  .hud-zone--right { grid-column: 2; grid-row: 1; flex-wrap: wrap; row-gap: 6px; }
  .dots { grid-column: 1 / -1; grid-row: 2; height: 34px; padding: 0 14px; gap: 10px; }
  .dot { width: 18px; height: 18px; }
  .hud-title { display: none; }
  .scorebox { min-width: 0; }
  .timer { font-size: 1.35rem; min-width: 58px; }
  .timer.timer--speed { font-size: 1.05rem; min-width: 0; }
  .streakbox { font-size: 0.75rem; padding: 2px 7px; }
  .hud-btn--wide { padding: 0 9px; font-size: 0.92rem; }
}

/* short and wide (phone landscape, squat windows): the one case where the
   pictures really are height-limited, so give the bar's padding back to them. */
@media (max-height: 520px) and (min-width: 701px) {
  #game { gap: 10px; }
  .hud { padding: 6px clamp(10px, 1vw, 26px); gap: 6px; }
  .timerbar { height: 10px; padding: 2px; }
  .timerbar--fine { padding: 2px 3px; }
}

/* ---------- overlay ---------- */
.overlay {
  position: fixed; inset: 0; display: grid; place-items: center;
  background: rgba(20, 12, 40, 0.72); z-index: 10; padding: 20px;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  animation: fadein 0.2s ease-out;
}
@keyframes fadein { from { opacity: 0; } to { opacity: 1; } }
.overlay-card {
  position: relative; overflow: hidden;
  background: var(--card); border-radius: clamp(24px, 1.6vw, 34px);
  padding: clamp(30px, 2.4vw, 46px) clamp(28px, 2.2vw, 44px); text-align: center;
  max-width: clamp(420px, 30vw, 600px); width: 100%;
  /* on a short screen the action buttons wrap and the card grows; never let it
     run off the top and bottom, scroll the card itself instead */
  max-height: calc(100vh - 40px); max-height: calc(100dvh - 40px); overflow: hidden auto;
  box-shadow: 0 24px 60px -12px rgba(0,0,0,0.6);
  animation: pop 0.3s ease-out;
}
/* a win is the reward beat: warm wash, gold rim and a glow behind the stars.
   A finished-but-not-won card stays calm and cool, never a scolding red. */
/* the warm wash is a background gradient, not a pseudo-element: a positioned
   glow would spill past the card and turn overflow-y into a stray scrollbar */
.overlay-card--win {
  background: radial-gradient(125% 85% at 50% -12%, rgba(255,201,60,0.34) 0%, rgba(255,201,60,0.12) 40%, rgba(255,255,255,0) 72%), var(--card);
  box-shadow: 0 24px 60px -12px rgba(0,0,0,0.6), 0 0 0 3px rgba(255,201,60,0.75);
}
.overlay-card--done { box-shadow: 0 24px 60px -12px rgba(0,0,0,0.6), 0 0 0 3px rgba(124,110,160,0.5); }
.overlay-card h2 { font-weight: 1000; font-size: clamp(1.7rem, min(1.9vw, 3.8vh), 2.5rem); letter-spacing: -0.01em; }
.overlay-card p { color: #5d5575; font-weight: 700; margin: 8px 0 20px;
  font-size: clamp(1rem, min(0.85vw, 1.7vh), 1.25rem); }
.result-badge {
  display: inline-block; margin-bottom: 10px;
  background: linear-gradient(135deg, #ff7a59, #e0475b); color: #fff;
  font-weight: 900; font-size: clamp(0.78rem, min(0.6vw, 1.2vh), 0.95rem);
  letter-spacing: 0.06em; text-transform: uppercase;
  border-radius: 999px; padding: 5px 14px;
  box-shadow: 0 6px 16px -6px rgba(224,71,91,0.9);
  animation: pop 0.45s 0.25s ease-out both;
}
.overlay-actions { display: flex; gap: clamp(10px, 0.6vw, 14px); justify-content: center; flex-wrap: wrap; }
.btn {
  background: var(--accent); color: #fff; border: none; border-radius: 14px;
  font-family: inherit; font-weight: 800; font-size: 1rem; padding: 12px 22px; cursor: pointer;
  box-shadow: 0 6px 0 rgba(0,0,0,0.15);
  transition: transform 0.1s ease;
}
/* the one accent button in a result card leads the eye */
.overlay-actions .btn { font-size: clamp(1rem, min(0.8vw, 1.6vh), 1.15rem); padding: clamp(12px, 0.8vw, 16px) clamp(22px, 1.4vw, 30px); }
.overlay-actions .btn:not(.btn--ghost) { box-shadow: 0 6px 0 rgba(0,0,0,0.15), 0 10px 26px -8px rgba(255,122,89,0.85); }
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(1px); box-shadow: 0 3px 0 rgba(0,0,0,0.15); }
.btn--ghost { background: #ece8f4; color: var(--ink); }

/* short screens (phone landscape): tighten the result card so it fits outright
   instead of merely being scrollable. Must stay last in the file: the overlay
   rules above are single-class too, so source order is what decides. */
@media (max-height: 560px) {
  .overlay { padding: 10px; }
  .overlay-card { padding: 18px 22px; border-radius: 20px; }
  .overlay-card h2 { font-size: 1.5rem; }
  .overlay-card p { margin: 6px 0 12px; font-size: 0.95rem; }
  .result-stars { font-size: 2rem; margin: 2px 0 0; }
  .result-badge { margin-bottom: 6px; }
  .overlay-actions .btn { padding: 10px 18px; font-size: 0.95rem; }
}
