/* „Užburtas namas" — iPad-Safari-first. One stage, letterboxed, never scrolls.
   Everything inside #frame is laid out in 1600×1000 scene units; #frame is
   scaled to fit the viewport, so no CSS below needs media queries. */

@font-face {
  font-family: 'Andika';
  src: url('/fonts/Andika-Regular.ttf') format('truetype');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Andika';
  src: url('/fonts/Andika-Bold.ttf') format('truetype');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

:root {
  --amber: #F5C86E;
  --wood: #8A5A3B;
  --wood-dark: #5C3A28;
  --teal: #2E4A52;
  --paper: #F6EBD7;
  --paper-2: #E4D3B6;
  --ink: #3A2A1C;
  --moss: #7A8C5A;
  --cap: #C0503C;
  --font: 'Andika', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  position: fixed;
  overscroll-behavior: none;
  background: #1B2226;
  font-family: var(--font);
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  touch-action: manipulation;
}

#app { width: 100%; height: 100%; }

#stage {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    radial-gradient(ellipse at 50% 45%, #26313400 0%, #12181B 100%),
    #1B2226;
}

#frame {
  position: relative;
  width: 1600px;
  height: 1000px;
  flex: 0 0 auto;
  transform-origin: 50% 50%;
  overflow: hidden;
  border-radius: 6px;
  box-shadow: 0 0 90px rgba(0, 0, 0, 0.7);
}

#scene {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

#ui {
  position: absolute;
  inset: 0;
  pointer-events: none;
  font-family: var(--font);
  color: var(--ink);
}

button {
  font-family: var(--font);
  -webkit-appearance: none;
  appearance: none;
  cursor: pointer;
  touch-action: manipulation;
}

/* ---------- hotspots ---------- */

.hs { cursor: pointer; }
.hitrect { fill: transparent; }

#scene.pulsing .hs { animation: hspulse 1.05s ease-in-out 2; }
@keyframes hspulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.6; }
}

.shaking {
  transform-box: fill-box;
  transform-origin: center;
  animation: shake 0.6s ease-in-out;
}
@keyframes shake {
  10%, 90% { transform: translateX(-7px); }
  30%, 70% { transform: translateX(9px); }
  50% { transform: translateX(-9px); }
}

/* A tap that arrived while a puzzle is still pausing after a wrong answer. The
   prop twitches just enough to say „I felt that", and nothing happens. This is
   the ONLY thing a lockout ever shows: no spinner, no counter, no scold. */
.nudging {
  transform-box: fill-box;
  transform-origin: center;
  animation: nudge 0.4s ease-in-out;
}
@keyframes nudge {
  25% { transform: translateX(-3px); }
  60% { transform: translateX(3px); }
  85% { transform: translateX(-1.5px); }
}

/* an ingredient already tipped into the bowl — a ghost, so the child can see
   how far down the recipe they are */
.used { opacity: 0.32; transition: opacity 0.35s ease; }
/* …and once the pancakes are served the ghosts go entirely, or their labels
   (MILTAI, KIAUŠINIS, ŠAUKŠTAS) sit faded across the finished plate */
.consumed { display: none; }

/* delight-only idle reactions */
.twitch { transform-box: fill-box; transform-origin: 50% 100%; animation: twitch 1.4s ease-in-out; }
@keyframes twitch { 20% { transform: rotate(-2.5deg); } 45% { transform: rotate(2deg); } 70% { transform: rotate(-1deg); } }

.sway { transform-box: fill-box; transform-origin: 50% 0%; animation: sway 1.5s ease-in-out; }
@keyframes sway { 25% { transform: rotate(3deg); } 60% { transform: rotate(-2.4deg); } 85% { transform: rotate(1deg); } }

.shine { animation: shine 1.5s ease-in-out; }
@keyframes shine { 40% { filter: brightness(1.35); } }

.glow { animation: glow 4.2s ease-in-out; }
@keyframes glow { 10%, 90% { filter: brightness(1.25); } }

