/* =========================================================================
   Puzzlers — Pipe Flow stylesheet
   Pipe tiles are pre-recolored PNGs sourced from Kenney's pipe/tile asset
   pack (elbow, T, cross, straight — each shipped as an "empty" and a
   "flow" variant) and re-tinted at build time into this game's palette:
   flowing liquid = Sky Teal, pipe bodies = Marigold Yellow with an Ink
   Outline stroke, and the board's tile grid = Blush Pink. Every tile is a
   single square-cropped sprite with its open connector nubs flush to the
   sprite's own edges, so rotating it in 90° steps and dropping it into any
   grid cell always lines up with its neighbors.
   ========================================================================= */

:root {
  --flow-teal: #44B4C4;
  --flow-teal-light: #7ED2DE;
  --pipe-marigold: #EBDA61;
  --pipe-marigold-light: #F5EBA4;
  --ink: #2E292B;
  --tile-blush: #E8C4DE;
  --tile-blush-alt: #DEB0D2;

  --page-bg: #FBF1F7;
  --ui-white: #FFFDFB;

  --board-size: min(94vw, 62dvh, 620px);

  --dur-rotate: 260ms;
  --dur-flow: 320ms;

  color-scheme: light;
}

/* --------------------------------- Reset -------------------------------- */
* { box-sizing: border-box; }
html, body {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
  overscroll-behavior: none;
  background: var(--page-bg);
}
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  color: var(--ink);
  /* Vertical scroll stays available as a fallback if the board ever runs
     taller than the viewport; pinch-zoom, horizontal pan, and rubber-band
     are what actually need blocking, and .board below goes further (its
     taps must never be misread as a scroll/zoom gesture). game.js adds
     matching gesturestart/double-tap-end guards for iOS Safari. */
  touch-action: pan-y;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  overflow-x: hidden;
}
img {
  max-width: 100%;
  display: block;
  -webkit-user-drag: none;
  -webkit-touch-callout: none;
}

/* ------------------------------- App shell ------------------------------- */
#app {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: max(14px, env(safe-area-inset-top)) max(14px, env(safe-area-inset-right))
           max(20px, env(safe-area-inset-bottom)) max(14px, env(safe-area-inset-left));
}

/* ---------------------------------- HUD ---------------------------------- */
.hud {
  width: min(94vw, 620px);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
}

.pill {
  background: var(--ui-white);
  border: 3px solid var(--ink);
  border-radius: 999px;
  padding: 6px 16px;
  box-shadow: 0 3px 0 var(--ink);
  flex: 0 0 auto;
}
.pill--level { background: var(--pipe-marigold); }
.pill--rotations { background: var(--flow-teal-light); }

.pill__content { display: flex; align-items: baseline; gap: 8px; }
.pill__label {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.09em;
  opacity: 0.75;
}
.pill__value {
  font-size: 22px;
  font-weight: 900;
  min-width: 1.2em;
  text-align: center;
  transition: transform 220ms ease;
}
.pill__value.is-bumped { animation: bump 420ms ease; }
@keyframes bump {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.45); }
  100% { transform: scale(1); }
}

.instructions {
  flex: 1 1 220px;
  margin: 0;
  font-size: 12.5px;
  line-height: 1.4;
  text-align: center;
  color: var(--ink);
  opacity: 0.85;
}
.instructions__chip {
  display: inline-block;
  padding: 0 6px;
  border-radius: 6px;
  font-weight: 800;
  color: var(--ink);
}
.instructions__chip--source { background: var(--flow-teal-light); }
.instructions__chip--dest { background: var(--pipe-marigold-light); }

/* --------------------------------- Board --------------------------------- */
.board-wrap {
  width: 100%;
  display: flex;
  justify-content: center;
}

.board {
  width: var(--board-size);
  height: var(--board-size);
  display: grid;
  grid-template-columns: repeat(var(--size), 1fr);
  grid-template-rows: repeat(var(--size), 1fr);
  border: 4px solid var(--ink);
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 6px 0 var(--ink);
  background: var(--tile-blush);
  /* Every gesture inside the board is a rotate-tap, never a scroll/zoom. */
  touch-action: none;
}

.cell {
  position: relative;
  background: var(--tile-blush);
  border: 1px solid rgba(46, 41, 43, 0.18);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
/* subtle checkerboard so the blush grid reads as tiles, not a flat field */
.cell.is-checker { background: var(--tile-blush-alt); }

.cell--pipe { cursor: pointer; }
.cell--pipe:active .pipe-visual { filter: brightness(0.94); }

/* -------------------------------- Pipe art -------------------------------- */
.pipe-visual {
  position: absolute;
  inset: 6%;
  transition: transform var(--dur-rotate) cubic-bezier(0.34, 1.56, 0.64, 1);
  will-change: transform;
}
.pipe-visual img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  pointer-events: none;
}
.pipe-visual__flow {
  opacity: 0;
  transition: opacity var(--dur-flow) ease;
}
.cell.is-wet .pipe-visual__flow { opacity: 1; }
.cell.is-wet .pipe-visual__empty { opacity: 0; transition: opacity var(--dur-flow) ease; }

