:root {
  --ink: #1d2a3a;
  --ink-soft: #4b5b70;
  --water: #3aa8ff;
  --water-deep: #1c7fe0;
  --water-light: #bfe6ff;
  --accent: #ff5a36;
  --good: #1fb46a;
  --warn: #ffb020;
  --danger: #ff4d3d;
  --panel: #fffaf2;
  --hud-bg: #2a6fb0;
  --font: ui-rounded, 'Nunito', 'Varela Round', 'Arial Rounded MT Bold', 'Roboto', system-ui, sans-serif;
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
}

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

html, body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
  background: #1b4f82;
  font-family: var(--font);
  color: var(--ink);
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}

button { font-family: inherit; }

#app {
  position: fixed;
  inset: 0;
  height: 100dvh;
  width: 100%;
  max-width: 520px;
  margin: 0 auto;
  display: grid;
  grid-template-rows: minmax(0, 8fr) minmax(0, 23fr) minmax(0, 2fr) minmax(0, 23fr) minmax(0, 15fr) minmax(0, 23fr);
  touch-action: none;
  overflow: hidden;
  background: #f4ead9;
  padding-bottom: var(--safe-bottom);
}

/* ---------- HUD ---------- */
/* Top bar: the readouts (water counter, clock) sit in dark translucent pills like the source chips on the cards;
   pause is the one lighter, round control. All three share one centre line. */
