/* =========================================================================
   Puzzlers — Match-3 stylesheet
   Handmade gem art: every shape+color combo is a cropped PNG of an actual
   marker drawing (assets/handmade/) — real ink and paper texture, not
   generated. `.gem__art` just points its background-image at the right
   file for the gem's data-shape/data-color; the pointer/hand cursor
   sprites are the one generated exception (no hand-drawn source for those).
   ========================================================================= */

:root {
  /* ---- Primary Mint & Teal Greens ---- */
  --teal-1: #40E0D0;   /* Bright Teal Accent   (highlight) */
  --teal-2: #2EE898;   /* Vibrant Mint         (light)     */
  --teal-3: #16C47F;   /* Mid Spring Green     (base)      */
  --teal-4: #0E8345;   /* Deep Emerald Shade   (shadow)    */

  /* ---- Classic Forest & Leaf Greens ---- */
  --forest-1: #33D17A; /* Light Lime Highlight (highlight) */
  --forest-2: #1FA463; /* Leaf Green           (light)     */
  --forest-3: #0F6B38; /* Deep Foliage         (base)      */
  --forest-4: #0A4220; /* Dark Moss Shadow     (shadow)    */

  /* ---- Gemstone Pinks & Magentas ---- */
  --pink-1: #FF66B2;   /* Bright Rose Pink     (highlight) */
  --pink-2: #E6397E;   /* Vibrant Fuchsia      (light)     */
  --pink-3: #B82A61;   /* Deep Magenta         (base)      */
  --pink-4: #801A42;   /* Dark Berry Shadow    (shadow)    */

  /* ---- UI Neutrals ---- */
  --ui-white: #FFFFFF;
  --ui-mint-tint: #E2F8EE;
  --ui-ink: #1A1A1A;

  --board-size: min(94vw, 94vh, 640px);
  --cell: calc(var(--board-size) / 8);
  /* Plain unitless scale factor (cellPx / 64), recomputed by game.js via
     ResizeObserver — kept in JS because dividing two lengths inside calc()
     to get a unitless number for transform:scale() is not reliable across
     browsers. Falls back to 1 before the first measurement. */
  --gem-scale: 1;

  /* Animation speed knobs — plain durations so game.js can speed them up
     during a Frenzy streak without touching any other rule. */
  --dur-motion: 280ms;  /* swap-slide + gravity-fall transitions */
  --dur-clear: 260ms;   /* matched-gem pop-out animation */

  color-scheme: light;
}

/* --------------------------------- Reset -------------------------------- */
* { box-sizing: border-box; }
html, body {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
  overscroll-behavior: none;
  background: var(--ui-mint-tint);
}
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  color: var(--ui-ink);
  /* Lock the page down so it behaves like a native app, not a scrollable
     document: no rubber-banding, no pinch zoom, no text selection drag. */
  touch-action: pan-y;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  overflow-x: hidden;
}
img { max-width: 100%; display: block; }

/* ------------------------------- App shell ------------------------------- */
#app {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(8px, 2vw, 18px);
  padding: env(safe-area-inset-top, 0) env(safe-area-inset-right, 0) env(safe-area-inset-bottom, 0) env(safe-area-inset-left, 0);
  padding-top: clamp(10px, 2vh, 22px);
  background:
    radial-gradient(120% 90% at 50% -10%, rgba(64, 224, 208, 0.18), transparent 60%),
    var(--ui-mint-tint);
}

/* ---------------------------------- HUD ---------------------------------- */
.hud {
  position: relative;
  width: min(96vw, 640px);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(6px, 1.6vw, 14px);
  align-items: stretch;
  transition: filter 0.25s ease;
}
/* A live Frenzy streak gets a teal ring on every pill — distinct from the
   Power meter's pink, so the two systems never read as one thing. */
