/* ========================= Spaghetti Words — styles ======================== */

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

/* 100dvh is the *visible* viewport. Plain 100% includes the strip hiding behind
   a phone's address bar, which pushes the bottom of the game off the screen. */
html, body {
  margin: 0;
  height: 100%;
  height: 100dvh;
  overflow: hidden;
  font-family: "Baloo 2", system-ui, "Segoe UI", sans-serif;
  user-select: none;
  -webkit-user-select: none;
  /* The viewport meta says user-scalable=no, but phones have ignored that for
     years. touch-action is what actually stops double-tap-to-zoom. */
  touch-action: manipulation;
}

#game {
  position: fixed;
  inset: 0;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  background: radial-gradient(130% 90% at 50% 0%, #fff3dd 0%, #ffe1b8 45%, #ffd0c2 100%);
  transition: background 0.5s ease;
}

/* The whole board rattles when the fork lands. */
#game.shake { animation: tableShake 0.35s ease; }
@keyframes tableShake {
  0%, 100% { transform: translate(0, 0); }
  20% { transform: translate(-7px, 4px) rotate(-0.6deg); }
  40% { transform: translate(6px, -5px) rotate(0.5deg); }
  60% { transform: translate(-4px, 3px); }
  80% { transform: translate(3px, -2px); }
}

/* --------------------------------- HUD ----------------------------------- */

#hud {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: clamp(6px, 2.2vw, 20px);
  flex-wrap: wrap;
  padding:
    calc(clamp(6px, 2vw, 14px) + env(safe-area-inset-top, 0px))
    calc(clamp(8px, 2vw, 16px) + env(safe-area-inset-right, 0px))
    clamp(6px, 2vw, 14px)
    calc(clamp(8px, 2vw, 16px) + env(safe-area-inset-left, 0px));
}

.hud-item { flex: 0 0 auto; text-align: center; }

#timer-num {
  font-size: clamp(28px, 7vw, 46px);
  font-weight: 800;
  line-height: 1;
  color: #b8341f;
}

/* The last few seconds go red and pulse. */
#timer-num.low { color: #e10046; animation: pulse 0.6s ease-in-out infinite; }
@keyframes pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.18); }
}

.mini-bar {
  width: clamp(64px, 18vw, 110px);
  height: 10px;
  margin-top: 4px;
  border-radius: 99px;
  background: rgba(184, 52, 31, 0.2);
  overflow: hidden;
}

.mini-bar > div {
  width: 100%;
  height: 100%;
  border-radius: 99px;
  background: linear-gradient(90deg, #ffb347, #e0402f);
  transform-origin: left center;
  transition: transform 0.15s linear;
}

#timer-num.low ~ .mini-bar > div { background: #e10046; }

/* Two words in, the clock drains four times faster. The badge always takes up
   its space and just fades in, so the HUD never jumps when it appears. */
#speed-badge {
  height: 15px;
  margin-top: 2px;
  font-size: clamp(10px, 2.6vw, 14px);
  font-weight: 800;
  line-height: 15px;
  color: #8a2be2;
  letter-spacing: 0.4px;
  opacity: 0;
  transition: opacity 0.2s ease;
}

#timer.fast #speed-badge { opacity: 1; animation: speedFlash 0.55s ease-in-out 3; }
#timer.fast #timer-num { color: #8a2be2; }
#timer.fast .mini-bar > div { background: linear-gradient(90deg, #c77dff, #8a2be2); }
#timer.fast #timer-num.low { color: #e10046; }
#timer.fast #timer-num.low ~ .mini-bar > div { background: #e10046; }

@keyframes speedFlash {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.25); }
}

.stat-label {
  font-size: clamp(13px, 3.2vw, 19px);
  font-weight: 700;
  color: #6b3a24;
  white-space: nowrap;
}