/* Pūkis idles: breathing always, mouth only while he speaks. */
.pukis .pukis-body { transform-box: fill-box; transform-origin: 50% 100%; animation: breathe 4.6s ease-in-out infinite; }
@keyframes breathe { 50% { transform: scaleY(1.025) scaleX(0.99); } }

.pukis .pukis-eyes { transform-box: fill-box; transform-origin: 50% 50%; animation: blink 6.2s ease-in-out infinite; }
@keyframes blink { 0%, 95%, 100% { transform: scaleY(1); } 97.5% { transform: scaleY(0.08); } }

.pukis.talking .pukis-mouth { transform-box: fill-box; transform-origin: 50% 50%; animation: talk 0.34s ease-in-out infinite; }
@keyframes talk { 50% { transform: scaleY(2.1) scaleX(0.85); } }

/* ---------- speech bubbles ---------- */

/* Explicit stacking, so DOM insertion order never decides who gets a tap:
   hud 5 < game layers 10 < tap catcher 50 < bubble 51 < sheets 60 < title 70. */
.tapcatch {
  position: absolute;
  inset: 0;
  z-index: 50;
  pointer-events: auto;
}

.bubble {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 51;
  /* Narrow on purpose. A bubble anchored on Pūkis in his corner gets pushed
     back into the middle of the room by its own width, and a wide one lands on
     whatever just opened. Short lines also suit a reader who is still sounding
     words out. */
  max-width: 640px;
  padding: 26px 36px;
  background: var(--paper);
  color: var(--ink);
  font-size: 38px;
  line-height: 1.34;
  border-radius: 30px;
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.45);
  pointer-events: none;
}
/* The resting state is VISIBLE and the entrance animates away from hidden, so
   a browser that suppresses animations (reduced motion) still shows the text. */
.bubble.in { animation: bubblein 0.22s ease-out; }
@keyframes bubblein { from { opacity: 0; transform: translateY(10px); } }

.bubble::after {
  content: '';
  position: absolute;
  left: var(--tail-x, 50%);
  margin-left: -18px;
  border: 18px solid transparent;
}
.bubble.tail-down::after { top: 100%; border-top-color: var(--paper); border-bottom: 0; }
.bubble.tail-up::after { bottom: 100%; border-bottom-color: var(--paper); border-top: 0; }

/* the house itself speaking — carved wood, not paper */
.bubble-door {
  background: var(--paper-2);
  border: 5px solid var(--wood);
  color: #4A3320;
  font-weight: 700;
}
.bubble-door.tail-down::after { border-top-color: var(--paper-2); }
.bubble-door.tail-up::after { border-bottom-color: var(--paper-2); }

/* ---------- paper overlays & panels ---------- */

.sheetwrap {
  position: absolute;
  inset: 0;
  z-index: 60;
  background: rgba(18, 12, 8, 0.66);
  pointer-events: auto;
  display: flex;
  align-items: center;
  justify-content: center;
}

.paper, .panel {
  position: relative;
  background: var(--paper);
  color: var(--ink);
  border-radius: 12px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.55);
}
.paper.in, .panel.in { animation: sheetin 0.2s ease-out; }
@keyframes sheetin { from { opacity: 0; transform: scale(0.96); } }

.paper {
  width: 900px;
  max-width: 90%;
  max-height: 88%;
  padding: 64px 74px 46px;
  overflow-y: auto;
  background-image: linear-gradient(rgba(140, 110, 70, 0.06) 1px, transparent 1px);
  background-size: 100% 56px;
}
.paper.wide { width: 1180px; }

.paper-close {
  position: absolute;
  top: 12px;
  right: 14px;
  width: 68px;
  height: 68px;
  border: none;
  border-radius: 50%;
  background: var(--wood);
  color: var(--paper);
  font-size: 34px;
  line-height: 1;
}
.paper-close:active { background: var(--wood-dark); }

.paper-body p { font-size: 35px; line-height: 1.45; margin: 0 0 24px; }
.paper-body h2 { font-size: 46px; margin: 0 0 30px; text-align: center; letter-spacing: 1px; }
.paper-body .riddle { font-weight: 700; font-size: 39px; line-height: 1.4; }
.paper-body .sign { text-align: right; font-style: italic; margin-bottom: 0; }
.paper-body ol.recipe { margin: 0; padding-left: 54px; }
.paper-body ol.recipe li { font-size: 36px; line-height: 1.4; margin-bottom: 22px; }


