/*
  ============================================================
  DODO STORYLAND — GAME SHELL STYLES
  ============================================================
  Shared visual chrome for every game page. Loaded AFTER the main
  site's styles.css (for the color tokens, fonts and button styles)
  and BEFORE each game's own <name>.css (for its scene-specific
  layout). Keeping this shared means every future game automatically
  looks like it belongs on Dodo Storyland, and a brand color tweak in
  the main styles.css flows through to the games too.
  ============================================================
*/

html, body{ height:100%; }
body.game-body{
  margin:0; overflow:hidden; background:var(--bg); color:var(--ink);
  font-family:"Segoe UI","Trebuchet MS",system-ui,-apple-system,Roboto,sans-serif;
  -webkit-font-smoothing:antialiased;
  touch-action:manipulation;
}

.game-screen{
  position:relative; width:100%; height:100vh; height:100dvh; overflow:hidden;
  display:flex; flex-direction:column;
}

/* ---------- top bar: back button + sound toggle ---------- */
.game-topbar{
  position:relative; z-index:20; display:flex; align-items:center; justify-content:space-between;
  padding:12px 14px; gap:10px; flex-wrap:wrap;
}
.game-topbar .btn{ min-height:44px; }
.game-back{
  display:inline-flex; align-items:center; gap:6px; padding:10px 18px; border-radius:999px;
  background:var(--surface); border:2px solid var(--line); color:var(--ink); font-weight:800;
  text-decoration:none; font-size:0.9rem; min-height:44px; box-shadow:0 4px 0 var(--line);
}
.game-back:hover{ transform:translateY(-1px); }
.game-sound-toggle{
  display:inline-flex; align-items:center; gap:6px; padding:10px 18px; border-radius:999px;
  background:var(--surface); border:2px solid var(--line); color:var(--ink); font-weight:800;
  font-size:0.9rem; cursor:pointer; min-height:44px; box-shadow:0 4px 0 var(--line);
}
.game-sound-toggle:hover{ transform:translateY(-1px); }

.game-progress{
  position:relative; z-index:20; text-align:center; font-weight:800; font-size:0.85rem;
  color:var(--ink-soft); padding:0 14px 8px;
}
.game-progress-bar{
  max-width:340px; margin:6px auto 0; height:8px; border-radius:999px; background:var(--line); overflow:hidden;
}
.game-progress-fill{
  height:100%; border-radius:999px; background:linear-gradient(90deg, var(--coral), var(--gold));
  transition:width .35s ease;
}

/* ---------- the scene itself ---------- */
.game-stage{
  position:relative; flex:1; margin:0 14px 14px; border-radius:28px; overflow:hidden;
  box-shadow:var(--shadow);
}

.confetti-canvas{ position:absolute; inset:0; z-index:15; pointer-events:none; width:100%; height:100%; }

/* ---------- character + speech bubble ----------
   A single character image, animated into many different "states"
   purely with CSS transforms (no extra art needed): idle breathing,
   searching side to side, thinking, surprised, confused, happy,
   excited and celebrating, plus a one-time entrance when the game
   opens. This is what keeps BunBun/Ellie feeling like a present,
   reacting character instead of a sticker glued next to the game. */
.game-character{
  position:absolute; z-index:10; display:flex; flex-direction:column; align-items:center;
  filter:drop-shadow(0 10px 14px rgba(0,0,0,0.22));
}
.game-character img{ display:block; width:100%; height:100%; object-fit:contain; transform-origin:50% 85%; }

/* One-time entrance: hops in from off-stage before the first line. */
.game-character.is-entering img{ animation:char-entrance .9s cubic-bezier(.34,1.56,.64,1) both; }
@keyframes char-entrance{
  0%{ transform:translateX(var(--enter-from,-140%)) scale(0.7) rotate(-8deg); opacity:0; }
  55%{ transform:translateX(calc(var(--enter-from,-140%) * 0.08)) scale(1.08) rotate(4deg); opacity:1; }
  75%{ transform:translateX(0) scale(0.97) rotate(-2deg); }
  100%{ transform:translateX(0) scale(1) rotate(0deg); }
}

.char-idle img{ animation:char-bob 3.6s ease-in-out infinite; }
.char-looking img{ animation:char-looking 2.6s ease-in-out; }
.char-thinking img{ animation:char-thinking-tilt 1.1s ease; }
.char-surprised img{ animation:char-surprised-pop .5s ease; }
.char-confused img{ animation:char-confused-wiggle .9s ease; }
.char-happy img{ animation:char-happy-bounce .7s ease; }
.char-excited img{ animation:char-excited-bounce .8s ease; }
.char-oops img{ animation:char-oops-shake .55s ease; }
.char-celebrate img{ animation:char-celebrate-jump 1.1s ease; }