.stat-label b { color: #b8341f; font-size: 1.15em; }

/* What the goblin will eat if he wins this round. It climbs every round, so it
   gets its own alarming red so you can see the stakes going up. */
.threat .stat-label { color: #93331f; }
.threat .stat-label b { color: #e10046; }

#score-num.bump,
#threat-num.bump { display: inline-block; animation: bump 0.3s ease; }
@keyframes bump {
  0% { transform: scale(1); }
  50% { transform: scale(1.6); color: #ff9500; }
  100% { transform: scale(1); }
}

#say-btn, #quit-btn {
  flex: 0 0 auto;
  font-size: clamp(18px, 4.6vw, 28px);
  line-height: 1;
  background: rgba(255, 255, 255, 0.92);
  border: 3px solid #f0a93c;
  border-radius: 50%;
  width: clamp(42px, 11vw, 56px);
  height: clamp(42px, 11vw, 56px);
  cursor: pointer;
  box-shadow: 0 4px 0 rgba(184, 100, 30, 0.3);
  transition: transform 0.1s ease, box-shadow 0.1s ease;
  touch-action: manipulation;
}

#say-btn { margin-left: auto; }

#say-btn:active, #quit-btn:active {
  transform: translateY(3px);
  box-shadow: 0 1px 0 rgba(184, 100, 30, 0.3);
}

/* -------------------------------- Stage ---------------------------------- */

/* min-height:0 is required, or the grid refuses to shrink inside the flex
   column and the letters get pushed off the bottom of a short screen. */
#stage {
  flex: 1 1 auto;
  min-height: 0;
  display: grid;
  gap: clamp(4px, 1.5vw, 12px);
  padding:
    clamp(4px, 1.5vw, 12px)
    calc(clamp(8px, 2.5vw, 20px) + env(safe-area-inset-right, 0px))
    calc(clamp(6px, 2vw, 16px) + env(safe-area-inset-bottom, 0px))
    calc(clamp(8px, 2.5vw, 20px) + env(safe-area-inset-left, 0px));

  /* Portrait: the list sits across the top as two rows of three. */
  grid-template-columns: 1fr;
  grid-template-rows: auto auto 1fr;
  grid-template-areas:
    "list"
    "hint"
    "jumble";
}

/* --------------------------- The list of six ------------------------------ */

#checklist-wrap { grid-area: list; min-width: 0; }

#list-title {
  font-size: clamp(12px, 3vw, 16px);
  font-weight: 800;
  color: #8a5a3a;
  margin-bottom: 4px;
  text-align: center;
}

#checklist {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(4px, 1.2vw, 10px);
}

.chk {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-width: 0;
  padding: clamp(3px, 0.9vw, 7px) clamp(4px, 1.2vw, 10px);
  background: rgba(255, 255, 255, 0.75);
  border: 2px solid #f0c98c;
  border-radius: 12px;
  animation: chkIn 0.35s cubic-bezier(0.34, 1.56, 0.64, 1) backwards;
}

@keyframes chkIn {
  from { transform: translateY(-14px) scale(0.7); opacity: 0; }
}

.chk-mark { font-size: clamp(10px, 2.6vw, 14px); line-height: 1; }

