/**
 * chompy.css — Chompy's own look.
 *
 * Everything in this game was inline styles, which is why it had no identity of its own: no
 * shared palette, no shared surface treatment, and the same purple/yellow pair repeated as
 * literals in six components with slightly different alpha each time. The tokens below are the
 * single source for that palette; components keep their inline layout, but colours and the
 * recurring surface treatments come from here.
 *
 * THE POSTER IS THE GAME'S BACKGROUND on every screen the player sees before the maze appears:
 * the HTML loading screen, the splash, and the main menu. One image, one identity, from the
 * first paint to the first frame of play — instead of a flat #0A0A0F that reads as "not loaded
 * yet". It is set on a ::before pseudo-element so the scrim on top of it never tints the poster
 * itself, and so the art can be `filter`-ed independently of the text sitting over it.
 */

:root {
  /* Palette — pulled from the art, not invented. Chompy's fur yellow is the accent; the
     pound's dark is the ground; the purple is the arcade shell's, kept so this game still
     reads as part of the same arcade. */
  --chompy-gold: #ffe600;
  --chompy-gold-dim: rgba(255, 230, 0, 0.35);
  --chompy-cream: #f4f1de;
  --chompy-cream-soft: rgba(244, 241, 222, 0.55);
  --chompy-violet: #7c52fb;
  --chompy-violet-line: rgba(124, 82, 251, 0.4);
  --chompy-violet-fill: rgba(124, 82, 251, 0.15);
  --chompy-ink: #0a0a0f;
  --chompy-ink-panel: rgba(15, 15, 20, 0.85);

  /* One radius scale, so panels/buttons/cards stop each picking their own. */
  --chompy-r-sm: 10px;
  --chompy-r-md: 14px;
  --chompy-r-lg: 22px;
}

/* ── The poster backdrop ───────────────────────────────────────────────────────
   The image is a real <img> (.chompy-poster-img), NOT a CSS background. It used to be
   `background-image: var(--chompy-poster)` on a ::before, and it rendered as a black screen:
   a url() inside a custom property is substituted as a raw token and resolved against the
   stylesheet that USES it — /assets/index-*.css in this build — so the path 404'd, and a
   var() fallback cannot rescue that because fallbacks only apply to an UNDEFINED property.
   An <img> is resolved against the document and fails visibly instead of silently. */
.chompy-poster-bg {
  position: relative;
  overflow: hidden;
  background-color: var(--chompy-ink);
  /* Fill the viewport rather than only the flow box. 100dvh, not 100vh: on mobile Safari 100vh
     is the tallest the viewport ever gets, so with the URL bar showing it overflows and the
     poster's bottom is cut off. dvh tracks the visible height. The vh line beneath is the
     fallback for engines without dvh. */
  min-height: 100vh;
  min-height: 100dvh;
  width: 100%;
}

.chompy-poster-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  z-index: 0;
  /* Near full strength. An earlier version ran brightness(0.62) under a 42-55% scrim, which
     left ~31% of the original luminance — the art was there and read as black. */
  filter: saturate(1.02) brightness(0.94);
  pointer-events: none;
  user-select: none;
}

/* A VIGNETTE, not a wash. Dark only in the top and bottom bands, where the arcade exit, the
   volume control and the PLAY button need something to sit against; near-clear through the
   middle so the artwork is actually visible. */
.chompy-poster-veil {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(180deg,
      rgba(8, 8, 12, 0.72) 0%,
      rgba(8, 8, 12, 0.18) 22%,
      rgba(8, 8, 12, 0.06) 48%,
      rgba(8, 8, 12, 0.34) 76%,
      rgba(8, 8, 12, 0.80) 100%);
}

/* Everything the player reads or taps sits above both layers. */
.chompy-poster-content {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}

/* The display face. 'Luckiest Guy' is a fat, hand-drawn, all-caps cartoon face — the childlike
   Disney register the music was written to, and it reads at a glance on a phone, which a thin
   arcade face does not. Loaded with a real fallback stack so a font-host failure degrades to a
   heavy system face rather than to nothing. */
:root {
  --chompy-display: 'Luckiest Guy', 'Arial Rounded MT Bold', 'Trebuchet MS',
                    -apple-system, BlinkMacSystemFont, sans-serif;
}

