/* nimiq.kids — kid tablet app skin. Same Nimiq brand tokens as app.css,
   but bigger and chunkier: users are 4-8, may not read yet, and poke with whole
   fingers. Emoji carry the meaning; text is decoration. Tuned for 800x1280 portrait. */

@font-face {
  font-family: 'Mulish';
  font-style: normal;
  font-weight: 200 1000;
  font-display: swap;
  src: url('/fonts/mulish-latin-wght-normal.woff2') format('woff2');
}

:root {
  --navy: #1F2348;
  --purple: #260133;
  --blue: #0582CA;
  --blue-2: #265DD7;
  --green: #21BCA5;
  --green-2: #41A38E;
  --gold: #E9B213;
  --orange: #EC991C;
  --red: #D94432;
  --card: #ffffff;
  --ink: #1F2348;
  --muted: rgba(31, 35, 72, 0.5);
  --r-pill: 500px;

  /* ---- the kid-app token set --------------------------------------------
     Four stylesheets had each re-typed the same decisions by hand: nine card
     radii, two elevations, seven press scales, sixteen literal copies of the
     Nimiq easing. Everything below is the single source of truth for those.
     Consumers all point here now; the transitional --r-card-legacy and the
     old --card-shadow are gone.

     Values come from the nimiq-ui scale, not from taste: radii are the
     published tier (pill / card 10 / tile 12 / small 6 / circle), elevation is
     the app-card and CTA shadow, and motion is --nimiq-ease with the spring
     reserved for :active only. */

  /* radius */
  --r-card: 10px;
  --r-tile: 12px;
  --r-small: 6px;
  --r-sheet: 24px;

  /* elevation */
  --sh-card: 0 8px 56px rgba(0, 0, 0, 0.111);
  --sh-cta: 0 8px 24px rgba(0, 0, 0, 0.15);

  /* motion — --nimiq-ease already ships on html{} from the legacy stylesheet */
  --ease: var(--nimiq-ease, var(--ease));
  --spring: cubic-bezier(0.41, 0.34, 0.26, 1.55);
  --t-press: 140ms;
  --t-ui: 250ms;
  --press-scale: 0.96;

  /* ink ladder + fills */
  --ink-70: rgba(31, 35, 72, 0.7);
  --ink-50: rgba(31, 35, 72, 0.5);
  --ink-30: rgba(31, 35, 72, 0.3);
  --fill-5: rgba(31, 35, 72, 0.05);
  --fill-6: rgba(31, 35, 72, 0.06);
  --fill-10: rgba(31, 35, 72, 0.1);

  /* type */
  --fs-display: 40px;
  --fs-title: 24px;
  --fs-head: 20px;
  --fs-body: 17px;
  --fs-label: 15px;
  --fs-small: 14px;
  --fs-micro: 12px;
  --fw-title: 700;
  --fw-body: 600;

  /* spacing */
  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px; --s5: 20px;
  --s6: 24px; --s7: 28px; --s8: 32px; --s9: 36px; --s10: 40px;
}

* { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }
html, body { height: 100%; }
body {
  font-family: 'Mulish', system-ui, -apple-system, sans-serif;
  color: var(--ink);
  min-height: 100dvh;
  overflow: hidden;
  user-select: none; -webkit-user-select: none;
  /* ⚠️ WHITE, TO MATCH THE DOCK, because the page background is only ever visible as
     a sliver underneath it. Every screen is fixed/inset:0, so the one place this
     colour can show is the strip below .k-dock when the safe-area inset and the
     dynamic viewport disagree by a pixel or two — which they do on a real phone and
     never in a headless render. It used to inherit #0d1020 from the egg timer's
     staged port stylesheet, and Andjroo saw exactly that: "a black line below my
     bottom navigation, in the border of the page." Matching the dock means a sliver
     is invisible rather than a different colour of line. */
  background: #fff;
}
button { font-family: inherit; cursor: pointer; border: none; background: none; color: inherit; }
img { max-width: 100%; }

/* The `hidden` ATTRIBUTE has to actually hide (#241). Same rule and same reason as
   public/parent/parent.css: the browser's `[hidden] { display: none }` is a UA rule, so any
   author `display` outranks it. Here it is `.jp-tile { display: flex }` in css/chart.css
   against `b.hidden = !hit` in js/lib/job-picker.js, which is the shared picker both apps
   render, so a search that matched two jobs still drew every tile in the matching groups.
   `!important` because chart.css is linked AFTER this file. */