.hud.is-frenzy .pill {
  box-shadow:
    0 3px 0 rgba(26, 26, 26, 0.25),
    inset 0 2px 0 rgba(255, 255, 255, 0.9),
    0 0 0 3px rgba(64, 224, 208, 0.55);
  animation: frenzyRing 0.6s ease-in-out infinite;
}
@keyframes frenzyRing {
  0%, 100% { box-shadow: 0 3px 0 rgba(26,26,26,0.25), inset 0 2px 0 rgba(255,255,255,0.9), 0 0 0 2px rgba(64,224,208,0.4); }
  50% { box-shadow: 0 3px 0 rgba(26,26,26,0.25), inset 0 2px 0 rgba(255,255,255,0.9), 0 0 0 5px rgba(64,224,208,0.65); }
}

/* "Pill-shaped panels" — flat rounded-rect UI chrome built purely from the
   palette, echoing the blank pill mockups on the asset sheet. */
.pill {
  position: relative;
  min-height: clamp(44px, 8vh, 60px);
  border-radius: 999px;
  background: var(--ui-white);
  border: 3px solid var(--ui-ink);
  box-shadow: 0 3px 0 rgba(26, 26, 26, 0.25), inset 0 2px 0 rgba(255, 255, 255, 0.9);
  display: flex;
  align-items: center;
  padding: 0 clamp(10px, 2.4vw, 20px);
  overflow: hidden;
}
.pill--score { border-color: var(--teal-4); }
.pill--power { border-color: var(--pink-3); background: linear-gradient(180deg, #fff, var(--ui-mint-tint)); }
.pill--hearts { border-color: var(--pink-4); }
/* Overflow:visible so the "+5s" time-bonus pop (below) isn't clipped as it
   drifts up past the pill's own rounded-corner boundary. */
.pill--timer { border-color: var(--forest-3); overflow: visible; }

.pill__content {
  display: flex;
  flex-direction: column;
  justify-content: center;
  width: 100%;
  line-height: 1.05;
}
.pill__label {
  font-size: clamp(9px, 1.6vw, 11px);
  font-weight: 800;
  letter-spacing: 0.08em;
  color: var(--forest-3);
  opacity: 0.75;
}
.pill--power .pill__label { color: var(--pink-3); }
.pill__value {
  font-size: clamp(16px, 3.6vw, 24px);
  font-weight: 800;
  color: var(--ui-ink);
  font-variant-numeric: tabular-nums;
}

.meter {
  position: relative;
  margin-top: 3px;
  height: clamp(10px, 2.2vh, 14px);
  border-radius: 999px;
  background: var(--ui-mint-tint);
  border: 2px solid var(--pink-3);
  overflow: hidden;
}
.meter__fill {
  height: 100%;
  width: 0%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--pink-1), var(--pink-2), var(--pink-3));
  transition: width 0.35s ease;
}
.meter__word {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: clamp(8px, 1.4vw, 10px);
  font-weight: 800;
  letter-spacing: 0.06em;
  color: var(--ui-ink);
  opacity: 0;
  transition: opacity 0.25s ease;
}
.meter__word.is-visible { opacity: 1; }

