/*
 * Shared scaffolding for Aprendo Mates drill games.
 * Design tokens, base page rules, and the responsive game screen grid live
 * here so every game (times tables, sums, ordering, ...) gets the same
 * look and the same phone/tablet/desktop layout for free. A game's own
 * style.css should only contain overrides specific to that game.
 */

@font-face {
  font-family: 'claire_handbold';
  src: url('claire.woff2') format('woff2'),
       url('claire.woff') format('woff');
  font-weight: normal;
  font-style: normal;
}

:root {
  --sky: #8fc8d1;
  --purple: #98599a;
  --purple-dark: #7a4380;
  --key: #e7b6d2;
  --key-text: #5a3467;
  --pink: #e74b61;
  --green: #3cb54a;
  --red: #e63030;
  --orange: #e8912e;
  --ink: #33313f;
  --pad-width: 300px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;
  background: var(--sky);
  font-family: 'claire_handbold', 'Comic Sans MS', sans-serif;
  color: var(--ink);
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
}

#game {
  position: relative;
  width: 100%;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
}

/* ---- ambient background clouds ---- */
.clouds-layer {
  position: absolute;
  inset: 0;
  overflow: hidden;
  z-index: 0;
  pointer-events: none;
}
.cloud {
  position: absolute;
  background: #fff;
  border-radius: 60px;
  animation-name: cloudDrift;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  animation-direction: alternate;
}
.cloud::before, .cloud::after {
  content: "";
  position: absolute;
  background: #fff;
  border-radius: 50%;
}
.cloud::before { width: 55%; height: 130%; top: -55%; left: 6%; }
.cloud::after  { width: 45%; height: 100%; top: -40%; right: 8%; }
.cloud.big { opacity: 0.4; }
.cloud.small { opacity: 0.45; }
@keyframes cloudDrift {
  from { transform: translateX(0); }
  to   { transform: translateX(var(--drift, 100px)); }
}

/* ---- language switcher (flag button, top right, above every screen) ---- */
.lang-switcher {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 20;
}
.lang-current {
  display: block;
  width: 44px;
  height: 44px;
  padding: 0;
  border-radius: 50%;
  border: 3px solid #fff;
  overflow: hidden;
  cursor: pointer;
  background: #fff;
  box-shadow: 0 3px 0 rgba(0,0,0,.15);
}
.lang-current img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.lang-menu {
  position: absolute;
  top: 52px;
  right: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 8px;
  background: rgba(255,255,255,.92);
  border-radius: 18px;
  box-shadow: 0 6px 16px rgba(0,0,0,.2);
}
.lang-option {
  display: block;
  width: 38px;
  height: 38px;
  padding: 0;
  border-radius: 50%;
  border: 2px solid #fff;
  overflow: hidden;
  cursor: pointer;
  box-shadow: 0 2px 0 rgba(0,0,0,.1);
}
.lang-option img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* ---- home / section navigation (top left, mirrors .lang-switcher) ----
 * Two round buttons: the Aprendo Mates badge -> site home, and a back
 * arrow -> this game's section menu page. Visible on every screen,
 * including mid-round; the in-game HUD reserves a left gutter for it (see
 * .hud-area below). Placed as a sibling of the .screen sections so a
 * screen's overflow never clips it. */
.home-nav {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 20;
  display: flex;
  gap: 8px;
}
.home-nav-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border-radius: 50%;
  border: 3px solid #fff;
  background: #fff;
  overflow: hidden;
  cursor: pointer;
  text-decoration: none;
  box-shadow: 0 3px 0 rgba(0,0,0,.15);
  -webkit-tap-highlight-color: transparent;
  transition: transform .05s;
}
.home-nav-btn:active {
  transform: translateY(3px);
  box-shadow: 0 1px 0 rgba(0,0,0,.15);
}
.home-nav-home img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 5px;
}
.home-nav-back svg {
  width: 24px;
  height: 24px;
  fill: none;
  stroke: var(--purple-dark);
  stroke-width: 3.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ---- generic screens ---- */
.screen {
  position: absolute;
  inset: 0;
  padding: 20px;
  overflow: auto;
}
.screen-center {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  text-align: center;
  min-height: 100%;
}

[hidden] { display: none !important; }

.logo {
  width: min(220px, 40vw);
  filter: drop-shadow(0 4px 6px rgba(0,0,0,.15));
}
.mascot {
  width: min(160px, 30vw);
}
h1.title {
  font-size: clamp(28px, 6vw, 48px);
  color: var(--purple-dark);
  margin: 0;
  text-shadow: 2px 2px 0 #fff;
}
.results p {
  font-size: 22px;
  max-width: 420px;
}
.results strong { color: var(--pink); }
.results #results-time {
  font-size: 17px;
  margin-top: 6px;
  color: var(--purple-dark);
  opacity: .8;
}