@keyframes char-bob{ 0%,100%{ transform:translateY(0) rotate(0deg);} 50%{ transform:translateY(-7px) rotate(-1deg);} }
@keyframes char-looking{
  0%,100%{ transform:rotate(0deg) translateX(0); }
  20%{ transform:rotate(-9deg) translateX(-5px); }
  50%{ transform:rotate(0deg) translateX(0); }
  70%{ transform:rotate(9deg) translateX(5px); }
  90%{ transform:rotate(0deg) translateX(0); }
}
@keyframes char-thinking-tilt{
  0%{ transform:rotate(0deg) scale(1); } 30%{ transform:rotate(-8deg) scale(1.02); }
  70%{ transform:rotate(-6deg) scale(1.02); } 100%{ transform:rotate(0deg) scale(1); }
}
@keyframes char-surprised-pop{
  0%{ transform:scale(1) translateY(0); } 35%{ transform:scale(1.18) translateY(-8px) rotate(-3deg); }
  60%{ transform:scale(0.96) translateY(2px) rotate(2deg); } 100%{ transform:scale(1) translateY(0) rotate(0deg); }
}
@keyframes char-confused-wiggle{
  0%,100%{ transform:rotate(0deg); } 15%{ transform:rotate(-10deg); } 35%{ transform:rotate(8deg); }
  55%{ transform:rotate(-6deg); } 75%{ transform:rotate(4deg); } 90%{ transform:rotate(-2deg); }
}
@keyframes char-happy-bounce{
  0%{ transform:scale(1) translateY(0);} 30%{ transform:scale(1.12,0.9) translateY(6px);}
  55%{ transform:scale(0.95,1.12) translateY(-22px) rotate(-4deg);} 75%{ transform:scale(1.05,0.96) translateY(0) rotate(3deg);}
  100%{ transform:scale(1) translateY(0) rotate(0deg);}
}
@keyframes char-excited-bounce{
  0%{ transform:scale(1) translateY(0) rotate(0deg); }
  20%{ transform:scale(1.1,0.92) translateY(4px) rotate(-3deg); }
  40%{ transform:scale(0.94,1.1) translateY(-18px) rotate(5deg); }
  60%{ transform:scale(1.08,0.94) translateY(2px) rotate(-4deg); }
  80%{ transform:scale(0.97,1.05) translateY(-10px) rotate(3deg); }
  100%{ transform:scale(1) translateY(0) rotate(0deg); }
}
@keyframes char-oops-shake{
  0%,100%{ transform:translateX(0) rotate(0deg);} 25%{ transform:translateX(-6px) rotate(-4deg);}
  50%{ transform:translateX(5px) rotate(3deg);} 75%{ transform:translateX(-3px) rotate(-2deg);}
}
@keyframes char-celebrate-jump{
  0%{ transform:translateY(0) rotate(0deg) scale(1);} 15%{ transform:translateY(-32px) rotate(-10deg) scale(1.1);}
  30%{ transform:translateY(0) rotate(8deg) scale(0.95);} 45%{ transform:translateY(-22px) rotate(-8deg) scale(1.08);}
  60%{ transform:translateY(0) rotate(6deg) scale(0.97);} 75%{ transform:translateY(-12px) rotate(-4deg) scale(1.04);}
  90%{ transform:translateY(0) rotate(2deg) scale(0.99);} 100%{ transform:translateY(0) rotate(0deg) scale(1);}
}
@media (prefers-reduced-motion:reduce){
  .char-idle img,.char-looking img,.char-thinking img,.char-surprised img,.char-confused img,
  .char-happy img,.char-excited img,.char-oops img,.char-celebrate img,
  .game-character.is-entering img{ animation:none; }
}

/* ---------- living background: drifting clouds + twinkling motes ----------
   Cheap, CSS-only ambient motion so the scene never feels like a static
   wallpaper behind the gameplay. Used sparingly — a few of each, slow,
   low-contrast — so they read as atmosphere, not distraction. */
.env-decor{ position:absolute; pointer-events:none; z-index:1; }
.env-cloud{
  background:rgba(255,255,255,0.75); border-radius:999px; filter:blur(0.5px);
  animation:env-drift linear infinite;
}
.env-cloud::before, .env-cloud::after{
  content:""; position:absolute; background:inherit; border-radius:999px;
}
.env-cloud::before{ width:60%; height:75%; top:-35%; left:8%; }
.env-cloud::after{ width:45%; height:60%; top:-25%; right:10%; }
@keyframes env-drift{ from{ transform:translateX(-12vw); } to{ transform:translateX(112vw); } }
.env-mote{
  width:6px; height:6px; border-radius:50%; background:rgba(255,255,255,0.85);
  animation:env-twinkle ease-in-out infinite;
}
@keyframes env-twinkle{
  0%,100%{ opacity:0; transform:translateY(0) scale(0.7); }
  50%{ opacity:0.9; transform:translateY(-14px) scale(1); }
}
.env-sway{ transform-origin:50% 100%; animation:env-sway-rock ease-in-out infinite; }
@keyframes env-sway-rock{ 0%,100%{ transform:rotate(-3deg); } 50%{ transform:rotate(3deg); } }
@media (prefers-reduced-motion:reduce){
  .env-cloud, .env-mote, .env-sway{ animation:none; }
}