.chk-word {
  font-size: clamp(12px, 3.1vw, 17px);
  font-weight: 800;
  letter-spacing: 0.5px;
  color: #6b3a24;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The word you're on right now. */
.chk.current {
  background: #fff6de;
  border-color: #ff9500;
  box-shadow: 0 0 0 3px rgba(255, 170, 40, 0.25);
}
.chk.current .chk-word { color: #b8341f; }

/* Spelled it! */
.chk.done { background: #eaffe9; border-color: #63c76e; }
.chk.done .chk-word { color: #2f9d4e; text-decoration: line-through; opacity: 0.8; }

/* ------------------------------- The hint -------------------------------- */

#hint {
  grid-area: hint;
  text-align: center;
  font-size: clamp(13px, 3.3vw, 19px);
  font-weight: 700;
  color: #8a4a2a;
  min-height: 1.2em;
  padding: 0 4px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --------------------------- The mixed-up letters ------------------------- */

#jumble-wrap {
  grid-area: jumble;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 0;
  min-width: 0;
}

/* --n is the number of letters, set by the game each time a word appears.
   minmax(0, --tile-max) is the trick that stops the row ever wrapping: tiles
   are at most --tile-max wide, but shrink freely when the word is long. */
#jumble {
  --tile-max: min(clamp(44px, 13vw, 96px), 20vh);
  display: grid;
  grid-template-columns: repeat(var(--n, 4), minmax(0, var(--tile-max)));
  justify-content: center;
  gap: clamp(4px, 1.4vw, 12px);
  max-width: 100%;
}

#jumble.locked { pointer-events: none; }
#jumble.locked .jtile { filter: saturate(0.7) brightness(0.97); }

.jtile {
  aspect-ratio: 3 / 4;
  min-width: 0;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: inherit;
  font-size: min(clamp(22px, 7.5vw, 52px), 9vh);
  font-weight: 800;
  color: #5a3020;
  background: linear-gradient(180deg, #fff, #fff3e2);
  border: 3px solid #f0a93c;
  border-radius: 14px;
  box-shadow: 0 5px 0 rgba(190, 120, 40, 0.3), 0 8px 14px rgba(0, 0, 0, 0.12);
  cursor: pointer;
  touch-action: manipulation;
  will-change: transform;
}

.jtile.in { animation: jtileIn 0.34s cubic-bezier(0.34, 1.56, 0.64, 1) backwards; }
@keyframes jtileIn {
  from { transform: translateY(-26px) scale(0.4); opacity: 0; }
}

/* The letter you've picked up, waiting for its partner. No transform here —
   the swap animation owns that — so it glows instead of lifting. */
.jtile.picked {
  border-color: #ff9500;
  background: #fff6de;
  color: #b8341f;
  animation: pickGlow 0.9s ease-in-out infinite;
}

@keyframes pickGlow {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255, 149, 0, 0.6), 0 5px 0 rgba(190, 120, 40, 0.3); }
  50% { box-shadow: 0 0 0 12px rgba(255, 149, 0, 0), 0 5px 0 rgba(190, 120, 40, 0.3); }
}

/* Mid-swap, so it passes over its neighbors instead of under them. */
.jtile.flying { position: relative; z-index: 5; }

.jtile.solved {
  border-color: #63c76e;
  background: #eaffe9;
  color: #2f9d4e;
  animation: solvePop 0.4s cubic-bezier(0.34, 1.8, 0.64, 1);
}

@keyframes solvePop {
  0% { box-shadow: 0 0 0 0 rgba(99, 199, 110, 0.7), 0 5px 0 rgba(90, 170, 100, 0.3); }
  100% { box-shadow: 0 0 0 16px rgba(99, 199, 110, 0), 0 5px 0 rgba(90, 170, 100, 0.3); }
}

/* -------------------- The spaghetti, the goblin, the fork ------------------ */

#pasta {
  position: fixed;
  inset: 0;
  z-index: 30;
  pointer-events: none;
}

#noodles {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.sauce-dot { animation: saucePop 0.3s cubic-bezier(0.34, 1.7, 0.64, 1) backwards; }
@keyframes saucePop { from { transform: scale(0); opacity: 0; } }

/* The bowl is the plain white 🥣 — sauce splatter shows up best on white. */
#bowl {
  position: absolute;
  left: 50%;
  bottom: calc(4px + env(safe-area-inset-bottom, 0px));
  font-size: clamp(48px, 15vw, 118px);
  line-height: 1;
  opacity: 0;
  transform: translateX(-50%) scale(0.2);
  filter: drop-shadow(0 6px 6px rgba(0, 0, 0, 0.28));
}

#bowl.show {
  opacity: 1;
  transform: translateX(-50%) scale(1);
  animation: bowlIn 0.34s cubic-bezier(0.34, 1.56, 0.64, 1);
}

@keyframes bowlIn {
  0% { transform: translateX(-50%) scale(0.2); opacity: 0; }
  60% { transform: translateX(-50%) scale(1.18); opacity: 1; }
  100% { transform: translateX(-50%) scale(1); opacity: 1; }
}

/* Whacked by the fork — which is exactly why the spaghetti comes out. */
#bowl.show.kick { animation: bowlKick 0.62s ease; }
@keyframes bowlKick {
  0%, 100% { transform: translateX(-50%) rotate(0deg); }
  25% { transform: translate(-58%, -8px) rotate(-22deg); }
  55% { transform: translate(-44%, 2px) rotate(14deg); }
  80% { transform: translateX(-52%) rotate(-6deg); }
}

/* --gob-x / --fork-x / --fork-drop are all set on #pasta by pasta.js from the
   bowl's live position, so the stab lands right wherever the bowl ended up. */
#goblin {
  position: absolute;
  left: 50%;
  top: 0;
  font-size: clamp(46px, 14vw, 110px);
  line-height: 1;
  opacity: 0;
  transform: translate(calc(var(--gob-x, 0px) - 50%), -170%);
  filter: drop-shadow(0 6px 6px rgba(0, 0, 0, 0.3));
}

#goblin.peek { opacity: 1; animation: goblinPeek 0.48s cubic-bezier(0.34, 1.4, 0.64, 1) forwards; }
@keyframes goblinPeek {
  from { transform: translate(calc(var(--gob-x, 0px) - 50%), -170%) rotate(0deg); }
  to { transform: translate(calc(var(--gob-x, 0px) - 50%), -14%) rotate(9deg); }
}