.panel {
  padding: 56px 64px 48px;
  text-align: center;
  max-width: 94%;
}
.panel-note { font-size: 32px; margin: 0 0 18px; }
.panel-task { font-size: 38px; font-weight: 700; line-height: 1.4; margin: 0 0 24px; }

/* the clock panel swaps between grandma's note and the steppers in place */
.panel-body { display: block; }
.panel-actions { display: flex; align-items: center; justify-content: center; gap: 26px; }

/* „Raštelis" — small on purpose. It reopens the note mid-puzzle; it must be
   findable without competing with „Pažadinti". */
.notebtn {
  border: 3px solid var(--wood);
  border-radius: 16px;
  background: var(--paper-2);
  color: var(--ink);
  font-size: 30px;
  font-weight: 700;
  padding: 14px 28px;
}
.notebtn:active { background: var(--wood); color: var(--paper); }

/* P2 — the letter dials. The panel sits low and dims lightly, so the six
   framed pictures on the wall above stay readable while the child turns the
   dials. That is the whole puzzle: look up, then set a letter. */
.dialpanel-wrap {
  align-items: flex-end;
  padding-bottom: 26px;
  background: rgba(18, 12, 8, 0.42);
}
/* Sitting low is not enough on its own: at the default panel padding the top
   edge landed across the middle of the picture frames, so the hint that sends
   the child to look at them pointed at half a duck. The panel now carries a
   „Mįslės" button as well, so the room it gives back comes off the top — the
   one-line reminder is short and centred, and never reaches the ✕. */
