/* Puzzle screen. Everything scoped to #puzzle-view. Colors and timings from
   css/tokens.css. The logbook, chips and scene (js/scene.js) are also used by
   the dig (#dig-view), which is why those rules use :is(). */

#puzzle-view {
  --pz-sil: #1f2633;
  --pz-sil-op: 0.42;
  background: #cfe9f7;
  touch-action: none;
}

:is(#puzzle-view, #dig-view) .pz-safe-probe {
  position: absolute;
  visibility: hidden;
  pointer-events: none;
  padding: env(safe-area-inset-top) env(safe-area-inset-right)
           env(safe-area-inset-bottom) env(safe-area-inset-left);
}

/* ---------- game ---------- */

:is(#puzzle-view, #dig-view) .pz-game {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  touch-action: none;
  z-index: 2;
}

/* Silhouette: translucent shadow over the watercolor, not a flat fill. */
:is(#puzzle-view, #dig-view) .pz-silhouette {
  opacity: var(--pz-sil-op);
  pointer-events: none;
}
/* The color comes from the #pz-sil-fill filter (also works for <image> and <use>);
   on vectors, strokes and inner opacities are also flattened. */
:is(#puzzle-view, #dig-view) .pz-sil-flood { flood-color: var(--pz-sil); }
:is(#puzzle-view, #dig-view) .pz-silhouette * {
  fill: var(--pz-sil) !important;
  stroke: none !important;
  opacity: 1 !important;
  fill-opacity: 1 !important;
  filter: none !important;
}

:is(#puzzle-view, #dig-view) .pz-sweep { display: none; pointer-events: none; mix-blend-mode: screen; }

:is(#puzzle-view, #dig-view) .pz-hit {
  fill: #000;
  fill-opacity: 0;
  pointer-events: all;
}
:is(#puzzle-view, #dig-view) .pz-piece { cursor: grab; }
:is(#puzzle-view, #dig-view) .pz-piece.pz-dragging { cursor: grabbing; }
/* Pieces with an image for the sheet (.pz-baked) already have their shadow painted. */
:is(#puzzle-view, #dig-view) .pz-loose .pz-piece:not(.pz-baked) { filter: drop-shadow(0 3px 2px rgba(46, 42, 36, 0.28)); }
:is(#puzzle-view, #dig-view) .pz-loose .pz-piece.pz-dragging { filter: drop-shadow(0 18px 12px rgba(46, 42, 36, 0.38)); }

:is(#puzzle-view, #dig-view) .pz-placed { pointer-events: none; }
:is(#puzzle-view, #dig-view) .pz-placed.pz-tappable { pointer-events: visiblePainted; cursor: pointer; }

:is(#puzzle-view, #dig-view) .pz-fx,
:is(#puzzle-view, #dig-view) .pz-decor { pointer-events: none; }

/* The piece's anchor (center of its real bbox) is at .pz-pop's origin;
   fill-box doesn't work with parts clipped by clip-path. */
:is(#puzzle-view, #dig-view) .pz-pop {
  transform-box: view-box;
  transform-origin: 0 0;
}
:is(#puzzle-view, #dig-view) .pz-pop.pz-popping { animation: pz-pop var(--t-settle) var(--ease-out); }
@keyframes pz-pop {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.05); }
  100% { transform: scale(1); }
}

/* ---------- logbook (right-hand sheet) ---------- */

:is(#puzzle-view, #dig-view) .pz-page {
  position: absolute;
  top: -24px;
  bottom: -24px;
  z-index: 1;
  pointer-events: none;
  background: url('../ui/page.webp') left center / 100% 100% no-repeat;
  filter: drop-shadow(-8px 0 14px rgba(46, 42, 36, 0.28));
  transform: rotate(1deg);
  transform-origin: 0 50%;
  transition: transform 700ms var(--ease-in-out), opacity 700ms var(--ease-in-out);
}
:is(#puzzle-view, #dig-view) .pz-page.pz-gone { transform: translateX(105%) rotate(4deg); }

:is(#puzzle-view, #dig-view) .pz-page-stain { position: absolute; height: auto; opacity: 0.42; }

:is(#puzzle-view, #dig-view) .pz-page-title {
  position: absolute;
  left: 30px;
  top: calc(var(--top) + 46px);
  max-width: calc(var(--inner) - 70px);
  font-family: var(--font-hand);
  font-weight: 700;
  line-height: 1;
  color: var(--c-earth);
  white-space: nowrap;
  z-index: 1;
  transform: rotate(-2deg);
  transform-origin: 0 50%;
}

:is(#puzzle-view, #dig-view) .pz-page-brush {
  position: absolute;
  left: 24px;
  top: calc(var(--top) + 70px);
  width: min(230px, calc(var(--inner) - 60px));
  height: auto;
  transform: rotate(-1.5deg);
}

:is(#puzzle-view, #dig-view) .pz-page-swatches {
  position: absolute;
  left: calc(18px + var(--inner) - 62px);
  top: calc(var(--top) + 30px);
  display: flex;
  flex-direction: column;
  gap: 5px;
}
:is(#puzzle-view, #dig-view) .pz-swatch {
  display: block;
  width: 22px;
  height: 18px;
  border-radius: 52% 48% 55% 45% / 50% 58% 42% 50%;
  opacity: 0.8;
  box-shadow: inset 0 0 0 2px rgba(0, 0, 0, 0.08);
}
:is(#puzzle-view, #dig-view) .pz-swatch:nth-child(2) { margin-left: 5px; width: 19px; }
:is(#puzzle-view, #dig-view) .pz-swatch:nth-child(3) { margin-left: 1px; width: 17px; height: 15px; }

/* Marks for each piece on the sheet (SVG, screen coordinates). */
:is(#puzzle-view, #dig-view) .pz-decor { transition: transform 700ms var(--ease-in-out), opacity 700ms var(--ease-in-out); }
:is(#puzzle-view, #dig-view) .pz-mark { transition: opacity var(--t-ui) var(--ease-out); }
/* Pencil outline of the piece's shape (#pz-trace filter): only while it's missing. */
:is(#puzzle-view, #dig-view) .pz-outline { display: none; }
:is(#puzzle-view, #dig-view) .pz-outline.pz-on { display: inline; animation: pz-fade-in var(--t-ui) var(--ease-out); }
@keyframes pz-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
:is(#puzzle-view, #dig-view) .pz-check {
  fill: none;
  stroke: var(--c-moss);
  stroke-width: 4.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0;
}
:is(#puzzle-view, #dig-view) .pz-check.pz-on { opacity: 0.9; }
:is(#puzzle-view, #dig-view) .pz-tally path {
  fill: none;
  stroke: rgba(62, 58, 52, 0.78);
  stroke-width: 4;
  stroke-linecap: round;
}
:is(#puzzle-view, #dig-view) .pz-doodle {
  fill: none;
  stroke: rgba(94, 84, 70, 0.45);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ---------- buttons: watercolor chips with an ink lip ---------- */

:is(#puzzle-view, #dig-view) .pz-tok {
  position: absolute;
  z-index: 3;
  isolation: isolate;
  touch-action: manipulation;
}
:is(#puzzle-view, #dig-view) .pz-tok::before,
:is(#puzzle-view, #dig-view) .pz-tok .pz-face {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--face) center / 100% 100% no-repeat;
}
/* Lip: the same chip in ink, peeking out from below. */
:is(#puzzle-view, #dig-view) .pz-tok::before {
  z-index: -1;
  transform: translateY(6%);
  filter: brightness(0.18) saturate(0);
  opacity: 0.9;
}
:is(#puzzle-view, #dig-view) .pz-tok .pz-face { transition: transform var(--t-tap) var(--ease-out); }
:is(#puzzle-view, #dig-view) .pz-tok:active .pz-face { transform: translateY(5%) scale(0.98, 0.96); }

:is(#puzzle-view, #dig-view) .pz-close {
  --face: url('../ui/btn_close.webp');
  top: calc(env(safe-area-inset-top) + 14px);
  left: calc(env(safe-area-inset-left) + 14px);
  width: 84px;
  height: 84px;
}

:is(#puzzle-view, #dig-view) .pz-next {
  --face: url('../ui/btn_next.webp');
  right: calc(env(safe-area-inset-right) + 28px);
  bottom: calc(env(safe-area-inset-bottom) + 28px);
  width: 132px;
  height: 132px;
  visibility: hidden;
  opacity: 0;
  transform: scale(0.9);
  transition: opacity 260ms var(--ease-out), transform 260ms var(--ease-out), visibility 0s 260ms;
}
:is(#puzzle-view, #dig-view) .pz-next.pz-show {
  visibility: visible;
  opacity: 1;
  transform: scale(1);
  transition: opacity 260ms var(--ease-out), transform 260ms var(--ease-out);
}
/* Local only: solve at once (see debug in main.js). */
:is(#puzzle-view, #dig-view) .dbg-solve {
  position: absolute;
  z-index: 3;
  top: calc(env(safe-area-inset-top) + 30px);
  left: calc(env(safe-area-inset-left) + 112px);
  padding: 0.06em 0.5em 0.14em;
  background: var(--c-paper);
  border: 3px solid var(--c-ink);
  border-radius: 14px;
  box-shadow: 0 5px 0 var(--c-ink);
  font-family: var(--font-hand);
  font-weight: 700;
  font-size: 30px;
  line-height: 1.1;
  color: var(--c-earth);
  transform: rotate(-2deg);
  transition: transform var(--t-tap) var(--ease-out), box-shadow var(--t-tap) var(--ease-out);
  touch-action: manipulation;
}
:is(#puzzle-view, #dig-view) .dbg-solve:active {
  transform: translateY(4px) rotate(-2deg);
  box-shadow: 0 1px 0 var(--c-ink);
}

/* The screen's only looping call to action: a breathing amber halo. */
:is(#puzzle-view, #dig-view) .pz-next::after {
  content: '';
  position: absolute;
  inset: -22%;
  z-index: -2;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(229, 154, 46, 0.55) 0%, rgba(229, 154, 46, 0) 68%);
  opacity: 0.35;
}
:is(#puzzle-view, #dig-view) .pz-next.pz-show::after { animation: pz-halo 2.4s ease-in-out infinite alternate; }
@keyframes pz-halo {
  from { opacity: 0.25; }
  to   { opacity: 0.9; }
}

@media (prefers-reduced-motion: reduce) {
  :is(#puzzle-view, #dig-view) .pz-next.pz-show::after { animation: none; opacity: 0.6; }
  :is(#puzzle-view, #dig-view) .pz-page,
  :is(#puzzle-view, #dig-view) .pz-decor { transition-duration: 160ms; }
}

/* ---------- scene (js/scene.js) ---------- */

:is(#puzzle-view, #dig-view) .pz-scene {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
  container-type: size;
}

/* Actual rectangle of the illustration: covers the screen like object-fit: cover and
   crops around the focal point (--fx, --fy). Layers use % and cqw/cqh from here. */
:is(#puzzle-view, #dig-view) .pz-stage {
  --sw: max(100cqw, 100cqh * var(--ar));
  --sh: max(100cqh, 100cqw / var(--ar));
  position: absolute;
  width: var(--sw);
  height: var(--sh);
  left: calc((100cqw - var(--sw)) * var(--fx));
  top: calc((100cqh - var(--sh)) * var(--fy));
  container-type: size;
}
:is(#puzzle-view, #dig-view) .pz-stage img {
  position: absolute;
  display: block;
  height: auto;
  user-select: none;
  -webkit-user-drag: none;
}
:is(#puzzle-view, #dig-view) .pz-stage .pz-stage-bg {
  inset: 0;
  width: 100%;
  height: 100%;
}

/* Crater glow: soft opacity pulse. */
:is(#puzzle-view, #dig-view) .pz-glow {
  translate: -50% -50%;
  opacity: var(--hi);
  animation: pz-pulse ease-in-out infinite alternate;
}
@keyframes pz-pulse {
  from { opacity: var(--lo); }
  to   { opacity: var(--hi); }
}

/* Smoke: base anchored at (left, top); rises, grows, sways and fades. */
:is(#puzzle-view, #dig-view) .pz-plume {
  translate: -50% -100%;
  transform-origin: 50% 100%;
  opacity: 0;
  animation: pz-plume linear infinite;
}
:is(#puzzle-view, #dig-view) .pz-plume-tall { will-change: transform, opacity; }
@keyframes pz-plume {
  0%   { transform: translate(0, 0) scale(1); opacity: 0; }
  20%  { opacity: 0.7; }
  35%  { transform: translate(4%, -6%) scale(1.12); }
  65%  { transform: translate(-4%, -12%) scale(1.26); opacity: 0.7; }
  100% { transform: translate(2%, -20%) scale(1.4); opacity: 0; }
}

/* Embers: rise from the crater with sideways drift and flicker. */
:is(#puzzle-view, #dig-view) .pz-ember {
  translate: -50% -50%;
  opacity: 0;
  animation: pz-ember linear infinite;
}
@keyframes pz-ember {
  0%   { transform: translate(0, 0); opacity: 0; }
  8%   { opacity: 1; }
  30%  { opacity: 0.5; }
  45%  { transform: translate(calc(var(--sway) * 1cqw), calc(var(--rise) * -0.45cqh)); opacity: 1; }
  70%  { opacity: 0.6; }
  85%  { opacity: 0.9; }
  100% { transform: translate(calc(var(--dx) * 1cqw), calc(var(--rise) * -1cqh)); opacity: 0; }
}

/* Light rays: anchored at the top; opacity pulse with a minimal sway. */
:is(#puzzle-view, #dig-view) .pz-ray {
  translate: calc(var(--ax) * -1) 0;
  transform-origin: var(--ax) 0;
  opacity: var(--hi);
  animation: pz-ray ease-in-out infinite alternate;
}
@keyframes pz-ray {
  from { opacity: var(--lo); transform: rotate(calc(var(--tilt) * -1)); }
  to   { opacity: var(--hi); transform: rotate(var(--tilt)); }
}

/* Fog: crosses from outside the frame (left) to outside the frame (right). */
:is(#puzzle-view, #dig-view) .pz-mist-layer {
  position: absolute;
  inset: 0;
}
:is(#puzzle-view, #dig-view) .pz-mist {
  left: 0;
  translate: 0 -50%;
  will-change: transform;
  animation: pz-drift linear infinite;
}
@keyframes pz-drift {
  from { transform: translateX(-100%); }
  to   { transform: translateX(100cqw); }
}

/* Leaves: the container falls and fades; the image sways and spins. */
:is(#puzzle-view, #dig-view) .pz-fall {
  position: absolute;
  top: 0;
  opacity: 0;
  animation: pz-fall linear infinite;
}
@keyframes pz-fall {
  0%   { transform: translateY(-12cqh); opacity: 0; }
  10%  { opacity: 0.95; }
  85%  { opacity: 0.95; }
  100% { transform: translateY(104cqh); opacity: 0; }
}
:is(#puzzle-view, #dig-view) .pz-fall .pz-leaf {
  position: static;
  width: 100%;
  animation: pz-sway ease-in-out infinite alternate;
}
@keyframes pz-sway {
  from { transform: translateX(calc(var(--sway) * -1cqw)) rotate(calc(var(--rot) - var(--spin))); }
  to   { transform: translateX(calc(var(--sway) * 1cqw)) rotate(calc(var(--rot) + var(--spin))); }
}

/* Spores: rise slowly with sideways drift and soft flicker. */
:is(#puzzle-view, #dig-view) .pz-spore {
  translate: -50% -50%;
  opacity: 0;
  animation: pz-spore linear infinite;
}
@keyframes pz-spore {
  0%   { transform: translate(0, 0); opacity: 0; }
  15%  { opacity: 0.9; }
  35%  { opacity: 0.45; }
  50%  { transform: translate(calc(var(--sway) * 1cqw), calc(var(--rise) * -0.5cqh)); opacity: 0.85; }
  70%  { opacity: 0.5; }
  85%  { opacity: 0.8; }
  100% { transform: translate(calc(var(--dx) * 1cqw), calc(var(--rise) * -1cqh)); opacity: 0; }
}

:is(#puzzle-view, #dig-view) .pz-bubble {
  position: absolute;
  border-radius: 50%;
  opacity: 0.35;
  animation: pz-float ease-in-out infinite alternate;
}
@keyframes pz-float {
  from { transform: translateY(0) scale(1); }
  to   { transform: translateY(-4vmin) scale(1.06); }
}

/* App in the background. */
:is(#puzzle-view, #dig-view) .pz-scene.pz-paused * { animation-play-state: paused; }

/* No motion: static background with the glow and light rays fixed. */
@media (prefers-reduced-motion: reduce) {
  :is(#puzzle-view, #dig-view) .pz-plume,
  :is(#puzzle-view, #dig-view) .pz-ember,
  :is(#puzzle-view, #dig-view) .pz-mist-layer,
  :is(#puzzle-view, #dig-view) .pz-fall,
  :is(#puzzle-view, #dig-view) .pz-spore { display: none; }
  :is(#puzzle-view, #dig-view) .pz-glow,
  :is(#puzzle-view, #dig-view) .pz-bubble { animation: none; }
  :is(#puzzle-view, #dig-view) .pz-ray { animation: none; opacity: var(--mid); }
}