/* --------------------------------- Hearts --------------------------------- */
.hearts {
  display: flex;
  gap: clamp(2px, 0.8vw, 5px);
  margin-top: 2px;
}
.heart {
  position: relative;
  width: clamp(14px, 3.4vw, 20px);
  height: clamp(14px, 3.4vw, 20px);
  flex: none;
}
.heart::before {
  content: "";
  position: absolute; inset: 0;
  -webkit-mask-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 29'%3E%3Cpath d='M16 28.5C9 23.7 1 17.6 1 9.9 1 4.9 4.8 1 9.6 1c2.9 0 5.4 1.4 6.4 3.7C17 2.4 19.5 1 22.4 1 27.2 1 31 4.9 31 9.9c0 7.7-8 13.8-15 18.6z'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 29'%3E%3Cpath d='M16 28.5C9 23.7 1 17.6 1 9.9 1 4.9 4.8 1 9.6 1c2.9 0 5.4 1.4 6.4 3.7C17 2.4 19.5 1 22.4 1 27.2 1 31 4.9 31 9.9c0 7.7-8 13.8-15 18.6z'/%3E%3C/svg%3E");
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
  background: var(--ui-mint-tint);
  border: 1.5px solid var(--pink-4);
  border-radius: 3px; /* softens the mask's un-rounded SVG corners slightly */
}
.heart.is-filled::before {
  border: none;
  background:
    radial-gradient(ellipse 40% 30% at 26% 22%, rgba(255,255,255,0.9) 0%, rgba(255,255,255,0) 70%),
    linear-gradient(135deg, var(--pink-1) 0%, var(--pink-2) 45%, var(--pink-3) 78%, var(--pink-4) 100%);
  filter: drop-shadow(0 1px 0 var(--pink-4));
}
.heart.is-losing { animation: heartPop 0.5s ease; }
@keyframes heartPop {
  0% { transform: scale(1) rotate(0); }
  30% { transform: scale(1.45) rotate(-10deg); }
  60% { transform: scale(0.8) rotate(8deg); }
  100% { transform: scale(1) rotate(0); }
}
/* Bonus heart from a tier clear — a teal glow (not pink) so it reads as a
   distinct, positive event rather than a variant of the loss shake. */
.heart.is-gained { animation: heartGain 0.65s ease; }
@keyframes heartGain {
  0% { transform: scale(1); filter: drop-shadow(0 0 0 rgba(64, 224, 208, 0)); }
  35% { transform: scale(1.55); filter: drop-shadow(0 0 6px rgba(64, 224, 208, 0.95)); }
  70% { transform: scale(0.92); filter: drop-shadow(0 0 2px rgba(64, 224, 208, 0.4)); }
  100% { transform: scale(1); filter: drop-shadow(0 0 0 rgba(64, 224, 208, 0)); }
}

/* --------------------------------- Timer --------------------------------- */
.timer-row {
  display: flex;
  align-items: baseline;
  gap: clamp(4px, 1.4vw, 8px);
}
.timer-progress {
  font-size: clamp(9px, 1.6vw, 11px);
  font-weight: 700;
  color: var(--forest-3);
  opacity: 0.75;
  font-variant-numeric: tabular-nums;
}
.pill--timer .pill__value.is-urgent {
  color: var(--pink-3);
  animation: urgentPulse 0.5s ease-in-out infinite;
}
@keyframes urgentPulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }

/* Floating "+5s" pop next to the timer pill when a bonus (combo, power
   surge, Frenzy) extends the clock. */
.time-bonus {
  position: absolute;
  top: -2px;
  right: clamp(8px, 2vw, 16px);
  z-index: 3;
  font-size: clamp(11px, 2.2vw, 13px);
  font-weight: 800;
  color: var(--teal-4);
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.8);
  opacity: 0;
  pointer-events: none;
}
.time-bonus.is-popping { animation: timeBonusPop 0.9s ease forwards; }
@keyframes timeBonusPop {
  0% { transform: translateY(6px) scale(0.9); opacity: 0; }
  20% { transform: translateY(-2px) scale(1.1); opacity: 1; }
  100% { transform: translateY(-20px) scale(1); opacity: 0; }
}

/* How many matches until the next Horizontal/Diagonal Time switch. */
.mode-progress {
  display: block;
  margin-top: 1px;
  font-size: clamp(8px, 1.5vw, 10px);
  font-weight: 700;
  color: var(--teal-4);
  opacity: 0.75;
  font-variant-numeric: tabular-nums;
}
.mode-progress.is-diagonal { color: var(--pink-3); }

