/* ── Rink ────────────────────────────────────────────────────────────────────
   A stone on ice. Push it and it does not stop until a wall stops it, inking
   every square it crosses.

   The whole teaching burden of this game falls on the MOTION. Nothing about a
   still picture says "this will keep going once you push it" — so the stone
   slides along its path rather than jumping, at a speed you can follow, and the
   ink lands behind it as it passes. A player who watches one push understands
   the rule without being told it.

   The board is one element per rink square, in the engine's dense order, so the
   deduce overlay can address a square by index.                               */

/* The whole screen is the swipe surface, so the whole screen has to own the
   gesture — otherwise the browser reads a swipe over the empty space beside the
   board as a page scroll and eats it. Nothing on this screen scrolls, so there
   is nothing to give up. */
.rink-play {
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}

.rink-play .q-stage {
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Everything that travels with the stone — its transform, and both trail strokes,
   which are transitioned from JS — is timed on --rk-slide and curved on
   --rk-glide (see tokens.css). Neither uses --ease: half of the "the stone is
   slow" feeling was --ease's slow start, not the duration. */
.rk-board {
  position: relative;
  display: grid;
  grid-template-columns: repeat(var(--rk-c), var(--rk-cs));
  grid-auto-rows: var(--rk-cs);
  touch-action: none;              /* the whole rink is a swipe surface */
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}

/* A square of the rink — but NOT drawn as a square. The floor is one continuous
   surface with a wall around it: only the sides that face off the rink carry a
   line, so what you see is a room with an outline and holes in it, not a grid of
   tiles. Squares outside the rink are not rendered at all.

   This matters for how the game reads. Ruling every cell turns the floor into
   graph paper and makes the un-inked squares look like the subject; the subject
   is the stone's path. */
.rk-cell {
  position: relative;
  box-sizing: border-box;
  background: var(--rk-ice);
  grid-column: calc(var(--c) + 1);
  grid-row: calc(var(--r) + 1);
}

/* the room's own walls, drawn per-square on the outward sides so they mitre at
   corners with no gaps — the only lines on the whole board */
.rk-cell.wt { border-top: 2.5px solid var(--rk-frame); }
.rk-cell.wr { border-right: 2.5px solid var(--rk-frame); }
.rk-cell.wb { border-bottom: 2.5px solid var(--rk-frame); }
.rk-cell.wl { border-left: 2.5px solid var(--rk-frame); }

/* ── the painted trail ───────────────────────────────────────────────────── */

/* The stone paints a THICK LINE where it has been, not a set of filled squares.
   A line is what a rolling stone actually leaves, it shows the order the room
   was covered in, and a route that doubles back reads as one continuous stroke
   rather than a block of colour with no story in it. */
.rk-trail {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
  overflow: visible;
}
.rk-ink {
  fill: none;
  stroke: var(--rk-ink);
  stroke-linecap: round;
  stroke-linejoin: round;
}
.rk-ink-dot { fill: var(--rk-ink); }
/* the wet head: a short bright window that rides with the stone and slides off
   the end of the run, leaving the dry colour settled behind it */
.rk-wet { stroke: var(--rk-ink-2); }

/* ── the stone ───────────────────────────────────────────────────────────── */

.rk-stone {
  position: absolute;
  z-index: var(--z-panel);
  border-radius: var(--radius-full);
  background: var(--rk-stone);
  border-bottom: 2px solid var(--rk-stone-2);
  box-sizing: border-box;
  pointer-events: none;
  /* the slide itself — the one thing that explains the rule */
  transition: transform var(--rk-slide, 0.12s) var(--rk-glide);
}

/* ── the swipe hint: which ways this square can be pushed ────────────────── */

.rk-arrow {
  position: absolute;
  z-index: var(--z-panel);
  pointer-events: none;
  opacity: 0.34;
  color: var(--rk-stone);
  transition: opacity var(--duration-1) var(--ease);
}
/* out of the way fast — the arrows now have to clear before a short slide has
   finished, not over the leisurely fade a 0.42s slide left room for */
.rk-board.moving .rk-arrow { opacity: 0; transition-duration: 0.06s; }

/* ── the refusal: a push into a wall ─────────────────────────────────────── */

.rk-board.rk-nudge { animation: rk-nudge 0.2s var(--ease); }
@keyframes rk-nudge {
  0%, 100% { transform: translateX(0); }
  40%      { transform: translateX(-3px); }
  70%      { transform: translateX(3px); }
}
@media (prefers-reduced-motion: reduce) {
  .rk-board.rk-nudge { animation: none; }
  .rk-stone { transition: none; }
}

/* ── solved ──────────────────────────────────────────────────────────────── */

/* The finished room does nothing extra. Recolouring the whole trail at once was
   the same wholesale flip the wet head exists to avoid — and the victory sheet
   is already on its way. */

/* ── the level-card / hub thumbnail ──────────────────────────────────────── */

.rk-mini {
  display: grid;
  grid-template-columns: repeat(var(--rk-c), 1fr);
  width: 100%;
  aspect-ratio: 1 / 1;
}
.rk-mini i {
  box-sizing: border-box;
  grid-column: calc(var(--c) + 1);
  grid-row: calc(var(--r) + 1);
  background: var(--rk-ice);
  border: 0.5px solid var(--rk-ice-2);
}
.rk-mini i.ink { background: var(--rk-ink); }
.rk-mini i.stone { background: var(--rk-stone); border-radius: var(--radius-full); }