[hidden] { display: none !important; }

/* ---------- one press recipe for the whole app ----------
   There were 17 ad-hoc :active rules using seven different press scales, three
   durations and two easings, while the six controls a small child presses most
   (.back-btn, .sheet-close, the picker tiles) had no press at all. One group,
   one answer to touch. The Nimiq spring is reserved for the press itself,
   which is exactly what it is for. */
:where(
  .back-btn, .sheet-close, .place-cancel, .tile, .mode-btn, .sound-play,
  .sound-pick, .k-grow-take, .mega-btn, .ch-task, .ch-money, .ch-dock-btn,
  .tm-opt, .stkp-tile, .game-tile, .games-card, .k-dock-btn,
  .k-contact, .pin-grid button, .bx-item, .ch-kid, .switch-kid, .dn-timer,
  .account-entry
) {
  transition: transform var(--t-press) var(--ease);
}
:where(
  .back-btn, .sheet-close, .place-cancel, .tile, .mode-btn, .sound-play,
  .sound-pick, .k-grow-take, .mega-btn, .ch-task, .ch-money, .ch-dock-btn,
  .tm-opt, .stkp-tile, .game-tile, .games-card, .k-dock-btn,
  .k-contact, .pin-grid button, .bx-item, .ch-kid, .switch-kid, .dn-timer,
  .account-entry
):active {
  transform: scale(var(--press-scale));
  transition-timing-function: var(--spring);
}

/* ---------- screen root + built-in background scenes ---------- */
.screen {
  position: fixed; inset: 0;
  overflow-y: auto;
  display: flex; flex-direction: column;
}
/* The entry animation lives on a class setScreen() re-triggers, not on .screen:
   this node is never reinserted, so an animation declared on .screen ran once
   at boot and never again. */
.screen.is-entering { animation: screen-in 260ms var(--ease); }
@keyframes screen-in { from { opacity: 0; transform: scale(0.985); } to { opacity: 1; transform: none; } }