.big-button {
  font-family: inherit;
  font-size: 28px;
  background: var(--pink);
  color: #fff;
  border: none;
  border-radius: 999px;
  padding: 16px 48px;
  cursor: pointer;
  box-shadow: 0 6px 0 #b5323f;
  transition: transform .05s;
}
.big-button:active {
  transform: translateY(4px);
  box-shadow: 0 2px 0 #b5323f;
}

/* ---- responsive game screen: stage (problem) + pad (input) + hud ---- */
.game-screen {
  display: grid;
  grid-template-areas: "hud" "stage" "pad";
  grid-template-rows: auto 1fr auto;
  grid-template-columns: 1fr;
  gap: 12px;
  height: 100%;
}

.hud-area {
  grid-area: hud;
  display: flex;
  flex-direction: column;
  gap: 8px;
  /* keep the score/timebar clear of the corner overlays that stay visible
     mid-round: the .home-nav cluster (top-left) and the flag switcher
     (top-right) */
  padding-left: 108px;
  padding-right: 60px;
}
.hud {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 20px;
  color: var(--purple-dark);
  font-weight: bold;
}
.hud .score::before { content: "⭐ "; }

/* Count-up stopwatch for the whole session - no countdown, nothing times
   out. Sits in the HUD slot the old draining bar used to fill. */
.hud-time {
  align-self: center;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 14px;
  background: rgba(255,255,255,.6);
  border: 2px solid #fff;
  border-radius: 999px;
  font-size: 18px;
  font-weight: bold;
  font-variant-numeric: tabular-nums;
  color: var(--purple-dark);
}
.hud-time::before { content: "⏱"; font-weight: normal; }

.stage-area {
  grid-area: stage;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  text-align: center;
  min-height: 0;
}

.pad-area {
  grid-area: pad;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Landscape / wide viewports: problem on the left, input pad on the right,
   both always visible with no scrolling. Keyed off shape (not device), so
   it adapts to whatever space is actually available. */
@media (min-width: 640px) and (orientation: landscape) {
  .game-screen {
    grid-template-areas: "hud hud" "stage pad";
    grid-template-columns: 1fr var(--pad-width);
    grid-template-rows: auto 1fr;
  }
  .hud-area { flex-direction: row; align-items: center; gap: 16px; }
  .hud { width: auto; flex: 1; }
  .hud-time { align-self: auto; margin-left: auto; }
}

/* ---- rocket progress indicator (lives inside the stage area) ---- */
.rocket-track {
  position: absolute;
  right: 2px;
  top: 0;
  bottom: 0;
  width: 50px;
  pointer-events: none;
}
.rocket-track .rail {
  position: absolute;
  left: 50%;
  top: 0; bottom: 0;
  width: 4px;
  background: rgba(255,255,255,.5);
  transform: translateX(-50%);
  border-radius: 4px;
}
.rocket-wrap {
  position: absolute;
  left: 50%;
  bottom: 0;
  transform: translate(-50%, 50%);
  transition: bottom .5s ease-out;
}
.rocket-img {
  display: block;
  width: 40px;
  height: 72px;
  object-fit: contain;
  object-position: center top;
  transform-origin: 50% 80%;
  animation: rocketTilt 2.6s ease-in-out infinite;
  filter: drop-shadow(0 4px 4px rgba(0,0,0,.15));
}
@keyframes rocketTilt {
  0%, 100% { transform: rotate(-5deg); }
  50%      { transform: rotate(5deg); }
}

/* ---- shared exercise UI: equation, typed answer, keypad, feedback ---- */
.equation {
  font-size: clamp(40px, 9vw, 80px);
  color: var(--purple-dark);
  text-shadow: 3px 3px 0 #fff;
  margin: 6px 0;
}
.answer-display {
  min-width: 140px;
  min-height: 56px;
  background: #fff;
  border-radius: 14px;
  font-size: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink);
  padding: 4px 18px;
  box-shadow: inset 0 2px 4px rgba(0,0,0,.15);
}