/* He missed, and he is NOT happy about it. */
#goblin.mad { opacity: 1; animation: goblinMad 0.64s ease forwards; }
@keyframes goblinMad {
  0%, 100% { transform: translate(calc(var(--gob-x, 0px) - 50%), -14%) rotate(9deg) scale(1); }
  20% { transform: translate(calc(var(--gob-x, 0px) - 50%), -20%) rotate(-11deg) scale(1.12); }
  50% { transform: translate(calc(var(--gob-x, 0px) - 50%), -10%) rotate(15deg) scale(1.14); }
  75% { transform: translate(calc(var(--gob-x, 0px) - 50%), -20%) rotate(-8deg) scale(1.08); }
}

#goblin.leave { opacity: 1; animation: goblinLeave 0.6s ease forwards; }
@keyframes goblinLeave {
  from { transform: translate(calc(var(--gob-x, 0px) - 50%), -14%) rotate(9deg); }
  to { transform: translate(calc(var(--gob-x, 0px) - 50%), -180%) rotate(-24deg); }
}

/* The fork comes down beside the bowl on purpose — that offset IS the miss. */
#fork {
  position: absolute;
  left: 50%;
  top: 0;
  font-size: clamp(40px, 12vw, 96px);
  line-height: 1;
  opacity: 0;
  transform: translate(calc(var(--fork-x, 60px) - 50%), -180%) rotate(184deg) scale(1.5);
  filter: drop-shadow(0 8px 8px rgba(0, 0, 0, 0.3));
}

#fork.show { opacity: 1; }
#fork.stab { animation: forkStab var(--fork-ms, 1100ms) cubic-bezier(0.45, 0, 0.55, 1); }

@keyframes forkStab {
  0% { transform: translate(calc(var(--fork-x, 60px) - 50%), -180%) rotate(184deg) scale(1.5); }
  40% { transform: translate(calc(var(--fork-x, 60px) - 50%), var(--fork-drop, 200px)) rotate(178deg) scale(1.5); }
  52% { transform: translate(calc(var(--fork-x, 60px) - 50%), calc(var(--fork-drop, 200px) + 16px)) rotate(166deg) scale(1.5); }
  70% { transform: translate(calc(var(--fork-x, 60px) - 50%), calc(var(--fork-drop, 200px) - 14px)) rotate(172deg) scale(1.5); }
  100% { transform: translate(calc(var(--fork-x, 60px) - 50%), -180%) rotate(190deg) scale(1.5); }
}

/* The hands ride on their own layer, OUTSIDE the board, above even the letters
   they're carrying (.fly-tile is z-index 70). A hand tucked inside the board
   can never paint in front of a letter pinned to the page — which is why these
   used to be invisible. */
#hands {
  position: fixed;
  inset: 0;
  z-index: 72;
  pointer-events: none;
}

/* A robot hand sprouting out of a noodle, right where it touched a letter.
   Deliberately BIG — wider than a letter tile — so you can't miss it closing
   around the letter. This is the joke of the whole game.

   Note the resting transform is the base style, not the end of an animation:
   the hand is authored VISIBLE, so switching its animation off mid-carry (which
   ui.js has to do to move it) leaves it sitting there rather than vanishing. */