/* gentle shimmer riding along wet pipes to sell motion without sprite frames */
.cell.is-wet .pipe-visual::after {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    120deg,
    rgba(255, 255, 255, 0) 0px,
    rgba(255, 255, 255, 0.55) 6px,
    rgba(255, 255, 255, 0) 14px
  );
  mix-blend-mode: soft-light;
  opacity: 0.8;
  animation: shimmer 1.1s linear infinite;
  pointer-events: none;
}
@keyframes shimmer {
  from { background-position: 0 0; }
  to   { background-position: -120px 0; }
}

/* --------------------------- Source / destination -------------------------- */
.node {
  position: absolute;
  inset: 14%;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 4px solid var(--ink);
  font-size: 0;
}
.node--source { background: radial-gradient(circle at 35% 30%, var(--flow-teal-light), var(--flow-teal)); }
.node--dest   { background: radial-gradient(circle at 35% 30%, var(--pipe-marigold-light), var(--pipe-marigold)); }
.node__glyph {
  width: 46%;
  height: 46%;
  border-radius: 50%;
  background: var(--ui-white);
  border: 3px solid var(--ink);
}
.node--dest .node__glyph { background: var(--ink); }

.cell.is-wet .node { box-shadow: 0 0 0 6px rgba(68, 180, 196, 0.35); }

/* stub connecting the node to the grid line it opens toward */
.node__stub {
  position: absolute;
  width: 30%;
  height: 30%;
  background: var(--pipe-marigold);
  border: 3px solid var(--ink);
}
.node__stub--N { top: -32%; left: 35%; width: 30%; height: 45%; }
.node__stub--S { bottom: -32%; left: 35%; width: 30%; height: 45%; }
.node__stub--E { right: -32%; top: 35%; height: 30%; width: 45%; }
.node__stub--W { left: -32%; top: 35%; height: 30%; width: 45%; }
.cell.is-wet .node__stub { background: var(--flow-teal); }

/* ----------------------------------- Win ----------------------------------- */
.cell.is-path {
  animation: pathGlow 900ms ease var(--step, 0ms) 1;
}
@keyframes pathGlow {
  0%   { box-shadow: inset 0 0 0 0 rgba(68, 180, 196, 0); }
  35%  { box-shadow: inset 0 0 0 6px rgba(68, 180, 196, 0.85); }
  100% { box-shadow: inset 0 0 0 0 rgba(68, 180, 196, 0); }
}

.win-toast {
  position: fixed;
  top: 18%;
  left: 50%;
  transform: translate(-50%, -12px) scale(0.85);
  opacity: 0;
  background: var(--ui-white);
  border: 4px solid var(--ink);
  border-radius: 18px;
  padding: 14px 26px;
  text-align: center;
  box-shadow: 0 8px 0 var(--ink);
  pointer-events: none;
  transition: opacity 260ms ease, transform 260ms cubic-bezier(0.34, 1.56, 0.64, 1);
  z-index: 20;
}
.win-toast[hidden] { display: flex; }
.win-toast.is-visible {
  opacity: 1;
  transform: translate(-50%, 0) scale(1);
}
.win-toast__title {
  display: block;
  font-size: 22px;
  font-weight: 900;
  color: var(--flow-teal);
  -webkit-text-stroke: 1px var(--ink);
}
.win-toast__subtitle {
  display: block;
  margin-top: 2px;
  font-size: 13px;
  font-weight: 700;
  opacity: 0.75;
}

.confetti {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 15;
  overflow: hidden;
}
.confetti__bit {
  position: absolute;
  width: 10px;
  height: 10px;
  border: 2px solid var(--ink);
  border-radius: 3px;
  top: var(--y);
  left: var(--x);
  background: var(--c);
  transform: rotate(var(--r0));
  animation: confettiFall var(--dur) ease-in forwards;
}
@keyframes confettiFall {
  to {
    transform: translate(var(--dx), var(--dy)) rotate(var(--r1));
    opacity: 0;
  }
}

/* --------------------------------- Layout -------------------------------- */
@media (max-width: 420px) {
  .instructions { font-size: 11.5px; }
  .pill__value { font-size: 18px; }
}

/* Short/landscape phones: the HUD's vertical footprint competes with the
   board for the same scarce dvh, so shrink the HUD chrome and let the
   board claim most of the height instead of width. */
@media (max-height: 480px) {
  :root { --board-size: min(90vw, 82dvh, 620px); }
  #app { gap: 8px; padding-top: max(8px, env(safe-area-inset-top)); }
  .instructions { display: none; }
  .pill { padding: 4px 12px; }
  .pill__label { font-size: 9px; }
  .pill__value { font-size: 16px; }
}

/* Coarse pointers (touch) get a slightly larger minimum board share so
   pipe tiles stay comfortably tap-sized even on an 8×8 late-game grid. */
@media (pointer: coarse) {
  :root { --board-size: min(96vw, 64dvh, 620px); }
}
@media (pointer: coarse) and (max-height: 480px) {
  :root { --board-size: min(92vw, 84dvh, 620px); }
}