/* ------------------------------- Frenzy tag ------------------------------- */
.frenzy-tag {
  align-self: center;
  width: min(96vw, 640px);
  text-align: center;
  font-size: clamp(11px, 2.4vw, 13px);
  font-weight: 800;
  letter-spacing: 0.08em;
  color: var(--ui-white);
  background: linear-gradient(90deg, var(--teal-2), var(--teal-4));
  border: 2px solid var(--ui-ink);
  border-radius: 999px;
  padding: 4px 12px;
  box-shadow: 0 2px 0 rgba(26, 26, 26, 0.25);
  animation: frenzyTagPop 0.3s ease;
}
@keyframes frenzyTagPop {
  from { transform: scale(0.8); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}

/* --------------------------------- Banner --------------------------------- */
.banner {
  width: min(96vw, 640px);
  text-align: center;
  font-weight: 800;
  font-size: clamp(13px, 3vw, 18px);
  color: var(--ui-white);
  background: linear-gradient(90deg, var(--teal-3), var(--forest-2));
  border: 3px solid var(--ui-ink);
  border-radius: 14px;
  padding: 8px 14px;
  box-shadow: 0 3px 0 rgba(26, 26, 26, 0.25);
  animation: bannerPop 0.35s ease;
}
.banner.is-bonus { background: linear-gradient(90deg, var(--pink-2), var(--pink-3)); }
@keyframes bannerPop {
  from { transform: scale(0.85); opacity: 0; }
  to   { transform: scale(1); opacity: 1; }
}

/* --------------------------------- Board --------------------------------- */
.board-wrap {
  width: 100%;
  display: flex;
  justify-content: center;
  touch-action: none; /* lock: no scroll/zoom while dragging gems */
}

.board {
  position: relative;
  width: var(--board-size);
  height: var(--board-size);
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  grid-template-rows: repeat(8, 1fr);
  background: var(--ui-white);
  border: 4px solid var(--ui-ink);
  border-radius: 16px;
  box-shadow: 0 6px 0 rgba(26, 26, 26, 0.25);
  overflow: hidden;
  touch-action: none;
}

.cell {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Checkerboard "background grid" built from the mint/teal neutrals. */
  background: var(--ui-mint-tint);
}
.cell:nth-child(16n+1), .cell:nth-child(16n+3), .cell:nth-child(16n+5), .cell:nth-child(16n+7),
.cell:nth-child(16n+10), .cell:nth-child(16n+12), .cell:nth-child(16n+14), .cell:nth-child(16n+16) {
  background: var(--ui-white);
}
.cell.is-drop-target {
  background: rgba(64, 224, 208, 0.35);
}

/* ----------------------------- Gem sprites ------------------------------- */
.gem {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: grab;
  will-change: transform;
  transition: transform 0.18s ease, opacity 0.18s ease;
  z-index: 2;
}
.gem:active { cursor: grabbing; }
.gem.is-selected .gem__art { filter: drop-shadow(0 0 0 transparent) brightness(1.12); }
.gem.is-selected::after {
  content: "";
  position: absolute;
  width: 82%;
  height: 82%;
  border-radius: 50%;
  border: 3px solid var(--pink-2);
  box-shadow: 0 0 0 3px rgba(255, 102, 178, 0.35);
  animation: selectPulse 0.9s ease-in-out infinite;
  pointer-events: none;
}
@keyframes selectPulse {
  0%, 100% { transform: scale(0.96); opacity: 0.9; }
  50% { transform: scale(1.04); opacity: 0.55; }
}
.gem.is-matched .gem__art {
  animation: gemClear var(--dur-clear) ease forwards;
}
@keyframes gemClear {
  to { transform: scale(0); opacity: 0; }
}
.gem.is-falling { transition: transform var(--dur-motion) cubic-bezier(.4,.0,.2,1); }
.gem.is-invalid-swap { animation: swapReject 0.3s ease; }
@keyframes swapReject {
  0%, 100% { transform: translate(0, 0); }
  25% { transform: translate(-4px, 0); }
  75% { transform: translate(4px, 0); }
}

.gem__art {
  /* Fixed native pixel box (set per-shape below) so layout math stays
     predictable; flex-shrink is disabled so the flex layout in .gem can
     never squash that box — responsiveness comes only from the
     transform:scale below, which is a paint-time effect. */
  flex: none;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  transform: scale(var(--gem-scale));
  transform-origin: center;
  /* Ambient contact shadow, cast down-right, light from the top-left. */
  filter: drop-shadow(1.5px 2.5px 1px rgba(8, 16, 12, 0.32));
}

/* Shape boxes — sized to each hand-drawn sprite's own aspect ratio. */
.gem[data-shape="pentagon"] .gem__art { width: 48px; height: 46px; }
.gem[data-shape="diamond"] .gem__art { width: 48px; height: 48px; }
.gem[data-shape="rectangle"] .gem__art { width: 64px; height: 32px; }
.gem[data-shape="circle"] .gem__art { width: 44px; height: 48px; }
.gem[data-shape="square"] .gem__art { width: 44px; height: 44px; }
.gem[data-shape="heart"] .gem__art { width: 44px; height: 46px; }
.gem[data-shape="star"] .gem__art { width: 42px; height: 46px; }

/* Handmade art — one cropped drawing per shape+color combo, used as-is (no
   runtime recoloring) since a marker drawing of a teal diamond and a pink
   diamond are genuinely different pieces of art. Each shape only has real
   art in its own one or three colors (see the GEM_TYPES list in game.js) —
   pentagon/diamond/rectangle in teal/forest/pink, circle in yellow, square
   in navy, heart in orange, star in purple — so this is exactly the combos
   that have real art, not a full cross product. */
.gem[data-shape="pentagon"][data-color="teal"] .gem__art { background-image: url("../assets/handmade/gem-pentagon-teal.png"); }
.gem[data-shape="pentagon"][data-color="forest"] .gem__art { background-image: url("../assets/handmade/gem-pentagon-forest.png"); }
.gem[data-shape="pentagon"][data-color="pink"] .gem__art { background-image: url("../assets/handmade/gem-pentagon-pink.png"); }
.gem[data-shape="diamond"][data-color="teal"] .gem__art { background-image: url("../assets/handmade/gem-diamond-teal.png"); }
.gem[data-shape="diamond"][data-color="forest"] .gem__art { background-image: url("../assets/handmade/gem-diamond-forest.png"); }
.gem[data-shape="diamond"][data-color="pink"] .gem__art { background-image: url("../assets/handmade/gem-diamond-pink.png"); }
.gem[data-shape="rectangle"][data-color="teal"] .gem__art { background-image: url("../assets/handmade/gem-rectangle-teal.png"); }
.gem[data-shape="rectangle"][data-color="forest"] .gem__art { background-image: url("../assets/handmade/gem-rectangle-forest.png"); }
.gem[data-shape="rectangle"][data-color="pink"] .gem__art { background-image: url("../assets/handmade/gem-rectangle-pink.png"); }
.gem[data-shape="circle"][data-color="yellow"] .gem__art { background-image: url("../assets/handmade/gem-circle-yellow.png"); }
.gem[data-shape="square"][data-color="navy"] .gem__art { background-image: url("../assets/handmade/gem-square-navy.png"); }
.gem[data-shape="heart"][data-color="orange"] .gem__art { background-image: url("../assets/handmade/gem-heart-orange.png"); }
.gem[data-shape="star"][data-color="purple"] .gem__art { background-image: url("../assets/handmade/gem-star-purple.png"); }

/* ---------------------------- Custom cursor ------------------------------ */
#cursorSprite {
  position: fixed;
  top: 0; left: 0;
  width: 20px; height: 24px;
  pointer-events: none;
  z-index: 999;
  background-image: url("../assets/handmade/cursor-pointer.svg");
  background-repeat: no-repeat;
  background-size: contain;
  filter: drop-shadow(0 2px 2px rgba(0,0,0,0.35));
  transform: translate(-2px, -2px);
  display: none;
}
#cursorSprite.is-dragging {
  width: 27px; height: 25px;
  background-image: url("../assets/handmade/cursor-hand.svg");
}
/* Only show the sprite cursor on real pointer devices; keep the system
   cursor as fallback and never intercept touch. */