.speech-bubble-game{
  position:absolute; z-index:11; max-width:min(72vw,320px); text-align:center;
  background:var(--surface); color:var(--ink); border:2px solid var(--line); border-radius:20px;
  padding:12px 18px; font-weight:800; font-size:clamp(0.95rem,2.4vw,1.15rem); line-height:1.3;
  box-shadow:var(--shadow); opacity:0; transform:translateY(8px) scale(0.92); pointer-events:none;
  transition:opacity .18s ease, transform .18s ease;
}
.speech-bubble-game::after{
  content:""; position:absolute; bottom:-10px; left:32px; width:18px; height:18px;
  background:var(--surface); border-right:2px solid var(--line); border-bottom:2px solid var(--line);
  transform:rotate(45deg);
}
.speech-bubble-game.is-visible{ opacity:1; transform:translateY(0) scale(1); }

/* ---------- generic tappable game object (letters / balloons) ----------
   Positioning and floating are split across two elements on purpose:
   .game-object-wrap holds the fixed left/top/centering transform (set
   once by JS and never animated), while the .game-object button inside
   it carries the floating/correct/wrong animations. Animating transform
   on the SAME element that also uses transform for centering would let
   the animation silently overwrite the centering offset — this keeps
   them independent. */
.game-object-wrap{ position:absolute; }
.game-object{
  display:flex; align-items:center; justify-content:center; width:100%; height:100%;
  border:none; background:none; padding:0; cursor:pointer; -webkit-tap-highlight-color:transparent;
  touch-action:manipulation; user-select:none;
}
.game-object:focus-visible{ outline:3px solid var(--blue); outline-offset:4px; border-radius:16px; }
.game-object.is-floating{ animation:obj-float 3.4s ease-in-out infinite; }
@keyframes obj-float{ 0%,100%{ transform:translateY(0);} 50%{ transform:translateY(-9px);} }
.game-object.is-correct{ animation:obj-correct .6s ease forwards; z-index:5; }
@keyframes obj-correct{
  0%{ transform:scale(1);} 35%{ transform:scale(1.35) rotate(-6deg);} 65%{ transform:scale(1.15) rotate(4deg);}
  100%{ transform:scale(1.2) rotate(0deg); opacity:0;}
}
.game-object.is-wrong{ animation:obj-wrong .5s ease; }
@keyframes obj-wrong{
  0%,100%{ transform:translateX(0) rotate(0deg);} 20%{ transform:translateX(-8px) rotate(-6deg);}
  40%{ transform:translateX(7px) rotate(5deg);} 60%{ transform:translateX(-5px) rotate(-3deg);} 80%{ transform:translateX(3px) rotate(2deg);}
}
@media (prefers-reduced-motion:reduce){
  .game-object.is-floating{ animation:none; }
  .game-object.is-correct{ animation:obj-correct-simple .3s ease forwards; }
  .game-object.is-wrong{ animation:none; }
  @keyframes obj-correct-simple{ to{ transform:scale(1.15); opacity:0; } }
}

/* ---------- completion overlay ---------- */
.completion-overlay{
  position:absolute; inset:0; z-index:30; display:flex; align-items:center; justify-content:center;
  background:color-mix(in srgb, var(--ink) 55%, transparent);
  opacity:0; pointer-events:none; transition:opacity .25s ease;
}
.completion-overlay.is-visible{ opacity:1; pointer-events:auto; }
.completion-card{
  background:var(--surface); border-radius:28px; padding:36px 30px; text-align:center; max-width:360px;
  box-shadow:0 24px 50px -12px rgba(0,0,0,0.5); transform:translateY(12px); transition:transform .25s ease;
}
.completion-overlay.is-visible .completion-card{ transform:translateY(0); }
.completion-title{ font-size:1.6rem; font-weight:800; margin:0 0 8px; }
.completion-subtitle{ color:var(--ink-soft); margin:0 0 22px; font-size:1rem; }
.completion-actions{ display:flex; gap:12px; justify-content:center; flex-wrap:wrap; }

@media (max-width:600px){
  .game-topbar{ padding:10px; }
  .game-stage{ margin:0 8px 8px; border-radius:20px; }
}