/* ── Wordmark ──────────────────────────────────────────────────────────────── */
.chompy-wordmark {
  font-family: var(--chompy-display);
  font-size: clamp(44px, 15vw, 66px);
  font-weight: 400; /* the face is already fat; 900 would synthesise a smeared fake bold */
  letter-spacing: 1px;
  color: var(--chompy-gold);
  /* Two shadows on purpose: the tight dark one keeps the glyph legible against a bright patch
     of poster, the wide gold one is the arcade glow. Glow alone disappears over light art. */
  text-shadow:
    0 2px 10px rgba(0, 0, 0, 0.85),
    0 0 34px rgba(255, 230, 0, 0.45);
  margin: 0;
  line-height: 1.05;
  text-align: center;
}

/* Solid gold, bold, and nothing else on the glyph.
   ⛑ This carried a 3.5px -webkit-text-stroke and a gradient fill, and it was HARDER to read, not
   easier: a text stroke is drawn on the glyph outline and grows inward, so at this size on a fat
   display face it closed up the counters — the holes in a, e, o, p filled with black and the
   word became a shape. The gradient went with it, because background-clip:text needs a
   transparent fill and left the letters reading outline-first.
   The one drop shadow that remains is NOT an outline: it sits behind the glyph and never touches
   its interior, and it is what keeps yellow legible where the poster is bright. */
.chompy-tagline {
  font-family: var(--chompy-display);
  /* The face is already fat; 700 would synthesise a smeared fake bold on top of it. */
  font-weight: 400;
  font-size: clamp(20px, 6.4vw, 27px);
  letter-spacing: 0.4px;
  line-height: 1.28;
  text-align: center;
  max-width: 320px;
  margin: 0 0 26px;
  color: var(--chompy-gold);
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.9);
}

/* ── The primary action ────────────────────────────────────────────────────── */
.chompy-play-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-width: 216px;
  /* 56px clears Apple's 44pt touch minimum with room to spare — this is the one control the
     whole title screen exists to offer. */
  min-height: 56px;
  padding: 0 30px;
  font-size: 19px;
  font-weight: 900;
  letter-spacing: 1.2px;
  color: var(--chompy-ink);
  background: var(--chompy-gold);
  border: none;
  border-radius: var(--chompy-r-lg);
  box-shadow:
    0 8px 26px rgba(0, 0, 0, 0.55),
    0 0 0 3px rgba(255, 230, 0, 0.18);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform 120ms ease, box-shadow 120ms ease;
}

.chompy-play-btn:active {
  transform: scale(0.97);
  box-shadow:
    0 4px 14px rgba(0, 0, 0, 0.55),
    0 0 0 3px rgba(255, 230, 0, 0.28);
}

/* PLAY ONLINE sits under PLAY as the secondary action: same size and touch target, outlined not filled. */
.chompy-online-btn {
  margin-top: 12px;
  color: var(--chompy-cream);
  background: rgba(10, 10, 15, 0.55);
  border: 2px solid var(--chompy-gold);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.45);
}

.chompy-play-btn:focus-visible {
  outline: 3px solid var(--chompy-cream);
  outline-offset: 3px;
}

/* ── Loading screen ────────────────────────────────────────────────────────── */
.chompy-loading-label {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 2.2px;
  text-transform: uppercase;
  color: var(--chompy-cream);
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.9);
}

.chompy-spinner {
  width: 38px;
  height: 38px;
  margin-top: 16px;
  border: 3px solid rgba(255, 230, 0, 0.22);
  border-top-color: var(--chompy-gold);
  border-radius: 50%;
  animation: chompy-spin 0.8s linear infinite;
}

@keyframes chompy-spin {
  to { transform: rotate(360deg); }
}

/* A player who has asked the OS to reduce motion should not get a spinning ring; hold it
   still and let the label carry the "still working" message. */
@media (prefers-reduced-motion: reduce) {
  .chompy-spinner { animation: none; }
  .chompy-play-btn { transition: none; }
}


/* ── LEVEL banner ──────────────────────────────────────────────────────────────
   The stylized "LEVEL n" card shown at the top of every level, during the 'ready' beat.
   Two stacked lines: the small tracked label, then the number big enough to read across a
   room. The gold sits on a dark stroke so it survives whatever the maze is doing behind it. */
.chompy-level-banner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  pointer-events: none;
  animation: chompy-level-pop 460ms cubic-bezier(0.2, 1.5, 0.4, 1) both;
}

.chompy-level-word {
  font-family: var(--chompy-display);
  font-size: clamp(22px, 7vw, 30px);
  letter-spacing: 5px;
  /* The tracking adds a trailing gap after the last glyph; pull it back so the word stays
     optically centred over the numeral. */
  text-indent: 5px;
  color: var(--chompy-cream);
  text-shadow: 0 2px 0 rgba(0, 0, 0, 0.9), 0 4px 18px rgba(0, 0, 0, 0.8);
}