@media (hover: hover) and (pointer: fine) {
  .board-wrap, .board, .gem { cursor: none; }
  #cursorSprite { display: block; }
}

/* ---------------------------- Bottom countdown ----------------------------- */
/* Appears only in a tier's final 10 seconds — a big, hard-to-miss beat
   separate from the small timer readout up in the HUD. */
.countdown-overlay {
  position: fixed;
  left: 50%;
  bottom: max(14px, env(safe-area-inset-bottom, 14px));
  transform: translateX(-50%);
  z-index: 60;
  pointer-events: none;
  width: clamp(52px, 13vw, 78px);
  height: clamp(52px, 13vw, 78px);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 3px solid var(--ui-ink);
  box-shadow: 0 4px 0 rgba(26, 26, 26, 0.3);
  background:
    radial-gradient(ellipse 40% 28% at 28% 24%, rgba(255,255,255,0.9) 0%, rgba(255,255,255,0) 70%),
    radial-gradient(ellipse 55% 42% at 82% 86%, var(--pink-4) 0%, transparent 62%),
    linear-gradient(135deg, var(--pink-1) 0%, var(--pink-2) 40%, var(--pink-3) 72%, var(--pink-4) 100%);
}
/* The base rule above sets display:flex unconditionally, which (being an
   author-origin declaration) outranks the browser default [hidden]{display:
   none} — so the hidden attribute needs its own, more specific override. */