#hud {
  --hud-pill: rgba(8, 32, 64, 0.34);
  --hud-pill-edge: inset 0 2px 3px rgba(0, 0, 0, 0.28), inset 0 -1px 0 rgba(255, 255, 255, 0.12);
  position: relative;
  z-index: 30;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 8px;
  padding: var(--safe-top) 12px 0;
  background: linear-gradient(#3787d2, #2c73b8 55%, #2767a6);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22), inset 0 -2px 0 rgba(10, 40, 80, 0.35), 0 3px 0 rgba(0, 0, 0, 0.14);
  color: #fff;
}
.hud-saved {
  justify-self: start;
  display: flex;
  align-items: baseline;
  gap: 4px;
  padding: 5px 10px 5px 8px;
  border-radius: 999px;
  background: var(--hud-pill);
  box-shadow: var(--hud-pill-edge);
  font-weight: 900;
  font-size: clamp(18px, 5.1vw, 23px);
  line-height: 1.1;
  transform-origin: left center;
  text-shadow: 0 2px 0 rgba(0, 0, 0, 0.2);
}
.hud-saved small { font-size: 0.55em; opacity: 0.85; }
.drop-icon { width: 1em; height: 1em; align-self: center; fill: #8fd3ff; filter: drop-shadow(0 1px 0 rgba(0, 0, 0, 0.25)); }
.drop-shine { fill: #fff; opacity: 0.8; }
.hud-saved.bump { animation: bumpSmall 180ms ease-out; }
.hud-saved.milestone { animation: bumpBig 700ms cubic-bezier(.2, 1.6, .4, 1); }
.hud-saved.milestone .drop-icon { fill: #fff; filter: drop-shadow(0 0 6px #bff); }
@keyframes bumpSmall { 50% { transform: translateY(-2px); } }
@keyframes bumpBig {
  /* A hop and a glow, no scaling: the counter never grows into the timer. */
  0%, 100% { transform: none; }
  25% { transform: translateY(-5px); color: #fff6a8; text-shadow: 0 0 10px rgba(255, 246, 168, 0.9), 0 2px 0 rgba(0, 0, 0, 0.2); }
  55% { transform: translateY(1px); }
}

/* The clock pill; from the pressure drop on, a slim water gauge runs along its bottom edge (it never moves the clock). */
#timerWrap {
  position: relative;
  padding: 4px 18px 7px;
  border-radius: 18px;
  background: var(--hud-pill);
  box-shadow: var(--hud-pill-edge);
}
#timer {
  font-weight: 900;
  font-size: clamp(27px, 7.4vw, 33px);
  letter-spacing: 1px;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 3px 0 rgba(0, 0, 0, 0.22);
}
#pressure {
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 3px;
  height: 4px;
  border-radius: 2px;
  background: rgba(0, 0, 0, 0.35);
  overflow: hidden;
  opacity: 0;
  transform: scaleX(0.3);
  transition: opacity 250ms, transform 350ms cubic-bezier(.2, 1.4, .4, 1);
}
#pressureFill {
  height: 100%;
  width: 100%;
  border-radius: 2px;
  background: linear-gradient(90deg, #ff4d3d, #ffb020 60%, #6fd3ff);
  transform-origin: left center;
}
.collapse #pressure { opacity: 1; transform: none; }
.collapse #timer { color: #ffe08a; }
.collapse.final #timer { animation: timerPulse 1s ease-in-out infinite; }
@keyframes timerPulse { 50% { transform: scale(1.08); color: #ffb3a8; } }

.hud-pause {
  justify-self: end;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 0;
  background: rgba(255, 255, 255, 0.2);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  box-shadow: inset 0 -3px 0 rgba(0, 0, 0, 0.15);
}
.hud-pause span { width: 6px; height: 16px; border-radius: 3px; background: #fff; box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2); }
.hud-pause:active { transform: translateY(1px); box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); }

/* ---------- Rooms / board ---------- */
.row { position: relative; display: grid; grid-template-columns: 1fr 1fr; }
.room.bathroom {
  background:
    linear-gradient(transparent 84%, #d9e7ee 84%, #c9dbe4),
    repeating-linear-gradient(90deg, transparent 0 35px, rgba(255, 255, 255, 0.35) 35px 37px),
    repeating-linear-gradient(transparent 0 35px, rgba(255, 255, 255, 0.35) 35px 37px),
    linear-gradient(#bfe3ef, #a9d6e6);
}
.room.kitchen {
  background:
    linear-gradient(transparent 84%, #d58c5c 84%, #c67a4b),
    linear-gradient(#fbeed8, #f5e2c3);
}
.room .cell + .cell { box-shadow: inset 2px 0 0 rgba(255, 255, 255, 0.45), inset 3px 0 0 rgba(0, 0, 0, 0.05); }
.level-break {
  position: relative;
  z-index: 2;
  background: linear-gradient(#e3d3bb, #cdb898 55%, #a88d68);
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.15), 0 -1px 0 rgba(0, 0, 0, 0.12);
}
.outside {
  grid-template-columns: 64% 36%;
  background:
    /* patio floor */
    linear-gradient(transparent 80%, #c3bdb2 80%, #aca69b),
    /* house exterior wall on the left (where the spigot mounts) */
    linear-gradient(90deg, #f1dcbb 0 36%, #e2c9a3 36% 37%, transparent 37%),
    /* low block wall */
    linear-gradient(transparent 44%, #efe6d6 44%, #e6dbc7 80%),
    /* sky */
    linear-gradient(#9fd8f5, #d6f0fb 44%);
}
.outside::before {
  /* block-wall mortar lines + a small plant tuft for the patio */
  content: '';
  position: absolute;
  left: 37%; right: 0; top: 44%; height: 36%;
  background:
    repeating-linear-gradient(transparent 0 11px, rgba(150, 125, 95, 0.22) 11px 12px),
    repeating-linear-gradient(90deg, transparent 0 34px, rgba(150, 125, 95, 0.18) 34px 35px);
  box-shadow: 0 -3px 0 #d8ccb6;
  pointer-events: none;
}
.outside::after {
  content: '';
  position: absolute;
  left: 38%; top: 30%;
  width: 26px; height: 20px;
  border-radius: 50% 50% 40% 40%;
  background: radial-gradient(circle at 30% 60%, #5cbf55 0 6px, transparent 7px),
    radial-gradient(circle at 60% 40%, #4aad44 0 7px, transparent 8px),
    radial-gradient(circle at 80% 70%, #63c85c 0 6px, transparent 7px);
  pointer-events: none;
}

.phase-prestart #ahora:not(.empty) #ahoraCont { animation: invite 1.5s ease-in-out infinite; }
@keyframes invite {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-7px) rotate(-1.5deg); }
}



.cell {
  position: relative;
  overflow: visible;
  touch-action: none;
}
.cell .fixture {
  position: absolute;
  pointer-events: none;
  transform-origin: 50% 20%;
  filter: drop-shadow(0 3px 2px rgba(0, 0, 0, 0.12));
}
.cell .fixture.react { animation: fixtureReact 260ms ease-out; }
.cell .fixture.sputter { animation: fixtureSputter 380ms steps(2) 4; }
/* Full-cell scene art: it is the room, so no cutout shadow and no squash on tap. */
.cell .fixture.scene { filter: none; animation: none; }
@keyframes fixtureReact { 35% { transform: scale(1.04, 0.97) translateY(1px); } 70% { transform: scale(0.99, 1.02); } }
@keyframes fixtureSputter { 0% { transform: translate(-1.5px, 0) rotate(-0.8deg); } 100% { transform: translate(1.5px, 0) rotate(0.8deg); } }

.cell .slot {
  position: absolute;
  bottom: 2%;
  width: 38%;
  height: 9%;
  transform: translateX(-50%);
  border-radius: 50%;
  border: 2px dashed rgba(29, 42, 58, 0.22);
  background: rgba(255, 255, 255, 0.18);
  transition: all 150ms;
  pointer-events: none;
}
.cell.occupied .slot { opacity: 0; }
.cell.compatible .slot {
  border: 3px solid #fff;
  background: rgba(120, 220, 255, 0.35);
  box-shadow: 0 0 14px 4px rgba(90, 200, 255, 0.7);
  animation: slotPulse 900ms ease-in-out infinite;
}
.cell.compatible::after {
  content: '';
  position: absolute;
  inset: 4px;
  border-radius: 16px;
  border: 3px solid rgba(255, 255, 255, 0.85);
  box-shadow: 0 0 12px rgba(80, 190, 255, 0.8), inset 0 0 18px rgba(80, 190, 255, 0.35);
  pointer-events: none;
}
.cell.snap::after { border-color: #fff; background: rgba(120, 220, 255, 0.18); }
@keyframes slotPulse { 50% { transform: translateX(-50%) scale(1.12); } }

/* Source indicator: open/closed icon + actual-flow bar + small number */
.ind {
  position: absolute;
  z-index: 6;
  top: 5px;
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 3px 7px 3px 4px;
  border-radius: 12px;
  background: rgba(29, 42, 58, 0.72);
  color: #fff;
  font-size: 10px;
  font-weight: 800;
  pointer-events: none;
  transition: background 150ms;
}
.ind .ind-icon { width: 16px; height: 16px; }
.ind .ind-icon .tap { fill: #cfd8e3; }
.ind .ind-icon .flow { fill: #6fd3ff; display: none; }
.ind .ind-icon .slash { stroke: #ff7a6b; stroke-width: 2.6; stroke-linecap: round; }
.ind.open { background: rgba(21, 110, 190, 0.9); }
.ind.open .ind-icon .flow { display: block; }
.ind.open .ind-icon .slash { display: none; }
.ind .bar { width: 34px; height: 6px; border-radius: 3px; background: rgba(255, 255, 255, 0.22); overflow: hidden; }
.ind .bar i { display: block; height: 100%; width: 0; background: linear-gradient(90deg, #6fd3ff, #d9f4ff); border-radius: 3px; }
.ind .num { min-width: 20px; font-variant-numeric: tabular-nums; opacity: 0.85; }
.ind.dry { background: rgba(120, 60, 40, 0.85); }

/* Placed containers */
.placed {
  position: absolute;
  z-index: 4;
  transform-origin: 50% 100%;
  touch-action: none;
}
.placed img, .stage-obj img, .drag-ghost img, .pile-item img, .flyer img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  pointer-events: none;
  -webkit-user-drag: none;
}
.placed.land { animation: landIn 260ms cubic-bezier(.2, 1.5, .4, 1); }
@keyframes landIn { 0% { transform: scale(1.12, 0.84); } 60% { transform: scale(0.96, 1.05); } 100% { transform: none; } }
.placed.prestart { filter: drop-shadow(0 0 6px rgba(255, 255, 255, 0.9)); }

.water-mask {
  position: absolute;
  inset: 0;
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  pointer-events: none;
}
.water-mask .water {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 0;
  background: linear-gradient(rgb(150 220 255 / calc(var(--wa, .7) + .2)), rgb(40 150 245 / var(--wa, .7)) 22%, rgb(20 110 220 / var(--wa, .7)));
  box-shadow: 0 -2px 6px rgba(120, 210, 255, 0.9);
  border-top: 4px solid #e8f7ff;
}
.fillbar {
  position: absolute;
  right: -15px;
  bottom: 6px;
  width: 12px;
  height: calc(100% - 16px);
  min-height: 34px;
  border-radius: 6px;
  background: rgba(29, 42, 58, 0.35);
  box-shadow: 0 0 0 1.5px rgba(255, 255, 255, 0.75);
  overflow: hidden;
}
.fillbar i { position: absolute; left: 0; right: 0; bottom: 0; background: linear-gradient(#9fe0ff, #2a90f0); border-radius: 4px; }
.fillpct {
  position: absolute;
  right: -24px;
  top: -10px;
  font-size: 14px;
  font-weight: 900;
  color: var(--ink);
  background: rgba(255, 255, 255, 0.92);
  padding: 1px 6px;
  border-radius: 8px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
  font-variant-numeric: tabular-nums;
}
.fulltag {
  position: absolute;
  left: 50%;
  top: 42%;
  transform: translateX(-50%) rotate(-6deg);
  font-size: var(--tag-size, 13px);
  font-weight: 900;
  color: #fff;
  background: var(--danger);
  padding: 1px 7px;
  border-radius: 8px;
  box-shadow: 0 2px 0 rgba(0, 0, 0, 0.25);
  display: none;
  letter-spacing: 0.5px;
}
.badge.warn1 .fillbar { box-shadow: 0 0 0 1.5px #fff, 0 0 8px 2px rgba(255, 200, 60, 0.9); }
.badge.warn1 .fillbar i { background: linear-gradient(#ffe08a, #ffb020); }
.placed.warn2 { animation: nearFull 420ms ease-in-out infinite; }
.badge.warn2 .fillpct { background: #ffb020; color: #fff; }
.placed.urgent { animation-duration: 260ms; }
.badge.urgent .fillbar { box-shadow: 0 0 0 2px #fff, 0 0 12px 4px rgba(255, 80, 60, 0.95); }
.badge.full .fulltag { display: block; animation: fullPop 500ms ease-in-out infinite alternate; }
.badge.full .fillbar i { background: linear-gradient(#ff9a8a, #ff4d3d); }
.badge.full .fillpct { display: none; }
.placed.overflow { animation: overflowWobble 300ms ease-in-out infinite; }
@keyframes nearFull { 50% { transform: scale(1.04, 0.97) rotate(-1.2deg); } }
@keyframes overflowWobble { 25% { transform: rotate(-2deg) scale(1.02, 0.98); } 75% { transform: rotate(2deg) scale(0.98, 1.02); } }
@keyframes fullPop { to { transform: translateX(-50%) rotate(4deg) scale(1.1); } }

/* ---------- Stockpile ---------- */
#stockpile { position: absolute; right: 0; top: 0; width: 36%; height: 100%; pointer-events: none; z-index: 3; overflow: hidden; }
#pileBase {
  /* small wooden pallet: the stockpile exists from the start */
  position: absolute;
  left: 10%; right: 6%; bottom: 7%;
  height: 7%;
  border-radius: 3px;
  background: repeating-linear-gradient(90deg, #c8955c 0 18%, #a8733e 18% 21%);
  box-shadow: 0 3px 0 #7d5329, 0 5px 4px rgba(0, 0, 0, 0.18);
}
#pileMound {
  position: absolute;
  left: 8%; right: 4%; bottom: 14%;
  height: 0;
  border-radius: 50% 50% 8px 8px / 100% 100% 8px 8px;
  background: linear-gradient(#8fb6cf, #6f94ad);
  opacity: 0.55;
  transition: height 400ms ease-out;
}
/* Own stacking layer, so a tall pile passes behind the "Guardado" label instead of over it. */
#pileItems { position: absolute; inset: 0; z-index: 1; }
.pile-item { position: absolute; transform-origin: 50% 100%; clip-path: inset(0 0 9% 0); }
.pile-item.old { filter: saturate(0.6) brightness(0.9); }
.pile-item.thunk { animation: pileThunk 420ms cubic-bezier(.2, 1.4, .4, 1); }
.pile-item.clean { animation: pileClean 620ms cubic-bezier(.2, 1.6, .35, 1); }
@keyframes pileThunk {
  0% { transform: translateY(-6px) scale(1.05, 0.95); }
  30% { transform: translateY(0) scale(1.18, 0.78); }
  60% { transform: translateY(-3px) scale(0.94, 1.07); }
  100% { transform: none; }
}
@keyframes pileClean {
  0% { transform: translateY(-4px) scale(1.1); }
  25% { transform: translateY(0) scale(1.3, 0.7); }
  55% { transform: translateY(-6px) scale(0.9, 1.15); }
  80% { transform: scale(1.04, 0.97); }
  100% { transform: none; }
}
#stockpile.pile-shake { animation: pileShake 200ms ease-out; }
@keyframes pileShake { 40% { transform: translateY(2px); } }

/* ---------- Staging ---------- */
#staging {
  position: relative;
  z-index: 10;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr) minmax(0, 1fr); /* content (the logo) never widens a column */
  grid-template-rows: minmax(0, 1fr);
  align-items: center;
  min-height: 0;
  padding: 6px 10px 8px;
  background: linear-gradient(#e9dcc6, #dccbb0);
  box-shadow: inset 0 3px 0 rgba(0, 0, 0, 0.08);
}
.stage-slot { position: relative; height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; }
#ahora { grid-column: 2; }
#proximo { grid-column: 3; height: 74%; align-self: end; margin-bottom: 6px; justify-self: center; width: 84%;
  background: rgba(255, 255, 255, 0.45); border-radius: 16px; box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.6); }
.stage-label {
  position: absolute;
  top: 2px;
  font-size: 12px;
  font-weight: 900;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--ink-soft);
}
#ahora .stage-label { font-size: 14px; color: var(--ink); }
.stage-base {
  position: absolute;
  bottom: 38px;
  width: 78%;
  height: 20px;
  border-radius: 50%;
  background: radial-gradient(rgba(0, 0, 0, 0.18), rgba(0, 0, 0, 0.04) 70%, transparent 72%);
}
.stage-obj { position: relative; width: 100%; height: 60%; min-height: 0; flex: none; margin-bottom: 44px; display: flex; justify-content: center; align-items: flex-end; }
.stage-obj .cont { max-width: 100%; max-height: 100%; flex: none; }
#ahoraObj .cont { touch-action: none; cursor: grab; transition: transform 160ms; }
#ahoraObj .cont.enter { animation: stageEnter 320ms cubic-bezier(.2, 1.5, .4, 1); }
@keyframes stageEnter { 0% { transform: translateX(60%) scale(0.55); opacity: 0.5; } 100% { transform: none; opacity: 1; } }
#proximoObj { height: 50%; margin-bottom: 28px; }
#proximoObj .cont.enter { animation: prevEnter 300ms ease-out; }
@keyframes prevEnter { 0% { transform: translateY(20px) scale(0.6); opacity: 0; } }
.stage-info {
  position: absolute;
  bottom: 4px;
  display: flex;
  align-items: center;
  gap: 5px;
  font-weight: 900;
  font-size: 15px;
  white-space: nowrap;
}
.stage-info .cap { background: var(--ink); color: #fff; border-radius: 9px; padding: 1px 7px; font-size: 14px; }
#proximoInfo { font-size: 12px; }
#proximoInfo .cap { font-size: 12px; background: var(--ink-soft); }
.info-stack { display: flex; flex-direction: column; align-items: center; gap: 3px; }
.info-line { display: flex; gap: 5px; align-items: center; }
.compat { display: flex; gap: 2px; }
#ahora.empty .stage-info { opacity: 0.35; }

/* The Chorritos wordmark (tester's logo art). */

.prompt {
  position: absolute;
  z-index: 25;
  left: 50%;
  transform: translate(-50%, -50%);
  padding: 7px 14px;
  border-radius: 20px;
  background: rgba(29, 42, 58, 0.85);
  color: #fff;
  font-weight: 900;
  font-size: 14px;
  white-space: nowrap;
  pointer-events: none;
  box-shadow: 0 4px 0 rgba(0, 0, 0, 0.15);
  animation: promptBob 1.6s ease-in-out infinite;
}
#app:not(.phase-prestart) .prompt { display: none; }
@keyframes promptBob { 50% { transform: translate(-50%, -58%); } }

/* ---------- Effects ---------- */
#fx { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 8; pointer-events: none; }
#badges { position: absolute; inset: 0; z-index: 9; pointer-events: none; }
.badge { position: absolute; }
.badge[hidden] { display: none; }
.ind.tr { transform: translateX(-100%); }
#fxLayer { position: absolute; inset: 0; z-index: 12; pointer-events: none; overflow: hidden; }
#dragLayer { position: absolute; inset: 0; z-index: 40; pointer-events: none; }
.drag-ghost { position: absolute; transform-origin: 50% 80%; filter: drop-shadow(0 10px 8px rgba(0, 0, 0, 0.3)); transition: transform 90ms; }
.drag-ghost.snap { transform: scale(1.1); filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.95)) drop-shadow(0 10px 8px rgba(0, 0, 0, 0.3)); }
.flyer { position: absolute; left: 0; top: 0; transform-origin: 50% 50%; }

/* Live water-loss chip under each source's flow indicator: green "✓ Sin pérdida" or red "−X gal/min". */
.loss {
  position: absolute;
  z-index: 6;
  padding: 2px 8px;
  border-radius: 10px;
  font-size: 11px;
  font-weight: 900;
  color: #fff;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  background: rgba(23, 150, 85, 0.9);
  box-shadow: 0 2px 0 rgba(0, 0, 0, 0.2);
  pointer-events: none;
  opacity: 0;
  transform: scale(0.8);
  transform-origin: left center;
  transition: opacity 160ms, transform 160ms;
}
.loss.tr { transform: translateX(-100%) scale(0.8); transform-origin: right center; }
.loss.show { opacity: 1; transform: scale(1); }
.loss.tr.show { transform: translateX(-100%) scale(1); }
.loss.bad { background: rgba(226, 64, 40, 0.94); }
.loss.severe { animation: lossPulse 700ms ease-in-out infinite; } /* same red and size as .bad; heavy waste only adds the pulse */
@keyframes lossPulse { 50% { box-shadow: 0 2px 0 rgba(0, 0, 0, 0.2), 0 0 10px 2px rgba(255, 70, 50, 0.8); } }
.ring {
  position: absolute;
  width: 20px; height: 20px;
  margin: -10px 0 0 -10px;
  border-radius: 50%;
  border: 4px solid #fff;
  box-shadow: 0 0 10px rgba(255, 240, 140, 0.9);
  animation: ringPop 520ms ease-out forwards;
}
@keyframes ringPop { to { transform: scale(4.2); opacity: 0; border-width: 1px; } }
.spark {
  position: absolute;
  width: 8px; height: 8px;
  margin: -4px 0 0 -4px;
  background: #fff6a8;
  clip-path: polygon(50% 0, 62% 38%, 100% 50%, 62% 62%, 50% 100%, 38% 62%, 0 50%, 38% 38%);
  animation: spark 600ms ease-out forwards;
}
@keyframes spark { to { transform: translate(var(--dx), var(--dy)) scale(0.2) rotate(90deg); opacity: 0; } }
/* "¡100 gal!": a gold badge that drops out from under the counter pill. It passes over the top-left card's chips
   for a second, so it is a solid pill (reads as a notification, never as text colliding with a chip). */
.milestone-flash {
  position: absolute;
  left: 14px;
  top: calc(100% + 6px);
  z-index: 31;
  pointer-events: none;
  white-space: nowrap;
  padding: 4px 13px 5px;
  border-radius: 999px;
  font-weight: 900;
  font-size: 17px;
  color: #5a3100;
  background: linear-gradient(#ffe68a, #f6b425);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7), 0 3px 0 rgba(130, 75, 0, 0.5), 0 6px 14px rgba(0, 0, 0, 0.28);
  animation: milestoneFlash 1100ms ease-out forwards;
}
@keyframes milestoneFlash {
  0% { transform: translateY(8px) scale(0.4) rotate(-8deg); opacity: 0; }
  18% { transform: translateY(0) scale(1.25) rotate(-4deg); opacity: 1; }
  70% { transform: translateY(-2px) scale(1) rotate(-4deg); opacity: 1; }
  100% { transform: translateY(-12px) scale(0.95) rotate(-4deg); opacity: 0; }
}

.banner {
  position: absolute;
  z-index: 35;
  left: 50%;
  top: 14%;
  transform: translate(-50%, -50%);
  font-weight: 900;
  font-size: 34px;
  color: #fff;
  white-space: nowrap;
  -webkit-text-stroke: 2px #1b4f82;
  paint-order: stroke fill;
  text-shadow: 0 4px 0 #1b4f82, 0 8px 14px rgba(0, 0, 0, 0.25);
  pointer-events: none;
  opacity: 0;
}
.banner.arrival { color: #dff5ff; animation: bannerIn 1150ms cubic-bezier(.2, 1.4, .4, 1) forwards; }
.banner.collapse {
  color: #ffe08a;
  -webkit-text-stroke-color: #8a2a12;
  text-shadow: 0 4px 0 #8a2a12, 0 8px 14px rgba(0, 0, 0, 0.3);
  animation: bannerIn 1900ms cubic-bezier(.2, 1.4, .4, 1) forwards;
  font-size: 30px;
}
/* 0:00: slams in over the board and holds through the end beat (results cover it). */
.banner.end {
  top: 38%;
  color: #fff;
  -webkit-text-stroke-color: #9c1f12;
  text-shadow: 0 4px 0 #9c1f12, 0 8px 18px rgba(0, 0, 0, 0.35);
  animation: bannerSlam 520ms cubic-bezier(.2, 1.5, .4, 1) forwards;
}
/* When the results arrive the end banner lifts away first, so the two titles never cross-fade over each other. */
.banner.end.leave { animation: bannerLeave 180ms ease-in forwards; }
@keyframes bannerLeave {
  from { transform: translate(-50%, -50%) scale(1) rotate(-3deg); opacity: 1; }
  to { transform: translate(-50%, -70%) scale(0.92) rotate(-3deg); opacity: 0; }
}
@keyframes bannerSlam {
  0% { transform: translate(-50%, -50%) scale(2.2) rotate(-6deg); opacity: 0; }
  60% { transform: translate(-50%, -50%) scale(0.94) rotate(-3deg); opacity: 1; }
  100% { transform: translate(-50%, -50%) scale(1) rotate(-3deg); opacity: 1; }
}
@keyframes bannerIn {
  0% { transform: translate(-50%, -50%) scale(0.3) rotate(-8deg); opacity: 0; }
  14% { transform: translate(-50%, -50%) scale(1.15) rotate(2deg); opacity: 1; }
  24% { transform: translate(-50%, -50%) scale(1) rotate(-2deg); opacity: 1; }
  82% { transform: translate(-50%, -50%) scale(1) rotate(-2deg); opacity: 1; }
  100% { transform: translate(-50%, -80%) scale(0.9) rotate(-2deg); opacity: 0; }
}

/* ---------- Overlays ---------- */
.overlay {
  position: absolute;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(#2f7cc4, #1b4f82);
  touch-action: none;
}
.overlay[hidden] { display: none; }
.panel {
  width: min(84%, 340px);
  background: var(--panel);
  border-radius: 24px;
  padding: 22px 20px 14px;
  box-shadow: 0 8px 0 rgba(0, 0, 0, 0.18);
  text-align: center;
}
.panel h2 { margin: 0 0 14px; font-size: 30px; font-weight: 900; }
.panel h2.ask { font-size: 24px; } /* the restart question fits one line */
.menu { display: flex; flex-direction: column; gap: 10px; }
.menu[hidden] { display: none; }
.menu p { margin: 4px 0 8px; font-size: 20px; font-weight: 900; }
/* Under the Llaves button: what the chosen valve mode does (pulled up into the button's gap). */
.menu p.valve-hint { margin: -6px 4px 0; font-size: 12.5px; font-weight: 700; line-height: 1.3; color: #6b7684; }
.row-btns { display: flex; gap: 10px; }
.row-btns .btn { flex: 1; }
.btn {
  border: 0;
  border-radius: 16px;
  padding: 14px 16px;
  font-size: 19px;
  font-weight: 900;
  color: var(--ink);
  background: #e9e1d4;
  box-shadow: inset 0 -4px 0 rgba(0, 0, 0, 0.12);
}
.btn:active { transform: translateY(2px); box-shadow: inset 0 -2px 0 rgba(0, 0, 0, 0.12); }
.btn.primary { background: linear-gradient(#ff7a4d, #ff5a36); color: #fff; box-shadow: inset 0 -4px 0 rgba(0, 0, 0, 0.18); }
.btn.ghost { background: transparent; box-shadow: inset 0 0 0 2px #d8cfbf; font-size: 16px; }
.version { margin-top: 12px; font-size: 11px; font-weight: 700; color: #8b95a3; letter-spacing: 0.5px; }

/* Menus and results sit over the board: the game stays visible, blurred and dimmed behind the card (tester). */
#pause,
.results {
  background: radial-gradient(circle at 50% 40%, rgba(20, 60, 110, 0.25), rgba(8, 22, 44, 0.6));
  -webkit-backdrop-filter: blur(5px) saturate(0.85);
  backdrop-filter: blur(5px) saturate(0.85);
  animation: overlayFade 220ms ease-out;
}
.results { animation-duration: 500ms; }
@keyframes overlayFade { from { -webkit-backdrop-filter: blur(0); backdrop-filter: blur(0); opacity: 0; } }
.result-card {
  position: relative;
  width: min(88%, 360px);
  background: var(--panel);
  border-radius: 28px;
  padding: 20px 20px 14px;
  text-align: center;
  box-shadow: 0 10px 0 rgba(0, 0, 0, 0.2);
  animation: cardIn 420ms cubic-bezier(.2, 1.3, .4, 1);
}
@keyframes cardIn { from { transform: translateY(30px) scale(0.92); opacity: 0; } }
.result-brand { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.result-logo { display: block; width: min(76%, 260px); height: auto; margin: 2px auto 0; filter: drop-shadow(0 2px 3px rgba(27, 79, 130, 0.25)); }
/* The logo is on every screen a player can screenshot (tester): loading, the first tutorial card, pre-start,
   the results card, and small on the board itself, in the dark strip left of the hose card. */
.story-logo { display: block; width: min(80%, 280px); height: auto; margin: 0 auto 6px; filter: drop-shadow(0 2px 3px rgba(27, 79, 130, 0.25)); }
.loading-logo { width: min(70vw, 300px); height: auto; margin-bottom: 18px; }
.board-logo {
  position: absolute;
  left: 8px;
  top: 50%;
  width: calc(25% - 16px);
  max-width: 110px;
  height: auto;
  transform: translateY(-50%) rotate(-4deg);
  pointer-events: none;
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.35));
}
.result-motif {
  height: 38px;
  margin: 6px auto 4px;
  width: 140px;
  display: block;
  animation: motifBob 2.4s ease-in-out infinite;
}
.stats { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 6px 0 12px; }
.stat { border-radius: 18px; padding: 10px 6px; }
.stat.saved { background: #dff1ff; }
.stat.wasted { background: #ffe6df; }
.stat-label { font-size: 13px; font-weight: 900; color: var(--ink-soft); }
.stat-val { font-size: 34px; font-weight: 900; line-height: 1.1; font-variant-numeric: tabular-nums; white-space: nowrap; letter-spacing: -0.5px; }
.stat.saved .stat-val { color: #1c6fc0; }
.stat.wasted .stat-val { color: #d9432e; }
.stat-val small { font-size: 14px; }
.results .stat { opacity: 0; transform: scale(0.7); }
.results.show-stats .stat { animation: statIn 380ms cubic-bezier(.2, 1.5, .4, 1) forwards; }
.results.show-stats .stat.wasted { animation-delay: 90ms; }
@keyframes statIn { to { opacity: 1; transform: none; } }
/* Shelf of banked containers (the storage bay, summarised). */
.shelf { margin: -2px 0 12px; }
.shelf-head { font-size: 13px; font-weight: 900; color: var(--ink-soft); margin-bottom: 4px; }
.shelf-head b { display: inline-block; min-width: 20px; padding: 0 6px; border-radius: 10px; background: #1c6fc0; color: #fff; font-size: 12px; line-height: 18px; }
.shelf-row {
  display: flex;
  justify-content: center;
  align-items: flex-end;
  gap: 4px;
  padding: 6px 8px 5px;
  border-radius: 12px;
  background: linear-gradient(transparent 70%, #d9c8ad 70%, #c9b391);
  box-shadow: inset 0 -3px 0 rgba(0, 0, 0, 0.1);
}
.shelf-row img { height: 34px; width: auto; filter: drop-shadow(0 2px 1px rgba(0, 0, 0, 0.2)); opacity: 0; transform: translateY(-14px) scale(0.6); }
.results.show-stats .shelf-row img { animation: shelfDrop 360ms cubic-bezier(.2, 1.5, .4, 1) forwards; }
@keyframes shelfDrop { to { opacity: 1; transform: none; } }
.shelf-more { align-self: center; margin-left: 4px; font-size: 14px; font-weight: 900; color: var(--ink-soft); }
.quote {
  margin: 0 0 8px;
  min-height: 2.5em;
  font-size: 20px;
  font-weight: 900;
  line-height: 1.25;
  color: var(--ink);
  opacity: 0;
  transform: scale(0.85) rotate(-2deg);
}
.results.show-quote .quote { animation: quoteIn 450ms cubic-bezier(.2, 1.6, .4, 1) forwards; }
@keyframes quoteIn { to { opacity: 1; transform: none; } }
.last-run { font-size: 13px; font-weight: 800; color: #8b95a3; min-height: 1.2em; margin-bottom: 10px; }
.again { width: 100%; font-size: 24px; padding: 16px; opacity: 0.45; transform: scale(0.94); transition: opacity 250ms, transform 250ms; }
.results.show-quote .again { opacity: 1; transform: none; }

.loading {
  position: absolute;
  inset: 0;
  z-index: 60;
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  background: #f4ead9;
  font-weight: 900;
  color: var(--ink-soft);
}
.phase-loading .loading.visible { display: flex; }
.spinner { width: 22px; height: 22px; border-radius: 50%; border: 4px solid #cfe3f3; border-top-color: var(--water-deep); animation: spin 800ms linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes motifBob { 50% { transform: translateY(-3px); } }

/* Collapse escalation: warm vignette builds as supply drains (presentation only). */
#vignette {
  position: absolute;
  inset: 0;
  z-index: 11;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(ellipse at 50% 45%, transparent 55%, rgba(255, 120, 40, 0.35) 80%, rgba(200, 40, 20, 0.55));
  transition: opacity 300ms linear;
}
.final #vignette { animation: vignettePulse 1s ease-in-out infinite; }
@keyframes vignettePulse { 50% { filter: brightness(1.35); } }
#app.shudder > .row, #app.shudder > .level-break { animation: shudder 360ms ease-out; }
@keyframes shudder {
  20% { transform: translate(-3px, 1px); }
  40% { transform: translate(3px, -1px); }
  60% { transform: translate(-2px, 1px); }
  80% { transform: translate(1px, 0); }
}

/* Drag over a source that can't take the container: say why. */
.drag-ghost .nope-tag {
  display: none;
  position: absolute;
  left: 50%;
  top: -12px;
  transform: translate(-50%, -100%) rotate(-4deg);
  background: #ff4d3d;
  color: #fff;
  font-weight: 900;
  font-size: 14px;
  padding: 2px 9px;
  border-radius: 10px;
  white-space: nowrap;
  box-shadow: 0 2px 0 rgba(0, 0, 0, 0.25);
}
.drag-ghost.nope .nope-tag { display: block; }
.drag-ghost.nope img { filter: sepia(1) saturate(4) hue-rotate(-40deg) brightness(0.9) opacity(0.8); }
.cell.nope::after {
  content: '';
  position: absolute;
  inset: 4px;
  border-radius: 16px;
  border: 3px dashed rgba(255, 77, 61, 0.85);
  background: rgba(255, 77, 61, 0.08);
  pointer-events: none;
}

/* Ahora fit icons: clear ✕ where the container doesn't fit. */
.compat span { position: relative; display: inline-block; }
.compat span img { width: 17px; height: 17px; object-fit: contain; border-radius: 4px; background: rgba(255, 255, 255, 0.7); padding: 1px; display: block; }
.compat span.no img { opacity: 0.3; filter: grayscale(1); background: transparent; }
.compat span.no::after {
  content: '✕';
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #e0321f;
  font-size: 15px;
  font-weight: 900;
}

/* Drag-start map: where the container can go and how much each spot catches. */
.cell-tag {
  display: none;
  position: absolute;
  z-index: 10; /* above the water canvas (#fx 8) and the readout badges (9) */
  left: 50%;
  top: calc(38% + 20px); /* clears the loss chip, which ends near 38% of the card */
  transform: translate(-50%, -50%);
  align-items: center;
  gap: 5px;
  padding: 4px 11px;
  border-radius: 14px;
  font-weight: 900;
  font-size: 17px;
  color: #fff;
  white-space: nowrap;
  pointer-events: none;
  box-shadow: 0 3px 0 rgba(0, 0, 0, 0.22), 0 0 0 2px rgba(255, 255, 255, 0.85);
  animation: tagIn 160ms cubic-bezier(.2, 1.6, .4, 1);
}
.cell.show-tag .cell-tag { display: flex; }
@keyframes tagIn { from { transform: translate(-50%, -50%) scale(0.6); opacity: 0; } }
.cell-tag .drops { display: flex; gap: 1px; }
.cell-tag .drops svg { width: 11px; height: 14px; fill: #fff; }
.cell-tag.qE { background: #17a35a; }
.cell-tag.qG { background: #e39b12; }
.cell-tag.qI { background: #e0501f; }
.cell-tag.fit { background: #d93a2b; font-size: 15px; }
.cell-tag.busy { background: #5b6878; font-size: 15px; }
/* Dim the card's contents, not the card: a filter on .cell would trap its tag under the water canvas. */
.cell.nofit > :not(.cell-tag) { filter: saturate(0.55) brightness(0.93); }
.cell.nofit.show-tag::after {
  content: '';
  position: absolute;
  inset: 4px;
  border-radius: 16px;
  border: 3px dashed rgba(217, 58, 43, 0.75);
  pointer-events: none;
}
.drag-ghost .nope-tag { display: none !important; }

/* ---------- Reward moments (0.1.7) ---------- */
.glow-burst {
  position: absolute;
  width: 120px; height: 120px;
  margin: -60px 0 0 -60px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 236, 140, 0.95), rgba(255, 200, 60, 0.55) 40%, transparent 70%);
  animation: glowBurst 620ms ease-out forwards;
}
@keyframes glowBurst {
  0% { transform: scale(0.2); opacity: 0; }
  25% { transform: scale(1.1); opacity: 1; }
  100% { transform: scale(1.6); opacity: 0; }
}
.ring.gold {
  width: 34px; height: 34px;
  margin: -17px 0 0 -17px;
  border: 5px solid #ffd54a;
  box-shadow: 0 0 14px 3px rgba(255, 200, 40, 0.9), inset 0 0 8px rgba(255, 240, 160, 0.9);
  animation: ringPop 560ms ease-out forwards;
}
.ring.gold.late { border-color: #fff4b8; animation-duration: 640ms; }
.spark.gold {
  width: 14px; height: 14px;
  margin: -7px 0 0 -7px;
  background: radial-gradient(circle, #fffbe0, #ffd02a 60%);
  filter: drop-shadow(0 0 4px rgba(255, 190, 30, 0.9));
  animation: spark 700ms cubic-bezier(.2, .8, .4, 1) forwards;
}
.pile-item.clean { animation: pileClean 620ms cubic-bezier(.2, 1.6, .35, 1), goldShine 900ms ease-out; }
@keyframes goldShine {
  0%, 20% { filter: drop-shadow(0 0 0 rgba(255, 210, 60, 0)); }
  35% { filter: drop-shadow(0 0 10px rgba(255, 210, 60, 1)) brightness(1.25); }
  100% { filter: drop-shadow(0 0 0 rgba(255, 210, 60, 0)); }
}
.puff {
  position: absolute;
  width: 26px; height: 12px;
  margin: -8px 0 0 -13px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(235, 225, 210, 0.95), rgba(200, 190, 175, 0.6) 60%, transparent 72%);
  animation: puff 520ms ease-out forwards;
  --pdx: -26px;
}
.puff.right { --pdx: 26px; }
@keyframes puff {
  0% { transform: translate(0, 0) scale(0.4); opacity: 0.9; }
  100% { transform: translate(var(--pdx), -10px) scale(1.5); opacity: 0; }
}
.cell-tag .secs { margin-left: 4px; padding-left: 7px; border-left: 2px solid rgba(255, 255, 255, 0.55); font-size: 14px; opacity: 0.95; }
.cell-tag .secs svg { width: 12px; height: 12px; margin-right: 2px; vertical-align: -1px; fill: none; stroke: #fff; stroke-width: 2.4; }

/* Basin front (rim/face) drawn over a placed container so it sits inside the sink. */
.cell .fixture-front { z-index: 5; filter: none; }

/* A thin dark edge keeps white/translucent containers readable against white fixtures. */
.placed > img { filter: drop-shadow(0 0 1px rgba(25, 45, 75, 0.7)) drop-shadow(0 1px 1px rgba(25, 45, 75, 0.35)); }

/* Developer options (?dev=1). Outside #app so game input never sees it. */
#devPanel { position: fixed; left: 0; right: 0; bottom: 0; max-width: 520px; margin: 0 auto; z-index: 1000; font: 12px/1.3 system-ui, sans-serif; color: #fff; pointer-events: none; }
#devPanel > * { pointer-events: auto; }
#devPanel .dev-toggle { position: absolute; left: 6px; bottom: 6px; padding: 3px 8px; border: 0; border-radius: 6px; background: rgba(20, 28, 40, 0.8); color: #ffd84a; font-weight: 800; }
#devPanel .dev-body { display: none; background: rgba(20, 28, 40, 0.92); padding: 6px 8px 34px; }
#devPanel.open .dev-body { display: block; }
#devPanel .dev-row { display: flex; align-items: center; gap: 5px; margin: 3px 0; flex-wrap: wrap; }
#devPanel .dev-row b { min-width: 62px; font-weight: 700; }
#devPanel select, #devPanel button, #devPanel input[type=number] { font: inherit; padding: 2px 3px; border-radius: 4px; border: 0; }
#devPanel input[type=number] { width: 52px; }
#devPanel input[type=range] { flex: 1; min-width: 60px; }
#devPanel .dev-pct { width: 34px; text-align: right; font-variant-numeric: tabular-nums; }
#devPanel .dev-diag { white-space: pre-wrap; opacity: 0.8; font-size: 11px; margin-top: 4px; }

/* ---------- Onboarding (first-run coach, bank coach, collapse line, Cómo jugar) ---------- */
.coach { position: absolute; inset: 0; z-index: 40; pointer-events: none; }
.coach[hidden] { display: none; }
.coach-scrim { position: absolute; inset: 0; background: rgba(12, 28, 48, 0.5); pointer-events: auto; animation: coachFade 220ms ease-out; }
.coach-frame {
  position: absolute;
  border-radius: 14px;
  border: 3px dashed rgba(255, 255, 255, 0.95);
  box-shadow: 0 0 0 4px rgba(120, 220, 255, 0.35), 0 0 22px rgba(120, 220, 255, 0.7), inset 0 0 0 9999px rgba(255, 255, 255, 0.08);
  animation: coachPulse 1.2s ease-in-out infinite;
}
.coach-hand { position: absolute; left: 0; top: 0; width: 46px; height: 46px; filter: drop-shadow(0 3px 3px rgba(0, 0, 0, 0.35)); z-index: 2; }
.coach-hand svg { width: 100%; height: 100%; display: block; }
.coach-ghost { position: absolute; left: 0; top: 0; z-index: 1; filter: drop-shadow(0 6px 6px rgba(0, 0, 0, 0.3)); }
.coach-ghost img { width: 100%; height: 100%; object-fit: contain; display: block; }
.coach-ring { position: absolute; width: 56px; height: 56px; border-radius: 50%; border: 3px solid #fff; box-shadow: 0 0 12px rgba(120, 220, 255, 0.9); }
.coach-card {
  position: absolute;
  left: 50%;
  bottom: 22px;
  transform: translateX(-50%);
  width: min(88%, 360px);
  padding: 16px 18px 14px;
  border-radius: 22px;
  background: var(--panel);
  box-shadow: 0 8px 0 rgba(0, 0, 0, 0.18), 0 12px 30px rgba(0, 0, 0, 0.3);
  text-align: center;
  pointer-events: auto;
  animation: coachCardIn 300ms cubic-bezier(.2, 1.4, .4, 1);
}
.coach-card p { margin: 0 0 10px; font-size: 19px; font-weight: 900; color: var(--ink); line-height: 1.25; }
.coach-card.story { bottom: auto; top: 50%; transform: translate(-50%, -50%); animation: coachStoryIn 380ms cubic-bezier(.2, 1.4, .4, 1); }
.coach-card.story h3 { margin: 2px 0 8px; font-size: 30px; font-weight: 900; color: #1c6fc0; -webkit-text-stroke: 1px #0f4a86; }
.coach-card.story p { font-size: 17px; font-weight: 800; color: var(--ink-soft); }
.coach-card.story p.goal { font-size: 18px; font-weight: 900; color: var(--ink); }
.coach-dots { display: flex; justify-content: center; gap: 6px; margin: 2px 0 12px; }
.coach-dots i { width: 8px; height: 8px; border-radius: 50%; background: rgba(29, 42, 58, 0.2); }
.coach-dots i.on { background: #ff5a36; width: 20px; border-radius: 4px; }
.coach-btn { width: 100%; }
.coach-bubble {
  position: absolute;
  max-width: 190px;
  padding: 10px 12px 10px;
  border-radius: 16px;
  background: #fff;
  box-shadow: 0 6px 0 rgba(0, 0, 0, 0.15), 0 10px 24px rgba(0, 0, 0, 0.3);
  text-align: center;
  pointer-events: auto;
  animation: coachFade 260ms ease-out;
}
.coach-bubble p { margin: 0 0 8px; font-size: 16px; font-weight: 900; color: var(--ink); line-height: 1.2; }
.coach-bubble .btn { padding: 6px 14px; font-size: 14px; }
.cell.coach-target .placed { filter: drop-shadow(0 0 8px rgba(255, 255, 255, 0.95)) drop-shadow(0 0 14px rgba(120, 220, 255, 0.9)); }
.coach-line {
  position: absolute;
  z-index: 36;
  left: 50%;
  top: calc(14% + 38px);
  transform: translateX(-50%);
  padding: 4px 12px;
  border-radius: 12px;
  background: rgba(29, 42, 58, 0.82);
  color: #ffe08a;
  font-size: 16px;
  font-weight: 900;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
}
.coach-line.show { animation: coachLine 3400ms ease-in-out forwards; }
@keyframes coachFade { from { opacity: 0; } }
@keyframes coachPulse { 50% { box-shadow: 0 0 0 7px rgba(120, 220, 255, 0.2), 0 0 30px rgba(120, 220, 255, 0.9), inset 0 0 0 9999px rgba(255, 255, 255, 0.12); } }
@keyframes coachCardIn { from { opacity: 0; transform: translateX(-50%) translateY(16px) scale(0.92); } }
@keyframes coachStoryIn { from { opacity: 0; transform: translate(-50%, -50%) scale(0.85); } }
@keyframes dropBob { 50% { transform: translateY(-4px); } }
@keyframes coachLine { 0% { opacity: 0; transform: translateX(-50%) translateY(6px); } 12%, 85% { opacity: 1; transform: translateX(-50%) translateY(0); } 100% { opacity: 0; } }
.how-list { list-style: none; margin: 4px 0 14px; padding: 0; text-align: left; }
.how-list li { display: flex; gap: 10px; align-items: flex-start; padding: 7px 2px; font-size: 15px; font-weight: 800; color: var(--ink); border-bottom: 1px solid rgba(29, 42, 58, 0.08); }
.how-list li.premise { color: #1c6fc0; }
.how-list li[hidden] { display: none; }
/* Each row's picture sits in the same framed tile (like the goal card's pictures), so the list reads as one set. */
.how-ico { width: 34px; height: 34px; flex: none; box-sizing: border-box; padding: 5px; border-radius: 10px; background: #e6f2fc; box-shadow: inset 0 0 0 1px rgba(28, 111, 192, 0.12); }
.how-list li { align-items: center; }
.how-list li.premise .how-ico { background: #d8ecff; }
#app:has(#coach.intro:not([hidden])) .prompt { display: none; }

/* ---------- Source cards: each playable source is a framed card on a dark board ---------- */
.room { padding: 6px; gap: 6px; }
.room.bathroom, .room.kitchen { background: linear-gradient(#2d4a69, #1f344e); }
.room .cell + .cell { box-shadow: none; }
.outside { padding: 6px 0 6px 6px; }
.cell { border-radius: var(--cell-r, 14px); }
.cell-frame {
  position: absolute;
  inset: 0;
  z-index: 5;
  border-radius: var(--cell-r, 14px);
  pointer-events: none;
  box-shadow:
    inset 0 0 0 2px rgba(255, 255, 255, 0.55),
    inset 0 0 0 3px rgba(0, 0, 0, 0.18),
    inset 0 -10px 14px -10px rgba(0, 0, 0, 0.35),
    0 3px 0 rgba(0, 0, 0, 0.25),
    0 6px 14px rgba(0, 0, 0, 0.3);
  transition: box-shadow 160ms;
}
.cell.compatible::after { inset: 3px; border-radius: calc(var(--cell-r, 14px) - 2px); }
.cell.press .cell-frame { animation: cardFlash 320ms ease-out; }
/* Finger down on a card (the tap only acts on release): a light wash so the press is felt at once. */
.cell-frame::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: rgba(255, 255, 255, 0.2);
  box-shadow: inset 0 0 0 3px rgba(255, 255, 255, 0.75);
  opacity: 0;
  transition: opacity 120ms;
}
.cell.held .cell-frame::after { opacity: 1; transition-duration: 40ms; }
.cell.press > .fixture.scene, .cell.press > .placed { animation: cardDip 260ms cubic-bezier(.3, 1.6, .5, 1); }
.cell.sputter .cell-frame { animation: cardSputter 380ms steps(2) 3; }
@keyframes cardFlash { 0% { box-shadow: inset 0 0 0 3px #fff, inset 0 0 26px rgba(160, 230, 255, 0.85), 0 0 18px rgba(120, 220, 255, 0.9); } }
@keyframes cardDip { 40% { transform: scale(0.985) translateY(1px); } }
@keyframes cardSputter { 0% { box-shadow: inset 0 0 0 2px rgba(255, 170, 90, 0.95), 0 0 12px rgba(255, 140, 60, 0.6); } 100% { box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.5); } }
.catch-fly {
  position: absolute;
  z-index: 34;
  padding: 1px 7px;
  border-radius: 10px;
  background: #1c7fe0;
  color: #fff;
  font-size: 12px;
  font-weight: 900;
  white-space: nowrap;
  pointer-events: none;
  box-shadow: 0 2px 0 rgba(0, 0, 0, 0.2);
  animation: none;
}
/* Goal card rows (first-run intro) */
.goal-row { display: flex; align-items: center; gap: 10px; margin: 8px 0; text-align: left; font-size: 16px; font-weight: 900; color: var(--ink); line-height: 1.2; }
.goal-pic { flex: none; box-sizing: border-box; width: 104px; display: inline-flex; align-items: baseline; justify-content: center; gap: 3px; padding: 6px 8px; border-radius: 14px; font-weight: 900; } /* one fixed column, so every row's text starts at the same x */
/* Goal card pictures: miniatures of the live UI on the surface they live on — the top bar's blue (clock and
   water pills, like #timerWrap / .hud-saved), the dark board (the five taps as running cards; a loss chip). */
.goal-card .goal-row { font-size: 15px; margin: 7px 0; }
.goal-pic.bar, .goal-pic.board { height: 44px; align-items: center; padding: 0 6px; overflow: hidden; }
.goal-pic.bar { background: linear-gradient(#3787d2, #2c73b8 55%, #2767a6); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22), inset 0 -2px 0 rgba(10, 40, 80, 0.35); }
.goal-pic.board { background: linear-gradient(#2d4a69, #1f344e); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08); }
.mini-pill {
  display: inline-flex;
  align-items: baseline;
  gap: 0;
  padding: 3px 9px;
  border-radius: 999px;
  background: rgba(8, 32, 64, 0.34);
  box-shadow: inset 0 2px 3px rgba(0, 0, 0, 0.28), inset 0 -1px 0 rgba(255, 255, 255, 0.12);
  color: #fff;
  font-size: 16px;
  font-weight: 900;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 2px 0 rgba(0, 0, 0, 0.2);
  white-space: nowrap;
}
.mini-pill.clock { font-size: 22px; border-radius: 12px; padding: 1px 12px 3px; }
.mini-pill svg { width: 13px; height: 13px; align-self: center; margin-right: 3px; }
.mini-pill svg path { fill: #8fd3ff; }
.mini-pill .dec { font-size: 0.62em; }
.mini-pill small:last-child { font-size: 0.6em; opacity: 0.85; margin-left: 3px; }
.goal-pic.five { gap: 3px; justify-content: center; }
.goal-pic.five i {
  width: 16px;
  height: 24px;
  border-radius: 5px;
  background-size: cover;
  background-position: center;
  box-shadow: 0 0 0 1.5px #2ecc71, 0 0 5px rgba(46, 204, 113, 0.7);
}
.mini-chip { padding: 2px 7px; border-radius: 9px; background: rgba(226, 64, 40, 0.94); box-shadow: 0 2px 0 rgba(0, 0, 0, 0.2); color: #fff; font-size: 12px; font-weight: 900; white-space: nowrap; }
.coach-card.do { pointer-events: none; padding: 12px 16px 8px; bottom: auto; }
.coach-card.do p { margin-bottom: 6px; }
/* Results grade: three drops, filled by performance, popping in one by one. */
.grade-drop { transform-box: fill-box; transform-origin: 50% 80%; }
.grade-drop:not(.on) path { fill: #d5dde6; }
.grade-drop:not(.on) ellipse { opacity: 0.4; }
.results.show-stats .grade-drop { animation: gradePop 420ms cubic-bezier(.2, 1.6, .4, 1) both; }
.results.show-stats .grade-drop:not(.on) { animation-name: gradeFade; }
@keyframes gradePop { 0% { transform: scale(0); } 100% { transform: scale(1); } }
@keyframes gradeFade { 0% { opacity: 0; } 100% { opacity: 1; } }

/* Results grade: three drops, filled by performance (bigger, no bob), popping in one by one. */
.result-motif { height: 46px; width: 160px; animation: none; }
.grade-drop { transform-box: fill-box; transform-origin: 50% 80%; }
.grade-drop:not(.on) path { fill: #d5dde6; }
.grade-drop:not(.on) ellipse { opacity: 0.4; }
.results.show-stats .grade-drop { animation: gradePop 420ms cubic-bezier(.2, 1.6, .4, 1) both; }
.results.show-stats .grade-drop:not(.on) { animation-name: gradeFade; }
@keyframes gradePop { 0% { transform: scale(0); } 100% { transform: scale(1); } }
@keyframes gradeFade { 0% { opacity: 0; } 100% { opacity: 1; } }

/* Goal modal pictures: the timer, and five running taps. */
.coach.goal .coach-card.story h3 { margin-bottom: 4px; }
.coach.goal .goal-row { font-size: 15px; margin: 7px 0; }

/* "Use all five" nudges (running only). */
.cell.nudge-place .slot {
  border: 3px dashed rgba(255, 255, 255, 0.95);
  background: rgba(120, 210, 255, 0.5);
  animation: slotNudge 1.3s ease-in-out infinite;
}
@keyframes slotNudge { 0%, 100% { transform: translateX(-50%) scale(1); box-shadow: 0 0 8px rgba(120, 210, 255, 0.7); } 50% { transform: translateX(-50%) scale(1.18); box-shadow: 0 0 18px 4px rgba(120, 210, 255, 0.95); } }
.cell.nudge-open .cell-frame { animation: nudgeBreathe 1.1s ease-in-out infinite; }
@keyframes nudgeBreathe { 50% { box-shadow: inset 0 0 0 4px rgba(255, 255, 255, 0.95), inset 0 0 22px rgba(255, 255, 255, 0.45), 0 0 14px rgba(255, 255, 255, 0.7); } }
.ind.nudge-open { background: rgba(230, 150, 20, 0.95); animation: indBounce 1.1s ease-in-out infinite; }
.ind.tr.nudge-open { animation-name: indBounceR; }
@keyframes indBounce { 0%, 60%, 100% { transform: translateY(0); } 30% { transform: translateY(-4px) scale(1.06); } }
@keyframes indBounceR { 0%, 60%, 100% { transform: translateX(-100%); } 30% { transform: translateX(-100%) translateY(-4px) scale(1.06); } }

/* Tutorial focus: everything but the needed area is blurred and dimmed while a step waits on the player. */
.coach-blur {
  position: absolute;
  inset: 0;
  pointer-events: none;
  -webkit-backdrop-filter: blur(4px) saturate(0.7) brightness(0.72);
  backdrop-filter: blur(4px) saturate(0.7) brightness(0.72);
  animation: coachFade 260ms ease-out;
}

/* Storage bay: a recessed, labelled zone of its own, clearly not part of the hose card. */
#stockpile {
  top: 6px;
  right: 6px;
  bottom: 6px;
  height: auto;
  width: calc(36% - 14px);
  border-radius: 14px;
  /* A soft recess in the staging's own warm palette (tester: the dark rim and hazard stripe looked out of place). */
  background: linear-gradient(#dccaaa, #d2bd98);
  box-shadow: inset 0 3px 7px rgba(110, 75, 30, 0.2), inset 0 0 0 1.5px rgba(150, 115, 70, 0.22), 0 1px 0 rgba(255, 255, 255, 0.6);
}
#pileLabel {
  position: absolute;
  z-index: 2;
  left: 50%;
  top: 6px;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px 2px 5px;
  border-radius: 10px;
  background: rgba(29, 42, 58, 0.9);
  color: #fff;
  font-size: 11px;
  font-weight: 800;
  white-space: nowrap;
}
/* Narrow phones: the bay is ~104px wide; drop the icon so "Guardado 24" stays inside it. */
@media (max-width: 400px) {
  #pileLabel { gap: 3px; }
  #pileLabel svg { display: none; }
}
#pileLabel svg { width: 12px; height: 12px; }
#pileLabel b { min-width: 12px; padding: 0 5px; border-radius: 7px; background: #1c7fe0; font-size: 11px; text-align: center; }
#savedVal { font-variant-numeric: tabular-nums; }
#savedVal .dec { font-size: 18px; opacity: 0.9; }

/* Bigger source readouts (tester): flow chip and live loss chip. */
.ind { padding: 4px 9px 4px 5px; gap: 5px; font-size: 13px; border-radius: 14px; }
.ind .ind-icon { width: 20px; height: 20px; }
.ind .bar { width: 44px; height: 8px; border-radius: 4px; }
.ind .bar i { border-radius: 4px; }
.ind .num { min-width: 28px; opacity: 1; }
.loss { font-size: 14px; padding: 3px 10px; border-radius: 12px; }


/* Equal source cards (tester): the three board rows share the same height, and the outdoor row is split
   like the rooms: hose card | storage bay, with the same 6px gutters on a dark board. Staging keeps its size. */
#app { grid-template-rows: minmax(0, 8fr) minmax(0, 20fr) minmax(0, 2fr) minmax(0, 20fr) minmax(0, 20fr) minmax(0, 23fr); }
.outside { grid-template-columns: 1fr 1fr; gap: 6px; padding: 6px; background: linear-gradient(#2d4a69, #1f344e); }
.outside::before, .outside::after { display: none; }
#stockpile { position: relative; inset: auto; top: auto; right: auto; bottom: auto; width: auto; height: auto; }

/* Card border = what the water is doing. */
.cell.st-off .cell-frame { box-shadow: inset 0 0 0 3px #4fa3e8, inset 0 0 0 4px rgba(0, 0, 0, 0.2), inset 0 -10px 14px -10px rgba(0, 0, 0, 0.35), 0 3px 0 rgba(0, 0, 0, 0.25), 0 6px 14px rgba(0, 0, 0, 0.3); }
.cell.st-good .cell-frame { box-shadow: inset 0 0 0 3px #2ecc71, inset 0 0 0 4px rgba(0, 0, 0, 0.2), inset 0 0 18px rgba(46, 204, 113, 0.35), 0 3px 0 rgba(0, 0, 0, 0.25), 0 0 14px rgba(46, 204, 113, 0.6); }
.cell.st-meh .cell-frame { box-shadow: inset 0 0 0 3px #f5c542, inset 0 0 0 4px rgba(0, 0, 0, 0.2), inset 0 0 18px rgba(245, 197, 66, 0.35), 0 3px 0 rgba(0, 0, 0, 0.25), 0 0 14px rgba(245, 197, 66, 0.6); }
.cell.st-bad .cell-frame { box-shadow: inset 0 0 0 3px #ff4a3d, inset 0 0 0 4px rgba(0, 0, 0, 0.2), inset 0 0 20px rgba(255, 74, 61, 0.4), 0 3px 0 rgba(0, 0, 0, 0.25), 0 0 16px rgba(255, 74, 61, 0.7); animation: badPulse 800ms ease-in-out infinite; }
@keyframes badPulse { 50% { box-shadow: inset 0 0 0 4px #ff6a5e, inset 0 0 0 5px rgba(0, 0, 0, 0.2), inset 0 0 26px rgba(255, 74, 61, 0.55), 0 3px 0 rgba(0, 0, 0, 0.25), 0 0 22px rgba(255, 74, 61, 0.9); } }

/* Layout v3 (tester): no bar between floors (one 6px gutter everywhere), the hose card centered alone in
   its row at the same width as the others, and the storage bay down in staging, left of Ahora. */
#app { grid-template-rows: minmax(0, 8fr) minmax(0, 21fr) 0 minmax(0, 21fr) minmax(0, 21fr) minmax(0, 23fr); }
.level-break { height: 0; background: none; box-shadow: none; }
#rowDown, #rowOut { padding-top: 0; }
.outside { grid-template-columns: 1fr; }
.cell-hose { justify-self: center; width: calc(50% - 3px); }
/* Same box as Próximo (tester), mirrored on the left: the two side cards frame Ahora symmetrically. */
#stockpile {
  grid-column: 1;
  grid-row: 1;
  align-self: end;
  justify-self: center;
  width: 84%;
  height: 74%;
  margin: 0 0 6px;
  border-radius: 16px;
  transition: opacity 250ms;
}
/* The empty bay shows before the round too (tester: it replaced the pre-start logo). */
#pileLabel { font-size: 10px; padding: 2px 6px 2px 4px; }
/* Pressure tutorial pictures: a draining pressure bar, and close-one-tap → more water in another. */
.goal-pic.press { background: #1f3a58; padding: 10px; }
.goal-pic.press i { display: block; width: 64px; height: 10px; border-radius: 5px; background: linear-gradient(90deg, #ff7a3c, #ffd84a); transform-origin: left center; animation: pressDrain 2s ease-in infinite; }
@keyframes pressDrain { 0% { transform: scaleX(1); } 85%, 100% { transform: scaleX(0.12); } }
.goal-pic.redirect { background: #dff1ff; padding: 6px 8px; }
.goal-pic.redirect svg { width: 72px; height: 36px; }
/* The HUD (and its pause button, where the tutorial toggle lives) stays above tutorial layers. */
#hud { z-index: 41; }
/* Decimals of the counter stay smaller than the gallons (sized with the pill, so "188.88 gal" fits at 360px). */
#savedVal .dec { font-size: 0.62em; }
/* Before the round the start prompt takes the Ahora label's place at the top of staging. */
#app.phase-prestart #ahora .stage-label { visibility: hidden; }
#app.phase-prestart .prompt { font-size: 13px; padding: 5px 12px; }
/* Source chips scale with the screen: full size on a Pixel 9 Pro XL-width screen, smaller on narrow phones so they don't bury the art. */
.ind { font-size: clamp(10.5px, 2.9vw, 13px); padding: 0.3em 0.7em 0.3em 0.4em; gap: 0.4em; }
.ind .ind-icon { width: 1.55em; height: 1.55em; }
.ind .bar { width: 3.4em; height: 0.62em; }
.ind .num { min-width: 2.1em; }
.loss { font-size: clamp(11px, 3.1vw, 14px); padding: 0.2em 0.7em; }
/* Results values: 2 decimals like the HUD, decimals smaller; columns may shrink so "188.88" fits. */
.stats { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.stat-val { font-size: 32px; letter-spacing: -0.5px; }
.stat-val .dec { font-size: 20px; }
.stat-val small { font-size: 13px; }
.stat-val { font-size: clamp(24px, 7.1vw, 32px); }
.stat-val .dec { font-size: clamp(15px, 4.4vw, 20px); }
/* Small spill on a good/poor-fit card: amber, not alarm red. */
.loss.bad.mild { background: rgba(214, 138, 18, 0.95); animation: none; }
/* Pre-start prompt slimmer on narrow phones, and a gentler invite bob, so neither touches a tall container. */
#app.phase-prestart .prompt { font-size: clamp(11px, 3.1vw, 13px); padding: 0.3em 0.9em; }
@keyframes invite { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-3px) rotate(-1.5deg); } }
/* Ahora label (name + gallons) scales with width so long names like "Caja plástica" fit narrow phones. */
#ahoraInfo .info-line { font-size: clamp(11px, 3.3vw, 15px); gap: 3px; }
#ahoraInfo .info-line .cap { font-size: clamp(10px, 3vw, 14px); padding: 1px 5px; }
/* Event banners scale with width so the longer titles (incl. the 1.15x pop) stay on screen on narrow phones. */
.banner { font-size: clamp(22px, 6.8vw, 34px); }
.banner.collapse { font-size: clamp(20px, 6.2vw, 30px); }

/* First drag step (tester: was messy): instruction, then a tidy two-column key of what the drag tags mean.
   Sample tags sit in one fixed column so every meaning starts at the same x, one short line each. */
.coach-card.do.legend { bottom: auto; width: min(94%, 400px); padding: 12px 14px 8px; }
.coach-card.do.legend > p:first-child { font-size: 17px; margin-bottom: 0; }
.lg-key {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 7px 10px;
  margin: 10px 2px 2px;
  padding-top: 10px;
  border-top: 1.5px solid rgba(29, 42, 58, 0.1);
  text-align: left;
}
.lg-key .lg-tags { display: flex; justify-content: center; gap: 3px; }
.lg-key .lg-text { font-size: 13.5px; font-weight: 800; line-height: 1.2; color: var(--ink-soft); }
.lg-key .cell-tag { display: inline-flex; position: static; transform: none; animation: none; flex: none; font-size: 12px; padding: 2px 7px; box-shadow: 0 2px 0 rgba(0, 0, 0, 0.18); }
.lg-key .cell-tag .drops svg { width: 8px; height: 11px; }
.lg-key .cell-tag .secs { margin: 0; padding: 0; border: 0; font-size: 12px; }
.coach-card.do.legend .coach-dots { margin: 8px 0 2px; }
/* Narrow phones: keep the key to one line per row so the card fits above a downstairs target. */
@media (max-width: 400px) {
  .coach-card.do.legend { padding: 10px 12px 6px; }
  .coach-card.do.legend > p:first-child { font-size: 15px; }
  .lg-key { gap: 5px 8px; margin-top: 8px; padding-top: 8px; }
  .lg-key .lg-text { font-size: 12px; }
  .lg-key .cell-tag { font-size: 11px; padding: 1px 6px; }
  .lg-key .cell-tag .secs { font-size: 11px; }
  .lg-key .cell-tag .drops svg { width: 7px; height: 10px; }
}
/* Staging hierarchy (tester): Ahora is the thing to grab, so it gets the strongest card on the row: bright
   raised panel, warm accent ring and glow, and its label as a pill on the top edge. Próximo stays a quiet
   preview; the storage bay stays recessed. */
#ahora {
  margin: 12px 4px 2px;
  height: calc(100% - 14px);
  border-radius: 18px;
  background: radial-gradient(ellipse at 50% 35%, #fffefb, #fff4e3 75%);
  box-shadow:
    0 0 0 3px #ff7a3c,
    0 0 16px 2px rgba(255, 122, 60, 0.45),
    0 5px 0 rgba(120, 60, 20, 0.18),
    inset 0 -6px 12px -6px rgba(120, 70, 20, 0.18);
  animation: ahoraGlow 2.2s ease-in-out infinite;
}
@keyframes ahoraGlow {
  50% { box-shadow: 0 0 0 3px #ff8a50, 0 0 24px 5px rgba(255, 122, 60, 0.6), 0 5px 0 rgba(120, 60, 20, 0.18), inset 0 -6px 12px -6px rgba(120, 70, 20, 0.18); }
}
#ahora .stage-label {
  top: -11px;
  z-index: 1;
  padding: 2px 12px;
  border-radius: 10px;
  background: linear-gradient(#ff8a50, #ff5a36);
  color: #fff;
  font-size: 13px;
  letter-spacing: 2px;
  box-shadow: 0 2px 0 rgba(0, 0, 0, 0.15);
}
#ahora.empty { animation: none; box-shadow: 0 0 0 2px rgba(255, 122, 60, 0.35), 0 4px 0 rgba(120, 60, 20, 0.12); }
#ahora .stage-base { bottom: 40px; }
/* Próximo: a preview, visibly secondary. */
#proximo { background: rgba(255, 255, 255, 0.28); box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, 0.45); }
#proximo .stage-label { color: rgba(90, 100, 115, 0.8); font-size: 11px; }
/* Bay label in the same voice as "PRÓXIMO": muted capitals, no dark chip; only the count keeps its badge. */
#pileLabel {
  top: 2px; /* same line as PRÓXIMO */
  gap: 4px;
  padding: 0;
  background: none;
  color: rgba(90, 100, 115, 0.8);
  font-size: 10px;
  font-weight: 900;
  letter-spacing: 0.6px; /* "RECOLECTADOS" keeps a margin inside the bay (it filled it edge to edge) */
  text-transform: uppercase;
}
#pileLabel svg { display: none; }
#pileLabel b { letter-spacing: 0; color: #fff; }
@media (max-width: 400px) {
  #pileLabel { font-size: 9px; letter-spacing: 0.2px; gap: 3px; }
  #pileLabel b { font-size: 10px; padding: 0 4px; }
}
/* "Recolectados" (tester) is too long to share a line with the count in the bay: word on top, badge under it. */
#pileLabel { flex-direction: column; gap: 2px; }
/* "Agua recolectada" is longer than "Agua guardada": keep both stat labels on one line on narrow phones. */
.stat-label { white-space: nowrap; font-size: clamp(10.5px, 3.3vw, 13px); }

/* Water pipe framing the screen (src/tubeFrame.js): shaded glass pipes, water with drifting streaks, brass
   T-fittings at the corners, bubbles and two small fish. */
#tubeFrame { position: absolute; inset: 0; z-index: 58; pointer-events: none; overflow: visible; }
.tube-outline { fill: none; stroke: rgba(15, 50, 95, 0.45); stroke-width: 0.8; }
.tube-shine { stroke: rgba(255, 255, 255, 0.75); stroke-width: 0.6; stroke-linecap: round; }
.tube-bubble { fill: rgba(235, 250, 255, 0.55); stroke: rgba(255, 255, 255, 0.9); stroke-width: 0.35; }
.tube-bubble-shine { fill: #fff; }
.tube-fitting { filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.35)); }
.tube-bubble.micro { fill: rgba(235, 250, 255, 0.5); stroke-width: 0.25; }
.tube-clip { filter: drop-shadow(0 0.6px 0.6px rgba(0, 0, 0, 0.35)); }
@media (prefers-reduced-motion: reduce) { .tube-fish, .tube-bubble, .tube-bubble-shine { display: none; } }
/* The frame's side pipes sit flush with the screen edge (tester); the board keeps a lane just wider than the pipe. */
.room, .outside { padding-left: 10px; padding-right: 10px; }
#hud { padding-left: 14px; padding-right: 14px; }
#staging { padding-left: 12px; padding-right: 12px; }
.board-logo { left: 12px; width: calc(25% - 18px); }

/* The coquí in the frame pipes (src/tubeFrame.js). */
.coqui-limb { fill: url(#coquiLimb); stroke: #4a2a0c; stroke-width: 0.3; stroke-linejoin: round; }
.coqui-toe { fill: #9a6630; stroke: #4a2a0c; stroke-width: 0.2; }
.coqui-disc { fill: #d9a45e; stroke: #4a2a0c; stroke-width: 0.25; }
.coqui-skin { stroke: #4a2a0c; stroke-width: 0.4; }
.tube-coqui { filter: drop-shadow(0 0.5px 0.6px rgba(0, 0, 0, 0.35)); }
@media (prefers-reduced-motion: reduce) { .tube-coqui { display: none; } }