.robo-hand {
  position: fixed;
  font-size: clamp(56px, 18vw, 118px);
  line-height: 1;
  pointer-events: none;
  transform: translate(-50%, -55%);
  animation: handPop 0.32s cubic-bezier(0.34, 1.7, 0.64, 1);
  /* A white halo, because 🦾 is gray and so is half the spaghetti. */
  filter:
    drop-shadow(0 0 9px #fff)
    drop-shadow(0 0 18px rgba(255, 255, 255, 0.85))
    drop-shadow(0 4px 6px rgba(0, 0, 0, 0.4));
}

@keyframes handPop {
  0% { transform: translate(-50%, -50%) scale(0) rotate(-40deg); }
  70% { transform: translate(-50%, -62%) scale(1.35) rotate(8deg); }
  100% { transform: translate(-50%, -55%) scale(1) rotate(0deg); }
}

/* The clench: it squeezes down onto the letter and shakes it. Not "forwards" —
   it settles back onto the resting transform, ready for the carry. */
.robo-hand.grip { animation: handGrip 0.42s cubic-bezier(0.34, 1.6, 0.64, 1); }

@keyframes handGrip {
  0% { transform: translate(-50%, -55%) scale(1) rotate(0deg); }
  30% { transform: translate(-50%, -48%) scale(1.22) rotate(-9deg); }
  55% { transform: translate(-50%, -57%) scale(0.9) rotate(7deg); }
  78% { transform: translate(-50%, -53%) scale(1.08) rotate(-4deg); }
  100% { transform: translate(-50%, -55%) scale(1) rotate(0deg); }
}

/* The letter reacting to being seized. */
.jtile.grabbed { animation: tileGrabbed 0.42s ease; }
@keyframes tileGrabbed {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  25% { transform: translate(-3px, 2px) rotate(-4deg); }
  60% { transform: translate(3px, -2px) rotate(4deg); }
}

/* A stolen letter in mid-air, being carried somewhere else. */
.fly-tile {
  position: fixed;
  z-index: 70;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: "Baloo 2", system-ui, sans-serif;
  font-weight: 800;
  color: #5a3020;
  background: linear-gradient(180deg, #fff, #fff3e2);
  border: 3px solid #e0402f;
  border-radius: 14px;
  box-shadow: 0 10px 22px rgba(0, 0, 0, 0.3);
  pointer-events: none;
  will-change: transform;
}

.fly-letter { font-size: min(clamp(22px, 7.5vw, 52px), 9vh); }

/* ------------------------------ The banner ------------------------------- */

#banner {
  position: fixed;
  left: 50%;
  top: 22%;
  z-index: 50;
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.4);
  padding: clamp(10px, 2.6vw, 18px) clamp(16px, 5vw, 34px);
  max-width: 92vw;
  text-align: center;
  font-size: clamp(17px, 4.6vw, 30px);
  font-weight: 800;
  color: #fff;
  background: linear-gradient(180deg, #ff7a4a, #e0402f);
  border: 4px solid #fff;
  border-radius: 22px;
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.35);
}

#banner.show {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
  animation: bannerIn 0.45s cubic-bezier(0.34, 1.56, 0.64, 1);
}

#banner.show.win { background: linear-gradient(180deg, #7be06a, #2f9d4e); }
#banner.show.speed { background: linear-gradient(180deg, #c77dff, #6a1fb0); }

@keyframes bannerIn {
  0% { transform: translate(-50%, -50%) scale(0.3) rotate(-6deg); opacity: 0; }
  60% { transform: translate(-50%, -50%) scale(1.12) rotate(2deg); opacity: 1; }
  100% { transform: translate(-50%, -50%) scale(1) rotate(0deg); opacity: 1; }
}

/* ------------------------------- FX canvas -------------------------------- */

#fx {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 40;
}

/* -------------------------------- Overlays -------------------------------- */

.overlay {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(70, 30, 20, 0.45);
  backdrop-filter: blur(3px);
  overflow-y: auto;
}

.overlay.show { display: flex; }

.card-box {
  background: #fff;
  border-radius: 28px;
  border: 6px solid #f0a93c;
  box-shadow: 0 16px 0 rgba(190, 120, 40, 0.28), 0 24px 40px rgba(0, 0, 0, 0.3);
  padding: clamp(20px, 5vw, 40px);
  max-width: 470px;
  width: 100%;
  text-align: center;
  animation: cardIn 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}

@keyframes cardIn {
  from { transform: scale(0.6) translateY(30px); opacity: 0; }
}

.card-emoji {
  font-size: clamp(46px, 12vw, 72px);
  line-height: 1;
  margin-bottom: 6px;
}

.card-box h1 {
  margin: 6px 0 12px;
  font-size: clamp(28px, 7.5vw, 46px);
  font-weight: 800;
  color: #e0402f;
  letter-spacing: 1px;
}

.card-box p {
  margin: 8px 0;
  font-size: clamp(15px, 3.6vw, 19px);
  font-weight: 500;
  color: #5a3a2a;
}

