/* De Speelkamer — vormgeving. Prentenboek-warm, mobile-first (380px+),
   tap-doelen ≥ 44px, dag/avond/nacht-thema via data-sfeer op #app. */

:root {
  --kk-melk: #fdf9f1;
  --kk-spar: #2e4b3f;
  --kk-boter: #f5c64f;
  --kk-boter-diep: #c58f2f;
  --kk-zalm: #e8877a;
  --kk-zalm-diep: #c9564a;
  --kk-mist: #8fa0a8;
  --kk-nacht: #22304a;
  --kk-papier: #ffffff;
  --kk-lijn: #e3dbc9;

  --bg: var(--kk-melk);
  --tekst: var(--kk-spar);
  --tekst-zacht: #5c7268;
  --kaart: var(--kk-papier);
  --schaduw: 0 3px 14px rgba(46, 75, 63, 0.1);
  /* De focusring stond op `--kk-zalm` en haalde nergens in de kamer de
     3:1-norm: gemeten 1,92 op de speelkist en 2,2-2,5 op de knoppen.
     Eén kleur kán het ook niet in beide themata — sparren is overdag
     9,1:1 maar 's nachts 1,2:1, en melk precies andersom. De ring volgt
     daarom het thema, net als de rest van dit bestand. */
  --kk-focus: var(--kk-spar);
}

#app[data-sfeer="nacht"] {
  --bg: #1b2740;
  --tekst: #f2ecdd;
  --tekst-zacht: #aeb9cd;
  --kaart: #2a3852;
  --kk-lijn: #3c4a68;
  --schaduw: 0 3px 14px rgba(10, 16, 30, 0.4);
  --kk-focus: var(--kk-melk);   /* 10,7-14,2:1 op de nachtvlakken */
}

#app[data-sfeer="avond"] {
  --bg: #f6efdf;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
}

body {
  background: var(--bg);
  color: var(--tekst);
  font-family: "Atkinson Hyperlegible", system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 16px;
  line-height: 1.45;
  transition: background 0.8s ease;
  overflow-x: hidden;
}

.app {
  max-width: 860px;
  margin: 0 auto;
  padding: 8px 10px calc(14px + env(safe-area-inset-bottom, 0px));
  display: flex;
  flex-direction: column;
  gap: 10px;
  height: 100dvh;
  min-height: 0;
  background: var(--bg);
  /* Óók color hier zetten: body's computed kleur erft anders de dag-waarde
     door, en dan blijven de headerchips 's nachts donker-op-donker. */
  color: var(--tekst);
  transition: background 0.8s ease, color 0.8s ease;
}

/* Op heel kleine schermen mag de pagina gewoon scrollen. */
@media (max-height: 430px) {
  .app {
    height: auto;
  }
}

/* Liggend op een telefoon werkte die ontsnapping juist averechts: de kolom werd
   losgelaten, maar `#scene` heeft `touch-action:none` en slikt de veeg — dus
   viel er niets te scrollen. Gemeten op 844x390: de scène stond 539px hoog in
   een frame van 333px en álle vijf actieknoppen zaten onbereikbaar op y=675 en
   lager. Een kind dat zijn telefoon draait, kreeg een lege kamer.
   Liggend is de bréédte ruim (794px) en de hoogte krap, dus zetten we de scène
   náást de bediening. Rasterplaatsing, zodat de DOM-volgorde (en daarmee de
   tabvolgorde) precies blijft zoals hij is. */
@media (orientation: landscape) and (max-height: 500px) {
  .app {
    height: 100dvh;
    display: grid;
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
    /* Rij 2 mag NIET tot nul samenklappen. Met `minmax(0, 1fr)` gebeurde dat
       zodra de knoppenkolom hoger werd dan het scherm, en dan steekt het
       meterblok van 40px gewoon uit zijn eigen cel — over het actieraster heen.
       `align-self` helpt daar niet tegen: rastercellen knippen niet. */
    grid-template-rows: auto minmax(min-content, 1fr) auto auto;
    column-gap: 12px;
  }
  .app > header.top {
    grid-column: 1 / -1;
    grid-row: 1;
  }
  .scene-wrap {
    grid-column: 1;
    grid-row: 2 / -1;
    min-height: 0;
    /* De rechterkolom is liggend hóger dan het scherm: zes actieknoppen van
       52px passen niet in de ~113px die er na kop, meters en gratisregel
       overblijft. Deze cel liep tot het eind van rij 4 en rekte daardoor mee tot
       315px in een venster van 273 — waarmee de kat (0 van 37px zichtbaar) én de
       speelkist (0 van 44px), de enige deur naar de zes spellen, onder de vouw
       zakten. Zonder scrollbalk, want `#scene` slikt de veeg.
       De scène hoort binnen het eerste scherm te blijven; de knoppen mogen
       eronder doorlopen, en dat ze half in beeld staan is meteen de aanwijzing
       dát er meer is. */
    max-height: calc(100dvh - 74px);
    align-self: start;
  }
  .meters {
    grid-column: 2;
    grid-row: 2;
    /* `center` in een rij die tot 0px samenklapt betekent: 20px boven én onder
       de cel uitsteken. Gemeten bedekte het actieraster zo 10px van het
       meterblok — precies de vulbalkjes. */
    align-self: start;
  }
  /* Twee kolommen, niet drie: de knoppenkolom is liggend smaller, en op drie
     kolommen brak "Winkeltje" af tot "Winkel-tje". */
  .acties {
    grid-column: 2;
    grid-row: 3;
    grid-template-columns: repeat(2, 1fr);
  }
  .gratis {
    grid-column: 2;
    grid-row: 4;
    margin: 0;
  }
}

/* ── De kamer wordt klaargezet ──
   Zolang `game.mjs` nog onderweg is staan de knoppen er wél, maar zit er niets
   achter. Ze zijn daarom `disabled` in de HTML; hier krijgen ze het uiterlijk
   dat daarbij hoort — rustig wachtend, niet kapot — en komt de regel in beeld
   die vertelt wát er gebeurt. `game.mjs` haalt `.laadt` er bij het opstarten af.
   Alleen de taal die bij dit document hoort blijft staan: de andere span is een
   terugval voor de andere kant en mag niet dubbel gelezen worden. */
.kamer-laadt {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  margin: 0;
  padding: 10px 16px;
  border-radius: 999px;
  background: var(--kk-melk, #fdf9f1);
  color: var(--tekst, #2e4b3f);
  font-family: "Baloo 2", "Atkinson Hyperlegible", system-ui, sans-serif;
  font-weight: 700;
  font-size: 15px;
  box-shadow: 0 4px 14px rgba(46, 75, 63, 0.16);
  pointer-events: none;
}
html[lang="nl"] .kamer-laadt [lang="en"],
html[lang="en"] .kamer-laadt [lang="nl"] {
  display: none;
}
.app:not(.laadt) .kamer-laadt {
  display: none;
}
/* `.wacht` is de korte stilte ná het laden: de kamer stáát er, maar de
   kennismaking begint pas 1,6 s later en tot dan doen de knoppen niets. Zelfde
   uiterlijk als tijdens het laden, zodat "nog niet" er ook uitziet als nog
   niet — in plaats van als kapot. */
.app.laadt .actie,
.app.laadt .ronde-knop,
.app.wacht .actie,
.app.wacht .ronde-knop {
  opacity: 0.55;
  box-shadow: none;
  cursor: default;
}

h1, h2, h3, .baloo {
  font-family: "Baloo 2", "Atkinson Hyperlegible", system-ui, sans-serif;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.verborgen {
  display: none !important;
}

.no-select {
  user-select: none;
  -webkit-user-select: none;
}

button {
  font-family: inherit;
  font-size: inherit;
  color: inherit;
  cursor: pointer;
}

button:focus-visible,
a:focus-visible,
input:focus-visible {
  outline: 3px solid var(--kk-focus);
  outline-offset: 2px;
  border-radius: 8px;
}

/* Hotspots in de svg zijn echte knoppen (role="button"), maar geen <button>:
   de generieke focus-regel hierboven raakt ze niet. Elke .hotspot met een
   tabindex krijgt daarom zijn eigen zichtbare ring (WCAG 2.4.7). */
.hotspot[tabindex]:focus-visible {
  outline: none;
  stroke: var(--kk-focus);
  /* `non-scaling-stroke` maakt dit 3 CSS-pixels op ELK formaat. Zonder die
     regel stond hier 8 user-units in de 800x560-viewBox, en de toelichting
     rekende met de schaal van een 390px-scherm (±0,46 → ±3,7 px). Maar de scène
     schaalt op `min(breedte/800, hoogte/560)`, en op een korte telefoon wint de
     hoogte: gemeten 0,193 op 320x568 en 0,207 op 360x568, oftewel een ring van
     1,54 en 1,66 px — onder de 2 px die WCAG 2.4.11/2.4.13 vragen, en precies
     op de speelkist, de enige deur naar de zes speeltjes. Dezelfde val als C24
     en C25, nu in de opmaak in plaats van in een meting. */
  stroke-width: 3;
  vector-effect: non-scaling-stroke;
}

/* ── Kop met visjes, level en knopjes ── */

.top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  flex-wrap: wrap;
}

.hud-links {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.munten,
.levelchip,
.streakchip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--kaart);
  border: 1.5px solid var(--kk-lijn);
  border-radius: 999px;
  padding: 6px 12px;
  min-height: 36px;
  box-shadow: var(--schaduw);
  font-variant-numeric: tabular-nums;
}

.munten strong,
.streakchip strong {
  font-family: "Baloo 2", sans-serif;
  font-size: 18px;
  line-height: 1;
}

.munt-icoon {
  display: inline-flex;
}

.munt-label {
  color: var(--tekst-zacht);
  font-size: 13px;
}

.levelchip {
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  padding: 5px 12px;
  border-radius: 14px;
}

#level-tekst {
  font-family: "Baloo 2", sans-serif;
  font-size: 14px;
  font-weight: 700;
  line-height: 1;
}