.dialpanel { padding: 34px 64px 24px; }
.dialpanel .panel-note { margin-bottom: 14px; }
.dialpanel .panel-actions { margin-top: 18px; }
.dialpanel .dial { gap: 6px; }
.dials { display: flex; gap: 16px; justify-content: center; }
.dial { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.dial-letter {
  width: 108px;
  height: 112px;
  line-height: 112px;
  background: var(--paper-2);
  border-radius: 14px;
  font-size: 66px;
  font-weight: 700;
  color: var(--ink);
}
.dialbtn {
  width: 108px;
  height: 74px;
  border: none;
  border-radius: 14px;
  background: var(--wood);
  color: var(--paper);
  font-size: 36px;
  line-height: 1;
}
.dialbtn:active { background: var(--wood-dark); }

/* P3 — the clock */
.clock-face {
  font-size: 104px;
  font-weight: 700;
  margin: 6px 0 18px;
  letter-spacing: 2px;
}
.steppers { display: flex; gap: 72px; justify-content: center; margin-bottom: 34px; }
.stepper-label { font-size: 30px; font-weight: 700; margin-bottom: 12px; letter-spacing: 1px; }
.stepper-ctl { display: flex; gap: 16px; }
.stepper-ctl .dialbtn { width: 92px; height: 92px; font-size: 46px; }

.bigbutton {
  border: none;
  border-radius: 22px;
  background: var(--cap);
  color: var(--paper);
  font-size: 46px;
  font-weight: 700;
  padding: 22px 60px;
  box-shadow: 0 8px 0 rgba(0, 0, 0, 0.22);
}
.bigbutton:active { transform: translateY(4px); box-shadow: 0 4px 0 rgba(0, 0, 0, 0.22); }
.bigbutton.ghost { background: var(--moss); }

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

.hud {
  position: absolute;
  z-index: 5;
  left: 28px;
  top: 22px;
  display: flex;
  align-items: center;
  gap: 24px;
  pointer-events: none;
  padding: 10px 20px 10px 14px;
  border-radius: 20px;
  background: rgba(20, 14, 10, 0.34);
}
.hud[hidden] { display: none; }
/* steps aside while anyone is speaking — see Engine.say() */
.hud { transition: opacity 0.18s ease; }
.hud.dimmed { opacity: 0; }
/* The four brass letter-wheels. A wheel that has not been found yet is a faint
   outline in its place, so the row reads „four of these, you have two" at a
   glance — and NOTHING in it is a letter. The whole point of the rebuild is
   that the child's inventory cannot spell the door's word. */
.hud-wheels { display: flex; gap: 10px; }
.hud-wheel svg { width: 62px; height: 62px; display: block; }
.hud-wheel .w-disc { fill: rgba(246, 235, 215, 0.08); stroke: rgba(246, 235, 215, 0.34); stroke-width: 2; }
.hud-wheel .w-rim { stroke: rgba(246, 235, 215, 0.26); }
.hud-wheel .w-ticks { stroke: rgba(246, 235, 215, 0.26); }
.hud-wheel .w-hub { fill: rgba(246, 235, 215, 0.2); }
.hud-wheel.lit .w-disc { fill: #C9973F; stroke: var(--amber); }
.hud-wheel.lit .w-rim { stroke: #7A5518; }
.hud-wheel.lit .w-ticks { stroke: #6B4A14; }
.hud-wheel.lit .w-hub { fill: #F6DFAE; }

.hud-items { display: flex; gap: 12px; }
.hud-item svg { width: 54px; height: 54px; display: block; }

/* ---------- title & ending ---------- */

.gamelayer { position: absolute; inset: 0; z-index: 10; pointer-events: none; }
.gamelayer > * { pointer-events: auto; }

.titlescreen {
  position: absolute;
  inset: 0;
  z-index: 70;
  pointer-events: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 24px;
  background: rgba(22, 16, 12, 0.8);
}
.title-h1 {
  margin: 0;
  font-size: 124px;
  font-weight: 700;
  color: var(--amber);
  text-shadow: 0 8px 26px rgba(0, 0, 0, 0.6);
  text-align: center;
}
.title-sub { margin: 0 0 26px; font-size: 46px; color: var(--paper); text-align: center; }
.title-buttons { display: flex; gap: 36px; }

.endingui {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 34px;
  padding-bottom: 64px;
}
/* The closing line lands on the busiest part of the garden — hollyhocks, the
   path, the watering can — and dark brown on mid-green is not a readable pair.
   It carries its own light instead: a halo that hugs the letters, so the line
   is legible over every colour under it while the garden stays whole. A scrim
   panel would read as a caption bar and wipe out the art it sits on. */
.ending-quiet {
  margin: 0;
  font-size: 44px;
  color: var(--ink);
  text-align: center;
  text-shadow:
    0 0 10px rgba(255, 252, 242, 0.98),
    0 0 20px rgba(255, 252, 242, 0.95),
    0 0 34px rgba(255, 252, 242, 0.8),
    0 0 54px rgba(255, 252, 242, 0.55);
}

/* ---------- P5 — the door's four wheels ---------- */

/* Centred, unlike the chest: nothing behind this panel is a clue, so there is
   nothing to keep visible. The wheels are brass rather than paper, so the lock
   reads as the thing bolted to the door and not as another sheet to read. */
.doorpanel { padding: 40px 64px 30px; }
/* The padding is what keeps the title clear of the ✕: the panel is sized by its
   widest child, so the title carries its own gutter on BOTH sides — the corner
   button gets its room and the line stays centred over the wheels. */
.doorpanel .panel-note {
  font-size: 34px;
  font-weight: 700;
  margin: 0 auto 22px;
  padding: 0 64px;
}
.doorpanel .dials { gap: 20px; }
.doorpanel .panel-actions { margin-top: 24px; }
.doorpanel .dial-letter {
  background: #E8C07A;
  border: 4px solid #A87C33;
  line-height: 104px; /* the 112px box minus its own border */
  color: #3A2A10;
}

/* the light that floods out when the door opens */
.lightburst::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(circle at 50% 42%, rgba(255, 242, 208, 0.95), rgba(255, 242, 208, 0) 62%);
  animation: burst 1.4s ease-out;
}
@keyframes burst { 0% { opacity: 0; } 25% { opacity: 1; } 100% { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; }
}