.chompy-level-number {
  font-family: var(--chompy-display);
  font-size: clamp(72px, 26vw, 128px);
  line-height: 0.9;
  color: var(--chompy-gold);
  -webkit-text-stroke: 3px rgba(8, 8, 12, 0.92);
  paint-order: stroke fill;   /* stroke UNDER the fill, or it eats into the glyph */
  text-shadow: 0 6px 0 rgba(8, 8, 12, 0.55), 0 0 42px rgba(255, 230, 0, 0.5);
}

.chompy-ready-word {
  font-family: var(--chompy-display);
  font-size: clamp(30px, 10vw, 44px);
  letter-spacing: 3px;
  text-indent: 3px;
  color: var(--chompy-cream);
  margin-top: 10px;
  text-shadow: 0 2px 0 rgba(0, 0, 0, 0.9), 0 0 26px rgba(255, 230, 0, 0.35);
  animation: chompy-ready-pulse 620ms ease-in-out infinite alternate;
}

@keyframes chompy-level-pop {
  from { opacity: 0; transform: scale(0.72); }
  to   { opacity: 1; transform: scale(1); }
}

@keyframes chompy-ready-pulse {
  from { opacity: 0.55; }
  to   { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .chompy-level-banner { animation: none; }
  .chompy-ready-word { animation: none; opacity: 1; }
}


/* ── How to play ───────────────────────────────────────────────────────────────
   Sits under PLAY, collapsed. PLAY stays the largest thing on the screen: a player who knows
   the game should never scroll past instructions to start one. */
.chompy-rules {
  width: 100%;
  max-width: 320px;
  margin-top: 18px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.chompy-rules-toggle {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  /* 44px is Apple's touch minimum; this control is small on purpose but must stay tappable. */
  min-height: 44px;
  padding: 0 18px;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 1.6px;
  color: var(--chompy-cream);
  background: rgba(12, 12, 18, 0.55);
  border: 1px solid rgba(244, 241, 222, 0.28);
  border-radius: var(--chompy-r-lg);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.chompy-rules-caret {
  display: inline-block;
  transition: transform 160ms ease;
  font-size: 11px;
}

.chompy-rules-caret.is-open { transform: rotate(180deg); }

.chompy-rules-list {
  list-style: none;
  margin: 12px 0 0;
  padding: 14px 16px;
  width: 100%;
  background: rgba(10, 10, 15, 0.82);
  border: 1px solid rgba(124, 82, 251, 0.3);
  border-radius: var(--chompy-r-md);
  /* The list can outgrow a short viewport once open; scroll it rather than pushing PLAY away. */
  max-height: 42vh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

.chompy-rules-item {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  font-size: 13px;
  line-height: 1.45;
  color: rgba(244, 241, 222, 0.9);
}

.chompy-rules-item + .chompy-rules-item { margin-top: 10px; }

.chompy-rules-icon {
  flex: 0 0 auto;
  width: 20px;
  text-align: center;
  font-size: 15px;
}

/* ── Level intro ───────────────────────────────────────────────────────────────
   The card between levels. It is a GATE: nothing moves until START is pressed, so the story is
   readable and the maze never starts while the player is reading it. */
.chompy-intro {
  position: absolute;
  inset: 0;
  z-index: 25;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  padding-top: calc(var(--sat, env(safe-area-inset-top, 0px)) + 16px);
  padding-bottom: calc(var(--sab, env(safe-area-inset-bottom, 0px)) + 16px);
  background: rgba(6, 6, 10, 0.88);
}

.chompy-intro-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  max-width: 360px;
  max-height: 100%;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 20px 20px 24px;
  background: linear-gradient(180deg, #14101f 0%, #0c0a14 100%);
  border: 1px solid rgba(124, 82, 251, 0.35);
  border-radius: var(--chompy-r-lg);
  text-align: center;
}

.chompy-intro-act {
  margin-top: 6px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1.6px;
  text-indent: 1.6px;
  color: rgba(124, 82, 251, 0.95);
}

.chompy-intro-title {
  font-family: var(--chompy-display);
  font-weight: 400;
  font-size: clamp(24px, 7.5vw, 30px);
  color: var(--chompy-cream);
  margin: 4px 0 12px;
  line-height: 1.15;
}

.chompy-intro-lines { width: 100%; }

.chompy-intro-line {
  margin: 0 0 9px;
  font-size: 14px;
  line-height: 1.5;
  color: rgba(244, 241, 222, 0.85);
  text-align: left;
}

.chompy-intro-start { margin-top: 18px; }