.xp-balk {
  display: block;
  width: 72px;
  height: 5px;
  border-radius: 3px;
  background: var(--kk-lijn);
  overflow: hidden;
}

.xp-vulling {
  display: block;
  height: 100%;
  width: 0%;
  border-radius: 3px;
  background: var(--kk-boter);
  transition: width 0.5s ease;
}

.hud-rechts {
  display: flex;
  gap: 8px;
}

.ronde-knop {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1.5px solid var(--kk-lijn);
  background: var(--kaart);
  font-size: 19px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--schaduw);
  transition: transform 0.15s ease;
}

.ronde-knop:hover {
  transform: scale(1.07);
}

.ronde-knop-taal {
  font-family: "Baloo 2", sans-serif;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.04em;
}

/* ── De scène ── */

/* Nederlandse woorden die nog op hun Engelse vervanging wachten: onzichtbaar,
   maar wél op hun plek — `visibility` houdt de knopmaten, zodat er niets
   verspringt zodra het woordenboek landt. */
html.wacht-taal [data-nl-tekst] {
  visibility: hidden;
}

.scene-wrap {
  position: relative;
  border-radius: 18px;
  overflow: hidden;
  box-shadow: var(--schaduw);
  border: 2px solid var(--kk-lijn);
  /* Zelfde tint als de kamermuur: als de scène niet de hele hoogte vult,
     leest de rand erboven als een stukje extra muur. */
  background: #e7ede2;
  transition: background 0.8s ease;
  flex: 1 1 auto;
  min-height: 170px;
}

#app[data-sfeer="avond"] .scene-wrap {
  background: #dde0d2;
}

#app[data-sfeer="nacht"] .scene-wrap {
  background: #2c3b54;
}

#scene {
  display: block;
  width: 100%;
  height: 100%;
  touch-action: none;
  /* Muur en vloer lopen buiten de viewBox door: geen letterbox-banden. */
  overflow: visible;
}

#scene.speelmodus {
  cursor: crosshair;
}

#scene.aaimodus {
  cursor: grab;
}

/* `left:50%` maakt het beschikbare vak voor een absoluut element de hélft van
   zijn ouder: de wolk kreeg 131 van de 262px op een 320-telefoon en brak daardoor
   over vijf regels, hoger dan de scène zelf. Dezelfde val als bij de eindstand
   van het Broodjeslab en de uitleg van de salon — een symmetrische band lost hem
   op en houdt de wolk even netjes gecentreerd. */
.banner {
  position: absolute;
  left: 3%;
  right: 3%;
  top: 10px;
  width: max-content;
  margin-inline: auto;
  max-width: 94%;
  background: rgba(253, 249, 241, 0.94);
  color: var(--kk-spar);
  border: 1.5px solid var(--kk-lijn);
  border-radius: 999px;
  padding: 8px 16px;
  font-size: 14px;
  text-align: center;
  box-shadow: var(--schaduw);
  pointer-events: none;
  animation: banner-in 0.4s ease both;
}

/* Zonder `left:50%` hoort er ook geen `translateX(-50%)` meer in de animatie —
   die zou de wolk nu een halve breedte naar links schuiven. */
@keyframes banner-in {
  from { opacity: 0; transform: translateY(-8px); }
  to { opacity: 1; transform: translateY(0); }
}

.foto-flits {
  position: absolute;
  inset: 0;
  background: #fff;
  pointer-events: none;
  animation: foto-flits 0.45s ease-out both;
  z-index: 5;
}

@keyframes foto-flits {
  from { opacity: 0.85; }
  to { opacity: 0; }
}

/* Deelt het vak van "Speel samen" in het actieraster (zie index.html): buiten
   het speelveld, dus geen tik meer die per ongeluk het potje beëindigt, en
   dezelfde plek dus geen layoutverschuiving. Eigen kleur zodat hij toch
   onmiskenbaar iets ánders is dan de zorgknoppen. */
.speel-stop.actie {
  border-color: var(--kk-spar);
  background: var(--kk-melk);
  color: var(--kk-spar);
  box-shadow: 0 3px 0 var(--kk-spar);
}

.speel-stop.actie:active {
  box-shadow: 0 1px 0 var(--kk-spar);
}

/* ── Meters ── */

.meters {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
}

.meter {
  background: var(--kaart);
  border: 1.5px solid var(--kk-lijn);
  border-radius: 14px;
  padding: 8px 10px;
  display: flex;
  flex-direction: column;
  gap: 5px;
  box-shadow: var(--schaduw);
  /* Een grid-item mag standaard niet smaller worden dan zijn eigen inhoud
     (`min-width: auto`). Daardoor hielden de vier meters en de zes knoppen hun
     intrinsieke breedte vast en liep de hele kamer zijwaarts over: gemeten
     vanaf een framebreedte van 341px (een iPhone SE) — de vierde meter half
     buiten beeld — tot 108px overloop op een Galaxy Fold, waar ook "Speel
     samen", "Borstel" en "Vriendenboekje" wegvielen. */
  min-width: 0;
}

/* Vier meters naast elkaar of twee rijen van twee. Die grens lag op 356px
   framebreedte, en dat pakte slecht uit: op een iPhone SE (375px scherm) is het
   frame 341px, dus vielen de meters daar terug op twee rijen — 86px in plaats
   van 40. Die 46px gingen rechtstreeks van de scène af, want die krijgt wat
   overblijft, en de kat werd er 26x30px van. Precies op het toestel dat het
   vaakst aan een kind wordt gegeven.
   De namen staan hieronder compacter zodra het krap wordt, en dan passen ze
   weer met z'n vieren. Twee rijen blijven de terugval voor écht smalle frames
   (Galaxy Fold), waar ook een klein lettertype het niet redt. */
@media (max-width: 355px) {
  .meter-kop {
    font-size: 11px;
    gap: 3px;
    white-space: nowrap;
  }
  .meter-kop svg {
    width: 13px;
    height: 13px;
  }
}
/* Het smalste geval: een 320px-telefoon geeft de kamer een frame van ~262px, en
   daar past zelfs een klein woord niet vier keer naast elkaar. Dan wijkt de
   naam en blijft het icoon staan — vier meters op één rij van ~30px in plaats
   van twee rijen van 86. Die 56px gaan naar de scène, waar de kat anders 21x25
   px groot is. De naam blijft in het `aria-label` van de meter staan, dus een
   schermlezer hoort nog steeds "Blijheid: 45 van 100". */