.countdown-overlay[hidden] { display: none; }
.countdown-overlay__num {
  font-size: clamp(22px, 5.6vw, 34px);
  font-weight: 800;
  color: var(--ui-white);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 2px 0 rgba(0, 0, 0, 0.3);
}
.countdown-overlay.is-tick { animation: countdownRing 0.5s ease; }
.countdown-overlay.is-tick .countdown-overlay__num { animation: countdownPop 0.5s ease; }
@keyframes countdownPop {
  0% { transform: scale(1.5); opacity: 0.3; }
  100% { transform: scale(1); opacity: 1; }
}
@keyframes countdownRing {
  0% { box-shadow: 0 4px 0 rgba(26,26,26,0.3), 0 0 0 9px rgba(184,42,97,0); }
  40% { box-shadow: 0 4px 0 rgba(26,26,26,0.3), 0 0 0 3px rgba(184,42,97,0.55); }
  100% { box-shadow: 0 4px 0 rgba(26,26,26,0.3), 0 0 0 0 rgba(184,42,97,0); }
}

/* --------------------------- Mode-switch interstitial ------------------------ */
/* Full-screen title card announcing a Horizontal Time <-> Diagonal Time
   switch. Blocks nothing itself (input is already locked by `busy` for its
   whole 5s hold) — it's purely the announcement. */
.mode-screen {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(10, 20, 15, 0.6);
}
.mode-screen[hidden] { display: none; }

.mode-screen__card {
  position: relative;
  overflow: hidden;
  width: min(90vw, 400px);
  border-radius: 20px;
  border: 4px solid var(--ui-ink);
  box-shadow: 0 8px 0 rgba(26, 26, 26, 0.35);
  padding: clamp(26px, 7vw, 40px) clamp(20px, 5vw, 30px);
  text-align: center;
  background: var(--ui-white);
  animation: modeScreenPop 0.4s cubic-bezier(.2, .85, .3, 1.3);
}
@keyframes modeScreenPop {
  from { transform: scale(0.75) rotate(-2deg); opacity: 0; }
  to { transform: scale(1) rotate(0); opacity: 1; }
}
/* Decorative backdrop pattern inside the card, themed to the mode it's
   announcing: diagonal hatching for Diagonal Time, a grid for Horizontal. */