.keypad {
  background: var(--purple);
  border-radius: 22px;
  padding: 14px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  box-shadow: 0 8px 0 var(--purple-dark);
}
.keypad button {
  font-family: inherit;
  font-size: 26px;
  width: 62px;
  height: 62px;
  border-radius: 14px;
  border: none;
  background: var(--key);
  color: var(--key-text);
  cursor: pointer;
}
.keypad button:active { filter: brightness(0.9); }
.keypad button.wide { grid-column: span 3; width: 100%; background: #fff; color: var(--purple-dark); font-weight: bold; }
.keypad button.del { background: #d88bb0; }

/* Reserves its own row above the equation (rather than floating on top of
   it) so the pop-in message never covers the equation, the typed answer,
   or the keypad - it has its own dedicated, always-empty-until-shown slot. */
.feedback {
  flex: none;
  min-height: 52px;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 10px;
  opacity: 0;
  transform: scale(0.6);
  pointer-events: none;
}
.feedback.show {
  animation: popIn .5s ease-out forwards;
}
@keyframes popIn {
  0%   { opacity: 0; transform: scale(0.4); }
  30%  { opacity: 1; transform: scale(1.15); }
  45%  { transform: scale(1); }
  80%  { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(1) translateY(-6px); }
}
.feedback img { width: 40px; }
.feedback span {
  font-size: 26px;
  color: var(--purple-dark);
  text-shadow: 2px 2px 0 #fff;
  white-space: nowrap;
}

/* ---- columnar worksheet (sumas / restas / multiplicación) --------------
 * A right-aligned grid the child fills digit by digit, like on paper.
 * Built by shared/columnar.js from a per-problem spec; each game only
 * feeds it numbers + a grader. One leading "sign" column (+ / − / ×) then
 * `--cols` place-value columns. Rows flow top to bottom: optional carry
 * rows (small digits above the operands), the given operands, a rule line,
 * and one or more editable answer rows. */
.worksheet {
  --cols: 3;
  /* the digit size everything else is derived from. Kept as a plain
     clamp() (no nested min()/max()) so it parses everywhere. */
  --digit: clamp(21px, 6.6vw, 42px);
  /* Simple track list - only the plain integer `--cols` and keywords, NO
     calc()/clamp() inside the template (some mobile browsers drop the whole
     `grid-template-columns` if a track uses a nested math function, which
     collapses every cell into one vertical stack). The explicit max-width
     gives the 1fr columns something real to divide. */
  display: grid;
  grid-template-columns: minmax(12px, auto) repeat(var(--cols), minmax(0, 1fr));
  width: 100%;
  max-width: calc(var(--cols) * 3rem + 3rem);
  align-items: end;
  gap: 3px 5px;
  padding: 12px 14px 16px;
  background: rgba(255, 255, 255, .58);
  border: 2px solid #fff;
  border-radius: 18px;
  box-shadow: 0 6px 0 rgba(122, 67, 128, .18), inset 0 2px 6px rgba(0, 0, 0, .08);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.worksheet .ws-row { display: contents; }

/* one grid cell */
.ws-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--digit);
  color: var(--purple-dark);
  min-width: 0;
}
.ws-cell.ws-sign {
  justify-content: flex-end;
  padding-right: 4px;
  color: var(--pink);
}
.ws-cell.ws-given { text-shadow: 2px 2px 0 #fff; }
.ws-cell.ws-blank { visibility: hidden; }

/* the horizontal rule under the operands / partial products. Spans the
 * whole row (including the sign column) so grid auto-placement can never
 * tuck another cell alongside it - the next row's sign cell would land
 * beside it and shove the answer digits out of column. */
.ws-rule {
  grid-column: 1 / -1;
  height: 4px;
  border-radius: 4px;
  background: var(--purple-dark);
  margin: 4px 0 2px;
}

/* editable digit box (answer + carry cells) */
.ws-input {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 1.34em;
  border-radius: 12px;
  background: #fff;
  border: 2px solid rgba(152, 89, 154, .3);
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, .14);
  font-size: var(--digit);
  color: var(--ink);
  cursor: pointer;
  transition: box-shadow .12s, background-color .12s, transform .1s;
  -webkit-tap-highlight-color: transparent;
}
.ws-input::after { content: "\00a0"; }
.ws-input:not(:empty)::after { content: none; }
.ws-input.ws-sel {
  box-shadow: 0 0 0 4px var(--purple), inset 0 2px 4px rgba(0, 0, 0, .16);
}
.ws-input.ws-bad {
  background: #f6cccc;
  animation: wsShake .35s;
}
.ws-input.ws-good { background: #cdeccf; }
/* a carry the child skipped, filled in afterwards as an aid (not an error) */
.ws-input.ws-hint {
  background: #ffe9cf;
  border-color: var(--orange);
  color: #c26a12;
  animation: wsPop .3s ease-out;
}
.ws-input.ws-locked { color: #b9a9c4; cursor: default; box-shadow: inset 0 2px 4px rgba(0, 0, 0, .1); }
@keyframes wsShake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-4px); }
  75% { transform: translateX(4px); }
}
/* each box pops as the worked solution fills itself in (see fillSolution) */
.ws-input.ws-fill { animation: wsPop .3s ease-out; }
@keyframes wsPop {
  0% { transform: scale(.5); }
  60% { transform: scale(1.15); }
  100% { transform: scale(1); }
}