@media (max-width: 300px) {
  .meter-naam {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .meter-kop {
    justify-content: center;
  }
}
/* Nóg smaller (Galaxy Fold, frame ~246px): dan is ook één rij met vier iconen
   te krap en zijn twee rijen van twee eerlijker. */
@media (max-width: 260px) {
  .meters {
    grid-template-columns: repeat(2, 1fr);
  }
}

.meter-kop {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--tekst-zacht);
}

.meter-kop svg {
  flex: none;
  color: var(--kk-zalm);
}

.meter-balk {
  display: block;
  height: 9px;
  background: var(--kk-lijn);
  border-radius: 5px;
  overflow: hidden;
}

.meter-vulling {
  display: block;
  height: 100%;
  border-radius: 5px;
  background: var(--kk-boter);
  transition: width 0.7s ease, background 0.7s ease;
}

.meter-vulling.goed { background: #8fbf6f; }
.meter-vulling.oke { background: var(--kk-boter); }
.meter-vulling.laag { background: var(--kk-zalm); }

/* ── Actieknoppen ── */

.acties {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}

@media (min-width: 560px) {
  .acties {
    grid-template-columns: repeat(3, 1fr);
  }
}

.actie {
  min-height: 52px;
  /* Zie `.meter`: zonder dit houdt de knop zijn labelbreedte vast en duwt hij
     het raster buiten het scherm. Het label mag wel over twee regels. */
  min-width: 0;
  text-align: center;
  /* "Vriendenboekje" is één woord van 110px en brak dus nergens: op een
     Galaxy Fold stak het als enige nog 8px buiten beeld. Afbreken mag, maar
     alleen als het écht niet past. */
  overflow-wrap: break-word;
  hyphens: auto;
  border-radius: 16px;
  border: 2px solid var(--kk-boter-diep);
  background: var(--kk-boter);
  color: #4a3a10;
  font-family: "Baloo 2", sans-serif;
  font-weight: 700;
  font-size: 15.5px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 8px 10px;
  box-shadow: 0 3px 0 var(--kk-boter-diep);
  transition: transform 0.12s ease, box-shadow 0.12s ease, opacity 0.2s ease;
  touch-action: manipulation;
}

.actie span {
  min-width: 0;
}

/* 's Nachts wachten eten, spelen en borstelen. De knop blijft aanraakbaar (de
   toast legt uit waarom), maar hij ziet er nu ook uit alsof hij slaapt — een
   kind dat niet leest zag anders geen enkel verschil met overdag. */
.actie.slaapt {
  /* `opacity` dimde óók de létters: gemeten 2,04:1 (inkt rgb(74,58,16) op
     rgb(162,137,73)). De uitzondering voor uitgeschakelde bediening geldt
     hier niet — deze knoppen blijven bewust aanraakbaar en antwoorden met
     een toast. Het vlák dooft nu, de tekst niet: 5,2:1. */
  background: #d4ae4d;
  border-style: dashed;
  border-color: #9a7c2a;
  box-shadow: none;
}

.actie.slaapt::after {
  content: "💤";
  font-size: 13px;
  margin-left: 2px;
}

/* Tijdens de kennismaking wijst de coach met een zachte ring naar de knop
   waar zijn zin over gaat: een kind dat nog niet vlot leest ziet dán waar het
   moet tikken. Geen rood, geen uitroepteken — dezelfde zalmtint als de rest
   van de kamer, en de puls staat stil zodra de speler rust wil. */
.actie.coach-doel {
  border-color: var(--kk-zalm);
  box-shadow: 0 3px 0 var(--kk-boter-diep), 0 0 0 4px rgba(232, 135, 122, 0.32);
  animation: coachpuls 1.6s ease-in-out infinite;
}

@keyframes coachpuls {
  0%,
  100% {
    box-shadow: 0 3px 0 var(--kk-boter-diep), 0 0 0 4px rgba(232, 135, 122, 0.32);
  }
  50% {
    box-shadow: 0 3px 0 var(--kk-boter-diep), 0 0 0 8px rgba(232, 135, 122, 0.14);
  }
}

/* Dezelfde aanwijzing op de bevestigknop van de naamstap. Die knop draagt zijn
   eigen schaduw, dus hier een omtrek in plaats van een box-shadow — anders
   vecht de puls met de knop zelf. */
.grote-knop.coach-doel {
  outline: 4px solid rgba(232, 135, 122, 0.45);
  outline-offset: 2px;
  animation: coachpuls-omtrek 1.6s ease-in-out infinite;
}

@keyframes coachpuls-omtrek {
  0%,
  100% {
    outline-color: rgba(232, 135, 122, 0.45);
    outline-offset: 2px;
  }
  50% {
    outline-color: rgba(232, 135, 122, 0.16);
    outline-offset: 7px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .actie.coach-doel,
  .grote-knop.coach-doel {
    animation: none;
  }
}

.rustig .actie.coach-doel,
body.rustig .actie.coach-doel,
.rustig .grote-knop.coach-doel,
body.rustig .grote-knop.coach-doel {
  animation: none;
}

.actie:active {
  transform: translateY(2px);
  box-shadow: 0 1px 0 var(--kk-boter-diep);
}

.actie-secundair {
  background: var(--kaart);
  border-color: var(--kk-lijn);
  color: var(--tekst);
  box-shadow: 0 3px 0 var(--kk-lijn);
}

.actie:disabled {
  opacity: 0.55;
  cursor: default;
  transform: none;
}

.actie-icoon {
  font-size: 19px;
}

.gratis {
  margin: 2px 4px 0;
  text-align: center;
  font-size: 12.5px;
  color: var(--tekst-zacht);
}

/* ── Panelen (winkeltje, boekje, eten, spelen, onboarding, reünie) ── */

.paneel-achtergrond {
  position: fixed;
  inset: 0;
  background: rgba(34, 48, 74, 0.5);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  z-index: 40;
  animation: fade-in 0.25s ease both;
}

@media (min-width: 560px) {
  .paneel-achtergrond {
    align-items: center;
    padding: 24px;
  }
}

@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

.paneel {
  background: var(--kk-melk);
  color: var(--kk-spar);
  width: 100%;
  max-width: 560px;
  max-height: min(86vh, 86dvh);
  border-radius: 22px 22px 0 0;
  padding: 18px 16px calc(18px + env(safe-area-inset-bottom, 0px));
  overflow-y: auto;
  /* Scrollen in het paneel mag niet doorketenen naar de wikkelpagina. Gemeten op
     320x568: bij de onderrand van het kistpaneel liep `window.scrollY` van 461
     naar 974 en schoof de bovenkant van het spelframe van +13 naar -500 — de
     hele kamer stond dan buiten beeld. Juist de veeg naar "Alle speeltjes"
     veroorzaakte dat, en dat is de weg naar de helft van het spelaanbod. */
  overscroll-behavior: contain;
  box-shadow: 0 -6px 40px rgba(20, 30, 51, 0.3);
  animation: paneel-in 0.3s cubic-bezier(0.22, 1, 0.36, 1) both;
}

@media (min-width: 560px) {
  .paneel {
    border-radius: 22px;
  }
}

/* Bescheiden entree: op een korte viewport (390×700) staat een paneel dat de
   volle hoogte gebruikt anders 30 px onder de vouw zolang de slide loopt —
   en in een gethrottelde/occluded tab blijft hij daar zelfs staan. */
@keyframes paneel-in {
  from { transform: translateY(12px); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

.paneel h2 {
  margin: 0 0 4px;
  font-size: 24px;
  line-height: 1.15;
}

.paneel-intro {
  margin: 0 0 14px;
  color: #5c7268;
  font-size: 14.5px;
}

.paneel-sluit {
  position: sticky;
  top: 0;
  float: right;
  width: 44px;
  height: 44px;
  margin: -6px -4px 0 8px;
  border-radius: 50%;
  border: 1.5px solid var(--kk-lijn);
  background: var(--kk-papier);
  font-size: 18px;
  z-index: 2;
}

/* Tabbladen in het winkeltje */
/* Vers geopend paneel: de bediening neemt heel even geen tikken aan, zodat de
   tweede tik van een ongeduldige vinger niet meteen iets koopt of een speeltje
   start. Alléén de knoppen — het paneel zelf blijft de tik opvangen, want de
   achtergrond sluit bij een klik. Zie PANEEL_RESPIJT_MS in game.mjs. */
.paneel.respijt button,
.paneel.respijt input,
.paneel.respijt a,
.paneel.respijt [role="button"] {
  pointer-events: none;
}

.tabs {
  display: flex;
  gap: 6px;
  margin-bottom: 12px;
  flex-wrap: wrap;
}

.tab {
  border: 1.5px solid var(--kk-lijn);
  background: var(--kk-papier);
  border-radius: 999px;
  padding: 8px 14px;
  /* 40 was de enige bediening in de hele kamer onder de 44px-norm — zelfs de
     sluitknop van ditzelfde paneel haalt 44x44. En dit zijn niet zomaar
     knopjes: ze zijn de énige weg naar speeltjes, decoratie en de
     kat-kleedkamer. Een tapdoel dat de toegang tot een hele pijler vormt,
     verdient de norm ook echt. */
  min-height: 44px;
  font-weight: 700;
  font-size: 14px;
  color: #5c7268;
}

.tab[aria-selected="true"] {
  background: var(--kk-spar);
  border-color: var(--kk-spar);
  color: var(--kk-melk);
}

.winkel-rooster {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 10px;
}

/* De voorraadkast ("Wat krijgt …?") heeft vaak maar één of twee soorten in
   huis. In het winkelraster liet dat op een breed paneel ~70% leegte links
   van niks staan — gecentreerd leest dezelfde kast als een keuze, niet als
   een gemis. Het voetje eronder benoemt de rest van de kast expliciet. */
.eten-rooster {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

.eten-rooster .winkel-kaart {
  flex: 0 1 200px;
}

.eten-voetje {
  margin: 10px 0 0;
  text-align: center;
  font-size: 13px;
  color: #5c7268;
}

.winkel-kaart {
  background: var(--kk-papier);
  border: 1.5px solid var(--kk-lijn);
  border-radius: 16px;
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  text-align: left;
}

.winkel-kaart.slot {
  opacity: 0.65;
}

.winkel-plaatje {
  height: 64px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--kk-melk);
  border-radius: 12px;
}

.winkel-plaatje svg {
  max-width: 100%;
  max-height: 60px;
}

.winkel-naam {
  font-family: "Baloo 2", sans-serif;
  font-weight: 700;
  font-size: 15px;
  line-height: 1.2;
}

.winkel-flavour {
  font-size: 12.5px;
  color: #5c7268;
  min-height: 32px;
}

.winkel-echt {
  font-size: 12.5px;
  margin: 2px 0 0;
}

.winkel-echt a {
  color: #3a6e60;
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.winkel-koop {
  min-height: 44px;
  border-radius: 12px;
  border: 2px solid var(--kk-boter-diep);
  background: var(--kk-boter);
  color: #4a3a10;
  font-family: "Baloo 2", sans-serif;
  font-weight: 700;
  font-size: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}

.winkel-koop.stil {
  background: var(--kk-papier);
  border-color: var(--kk-lijn);
  color: #5c7268;
}

.winkel-koop:disabled {
  opacity: 0.6;
  cursor: default;
}

.winkel-status {
  font-size: 12.5px;
  color: #3a6e60;
  font-weight: 700;
}

/* Een item dat je met goed spelen verdient: geen slotje maar de uitnodiging. */
.winkel-kaart.wacht {
  border-style: dashed;
  border-color: var(--kk-boter-diep);
}

.winkel-voorwaarde {
  display: block;
  border-radius: 12px;
  padding: 8px 10px;
  background: #fbefd3;
  color: #4a3a10;
  font-size: 12.5px;
  line-height: 1.35;
  font-weight: 700;
}

/* Naam wijzigen */
.naam-rij {
  display: flex;
  gap: 8px;
  margin-top: 14px;
  flex-wrap: wrap;
}

.naam-rij input {
  flex: 1;
  min-width: 150px;
  min-height: 44px;
  border-radius: 12px;
  border: 1.5px solid var(--kk-lijn);
  padding: 8px 12px;
  font-family: inherit;
  font-size: 15px;
  background: var(--kk-papier);
  color: var(--kk-spar);
}

.naam-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: center;
  margin: 0 0 4px;
}

.naam-chip {
  min-height: 44px;
  padding: 8px 16px;
  border-radius: 999px;
  border: 1.5px solid var(--kk-lijn);
  background: var(--kk-papier);
  color: var(--kk-spar);
  font-family: "Baloo 2", sans-serif;
  font-weight: 700;
  font-size: 15px;
}

.naam-chip.aan {
  border-color: var(--kk-boter-diep);
  background: var(--kk-boter);
  color: #4a3a10;
}

/* ── Stijlkiezer (jouw kat) ── */

/* Compact gehouden: de kiezer moet óók op een korte viewport (390×700)
   volledig binnen beeld vallen — een keuzescherm dat je moet scrollen mist
   de helft van de swatches. */
.stijl-kiezer {
  text-align: center;
}

/* De bevestigknop lag ónder de vouw van het paneel: op een iPhone 12 begon hij
   op 584 px in een spelvenster van 569, op een iPhone SE op 572 in 486. Tijdens
   de kennismaking is dit paneel onsluitbaar en draagt hij geen coachring, dus
   een kind dat niet leest stond daar stil — de enige harde poort in de hele
   kennismaking. Hij plakt nu onderaan het paneel: altijd in beeld, hoe kort het
   scherm ook is. De strook eronder is dezelfde tint als het paneel, zodat de
   swatches er netjes achter wegschuiven. */
.stijl-kiezer .grote-knop {
  position: sticky;
  bottom: 0;
  z-index: 2;
  margin-top: 14px;
  /* Een zachte schaduw naar boven scheidt hem van de swatches die eronder
     doorschuiven; zonder dat lijkt hij er middenin te zweven. */
  box-shadow: 0 -12px 16px -12px rgba(20, 30, 51, 0.45);
}

/* Swatches zijn om te tikken en te slepen, niet om te lezen: zonder dit kleurde
   een veeg over de rijen "Patroontje" blauw op, alsof je tekst selecteerde. */
.stijl-kiezer .stijl-groep-kop,
.stijl-kiezer .stijl-label,
.stijl-kiezer .stijl-knop,
.stijl-kiezer .stijl-rij {
  user-select: none;
  -webkit-user-select: none;
}

.stijl-kiezer h2 {
  font-size: 22px;
  margin: 0 0 2px;
}

.stijl-kiezer .paneel-intro {
  margin: 0 0 4px;
  font-size: 13.5px;
}

.stijl-preview {
  display: block;
  width: 96px;
  height: 96px;
  margin: 0 auto;
}

.stijl-groep {
  margin-top: 5px;
  text-align: left;
}

.stijl-groep:first-of-type {
  margin-top: 2px;
}

.stijl-groep-kop {
  margin: 0 0 3px;
  font-size: 12px;
  font-weight: 700;
  color: var(--tekst-zacht);
}

.stijl-rij {
  display: grid;
  gap: 6px;
}

.stijl-rij.vachten {
  grid-template-columns: repeat(4, 1fr);
}

.stijl-rij.patronen {
  grid-template-columns: repeat(5, 1fr);
}

.stijl-rij.beffen {
  grid-template-columns: repeat(3, 1fr);
}

.stijl-knop {
  min-height: 44px;
  padding: 3px 2px;
  border-radius: 12px;
  border: 2px solid var(--kk-lijn);
  background: var(--kk-papier);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
}

.stijl-knop[aria-pressed="true"] {
  border-color: var(--kk-spar);
  box-shadow: inset 0 0 0 2px var(--kk-boter);
}

/* Halve kat (kop + voorpootjes): breed genoeg om sokjes te laten zien. */
.stijl-rij.patronen .stijl-knop svg {
  width: 100%;
  height: 46px;
}

.stijl-label {
  font-size: 10.5px;
  line-height: 1.15;
  font-weight: 700;
  color: var(--tekst-zacht);
  text-align: center;
  hyphens: auto;
}

.stijl-vlek {
  display: block;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 2px solid var(--kk-lijn);
}

.stijl-kiezer .grote-knop {
  margin-top: 8px;
}

.stijl-spiegelhint {
  margin: 12px 0 0;
  font-size: 12.5px;
  color: var(--tekst-zacht);
  text-align: left;
}

/* ── Vriendenboekje ── */

.boekje-teller {
  font-weight: 700;
  color: #3a6e60;
  font-size: 14px;
  margin: 0 0 10px;
}

.boekje-rooster {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 10px;
}

.boekje-kaart {
  background: var(--kk-papier);
  border: 1.5px solid var(--kk-lijn);
  border-radius: 16px;
  padding: 12px 10px;
  text-align: center;
  position: relative;
  overflow: hidden;
}

.boekje-kaart::before {
  content: "";
  position: absolute;
  inset: 5px;
  border: 1.5px dashed var(--kk-lijn);
  border-radius: 12px;
  pointer-events: none;
}

.boekje-kaart svg {
  width: 84px;
  height: 82px;
}

.boekje-naam {
  font-family: "Baloo 2", sans-serif;
  font-weight: 700;
  font-size: 16px;
  margin: 2px 0 0;
}

.boekje-info {
  font-size: 12.5px;
  color: #5c7268;
  margin: 2px 0 0;
}

.boekje-info strong {
  color: var(--kk-spar);
}

.boekje-zeldzaam {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  border-radius: 999px;
  padding: 2px 9px;
  margin-top: 6px;
  background: var(--kk-melk);
  color: #5c7268;
  border: 1px solid var(--kk-lijn);
}

/* Moos' erekaart: dezelfde vorm, één tint warmer — geen 13e verzamelkaart. */
.boekje-kaart.mascotte {
  border-color: var(--kk-boter-diep);
  background: #fff6e2;
  grid-column: 1 / -1;
}

.boekje-zeldzaam.mascotte { color: #8a5a06; border-color: var(--kk-boter-diep); background: var(--kk-boter); }
.boekje-zeldzaam.ongewoon { color: #3a6e60; border-color: #9cc3b3; }
.boekje-zeldzaam.zeldzaam { color: #8a5a06; border-color: #e2c07a; }
.boekje-zeldzaam.legendarisch { color: #22304a; border-color: #8fa0a8; background: #eef2f4; }

/* ── Onboarding & reünie ── */

.intro-kaart {
  text-align: center;
  padding: 6px 4px;
}

.intro-kaart svg.intro-kat {
  width: 150px;
  height: 150px;
}

/* Het cadeau van stap 7: het speeltje dat bovenop de kist ligt, groot genoeg
   om als geschenk te lezen. `spelVoorwerp()` levert zijn eigen svg mee. */
.intro-kist {
  display: block;
  margin: 0 auto 2px;
}

.intro-kist svg {
  width: 108px;
  height: 108px;
}

.intro-kaart h2 {
  font-size: 26px;
}

.intro-kaart p {
  color: #5c7268;
  font-size: 15.5px;
  max-width: 40ch;
  margin: 8px auto 16px;
}

.grote-knop {
  min-height: 52px;
  border-radius: 999px;
  border: 2px solid var(--kk-boter-diep);
  background: var(--kk-boter);
  color: #4a3a10;
  font-family: "Baloo 2", sans-serif;
  font-weight: 700;
  font-size: 17px;
  padding: 10px 28px;
  box-shadow: 0 3px 0 var(--kk-boter-diep);
}

.grote-knop:active {
  transform: translateY(2px);
  box-shadow: 0 1px 0 var(--kk-boter-diep);
}

/* Bovenaan tegen de muur: onderaan lag de coach op de wolbal én op Moos zelf,
   precies de twee dingen waar de kennismaking naar wijst (zie
   `plaatsCoachBanner`, dat de nachtbanner en een lage scène opvangt). */
/* Deelt het keyframe `banner-in` met `.banner`, en dat is misgegaan: toen daar
   in r34 de `translateX(-50%)` uit verdween (die wolk kreeg een symmetrische
   band), bleef deze wolk met `left:50%` achter. Met `animation-fill-mode: both`
   wint de eindwaarde van het keyframe van de cascade, dus de centrering viel weg
   en de wolk stond permanent een halve breedte naar rechts — gemeten 98px buiten
   beeld op 320x568 en 127px op 390x844, in beide talen. Van de eerste zin die
   een nieuwe speler leest ("…kies 'Geef eten'") bleef 44 van de 74 tekens over.
   Dezelfde band als `.banner` dus, zonder transform om over te struikelen. */
.intro-stap-banner {
  position: absolute;
  left: 3%;
  right: 3%;
  top: 12px;
  margin-inline: auto;
  width: min(92%, 420px);
  background: rgba(253, 249, 241, 0.96);
  border: 2px solid var(--kk-boter);
  border-radius: 16px;
  /* `--coach-schaal` wordt gezet door `krimpCoachTotHijBovenDeKatPast()`: op een
     korte telefoon moet de wolk in de vrije band bóven de kat passen, en in het
     Engels breekt dezelfde zin over meer regels dan in het Nederlands. */
  padding: calc(10px * var(--coach-schaal, 1)) calc(14px * var(--coach-schaal, 1));
  font-size: calc(14.5px * var(--coach-schaal, 1));
  text-align: center;
  box-shadow: var(--schaduw);
  pointer-events: none;
  animation: banner-in 0.4s ease both;
  color: var(--kk-spar);
}

/* ── Toasts ── */

.toasts {
  /* ABSOLUUT binnen `.scene-wrap`, niet fixed in het venster: zo beweegt de
     laan mee met de kamer en klipt `overflow: hidden` haar erbinnen. Dat
     vervangt --toast-links en --toast-max door twee regels die niets
     kunnen missen. */
  position: absolute;
  left: 50%;
  /* De laan hangt in de KAMER, niet in het venster — in beide assen. Dat is de
     structurele les van vier verhuizingen: `bottom: 64px` lag in de knoppen, aan
     het actieraster hangend lag hij op de meterrij, en op de muur gecentreerd op
     het VENSTER liep hij liggend dwars over "Geef eten" (88% op 844x390), want
     daar staat het actieraster náást de scène. Een laan die aan `.scene-wrap`
     hangt kan die kolom niet meer bereiken. `borgToastLaan()` zet alle drie. */
  top: var(--toast-top, 12px);
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  z-index: 60;
  pointer-events: none;
  width: max-content;
  max-width: calc(100% - 16px);
}

.toast {
  background: var(--kk-spar);
  color: var(--kk-melk);
  border-radius: 999px;
  /* `--toast-schaal` wordt gezet door `snoeiToastLaan()` als de laatste toast
     niet in de vrije band past. Krimpen is beter dan weglaten: de melding blijft
     leesbaar, alleen kleiner. Zie het commentaar daar voor de meting. */
  padding: calc(9px * var(--toast-schaal, 1)) calc(18px * var(--toast-schaal, 1));
  font-size: calc(14px * var(--toast-schaal, 1));
  font-weight: 700;
  box-shadow: 0 4px 18px rgba(20, 30, 51, 0.35);
  animation: toast-in 0.35s cubic-bezier(0.22, 1, 0.36, 1) both, toast-uit 0.4s ease 4.4s both;
  display: flex;
  align-items: center;
  gap: 7px;
  max-width: 100%;
}

.toast.feest {
  background: var(--kk-boter);
  color: #4a3a10;
}

/* Zonder entree-animatie: `toast-in` begint op opacity 0 met fill-mode `both`,
   en in een rustige of gethrottelde context (playtest, verborgen tab) staat
   die animatie stil — dan hangt de toast onzichtbaar in de DOM. */
.toast.direct {
  animation: none;
}

@keyframes toast-in {
  from { opacity: 0; transform: translateY(12px) scale(0.95); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes toast-uit {
  to { opacity: 0; transform: translateY(8px); }
}

/* ── De speelkist: hooguit drie kaartjes, daarachter een collectie ── */

.kist-kaarten {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 10px;
}

.kist-kaart {
  background: var(--kk-papier);
  border: 1.5px solid var(--kk-lijn);
  border-radius: 16px;
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  text-align: left;
  min-height: 44px;
}

.kist-kaart:hover {
  border-color: var(--kk-zalm);
}

/* Het beeldblok van een kaart mét manieren van spelen is zélf een knop, zodat
   beeld, naam en uitleg niet dood zijn. Hij mag niets aan het kaartuiterlijk
   veranderen: alleen de aanraakbaarheid komt erbij. */
.kist-kaart-vlak {
  display: flex;
  flex-direction: column;
  gap: 4px;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}

/* Ligt wél in de kist, maar het speeltje wordt nog klaargezet (M4/M5): geen
   speelbelofte doen die de kaart niet waarmaakt — gestippeld, rustig, plat. */
.kist-kaart.bijna {
  background: transparent;
  border-style: dashed;
  border-color: var(--kk-mist);
  opacity: 0.85;
}

.kist-kaart.bijna .kist-kaart-naam {
  color: #5c7268;
  font-weight: 600;
}

.kist-kaart.bijna:hover {
  border-color: var(--kk-mist);
}

/* Binnengekomen via een deep-link: dít speeltje zocht je. */
.kist-kaart.uitgelicht {
  border-color: var(--kk-zalm);
  box-shadow: 0 0 0 3px rgba(232, 135, 122, 0.28);
}

.kist-melding {
  margin: 0 0 14px;
  padding: 10px 12px;
  border-radius: 14px;
  background: #fdf3e4;
  color: #5c7268;
  font-size: 14.5px;
}

/* 's Nachts blijft de kist open, maar wel in rustige stand. */
.kist-nacht {
  margin: 0 0 12px;
  padding: 9px 12px;
  border-radius: 14px;
  background: rgba(34, 48, 74, 0.08);
  color: #4a5c6b;
  font-size: 14px;
}

/* Dezelfde twee regels als op het krijtbordje in de kamer. */
.kist-krijt {
  margin: 12px 0 0;
  color: #5c7268;
  font-size: 13.5px;
  text-align: center;
}

.kist-stickers {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 0 0 12px;
  color: #5c7268;
  font-size: 13.5px;
}

.kist-sticker {
  padding: 3px 9px;
  border: 1.5px solid var(--kk-mist);
  border-radius: 999px;
  background: var(--kk-melk);
  color: var(--kk-spar);
  font-size: 12.5px;
}

/* Het voorwerp én jouw kat ernaast: dit ligt in jóuw kist. */
.kist-kaart-beeld {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 2px;
  min-height: 62px;
}

.kist-kaart-beeld svg {
  display: block;
  width: 58px;
  height: 58px;
}

/* Jouw kat staat naast het voorwerp: dit ligt in jóuw kist. */
.kist-kaart-kat {
  display: block;
  margin-bottom: -4px;
}

.kist-kaart-kat svg {
  width: 52px;
  height: 50px;
}

.kist-kaart-naam {
  font-family: "Baloo 2", "Atkinson Hyperlegible", system-ui, sans-serif;
  font-weight: 700;
  font-size: 16px;
  color: var(--kk-spar);
}

.kist-kaart-uitleg {
  font-size: 13px;
  color: #5c7268;
}

/* Voetje van een kaartje-zonder-modusknoppen: toestand of record, tegen de
   onderrand aan — zodat deze kaart naast een kaartje mét knoppen niet met
   een leeg blok bodem eindigt (het raster rekt kaarten even hoog). */
.kist-kaart-toestand {
  margin-top: auto;
  padding-top: 6px;
  font-size: 12.5px;
  font-weight: 700;
  color: #3a6e60;
}

/* De startchip op een kaartje met één manier van spelen. De kaart ís de knop —
   dit is geen tweede knop, alleen de zichtbare belofte ervan, in dezelfde vorm
   als de manier-chips hieronder. Zonder deze chip was het enige knopvormige op
   het keuzescherm de chips van de búúrkaart, en startte een tik het verkeerde
   speeltje. `pointer-events:none` zodat de kaart één trefvlak blijft. */
.kist-kaart-start {
  align-self: center;
  margin-top: 6px;
  padding: 7px 14px;
  border-radius: 999px;
  border: 1.5px solid var(--kk-lijn);
  background: var(--kk-melk);
  color: var(--kk-spar);
  font-weight: 800;
  font-size: 13.5px;
  white-space: nowrap;
  pointer-events: none;
}

.kist-kaart:hover .kist-kaart-start,
.kist-kaart:focus-visible .kist-kaart-start {
  border-color: var(--kk-zalm);
}

/* Speeltjes met meer dan één manier van spelen: één startknop per manier. */
.kist-modi {
  display: flex;
  gap: 6px;
  margin-top: 4px;
  flex-wrap: wrap;
}

.kist-modus-knop {
  flex: 1 1 auto;
  min-height: 44px;
  padding: 0 10px;
  border-radius: 999px;
  border: 1.5px solid var(--kk-lijn);
  background: var(--kk-melk);
  color: var(--kk-spar);
  font-weight: 700;
  font-size: 14px;
  white-space: nowrap;
}

.kist-modus-knop:hover {
  border-color: var(--kk-zalm);
}

/* 's Nachts staat de klokloze manier van spelen voorop, met een maanzacht
   accent. Gejaagd blijft gewoon beschikbaar — niets gaat op slot. */
.kist-modus-knop.nacht {
  border-color: var(--kk-nacht);
  background: linear-gradient(180deg, rgba(34, 48, 74, 0.1), rgba(245, 198, 79, 0.14));
  box-shadow: 0 0 0 3px rgba(34, 48, 74, 0.12);
}

/* De deur naar de andere helft van het spelaanbod blijft aan de onderrand van
   het paneel plakken. Zonder dit stond hij 104 tot 199px onder de vouw op 8 van
   de 10 gemeten combinaties: een kind dat niet doorscrolt zag drie speeltjes en
   dacht dat dat alles was. Het paneel scrolt zelf (`.paneel { overflow-y:auto }`),
   dus `sticky` hangt hier aan de zichtbare onderrand van dat paneel.
   De voet draagt de paneelkleur, anders scrollen de kaarten er zichtbaar
   dwars doorheen; hij loopt door tot in de onderrand van het paneel zodat er
   geen streepje inhoud onder de knop door piept. */
.kist-voet {
  position: sticky;
  bottom: 0;
  margin-top: 12px;
  /* De voet draagt zelf de onderrand van het paneel, zodat de knop niet tegen
     de rand plakt maar op dezelfde 18px staat als de rest van de inhoud. De
     negatieve marge haalt die hoogte weer uit de doorloop, anders groeit het
     paneel met een lege strook onderaan. */
  margin-bottom: calc(-18px - env(safe-area-inset-bottom, 0px));
  padding-bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  background: var(--kk-melk);
  z-index: 1;
}

.kist-alles {
  width: 100%;
  min-height: 48px;
  border-radius: 999px;
  border: 1.5px solid var(--kk-lijn);
  background: var(--kk-papier);
  font-weight: 700;
  color: #5c7268;
}

/* De collectie is een lijst, nooit een raster van gelijke tegels. */
.kist-lijst {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.kist-regel {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 56px;
  padding: 8px 12px;
  text-align: left;
  background: var(--kk-papier);
  border: 1.5px solid var(--kk-lijn);
  border-radius: 14px;
}

/* Nog onderin de kist: rustiger dan een klaarliggend speeltje, maar wél een
   knop — tikken opent de kist met dit speeltje bovenop (zie `toonNogNiet`). */
.kist-regel.wacht {
  opacity: 0.82;
  border-style: dashed;
}

.kist-regel svg {
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
}

.kist-regel-tekst {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.kist-regel-naam {
  font-weight: 700;
  color: var(--kk-spar);
}

.kist-regel-toestand {
  font-size: 13px;
  color: #5c7268;
}

/* ── Speelmodus: het volle scherm om een speeltje heen ── */

/* Sibling van #app (zie index.html). Eigen crème ondergrond: de sfeer van de
   kamer hoort niet over het speelveld heen te kleuren. */
#speelmodus.speelmodus {
  position: fixed;
  inset: 0;
  z-index: 70;
  display: flex;
  flex-direction: column;
  /* Op een breed bureaublad is een spelkolom van ~550px omringd door kale
     crème: het speelveld zweeft dan in het niets. Deze laag krijgt daarom een
     zachte kamerondergrond — twee brede gloeden in boter en sparzacht plus een
     fijn stippenweefsel, allemaal binnen het zespalet en licht genoeg om de
     kleuren van het spel zelf met rust te laten. */
  background-color: var(--kk-melk);
  background-image:
    radial-gradient(120% 90% at 50% -20%, rgba(245, 198, 79, 0.16), rgba(245, 198, 79, 0) 60%),
    radial-gradient(120% 90% at 50% 120%, rgba(46, 75, 63, 0.1), rgba(46, 75, 63, 0) 62%),
    radial-gradient(circle at center, rgba(46, 75, 63, 0.055) 1.1px, rgba(46, 75, 63, 0) 1.2px);
  background-size: 100% 100%, 100% 100%, 22px 22px;
  opacity: 0;
  touch-action: none;
  overscroll-behavior: contain;
}

/* De zachte veeg (≥250 ms) zit bewust op een eigen klasse: in een rustige of
   gethrottelde context (playtest, verborgen tab) staat de transitie stil, en
   dan zou de laag onzichtbaar-maar-actief blijven staan. */
#speelmodus.speelmodus.veeg {
  transition: opacity 0.28s ease;
}

#speelmodus.speelmodus.aan {
  opacity: 1;
}

/* 52px: alleen dán past een tapdoel van 44×44 met wat lucht eromheen. */
.speelmodus-balk {
  display: flex;
  align-items: center;
  gap: 6px;
  height: 52px;
  min-height: 52px;
  padding: 0 6px 0 12px;
  background: var(--kk-spar);
  color: var(--kk-melk);
  padding-top: env(safe-area-inset-top, 0px);
  box-sizing: content-box;
}

/* Tijdens de pauze ligt de modale kaart over deze balk heen. De knoppen zijn dan
   niet te gebruiken, en dat mag je zien: een gouden "Klaar" die er klaar bij
   staat en niets doet, laat een kind dat wég moet twaalf keer tikken. `inert`
   staat in game.mjs; dit is alleen wat het oog vertelt. */
.speelmodus-balk.gepauzeerd {
  opacity: 0.45;
  filter: saturate(0.6);
}

/* De Klaar-knop staat vóóraan in de DOM (dus eerst in de tabvolgorde) maar
   rechts in beeld — de uitgang mag nooit naast het speelveld zitten. */
.speelmodus-naam {
  order: 1;
  /* Krimpt als eerste: liever "De Snoetjesd…" dan een kat zonder naam. */
  flex: 0 1 auto;
  min-width: 0;
  font-family: "Baloo 2", "Atkinson Hyperlegible", system-ui, sans-serif;
  font-weight: 700;
  font-size: 15px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Zodra "Nog een keer!" erbij komt past de spelnaam op een telefoon niet meer
   naast de kattennaam — en dan knapte hij af tot "Het Bro… · Zebra". De naam
   van de kat heeft ontwerp-voorrang, dus wijkt de SPELNAAM volledig in plaats
   van te ellipsen. Visueel weg, niet uit de toegankelijkheidsboom: hij is de
   `aria-labelledby` van de dialoog.

   De grens stond eerst op 420px en is toen verlaagd naar 360px, omdat de
   spelnaam "op 390px er weer naast paste". Die meting klopte niet: ze is gedaan
   in een nagebootste stand, niet ná een échte ronde. Twee keuringspanels vonden
   het onafhankelijk, en nameten in de stand die een kind ziet geeft
   "Het Kattenparcours" (132px nodig) **60px op 375, 75px op 390 en zelfs 108px
   op 430** — dus afgekapt tot "Het Katt…" op elk telefoonformaat. De grens ligt
   nu op 480px: pas boven een frame van ~460px past de langste naam er echt bij.
   "Klaar" blijft altijd volledig in beeld; die knop is de uitgang en mag nooit
   wijken. */
@media (max-width: 480px) {
  .speelmodus.met-opnieuw .speelmodus-naam {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

/* De naam van de kat krimpt nooit: het potje is van háár. Het scheidings-
   puntje is decoratie en hoort bij de spélnaam ervóór — het leeft daarom in
   CSS, zodat het mee kan verdwijnen als de spelnaam wijkt (zie hieronder)
   en de balk nooit "· Zebra" leest. */
.speelmodus-kat {
  order: 2;
  flex: 0 0 auto;
  margin-right: auto;
  font-weight: 400;
  font-size: 14px;
  opacity: 0.85;
  white-space: nowrap;
}

.speelmodus-kat::before {
  content: "· ";
}

@media (max-width: 420px) {
  .speelmodus.met-opnieuw .speelmodus-kat::before {
    content: "";
  }
}

/* Verschijnt pas ná een afgeronde ronde; staat in de tabvolgorde ná Klaar. */
.speelmodus-opnieuw {
  order: 3;
  flex: 0 0 auto;
  min-height: 44px;
  min-width: 44px;
  padding: 0 14px;
  border-radius: 999px;
  border: 0;
  background: var(--kk-melk);
  color: var(--kk-spar);
  font-weight: 700;
  font-size: 15px;
  white-space: nowrap;
}

.speelmodus-geluid {
  order: 4;
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  border-radius: 999px;
  border: 0;
  background: transparent;
  color: var(--kk-melk);
  font-size: 18px;
}

.speelmodus-klaar {
  order: 5;
  flex: 0 0 auto;
  min-height: 44px;
  min-width: 44px;
  padding: 0 18px;
  border-radius: 999px;
  border: 0;
  background: var(--kk-boter);
  color: #4a3a10;
  font-weight: 700;
  font-size: 15px;
}

/* Het beloningsmoment ín de speelmodus: klein, warm, en meteen zichtbaar op
   het scherm waar de speler kijkt. De toast in de kamer komt daarna. */
.speelmodus-beloning {
  position: absolute;
  /* Dezelfde valkuil als de eindkaarten hadden: `left:50%` +
     `translateX(-50%)` beperkt de shrink-to-fit-breedte tot de hélft van de
     laag, dus de max-width hieronder deed niets. De pil werd daardoor ~195px
     breed en 136–159px hóóg — te hoog om nog ergens tussen te passen, waarna
     hij op het gereedschap van de Kattensalon belandde. Een symmetrische band
     met max-content geeft hem zijn breedte terug en halveert zijn hoogte. */
  left: 5%;
  right: 5%;
  width: max-content;
  margin-inline: auto;
  /* Startplek; `pilTop()` zet de echte `top` zodra de pil gemeten is. */
  top: calc(52px + env(safe-area-inset-top, 0px) + 10px);
  display: flex;
  align-items: center;
  gap: 7px;
  max-width: 90%;
  padding: 10px 18px;
  border-radius: 999px;
  background: var(--kk-boter);
  color: #4a3a10;
  font-weight: 700;
  text-align: center;
  box-shadow: 0 4px 18px rgba(20, 30, 51, 0.35);
  pointer-events: none;
}

/* Elke bundel tekent zijn eigen crème ondergrond over de volle framebreedte.
   Op een breed bureaublad werd dat een zee van crème met een kolom van ~550px
   er eenzaam in. Het frame krijgt daarom een maximumbreedte: links en rechts
   komt de kamerondergrond van `#speelmodus` tevoorschijn, waardoor het spel in
   een lijst staat in plaats van in het niets te zweven. Ruim genoeg dat geen
   enkel spel krapper wordt dan het al was (de breedste kolom meet 760px). */
.speelmodus-frame {
  flex: 1 1 auto;
  width: min(100%, 1080px);
  margin-inline: auto;
  min-height: 0;
  border: 0;
  display: block;
  background: transparent;
}

/* Wachtregel als eigen chipje: hij ligt over het spel dat nog laadt, en moet
   dus ook op een donkere splash leesbaar blijven. */
.speelmodus-wacht {
  position: absolute;
  left: 50%;
  top: 60%;
  transform: translateX(-50%);
  margin: 0;
  max-width: 90%;
  padding: 8px 16px;
  border-radius: 999px;
  background: var(--kk-melk);
  color: #5c7268;
  font-weight: 700;
  text-align: center;
  box-shadow: 0 4px 18px rgba(20, 30, 51, 0.25);
  pointer-events: none;
}

/* De pauzelaag deelt de vorm van de stopvraag: zelfde kaart, zelfde knop,
   alleen een andere vraag. */
.speelmodus-vraag,
.speelmodus-pauzelaag {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(34, 48, 74, 0.55);
}

.speelmodus-vraag-kaart {
  background: var(--kk-melk);
  color: var(--kk-spar);
  border-radius: 20px;
  padding: 20px 18px;
  width: 100%;
  max-width: 340px;
  text-align: center;
  box-shadow: 0 6px 40px rgba(20, 30, 51, 0.35);
}

/* De waarschuwing bij een geklokt spel: rustig, geen alarm — het is informatie
   vóór een keuze, geen berisping. */
.speelmodus-vraag-uitleg {
  margin: -6px 0 14px;
  font-size: 14.5px;
  font-weight: 600;
  color: var(--kk-inkt-zacht, #4b6a5e);
}

.speelmodus-vraag-kaart h2 {
  margin: 0 0 14px;
  font-size: 21px;
}

.speelmodus-vraag-knoppen {
  display: flex;
  gap: 10px;
  justify-content: center;
  flex-wrap: wrap;
}

.speelmodus-vraag-knoppen button {
  min-height: 48px;
  padding: 0 18px;
  border-radius: 999px;
  border: 1.5px solid var(--kk-lijn);
  background: var(--kk-papier);
  font-weight: 700;
  color: #5c7268;
}

.speelmodus-vraag-knoppen .primair {
  background: var(--kk-spar);
  border-color: var(--kk-spar);
  color: var(--kk-melk);
}

/* ── Rustige modus ── */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }

  /* Spec: bij reduced motion blijft alléén de rustige ademhaling over. */
  #scene .adem.anim {
    animation-duration: 3.2s !important;
  }
}

/* Korte telefoons in portret. Gemeten met alle blokken los: op 360x640 is het
   frame 548px hoog terwijl de kamer 661px vraagt — kop 88, scène 170, meters
   108, knoppen 190, slotregel 54. Winkeltje en Vriendenboekje vielen daardoor
   46px buiten beeld, en op 320x568 zelfs Aai en Borstel. Zelfs een iPhone SE
   (375x667, frame 572) miste de onderste rij met 22px. Er is geen enkel blok
   dat dit alleen kan opvangen, dus schikt élk blok een beetje in: de scène
   krimpt, de meters worden compacter, de knoppen zakken naar 46px (nog steeds
   boven de norm) en de slotregel wordt één regel. */
@media (max-height: 700px) {
  .scene-wrap {
    min-height: 120px;
  }
  .meters {
    gap: 6px;
  }
  .meter {
    padding: 5px 8px;
    gap: 3px;
  }
  /* De naam van een meter mag niet afbreken. Deed hij dat wél, dan werd élke
     meter twee regels hoog en het hele blok 90 px in plaats van 44 — en die 46
     px gingen rechtstreeks van de scène af, want die krijgt wat overblijft.
     Het omslagpunt lag messcherp tussen 390 px (42 px hoog, één regel) en 375 px
     (90 px, twee regels): op een iPhone SE was de kat daardoor 26x30 px. Kleiner
     gezet past "Blijheid" weer naast zijn icoontje; de volledige naam staat
     sowieso in het `aria-label` van de meter. */
  .meter-kop {
    font-size: 11px;
    gap: 3px;
    white-space: nowrap;
  }
  .meter-kop svg {
    width: 13px;
    height: 13px;
  }
  .actie {
    min-height: 46px;
  }
  .acties {
    gap: 6px;
  }
  .gratis {
    font-size: 11px;
    margin-top: 0;
  }
  /* De aanwijzingswolk lag over de kat die hij uitlegt. Op een scène van 108 tot
     138px is elke wolk van vier regels hoger dan het dier eronder: gemeten dekte
     hij 100% van een kat van 21x24px, en op 320px stak hij er 33px onderuit —
     buiten de kamer. Hier is hij smal, klein en strak tegen de bovenrand, zodat
     hij een strook pakt in plaats van het midden. Hij blijft leesbaar (11px
     boven de 12px-ondergrens van de mobielpoort geldt niet voor deze laag: die
     meet op 390px, waar de wolk gewoon 14px is). */
  .banner {
    top: 4px;
    max-width: 96%;
    padding: 5px 10px;
    font-size: 12px;
    line-height: 1.25;
    border-radius: 14px;
  }
}

/* De smalste toestellen (frame ~286px op een 320px-telefoon, ~246px op een
   Galaxy Fold). Daar breken de knoplabels naar een tweede regel en groeit het
   actieraster van 150 naar 203px, waardoor Winkeltje en Vriendenboekje alsnog
   wegvielen. Kleiner zetten houdt ze op een regel; de knop zelf blijft op de
   44px-norm staan. */
@media (max-height: 700px) and (max-width: 320px) {
  .scene-wrap {
    min-height: 100px;
  }
  .actie {
    min-height: 44px;
    font-size: 13px;
  }
  .actie-icoon {
    font-size: 15px;
  }
  .munten,
  .levelchip,
  .streakchip {
    padding: 4px 9px;
    min-height: 32px;
  }
  .gratis {
    font-size: 10px;
  }
}

/* Liggend is de knoppenkolom smal, en dan eet de chrome het label op. Gemeten
   op 568x320 (een frame van 534x273): de kolom is 228px, dus een knop 111px —
   waarvan er 47 opgaan aan padding (20), emoji (19) en gap (8). Er blijft 57 tot
   64px over en "Winkeltje" vraagt er 70, dus brak hij af tot "Winkel-tje" — het
   euvel dat het liggende blok hierboven al eens had opgelost. Vijf van de zes
   labels braken zo, in beide talen.
   Deze regels staan bewust hier en niet in dat blok: dat staat vóór de
   basisregels van `.actie`, en op gelijke specificiteit wint de laatste — een
   `font-size` daar werd dus meteen weer overschreven door de 15,5px hieronder.
   De knop houdt zijn 44px-norm; alleen de letters en de emoji schikken in,
   dezelfde keuze die dit bestand al maakt voor een frame onder de 320px. */
@media (orientation: landscape) and (max-height: 500px) {
  .actie {
    font-size: 13px;
    gap: 6px;
  }
  .actie-icoon {
    font-size: 15px;
  }
}

/* Pauzeknop in de speelmodusbalk. Staat er alleen bij spellen mét een klok. */
.speelmodus-pauze {
  order: 2;
  flex: none;
  min-height: 44px;
  padding: 0 12px;
  border-radius: 12px;
  border: 2px solid rgba(253, 249, 241, 0.28);
  background: rgba(253, 249, 241, 0.12);
  color: var(--kk-melk);
  font-weight: 700;
  font-size: 14px;
  white-space: nowrap;
}

/* De speelmodusbalk mag nóóit overlopen: hij draagt de enige uitgang. Hij heeft
   geen `flex-wrap`, dus wat er niet past valt er stilzwijgend buiten — en dat
   was uitgerekend "Klaar" (die staat achteraan in de leesvolgorde). Gemeten na
   een afgelopen potje in het Nederlands: 436px in een venster van 360 en 320,
   met "Klaar" 0px zichtbaar. Twee sloten: de pauzeknop verdwijnt zodra de ronde
   voorbij is (zie `toonOpnieuwKnop`), en op een smal scherm wijkt ook de
   kattennaam — die is versiering, de uitgang niet. */
@media (max-width: 360px) {
  .speelmodus-kat {
    display: none;
  }
}

/* Onder 360px was de kattennaam al geweken, maar bleef de spelnaam alsnog tot
   32% geknipt ("Alle…") terwijl "⏸️ Even pauze" 127px opeiste. Het woord in die
   knop is versiering — het pauzesymbool draagt de betekenis, en `aria-label`
   draagt de naam. Zonder dat woord houdt de spelnaam ~85px extra over. */
/* De grens stond op 380px, en precies daarboven — op de maatgevende 390px —
   hield "⏸️ Even pauze" zijn volle 127px terwijl de spelnaam 63 van de 113px
   kreeg die hij nodig had ("De Snoet…"). Dat is de omgekeerde rangorde van B2,
   die zegt dat de spelnaam wint omdat die vertelt waar je in zit. Alleen de
   drie geklokte spellen dragen deze knop, dus alleen daar speelde het. */
@media (max-width: 430px) {
  .speelmodus-pauze .pauze-woord {
    display: none;
  }
  .speelmodus-pauze {
    /* Zonder woord blijft alleen het emoji over, en `padding:0 10px` maakte de
       knop 43 px breed — één pixel onder de norm waarvoor de kist-hotspot en de
       wolbal juist zijn opgetrokken. Een norm die je zelf oplegt, geldt ook voor
       je eigen knoppen. */
    min-width: 44px;
    padding: 0 10px;
  }
}