.mode-screen__card::before {
  content: "";
  position: absolute;
  inset: 0;
  opacity: 0.16;
  pointer-events: none;
}
.mode-screen__card.is-diagonal::before {
  background: repeating-linear-gradient(45deg, var(--pink-3) 0 6px, transparent 6px 24px);
}
.mode-screen__card.is-orthogonal::before {
  background:
    repeating-linear-gradient(0deg, var(--teal-3) 0 4px, transparent 4px 28px),
    repeating-linear-gradient(90deg, var(--teal-3) 0 4px, transparent 4px 28px);
}
.mode-screen__title {
  position: relative;
  font-size: clamp(24px, 7vw, 32px);
  font-weight: 800;
  letter-spacing: 0.03em;
  margin-bottom: 10px;
  text-wrap: balance;
}
.mode-screen__card.is-diagonal .mode-screen__title { color: var(--pink-3); }
.mode-screen__card.is-orthogonal .mode-screen__title { color: var(--teal-4); }
.mode-screen__subtitle {
  position: relative;
  margin: 0;
  font-size: clamp(13px, 3.4vw, 15px);
  font-weight: 600;
  color: var(--ui-ink);
  opacity: 0.85;
  line-height: 1.4;
}
.mode-screen__timer {
  position: relative;
  margin-top: 16px;
  font-size: clamp(11px, 2.6vw, 13px);
  font-weight: 700;
  letter-spacing: 0.05em;
  opacity: 0.6;
  font-variant-numeric: tabular-nums;
}

/* --------------------------------- Legend --------------------------------- */
.legend {
  display: flex;
  gap: 10px;
  padding-bottom: env(safe-area-inset-bottom, 10px);
}
.legend__chip {
  width: clamp(14px, 3vw, 20px);
  height: clamp(14px, 3vw, 20px);
  border-radius: 50%;
  border: 2px solid var(--ui-ink);
}
.legend__chip--teal   { background: linear-gradient(135deg, var(--teal-1), var(--teal-4)); }
.legend__chip--forest { background: linear-gradient(135deg, var(--forest-1), var(--forest-4)); }
.legend__chip--pink   { background: linear-gradient(135deg, var(--pink-1), var(--pink-4)); }

/* ============================ Responsive layout ============================ */

/* Small phones, portrait — 4 pills wrap into a 2x2 grid */
@media (max-width: 420px) {
  .hud { grid-template-columns: repeat(2, 1fr); }
  .pill__label { letter-spacing: 0.04em; }
}

/* Landscape phones: keep the board from ever forcing horizontal scroll and
   shrink the HUD so the board still fits above the fold. */
@media (orientation: landscape) and (max-height: 480px) {
  #app {
    flex-direction: row;
    align-items: center;
    justify-content: center;
    gap: clamp(8px, 2vw, 16px);
    padding-top: env(safe-area-inset-top, 8px);
  }
  .hud {
    width: clamp(200px, 34vw, 300px);
    grid-template-columns: repeat(2, 1fr);
  }
  .banner { position: fixed; top: 6px; left: 50%; transform: translateX(-50%); width: max-content; }
  .frenzy-tag { position: fixed; top: 6px; left: 50%; transform: translateX(-50%); width: max-content; }
  .legend { flex-direction: column; }
  :root { --board-size: min(90vh, 90vw, 560px); }
}

/* Larger tablets / desktop: cap board size, give the HUD more breathing room */
@media (min-width: 900px) {
  :root { --board-size: min(72vh, 640px); }
  .hud { width: 640px; }
}

@media (prefers-reduced-motion: reduce) {
  .gem, .gem__art, .meter__fill, .banner, .heart, .hud.is-frenzy .pill,
  .frenzy-tag, .pill__value.is-urgent, .countdown-overlay, .countdown-overlay__num,
  .mode-screen__card, .time-bonus {
    animation: none !important; transition: none !important;
  }
}