/* carry cells: a shorter row of smaller boxes tucked above the operands
 * (the grid's `align-items: end` drops them right onto the operand row) */
.ws-carry {
  width: 74%;
  min-height: 1.3em;   /* 1em here == 0.62 * --digit (font-size below) */
  font-size: 0.62em;
  border-radius: 9px;
  background: #fdeef6;
  color: var(--pink);
}
.ws-carry.ws-sel {
  box-shadow: 0 0 0 3px var(--pink), inset 0 2px 4px rgba(0, 0, 0, .16);
}

/* subtraction "llevando": a minuend digit the child has borrowed FROM.
 * The original is struck through with its reduced value above it; the
 * column to its right shows a small "1" prefix (it became e.g. 13). */
.ws-given.ws-borrowable { cursor: pointer; -webkit-tap-highlight-color: transparent; }
.ws-given.ws-borrowed .ws-digit {
  position: relative;
  opacity: .45;
}
.ws-given.ws-borrowed .ws-digit::after {
  content: "";
  position: absolute;
  left: -2px; right: -2px; top: 52%;
  height: 3px;
  background: var(--red);
  transform: rotate(-12deg);
}
/* borrow marks filled in afterwards as an aid show orange, not red */
.ws-given.ws-borrow-hint .ws-digit::after { background: var(--orange); }
.ws-mark-hint { color: var(--orange) !important; }
.ws-given { position: relative; }
.ws-given .ws-reduced,
.ws-given .ws-carried-one {
  position: absolute;
  top: -0.5em;
  font-size: .52em;
  font-weight: bold;
  line-height: 1;
  color: var(--red);
  text-shadow: 1px 1px 0 #fff;
}
.ws-given .ws-reduced { right: -2%; }
.ws-given .ws-carried-one { left: -4%; }

/* multiplication: rows outside the active step are dimmed */
.worksheet.ws-stepped .ws-step { opacity: .32; pointer-events: none; transition: opacity .3s; }
.worksheet.ws-stepped .ws-step.ws-step-active { opacity: 1; pointer-events: auto; }
