/* ============================================================
   Jugnu Jar — css/games.css
   Jugnu Merge.

   Merge runs a night palette because fireflies need the dark.
   The shared furniture below — level badge, goal bar, combo pip,
   the session bar and the teaching line — is prefixed `.mg-` but
   is not Merge's alone; a second game pairs its own prefix onto
   these selectors rather than restating them.
   ============================================================ */

/* ---- activity cards and pills ---- */

.act-card.merge  { background: linear-gradient(150deg, #c9a9ff, #5b3bb8); }
.act-card.gate   { background: linear-gradient(150deg, #7fd8ff, #12508f); }

.act-pill.merge  { background: #efe6ff; color: #58329e; }
.act-pill.gate   { background: #e2f4ff; color: #0d4a86; }

/* The home tile.
   `color` and the .age-badge override are NOT optional: .subject-card is
   dark-ink-on-light by default, so a dark tile without them renders dark text
   on a dark background. That shipped once, at 1.75 contrast. */
.subject-card.games { background: linear-gradient(150deg, #6b5bd6, #35246e); color: #fff; }
.subject-card.games .age-badge { background: rgba(255,255,255,.28); color: #fff; }

/* ---- shared furniture ---- */

.mg-screen, .rc-screen {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 720px;
  margin: 0 auto;
  width: 100%;
}
.mg-top, .rc-top {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  flex-wrap: wrap;
}
.mg-side, .rc-side {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
}

/* The level badge: a name, not a number, so a child can say it out loud. */
.mg-level, .rc-level {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 12px;
  border-radius: var(--r-pill);
  background: hsl(var(--lv-hue, 38) 70% 92%);
  color: hsl(var(--lv-hue, 38) 70% 24%);
  font-weight: 900;
  font-size: 14px;
  white-space: nowrap;
  transition: transform .2s ease;
}
.mg-level-emoji, .rc-level-emoji { font-size: 18px; line-height: 1; }
.mg-level.levelled, .rc-level.levelled { animation: lv-pop .9s ease; }
@keyframes lv-pop {
  0%, 100% { transform: scale(1); }
  30%      { transform: scale(1.3) rotate(-4deg); }
  60%      { transform: scale(1.12); }
}

/* How far round the current level. A bar rather than a number, because the
   number that matters is the count of things made. */
.mg-goal, .rc-goal {
  width: 110px;
  height: 7px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .25);
  overflow: hidden;
}
/* One `> i`, not two. The DOM is `div.mg-goal > i`, so `> i > i` matched
   nothing and the goal bar has never filled in either game — it just sat
   there as an empty groove. */
.mg-goal > i, .rc-goal > i {
  display: block; height: 100%; width: 0;
  border-radius: var(--r-pill);
  background: linear-gradient(90deg, #ffd45e, #ff9f1c);
  transition: width .3s ease;
}

.mg-combo, .rc-combo {
  font-size: 12px;
  font-weight: 900;
  color: #ffd45e;
  min-height: 1em;
  white-space: nowrap;
}

/* The session bar. How much of the night is left — never how long you have
   for THIS one. Hideable, because a visible countdown on a single question is
   the part of timing that does measurable harm. */
.mg-dawn, .rc-lap {
  height: 10px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .18);
  overflow: hidden;
}
.mg-dawn > i, .rc-lap > i {
  display: block; height: 100%; width: 0;
  border-radius: var(--r-pill);
  background: linear-gradient(90deg, #4a3a8c, #ffb02e, #ffe98a);
  transition: width .25s linear;
}
.mg-dawn.hidden, .rc-lap.hidden { display: none; }

.mg-says, .rc-says {
  text-align: center;
  font-weight: 800;
  font-size: clamp(14px, 3.4vw, 17px);
  min-height: 2.6em;
  margin: 0;
  padding: 7px 12px;
  border-radius: var(--r-md);
  background: rgba(255, 255, 255, .14);
  color: #fff;
}
.mg-says.good, .rc-says.good { background: rgba(126, 217, 87, .28); color: #eaffe2; }
.mg-says.warn, .rc-says.warn { background: rgba(255, 176, 46, .26); color: #fff3dd; }

.mg-skip, .rc-skip { width: 40px; height: 40px; font-size: 19px; }

/* ============================================================
   Jugnu Merge
   ============================================================ */

.mg-jar {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 8px 22px 10px;
  border-radius: var(--r-lg);
  background: linear-gradient(170deg, rgba(149, 210, 218, .32), rgba(74, 151, 168, .5));
  border: 3px solid rgba(255, 255, 255, .45);
  box-shadow: var(--shadow-1);
  min-width: 132px;
}
.mg-jar-label { font-size: 13px; font-weight: 800; color: rgba(255,255,255,.9); letter-spacing: .04em; }
.mg-target {
  font-size: clamp(38px, 11vw, 56px);
  font-weight: 900;
  line-height: 1.05;
  color: #fff;
  text-shadow: 0 2px 8px rgba(20, 12, 45, .5);
}
.mg-made { font-size: 13px; font-weight: 800; color: #ffe98a; }

.mg-sky {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
  min-height: 300px;
  max-height: 56vh;
  border-radius: var(--r-lg);
  background:
    radial-gradient(circle at 20% 18%, rgba(120, 100, 220, .35), transparent 45%),
    radial-gradient(circle at 78% 72%, rgba(80, 60, 170, .4), transparent 50%),
    linear-gradient(170deg, #241a52, #120c2c);
  background-color: #1a1240;
  border: 3px solid rgba(255, 255, 255, .16);
  overflow: hidden;
  touch-action: none;          /* dragging a firefly must not scroll the page */
}

/* A firefly's size carries its value — see sizeFor() — so the number stops
   being a label painted on a light and becomes a quantity you can see. */
.jugnu {
  position: absolute;
  transform: translate(-50%, -50%);
  border: 0;
  border-radius: 50%;
  padding: 0;
  cursor: grab;
  display: grid;
  place-items: center;
  background: radial-gradient(circle at 35% 30%, #fffbe6, #ffc93c);
  box-shadow: 0 0 14px 4px rgba(255, 216, 110, .5);
  animation: jugnu-glow 2.4s ease-in-out infinite;
  transition: box-shadow .18s ease, filter .18s ease;
  touch-action: none;
}
.jugnu:active { cursor: grabbing; }
.jugnu-num {
  font-size: clamp(16px, 4.4vw, 22px);
  font-weight: 900;
  color: #4a3208;
  pointer-events: none;
}
.jugnu.held {
  box-shadow: 0 0 0 4px #fff, 0 0 22px 9px rgba(255, 216, 110, .85);
  z-index: 3;
}
.jugnu.merged  { animation: jugnu-merge .26s ease; }
.jugnu.reject  { animation: jugnu-reject .42s ease; }
.jugnu.arriving{ animation: jugnu-arrive .5s ease; }
.jugnu.into-jar{ animation: jugnu-jar .28s ease forwards; }

@keyframes jugnu-glow {
  0%, 100% { box-shadow: 0 0 12px 3px rgba(255, 216, 110, .42); }
  50%      { box-shadow: 0 0 18px 7px rgba(255, 216, 110, .72); }
}
@keyframes jugnu-merge {
  0%   { transform: translate(-50%, -50%) scale(.75); }
  55%  { transform: translate(-50%, -50%) scale(1.22); }
  100% { transform: translate(-50%, -50%) scale(1); }
}
@keyframes jugnu-reject {
  0%, 100% { transform: translate(-50%, -50%); }
  25%      { transform: translate(-62%, -50%) rotate(-8deg); }
  75%      { transform: translate(-38%, -50%) rotate(8deg); }
}
@keyframes jugnu-arrive {
  0%   { transform: translate(-50%, -50%) scale(0); opacity: 0; }
  100% { transform: translate(-50%, -50%) scale(1); opacity: 1; }
}
@keyframes jugnu-jar {
  0%   { transform: translate(-50%, -50%) scale(1); opacity: 1; }
  100% { transform: translate(-50%, -260%) scale(.25); opacity: 0; }
}

/* Reduced motion: the fireflies hold station and stop pulsing. Every number is
   still there, still draggable, still tappable — the game is unchanged, it
   simply stops moving. */
.mg-sky.still .jugnu { animation: none; }

/* ============================================================
   The end-of-game card — built to be held up to a grown-up
   ============================================================ */

.game-result { max-width: 420px; }
.gr-badge {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 8px 18px;
  margin: 0 auto 6px;
  border-radius: var(--r-pill);
  background: hsl(var(--gr-hue, 38) 72% 92%);
  color: hsl(var(--gr-hue, 38) 72% 24%);
}
.gr-emoji { font-size: 30px; line-height: 1; }
.gr-level { font-size: 21px; font-weight: 900; }
.gr-crossed {
  font-size: 15px;
  font-weight: 900;
  color: #b3560a;
  margin-bottom: 4px;
}
/* One huge number, because it is the thing the child is meant to say. */
.gr-made { display: flex; align-items: baseline; justify-content: center; gap: 8px; margin: 2px 0; }
.gr-number { font-size: clamp(48px, 15vw, 70px); font-weight: 900; line-height: 1; color: var(--c-ink); }
.gr-noun { font-size: 19px; font-weight: 800; color: var(--c-ink-soft); }
.gr-best { font-size: 14px; font-weight: 700; color: var(--c-ink-soft); }
.gr-combo { font-size: 13px; font-weight: 800; color: #b3560a; margin-top: 2px; }
.gr-brag {
  margin: 10px 0 4px;
  padding: 9px 12px;
  border-radius: var(--r-md);
  background: #f4f0ff;
  font-size: 15px;
  font-weight: 800;
  color: #4a3a8c;
}

/* A single shake, reserved for crossing a level. Testing four levels of
   feedback on 3,018 players found EXTREME juice as harmful as none at all,
   so this is deliberately not wired to ordinary correct answers. */
#screen-root.shake { animation: screen-shake .26s ease; }
@keyframes screen-shake {
  0%, 100% { transform: translate(0, 0); }
  20%      { transform: translate(-5px, 3px); }
  40%      { transform: translate(5px, -3px); }
  60%      { transform: translate(-3px, -2px); }
  80%      { transform: translate(3px, 2px); }
}

@media (max-width: 420px) {
  .mg-sky { min-height: 260px; }
}

/* ============================================================
   Gate Racer — the road, the arches and the two convoys

   The canvas carries the spectacle; the two gates are real
   <button>s laid over it. That is deliberate. It buys keyboard
   access, screen-reader labels, proper touch targets and a
   version that still plays under reduced motion, none of which
   a canvas hit-test gives you for free.

   Note the prefix is `.rc-`, not `.gr-`. `.gr-` already belongs
   to the end-of-game result card, and `.gr-level`, `.gr-made`
   and `.gr-combo` collided exactly — the same class of bug as
   the story reader inheriting `.speaking` from animations.css.
   ============================================================ */

.rc-made {
  font-size: 19px; font-weight: 900; color: #ffd96b;
  text-shadow: 0 1px 0 rgba(0,0,0,.35);
}

.rc-stage {
  position: relative;
  width: 100%;
  border-radius: var(--r-lg);
  overflow: hidden;
  border: 3px solid rgba(255,255,255,.28);
  box-shadow: var(--shadow-1);
}

.rc-road {
  display: block;
  width: 100%;
  height: clamp(300px, 46vh, 430px);
  touch-action: manipulation;
}

/* The two gates. Transparent, because colour must not tell a child which one
   is better — that is the single thing that makes the commercial version of
   this mechanic fake. Both arches look identical and always will. */
.rc-pick {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 50%;
  border: 0;
  background: transparent;
  cursor: pointer;
  padding: 0;
  display: flex;
  align-items: flex-start;
  justify-content: center;
}
.rc-pick-l { left: 0; }
.rc-pick-r { right: 0; }
.rc-pick:disabled { cursor: default; }

/* The label is drawn on the canvas arch; this one is for focus and for the
   moment a keyboard user needs to see where they are. */
.rc-pick-label {
  margin-top: 8px;
  padding: 2px 10px;
  border-radius: var(--r-pill);
  font-size: 15px;
  font-weight: 800;
  color: transparent;
}
.rc-pick:focus-visible { outline: none; }
.rc-pick:focus-visible .rc-pick-label {
  color: #21304f;
  background: #fff;
  box-shadow: 0 0 0 3px #ffd96b;
}
.rc-pick:not(:disabled):hover .rc-pick-label {
  background: rgba(255,255,255,.22);
}

@media (max-height: 760px) {
  .rc-road { height: clamp(260px, 40vh, 340px); }
}