.bg-meadow { background: linear-gradient(180deg, #AEE3FF 0%, #DFF7E8 52%, #A9E6A0 100%); }
.bg-ocean  { background: linear-gradient(180deg, #7FD4FF 0%, #4FC3E8 45%, #21BCA5 100%); }
.bg-space  { background: radial-gradient(130% 110% at 50% 110%, #3A1C5C 0%, #260133 55%, #1F2348 100%); }
.bg-city   { background: linear-gradient(180deg, #FFE3A9 0%, #FFB98A 55%, #F58C7F 100%); }
/* THE ONE PLACE THE SCENE IS SIZED, for every screen in the app. This class and
   the artwork both land on #kid-app (setScreen applies bgFor()'s two halves
   together), which is the only element that is always exactly the viewport --
   a screen's own root grows with its content, and the Treasure Box's is 1192px
   tall on an 844px phone. `cover` because it is one of only two values that
   preserve the art's aspect ratio; never give this a two-value size. */
.bg-image  { background-size: cover; background-position: center; background-repeat: no-repeat; }
/* The dark-scene overrides key off .bg-dark (util.js DARK_BGS), NOT .bg-space:
   bgFor() returns "bg-image bg-dark" whenever catalog art exists, and space.jpg
   does ship, so a .bg-space-scoped rule never matches the real artwork. The
   .bg-space gradient above stays -- that IS the pre-art fallback. */
.bg-dark, .bg-dark .greet, .bg-dark .task-title, .bg-dark .task-clock { color: #fff; }

/* ---------- shared bits ---------- */
.back-btn {
  /* centered on the same line as the corner control, one shared gutter --
     see the --kid-chrome-* block in wallet.css */
  position: absolute; z-index: 5;
  top: calc(var(--kid-chrome-center, 33px) - var(--back-size, 56px) / 2);
  left: var(--kid-chrome-gutter, 24px);
  width: var(--back-size, 56px); height: var(--back-size, 56px); border-radius: 50%;
  background: rgba(255, 255, 255, 0.92); box-shadow: var(--sh-card);
  font-size: 34px; font-weight: 800; color: var(--navy);
  display: grid; place-items: center;
}
.mega-btn {
  min-height: 96px; min-width: 300px; padding: 18px 40px;
  border-radius: var(--r-pill);
  background-image: radial-gradient(100% 100% at bottom right, var(--blue-2), var(--blue));
  color: #fff; font-size: 36px; font-weight: 800; letter-spacing: 0.3px;
  box-shadow: var(--sh-cta);
  transition: transform var(--t-press) var(--ease), background-color var(--t-ui) var(--ease), color var(--t-ui) var(--ease);
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
}
.mega-btn.green { background-image: radial-gradient(100% 100% at bottom right, var(--green-2), var(--green)); box-shadow: var(--sh-cta); }
.mega-btn.blue { background-image: radial-gradient(100% 100% at bottom right, var(--blue-2), var(--blue)); }
.mega-btn.gold { background-image: radial-gradient(100% 100% at bottom right, var(--orange), var(--gold)); box-shadow: var(--sh-cta); }
/* The second answer on a two-answer sheet. Same pill, same height, no colour and
   no lift: the wallet's own secondary is a flat neutral pill, and "Not yet" must
   not compete with the answer that finishes the job. DECLARED ABOVE :disabled on
   purpose — .mega-btn.quiet and .mega-btn:disabled are both 0,2,0, so a later
   .quiet would win and paint a disabled one live. Same trap, third time. */
.mega-btn.quiet {
  background-image: none; background: var(--fill-10); color: var(--navy); box-shadow: none;
}
/* AFTER the colour variants, and matching their specificity. This rule already
   existed but sat above them: `.mega-btn:disabled` and `.mega-btn.blue` are both
   0,2,0, so the later one won and every disabled primary in the app still
   painted a live blue gradient with grey text on it. The wallet greys the whole
   pill (reference: SEND NIM before an amount is entered), which is the only
   version a kid can read as "not yet". */
.mega-btn:disabled,
.mega-btn.blue:disabled, .mega-btn.green:disabled, .mega-btn.gold:disabled {
  background-image: none; background: var(--fill-10); color: var(--ink-30); box-shadow: none;
}

#confetti { position: fixed; inset: 0; pointer-events: none; z-index: 60; }
.kid-toast {
  position: fixed; left: 50%; transform: translateX(-50%) translateY(20px);
  bottom: calc(var(--kid-dock-h, 0px) + 24px + env(safe-area-inset-bottom));
  background: var(--navy); color: #fff; font-size: 24px; font-weight: 800;
  padding: 18px 30px; border-radius: var(--r-pill); opacity: 0; pointer-events: none;
  transition: opacity var(--t-ui) var(--ease), transform var(--t-ui) var(--ease);
  z-index: 70; max-width: 90vw; text-align: center;
}
.kid-toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
/* A toast that is a CONTROL, not a message: the approval notice says "tap for your sticker"
   (approved.js), and the base rule is pointer-events: none so ordinary toasts stay out of the
   way of the screen behind them. util.js's toast() adds and removes this with the handler. */
.kid-toast.is-tappable { pointer-events: auto; cursor: pointer; }

/* The avatar login's own skin is GONE: the roster is the registry account-list
   on the connect screen's composition now (connect.css), so .login / .who-grid /
   .who-card / .who-name had no markup left to style. The @keyframes bob went
   with them -- nothing else referenced it. */

/* ---------- K3 games launcher (kiosk-only: card renders IFF wrapper says UNLOCKED) ---------- */
.games-card {
  display: flex; align-items: center; gap: 22px; text-align: left;
  background-image: radial-gradient(100% 100% at bottom right, var(--green-2), var(--green));
  border-radius: var(--r-card); box-shadow: var(--sh-cta);
  padding: 26px 28px; min-height: 130px;
}
.games-card-title { flex: 1; min-width: 0; font-size: 36px; font-weight: 800; color: #fff; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.games-card-go {
  width: 76px; height: 76px; border-radius: 50%; flex: none;
  background: rgba(255, 255, 255, 0.92); color: var(--green-2);
  display: grid; place-items: center;
}

.games-screen::before { content: ""; position: fixed; inset: 0; background: rgba(255, 255, 255, 0.55); pointer-events: none; }
.games-screen.bg-dark::before { background: rgba(38, 1, 51, 0.28); }
.games { position: relative; flex: 1; display: flex; flex-direction: column; padding: 26px 30px 46px; gap: 30px; }
.games-hd { display: flex; align-items: center; justify-content: center; gap: 20px; margin-top: 10px; padding: 0 90px; }
.games-emoji { font-size: 72px; line-height: 1; }
.games-title { font-size: 46px; font-weight: 800; color: var(--navy); text-align: center; }
.bg-dark .games-title { color: #fff; }
.games-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 26px; align-content: start; padding-bottom: 30px;
}
.game-tile {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px;
  background: var(--card); border-radius: var(--r-card); box-shadow: var(--sh-card);
  padding: 26px 18px; min-height: 220px; transition: transform var(--t-press) var(--ease);
}
.game-icon { width: 108px; height: 108px; border-radius: var(--r-tile); object-fit: contain; }
.game-icon-fallback { display: grid; place-items: center; font-size: 76px; background: rgba(31, 35, 72, 0.06); }
.game-label {
  max-width: 100%; font-size: 26px; font-weight: 800; color: var(--navy); text-align: center;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.games-empty { grid-column: 1 / -1; text-align: center; font-size: 90px; padding: 60px 0; }

/* ---------- task (egg) screen ---------- */
.task { position: relative; flex: 1; display: flex; flex-direction: column; align-items: center; padding: 26px 30px 46px; gap: 12px; }
.task-head { display: flex; align-items: center; gap: 20px; margin-top: 8px; padding: 0 90px; }
.task-emoji { font-size: 74px; line-height: 1; }
.task-title { font-size: 46px; font-weight: 800; color: var(--navy); text-align: center; }
.egg-stage { flex: 1; width: 100%; display: grid; place-items: center; min-height: 0; }
.egg-stage :is(.egg-rig, .maker-rig, .pola-rig) { max-width: min(66vw, 480px); }
.task-clock { font-size: 88px; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--navy); line-height: 1; }
.time-bar { width: min(78vw, 560px); height: 26px; border-radius: var(--r-pill); background: rgba(31, 35, 72, 0.14); overflow: hidden; }
.bg-dark .time-bar { background: rgba(255, 255, 255, 0.2); }
.time-bar i { display: block; height: 100%; border-radius: var(--r-pill); background: linear-gradient(90deg, var(--gold), var(--orange)); transition: width var(--t-ui) var(--ease); }
.task-actions { min-height: 110px; display: grid; place-items: center; padding-top: 10px; }

/* ---------- waiting screen ---------- */
.waiting { position: relative; flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 26px; padding: 40px; text-align: center; }
.waiting::before { content: ""; position: fixed; inset: 0; background: rgba(255, 255, 255, 0.6); pointer-events: none; }
.waiting > :not(.back-btn) { position: relative; } /* lift above the ::before wash; the back button stays pinned top-left */
.w-party { animation: bob 2s ease-in-out infinite; }
.w-title { font-size: 56px; font-weight: 700; color: var(--navy); }
.w-wait { font-size: 34px; font-weight: 800; color: var(--muted); display: flex; align-items: center; gap: 10px; }
.w-hour { display: inline-flex; animation: flip 2.6s ease-in-out infinite; }
@keyframes flip { 0%, 70%, 100% { transform: rotate(0); } 80% { transform: rotate(180deg); } 90% { transform: rotate(360deg); } }
.w-photo img { width: 130px; height: 130px; object-fit: cover; border-radius: var(--r-card); box-shadow: var(--sh-card); vertical-align: middle; }
.w-photo span { font-size: 26px; font-weight: 800; color: var(--green-2); margin-left: 12px; }
.w-actions { display: flex; flex-direction: column; gap: 22px; }

/* ---------- PIN pad ---------- */
.pin-screen { background: linear-gradient(180deg, #F4F4F4, #E8E9F2); }
.pinpad { position: relative; flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 24px; padding: 40px; }
.pinpad.shake { animation: shake 0.45s ease; }
@keyframes shake { 0%, 100% { transform: translateX(0); } 20% { transform: translateX(-16px); } 40% { transform: translateX(14px); } 60% { transform: translateX(-10px); } 80% { transform: translateX(8px); } }
.pin-lock { font-size: 80px; }
.pin-prompt { font-size: 32px; font-weight: 800; color: var(--navy); text-align: center; max-width: 560px; }
.pin-dots { font-size: 38px; letter-spacing: 14px; color: var(--navy); min-height: 52px; }
.pin-grid { display: grid; grid-template-columns: repeat(3, 128px); gap: 20px; }
.pin-grid button {
  height: 128px; border-radius: var(--r-tile); font-size: 46px; font-weight: 800; color: var(--navy);
  background: var(--card); box-shadow: var(--sh-card); transition: transform var(--t-press) var(--ease);
}
.pin-grid button.ok { background-image: radial-gradient(100% 100% at bottom right, var(--green-2), var(--green)); color: #fff; }
.pin-grid button .k-icon { font-size: 40px; margin: 0 auto; }

/* ---------- +NIM celebration overlay ---------- */
.kid-overlay {
  position: fixed; inset: 0; z-index: 50; display: none;
  background: rgba(31, 35, 72, 0.6);
}
.kid-overlay.show { display: grid; place-items: center; }
.celebrate-box { position: relative; display: flex; flex-direction: column; align-items: center; gap: 24px; }
/* "See this on the chain" — the proof, for the grown-up (or the judge) who wants to check.
   It ARRIVES AFTER the pill: the +NIM pill flies up into the balance, and a second thing
   competing with that flight is the one moment in the app that should have nothing else in
   it. So it fades in once the pill has gone, into the space the pill left. A solid card
   rather than a translucent chip — the overlay's own scrim is a 60% navy wash over whatever
   the board happens to be, so anything semi-transparent lands on an unknown backdrop. */
.k-receipt-link {
  border: 0; background: var(--card); color: var(--ink);
  font: inherit; font-size: 17px; font-weight: 600;
  padding: 12px 22px; border-radius: var(--r-pill); cursor: pointer;
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.28);
  opacity: 0; animation: k-receipt-in 360ms ease-out 900ms forwards;
}
.k-receipt-link:active { transform: scale(0.96); }
@keyframes k-receipt-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .k-receipt-link { animation: none; opacity: 1; }
}

/* ---------- payout ceremony ---------- */
.payout { position: relative; flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 26px; padding: 40px; color: #fff; }
.p-title { font-size: 58px; font-weight: 700; }
.p-value { font-size: 92px; font-weight: 800; line-height: 1; }
.p-value span { font-size: 40px; font-weight: 800; opacity: 0.75; }
.p-qr { width: min(46vw, 340px); aspect-ratio: 1; background: #fff; border-radius: var(--r-card); padding: 20px; box-shadow: 0 12px 40px rgba(0, 0, 0, 0.35); }
.p-actions { min-height: 110px; display: grid; place-items: center; }
.coin-rain { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.coin-coin { position: absolute; top: -60px; font-size: 44px; animation: coin-fall 2.8s linear infinite; animation-delay: calc(var(--i) * 0.28s); }
@keyframes coin-fall {
  0% { transform: translateY(0) rotate(0); opacity: 0; }
  8% { opacity: 1; }
  100% { transform: translateY(115vh) rotate(300deg); opacity: 1; }
}

/* ---------- bottom sheet (studio + free timer) ---------- */
.kid-scrim {
  position: fixed; inset: 0; z-index: 40; background: rgba(31, 35, 72, 0.45);
  opacity: 0; pointer-events: none; transition: opacity var(--t-ui) var(--ease); display: flex; align-items: flex-end; justify-content: center;
}
.kid-scrim.show { opacity: 1; pointer-events: auto; }
.kid-sheet {
  position: relative; width: 100%; max-height: 78dvh; overflow-y: auto;
  background: #fff; border-radius: var(--r-sheet) var(--r-sheet) 0 0;
  padding: 34px 30px calc(40px + env(safe-area-inset-bottom));
  transform: translateY(100%); transition: transform var(--t-ui) var(--ease);
  display: flex; flex-direction: column; align-items: center; gap: 26px;
}
.kid-scrim.show .kid-sheet { transform: translateY(0); }
/* Sheet header, per the Little Timer reference: close on the LEFT, the sheet's
   name centred over it, and a quiet line beneath. The buttons that open these
   sheets carry no words — the words are here. */
.sheet-hd { position: relative; width: 100%; display: grid; place-items: center; min-height: 68px; }
.sheet-close {
  position: absolute; top: 50%; left: 0; transform: translateY(-50%);
  width: 68px; height: 68px; border-radius: 50%;
  background: rgba(31, 35, 72, 0.08); font-size: 30px; font-weight: 800; color: var(--navy);
  display: grid; place-items: center;
}
.sheet-name { font-size: 34px; font-weight: 800; color: var(--navy); text-align: center; }
.sheet-sub {
  margin: -14px 0 0; max-width: 30ch; text-align: center;
  font-size: 22px; font-weight: 600; color: rgba(31, 35, 72, 0.45); line-height: 1.35;
}

.mode-row { display: flex; gap: 22px; }
.mode-btn {
  width: 128px; height: 104px; border-radius: var(--r-tile); font-size: 52px;
  background: rgba(31, 35, 72, 0.06); display: grid; place-items: center;
  border: 4px solid transparent;
}
.mode-btn.on { border-color: transparent; box-shadow: inset 0 0 0 3px var(--blue); background: rgba(5, 130, 202, 0.10); }

.tile-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; justify-items: center; }
.tile {
  width: 132px; height: 132px; border-radius: var(--r-tile); overflow: hidden;
  background: rgba(31, 35, 72, 0.06); display: grid; place-items: center;
  border: 4px solid transparent; font-size: 44px; position: relative;
}
.tile img { width: 100%; height: 100%; object-fit: cover; }
.tile.on { border-color: transparent; box-shadow: inset 0 0 0 3px var(--blue); }
/* top-right: bottom-right lands the badge on the .timer-tile-label */
.tile.on::after { content: "✓"; position: absolute; right: 6px; top: 6px; width: 40px; height: 40px; border-radius: 50%; background-image: radial-gradient(100% 100% at bottom right, var(--blue-2), var(--blue)); color: #fff; font-size: 24px; font-weight: 800; display: grid; place-items: center; }
.tile.preview { opacity: 0.85; }
.tile.camera { border: 4px dashed rgba(31, 35, 72, 0.25); background: transparent; color: var(--muted); font-size: 38px; font-weight: 800; cursor: pointer; display: grid; place-items: center; }
.bg-tile span { font-size: 52px; filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.25)); }
.bg-tile { background-size: cover; background-position: center; }

/* ---------- the "me" sheet (behind the kid's own name) ----------
   Who you are, and what your app looks like. Taller than the studio sheets
   because the scene grid is meant to GROW: more backgrounds are coming, and a
   sheet sized to today's four would have to be resized every time one lands.
   The grid scrolls inside the sheet rather than the sheet growing past the
   screen, so the name and the Switch-kid row stay put while the scenes move. */
.me-row {
  display: flex; align-items: center; gap: 16px; width: 100%;
  padding: 16px 20px; border-radius: var(--r-card);
  background: var(--fill-6); color: var(--navy);
  font-size: 26px; font-weight: 800; text-align: left;
}
/* The glyph is a generated mask, so it tints with the row's colour like every
   other one in the app rather than being a baked-in picture. */
.me-row-ic { font-size: 30px; flex: none; }
/* The other kids' faces, pushed to the right end of the row. margin-left:auto
   rather than justify-content:space-between, so the glyph and the words stay
   together on the left instead of spreading across the row.
   No wrapper of our own around identiconImg(): it already emits its own
   .identicon, and nesting one inside another lets the inner 10rem width win. */
.me-row-kids { display: flex; align-items: center; gap: 8px; margin-left: auto; flex: none; }
.me-row-kids .identicon { width: 40px; height: 40px; }
.me-row-kids .identicon img { width: 100%; height: 100%; }
.me-face-more {
  font-style: normal; font-size: 20px; font-weight: 800;
  color: rgba(31, 35, 72, 0.45);
}
.me-section { width: 100%; display: flex; flex-direction: column; gap: 14px; min-height: 0; }
.me-lbl {
  margin: 0; font-size: 22px; font-weight: 800;
  color: rgba(31, 35, 72, 0.45); letter-spacing: 0.2px;
}
/* No fade. It was there to hint at a scroll, but the grid lays out three whole
   rows and the empty slots below the real scenes already say "more goes here" —
   a fade over a dotted slot just reads as the slot being broken. It still
   scrolls if the catalogue ever outgrows three rows; it simply does not
   pretend to. */
.me-bgs {
  /* Four across everywhere, not the studio grid's three. On a tablet three
     columns makes each scene ~250px, so the three rows this sheet lays out
     could not be seen without scrolling — which defeats the point of laying
     out three rows. The cap is sized to hold all three. */
  grid-template-columns: repeat(4, 1fr);
  overflow-y: auto; overscroll-behavior: contain;
  padding-bottom: 4px; min-height: 0;
  max-height: min(58svh, 700px);
}
/* The scenes fill their columns rather than keeping the studio tile's fixed
   width. A scene is a picture of a place, so it wants to be as big as the row
   allows; and once the grid governs the size, adding backgrounds only ever adds
   ROWS -- the sheet never has to be re-tuned as the catalogue grows.
   align-items:start is load-bearing: a grid stretches its items by default, and
   a stretched item ignores aspect-ratio, so with more than one row every scene
   was drawn as a tall strip instead of a square. */
.me-bgs { align-items: start; }
.me-bgs .tile { width: 100%; height: auto; aspect-ratio: 1; }

/* The empty slots: where scenes that have not shipped yet will go. A dotted
   outline is the app's own idiom for a space waiting to be filled -- the same
   thing .ch-slot-empty does for a sticker a kid has not placed. Deliberately
   quiet: they are not buttons, they are the shape of what is coming. */
.me-bgs .bg-slot {
  background: transparent; box-shadow: none;
  border: 3px dashed rgba(31, 35, 72, 0.22);
  display: grid; place-items: center;
}
/* The one that IS a button. Louder than its neighbours because it is the only
   slot a kid can do anything with. */
.me-bgs .bg-slot-add { border-color: rgba(5, 130, 202, 0.45); color: var(--blue); }
.bg-slot-ic { font-size: 40px; }
/* The sheet itself rides higher than the studio's 78dvh, because this one is
   the scene picker and a kid should see several rows of scenes at once. svh,
   not dvh: iOS reports the LARGE viewport to dvh while its bars are showing. */
.kid-scrim:has(.me-bgs) .kid-sheet { max-height: 88svh; }

/* Timer-style tiles (studio Timer sheet): mini rig preview + name. */
.timer-tile { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; padding: 8px 6px; }
.timer-prev { display: block; width: 64px; }
.timer-prev svg { display: block; width: 100%; height: auto; }
.timer-tile-label {
  font-size: 13px; font-weight: 800; color: var(--navy);
  line-height: 1.15; text-align: center; white-space: normal;
  max-width: 6em; /* two-word names wrap to 2 lines, clear of the .on check badge */
}

.sound-section { width: 100%; max-width: 560px; display: flex; flex-direction: column; gap: 12px; }
/* One label spec across sheets and screens. .sound-hd declared size only, so
   weight fell back to 400 and it outranked .sheet-name -- 5px larger and 400
   lighter than the title above it. */
.sound-hd, .k-section-hd, .stkp-hd {
  font-size: var(--fs-label); font-weight: var(--fw-title); color: var(--ink-50);
}
.sound-row { display: flex; align-items: center; gap: 14px; background: rgba(31, 35, 72, 0.05); border-radius: var(--r-card); padding: 10px 14px; border: 3px solid transparent; }
.sound-row.on { border-color: transparent; box-shadow: inset 0 0 0 3px var(--blue); background: rgba(5, 130, 202, 0.10); }
.sound-play { width: 76px; height: 76px; border-radius: 50%; background: var(--card); box-shadow: var(--sh-card); font-size: 30px; display: grid; place-items: center; }
.sound-play.playing { background: var(--green); color: #fff; }
.sound-play.mute { box-shadow: none; background: transparent; }
.sound-pick { flex: 1; text-align: left; font-size: 28px; font-weight: 800; color: var(--navy); min-height: 76px; }
.soon { font-size: 26px; font-weight: 800; color: var(--muted); padding: 14px; text-align: center; }

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  .screen, .screen.is-entering, .w-party, .w-hour, .coin-coin { animation: none; }
  .kid-sheet, .kid-scrim, .kid-toast { transition: none; }
}