.card-box p.small { font-size: clamp(13px, 3vw, 16px); color: #8a7060; }

.card-box .new-best {
  font-weight: 800;
  color: #ff9500;
  font-size: clamp(17px, 4.2vw, 22px);
}

.big-btn {
  margin-top: 18px;
  font-family: inherit;
  font-size: clamp(19px, 4.8vw, 27px);
  font-weight: 800;
  color: #fff;
  background: linear-gradient(180deg, #ff7a4a, #e0402f);
  border: none;
  border-radius: 99px;
  padding: 14px 32px;
  cursor: pointer;
  box-shadow: 0 6px 0 #a82a1c, 0 10px 18px rgba(0, 0, 0, 0.25);
  transition: transform 0.1s ease, box-shadow 0.1s ease;
  touch-action: manipulation;
}

.big-btn:active {
  transform: translateY(4px);
  box-shadow: 0 2px 0 #a82a1c, 0 4px 10px rgba(0, 0, 0, 0.25);
}

.change-btn {
  display: block;
  margin: 14px auto 0;
  font-family: inherit;
  font-size: clamp(14px, 3.4vw, 18px);
  font-weight: 700;
  color: #8a4a2a;
  background: #fff3e2;
  border: 3px solid #f0c98c;
  border-radius: 99px;
  padding: 8px 22px;
  cursor: pointer;
  touch-action: manipulation;
}

.change-btn:active { transform: translateY(2px); }

/* ============================ Wide screens ================================ */

/* Landscape phones, tablets and desktop: the list becomes a rail down the left
   as six stacked rows, and the letters get the whole rest of the screen.
   min-aspect-ratio rather than orientation, so a squarish window keeps the
   safer stacked layout. */
@media (min-aspect-ratio: 1 / 1) {
  #stage {
    grid-template-columns: clamp(96px, 24vw, 210px) 1fr;
    grid-template-rows: auto 1fr;
    grid-template-areas:
      "list hint"
      "list jumble";
    column-gap: clamp(8px, 2vw, 20px);
  }

  #checklist { grid-template-columns: minmax(0, 1fr); }
  #list-title { text-align: left; }
  .chk { justify-content: flex-start; }
}

/* ============================== Small phones ============================== */

@media (max-width: 430px) {
  #hud { gap: 5px; }
  #timer-num { font-size: clamp(24px, 6.5vw, 34px); }
  .mini-bar { width: clamp(52px, 15vw, 78px); height: 8px; }
  #speed-badge { height: 13px; line-height: 13px; font-size: 10px; }
  .stat-label { font-size: 11px; }
  /* Four stats plus two buttons is a lot of phone. The goblin's chip loses its
     word and keeps its number — 👺 3 ⭐ says everything it needs to. */
  .threat-word { display: none; }
  #say-btn, #quit-btn { width: 40px; height: 40px; font-size: 18px; border-width: 2px; }
  .chk-word { font-size: 12px; letter-spacing: 0.3px; }
  #hint { font-size: 13px; }
  #jumble { --tile-max: min(clamp(38px, 12.5vw, 70px), 19vh); }
}

/* Phone held sideways: there's plenty of width and almost no height, so the
   letters have to be sized by height instead, and the furniture gives way. */
@media (max-height: 560px) {
  #hud {
    padding-top: calc(4px + env(safe-area-inset-top, 0px));
    padding-bottom: 4px;
    gap: 8px;
  }
  #timer-num { font-size: 26px; }
  .mini-bar { height: 7px; margin-top: 2px; }
  #speed-badge { height: 12px; line-height: 12px; font-size: 10px; margin-top: 1px; }
  .threat-word { display: none; }
  #list-title { display: none; }
  .chk { padding: 2px 6px; border-width: 2px; border-radius: 9px; }
  .chk-word { font-size: 12px; }
  #hint { font-size: 12px; }
  #jumble { --tile-max: min(clamp(38px, 11vh, 78px), 13vw); }
  .jtile { font-size: min(6.5vh, 6vw); border-radius: 10px; }
  #bowl { font-size: clamp(38px, 13vh, 74px); }
  #goblin { font-size: clamp(36px, 12vh, 70px); }
  #fork { font-size: clamp(32px, 11vh, 64px); }
  /* Sideways there's no height to spare, so the hands go by height too — still
     bigger than a letter tile, which is the only thing that really matters. */
  .robo-hand { font-size: clamp(44px, 17vh, 100px); }
}

/* ========================= Gentler on the eyes ============================ */

@media (prefers-reduced-motion: reduce) {
  #timer-num.low,
  .jtile.picked,
  .chk,
  .sauce-dot,
  #banner.show,
  .card-box { animation: none; }
  #game.shake { animation: none; }
  .mini-bar > div { transition: none; }
  /* Safe to switch off: a .robo-hand's resting look is its own base style, not
     the tail end of an animation, so it still sits there in plain sight. */
  .robo-hand,
  .robo-hand.grip,
  .jtile.grabbed { animation: none; }
}
