/* AUTOMATISCH KOPIERT aus HeldenEngine – hier NICHT bearbeiten!
   Änderungen gehören in HeldenEngine/engine.css und werden mit
   `node HeldenEngine/sync.js` verteilt. */
/* =============================================================================
   HeldenEngine – Grundstyles der gemeinsamen Bausteine
   -----------------------------------------------------------------------------
   Deckt nur ab, was die Engine an Ansichten mitbringt: Shop, Sticker-Album,
   Einführung, Banner, Phasen-Kopfzeilen, Schreib- und Sortier-Aufgaben.

   Die App bindet diese Datei VOR ihrem eigenen styles.css ein – so kann jede
   App alles überschreiben, ohne dass hier etwas angepasst werden muss.
   Farben kommen aus zwei Variablen, die die App setzt:
       --he-akzent   Hauptfarbe der App
       --he-flaeche  Kartenhintergrund
   ========================================================================== */

:root {
  --he-akzent: #4caf50;
  --he-akzent-dunkel: #388e3c;
  --he-flaeche: #ffffff;
  --he-rand: rgba(0, 0, 0, 0.1);
  --he-text: #17233a;
  --he-text-leise: #6b7280;
  --he-radius: 16px;
  --he-schatten: 0 2px 8px rgba(0, 0, 0, 0.08);
}

/* Einheitliche Emoji-Grafiken (Twemoji) */
img.twe {
  height: 1em;
  width: 1em;
  vertical-align: -0.12em;
  display: inline-block;
}

/* --- Konfetti ------------------------------------------------------------ */
.confetti-piece,
.confetti {
  position: fixed;
  top: -20px;
  z-index: 9999;
  pointer-events: none;
  border-radius: 2px;
  animation: he-fall linear forwards;
}
@keyframes he-fall {
  to { transform: translateY(105vh) rotate(720deg); opacity: 0; }
}

/* --- Rückmeldung über dem Spielfeld -------------------------------------- */
.feedback-overlay {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.25);
  z-index: 900;
  pointer-events: none;
}
.feedback-overlay[hidden] { display: none; }

/* --- Tipp-Dialog: bleibt stehen, bis er aktiv geschlossen wird ------------ */
.hint-overlay {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.35);
  z-index: 950;
  padding: 24px;
}
.hint-overlay[hidden] { display: none; }
.hint-dialog {
  background: var(--he-flaeche);
  border-radius: 20px;
  padding: 24px 22px 20px;
  max-width: 420px;
  width: 100%;
  text-align: center;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.25);
  animation: he-pop 0.25s ease;
}
.hint-dialog-icon { font-size: 40px; line-height: 1; }
.hint-dialog-text {
  margin-top: 12px;
  font-size: 18px;
  font-weight: 600;
  line-height: 1.45;
  color: var(--he-text);
}
.hint-dialog-close {
  margin-top: 18px;
  padding: 12px 28px;
  border: none;
  border-radius: 999px;
  background: var(--he-akzent);
  color: #fff;
  font-size: 17px;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 3px 0 var(--he-akzent-dunkel);
}
.hint-dialog-close:active { transform: translateY(2px); box-shadow: none; }

/* --- Geschwister-Apps im Eltern-Bereich ----------------------------------- */
.family-section { margin-top: 24px; padding: 0 4px 8px; }
.family-title { margin: 0 0 2px; font-size: 17px; color: var(--he-text); }
.family-sub { margin: 0 0 10px; font-size: 13px; color: var(--he-text-leise); }
.family-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
.family-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  background: var(--he-flaeche);
  border: 2px solid var(--he-rand);
  border-radius: var(--he-radius);
  padding: 12px 8px;
  cursor: pointer;
  box-shadow: var(--he-schatten);
  text-align: center;
}
.family-card:active { transform: scale(0.97); }
.family-icon { font-size: 34px; line-height: 1.1; }
.family-name { font-weight: 700; font-size: 14px; color: var(--he-text); }
.family-fach { font-size: 12px; color: var(--he-text-leise); line-height: 1.3; }
.feedback-content {
  background: var(--he-flaeche);
  border-radius: 20px;
  padding: 18px 26px;
  font-size: 20px;
  font-weight: 700;
  color: var(--he-text);
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.25);
  display: flex;
  align-items: center;
  gap: 10px;
  animation: he-pop 0.25s ease;
  max-width: 88vw;
  text-align: center;
}
.feedback-icon { font-size: 30px; }
@keyframes he-pop {
  from { transform: scale(0.7); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}

/* --- Banner-Reihe (Streak, Tagesaufgabe, Wochenziel) --------------------- */
.banner-row {
  display: flex;
  gap: 8px;
  padding: 0 12px 10px;
  overflow-x: auto;
}
.banner-card {
  flex: 1 0 30%;
  min-width: 104px;
  background: var(--he-flaeche);
  border-radius: var(--he-radius);
  padding: 10px;
  display: flex;
  align-items: center;
  gap: 8px;
  box-shadow: var(--he-schatten);
  cursor: pointer;
  border: 2px solid transparent;
}
.banner-card.weekly { border-color: var(--he-akzent); }
.banner-icon { font-size: 22px; }
.banner-text {
  font-size: 15px;
  font-weight: 700;
  color: var(--he-text);
  line-height: 1.15;
}
.banner-text small {
  display: block;
  font-size: 11px;
  font-weight: 500;
  color: var(--he-text-leise);
}
.wc-bar {
  margin-top: 4px;
  height: 4px;
  background: var(--he-rand);
  border-radius: 3px;
  overflow: hidden;
}
.wc-bar > div {
  height: 100%;
  background: var(--he-akzent);
  border-radius: 3px;
}

/* --- Fortschrittszeile im Eltern-Bereich ---------------------------------
   Der Name stand in einem zu schmalen Feld („1. Klasse" in 74 px), also brach
   er um – und das Schloss rutschte allein in die zweite Zeile. Auf dem Handy
   sah jede Zeile aus wie zwei. Der Name darf jetzt so breit werden, wie er
   ist; der Balken gibt den Platz her, den er dafür braucht. */
.progress-line .name,
.progress-world-name {
  white-space: nowrap;
  flex: 0 0 auto;
  width: auto;
  min-width: 0;
}
.progress-line .mini-bar,
.progress-world-row .mini-bar { flex: 1 1 40px; min-width: 40px; }

/* --- Fragekarte ----------------------------------------------------------
   Vier Apps hatten sie in ihrem styles.css, RechenHelden nicht – dort stand
   die Aufgabe als nackter Text ohne Karte, obwohl die Engine denselben
   `.question-card`-Rahmen erzeugt. Der Grundstil gehört deshalb hierher; wer
   ihn anders will (DenkHelden mit größerem Radius), überschreibt ihn wie
   bisher in seiner eigenen Datei. */
.question-card {
  background: var(--c-card, var(--card, var(--he-flaeche)));
  border-radius: var(--radius, 20px);
  padding: 20px 16px;
  text-align: center;
  box-shadow: var(--c-shadow, var(--shadow, var(--he-schatten)));
  max-width: 420px;
  width: 100%;
  margin: 0 auto;
}

/* --- „🎁 10 gratis" auf der Klassenkarte ---------------------------------
   ⚠️ Die vier Geschwister-Apps hatten dafür `.class-card .lock-badge
   { top: 8px; right: 8px; font-size: 20px }` – eine Regel für ein einzelnes
   Schloss-Emoji. Die Engine schreibt dort aber einen ganzen Hinweis hinein
   („🎁 10 gratis"), der in 20px quer über die Klassenziffer lief. Jetzt eine
   kleine Pille am oberen Rand, wie RechenHelden sie schon hatte. */
.class-card { position: relative; }
.class-card .lock-badge,
.class-badge {
  position: absolute;
  top: -10px;
  right: 10px;
  left: auto;
  font-size: 11px;
  font-weight: 700;
  line-height: 1.4;
  white-space: nowrap;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--c-accent, var(--gold, var(--he-akzent)));
  color: #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .2);
}

/* --- Trainer & Abzeichen auf der Startseite ------------------------------
   Beide Knöpfe stehen in jeder App im HTML, aber nur RechenHelden hatte den
   Kartenstil dazu in seinem styles.css. In DeutschHelden, EnglischHelden,
   ForscherHelden und DenkHelden standen sie deshalb als nackter Text unter
   den Klassenkarten – man hielt sie kaum für Knöpfe. Der Stil gehört hierher
   und nicht in vier Kopien: Die Knöpfe kommen aus der gemeinsamen Vorlage,
   also auch ihr Aussehen. Jede App darf ihn in ihrem styles.css weiterhin
   überschreiben, weil die App-Datei nach dieser geladen wird. */
.extra-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
  padding: 12px 16px 0;
}
/* ⚠️ Die Apps benennen ihre Farben unterschiedlich: RechenHelden nutzt
   `--card/--line/--shadow`, die vier Geschwister aus dem LernHelden-Stamm
   `--c-card/--c-primary/--c-shadow`. Deshalb hier eine Fallback-Kette statt
   einer Wette auf ein Schema – so trägt jede App ihre eigenen Farben, und die
   `--he-*`-Werte greifen nur, wenn eine App gar nichts davon kennt. */
.extra-card {
  background: var(--c-card, var(--card, var(--he-flaeche)));
  border: 3px solid var(--line, transparent);
  border-radius: var(--radius, 20px);
  padding: 14px;
  box-shadow: var(--c-shadow, var(--shadow, var(--he-schatten)));
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 1px;
  cursor: pointer;
  font: inherit;
  color: var(--c-text, var(--ink, var(--he-text)));
}
.extra-card:active { transform: translateY(2px); box-shadow: none; }
/* Der Trainer bekommt die Akzentfarbe der App – er ist die Zugabe neben den
   Klassen, nicht eine weitere Klasse. */
.extra-card.trainer { border-color: var(--c-accent, var(--gold, var(--he-akzent))); }
.extra-icon { font-size: 26px; }
.extra-title { font-weight: 700; font-size: 17px; }
.extra-sub { font-size: 13px; color: var(--c-muted, var(--ink-soft, var(--he-text-leise))); }

/* --- Phasen-Kopfzeile in der Level-Liste --------------------------------- */
.phase-header {
  padding: 12px 14px 6px;
  grid-column: 1 / -1;
}
.phase-title {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
}
.phase-name { font-weight: 800; color: var(--he-text); }
.phase-progress { font-size: 12px; color: var(--he-text-leise); }
.phase-bar {
  margin-top: 6px;
  height: 6px;
  background: var(--he-rand);
  border-radius: 4px;
  overflow: hidden;
}
.phase-bar > div {
  height: 100%;
  background: var(--he-akzent);
  border-radius: 4px;
  transition: width 0.3s ease;
}
.phase-header.complete .phase-name { color: var(--he-akzent-dunkel); }
.phase-header.locked { opacity: 0.55; }
.phase-section {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 8px;
  padding: 0 12px 8px;
  grid-column: 1 / -1;
}
.phase-section.locked { opacity: 0.45; }
.level-tile {
  aspect-ratio: 1;
  border: 2px solid var(--he-rand);
  border-radius: 14px;
  background: var(--he-flaeche);
  font-weight: 800;
  color: var(--he-text);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 2px;
}
.level-tile.completed { border-color: var(--he-akzent); background: color-mix(in srgb, var(--he-akzent) 12%, #fff); }
.level-tile.locked { opacity: 0.45; }
.level-tile .level-num { font-size: 17px; }
.level-tile .level-stars { font-size: 9px; line-height: 1; }

/* --- Frage und Anker ----------------------------------------------------- */
.question-anchor {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  margin: 10px 0;
}
.question-anchor.tappable { cursor: pointer; }
.anchor-img { font-size: 62px; line-height: 1.1; }
.anchor-word {
  font-size: 26px;
  font-weight: 800;
  letter-spacing: 1px;
  color: var(--he-text);
}
.anchor-hint { font-size: 17px; }
.anchor-hint-only { font-size: 14px; color: var(--he-text-leise); }
.anchor-sentence {
  font-size: 20px;
  font-weight: 600;
  color: var(--he-text);
  text-align: center;
  line-height: 1.5;
}
.anchor-sentence .gap {
  display: inline-block;
  min-width: 68px;
  border-bottom: 3px solid var(--he-akzent);
  margin: 0 4px;
  vertical-align: baseline;
}
.anchor-sentence .gap.filled { border-bottom-color: var(--he-akzent-dunkel); font-weight: 800; }
.question-target { font-size: 46px; text-align: center; }
.dots-hint { text-align: center; color: var(--he-text-leise); font-size: 14px; }

/* --- Ausmalen (MalHelden) -------------------------------------------------- */
.mal-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 0 14px 16px;
}
.mal-bild {
  width: 100%;
  max-width: min(420px, 62vh);
  background: #fff;
  border: 2px solid var(--he-rand);
  border-radius: 18px;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.mal-flaeche { cursor: pointer; stroke: #64748b; stroke-width: 1.2; transition: fill 0.15s; }
.mal-flaeche.bunt { stroke: #475569; }
/* Die CSS-Regel gewinnt gegen das fill-Attribut – kurzer roter Blitz bei Fehltipps. */
.mal-flaeche.falsch { fill: #fca5a5; }
.mal-label {
  pointer-events: none;
  text-anchor: middle;
  font-weight: 800;
  font-family: inherit;
  fill: #334155;
  paint-order: stroke;
  stroke: rgba(255, 255, 255, 0.85);
  stroke-width: 3;
}
.mal-deko, .mal-deko * { pointer-events: none; }
.mal-rest { text-align: center; color: var(--he-text-leise); font-size: 14px; min-height: 18px; }
.mal-palette {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  max-width: 420px;
}
.mal-farbe {
  position: relative;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: 3px solid rgba(0, 0, 0, 0.18);
  padding: 0;
  font-size: 15px;
  font-weight: 800;
  color: #fff;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.55);
  cursor: pointer;
  transition: transform 0.12s, box-shadow 0.12s, opacity 0.12s;
}
.mal-farbe.hell { color: #17233a; text-shadow: 0 1px 2px rgba(255, 255, 255, 0.7); }

/* Glitzerfarben: vier funkelnde Punkte über der Grundfarbe, damit der
   Unterschied schon in der Palette zu sehen ist – nicht erst beim Malen. */
.mal-farbe.glitzer::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background-image:
    radial-gradient(circle at 30% 28%, rgba(255, 255, 255, .95) 0 7%, transparent 8%),
    radial-gradient(circle at 68% 55%, rgba(255, 255, 255, .85) 0 5%, transparent 6%),
    radial-gradient(circle at 42% 78%, rgba(255, 255, 255, .9) 0 5%, transparent 6%),
    radial-gradient(circle at 80% 25%, rgba(255, 255, 255, .8) 0 4%, transparent 5%);
  pointer-events: none;
}
/* Ungekauft: Schloss statt Funkeln, Farbe bleibt sichtbar (Kaufanreiz) aber
   nicht wählbar. */
.mal-farbe-schloss {
  display: none;
  position: absolute;
  inset: 0;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  background: rgba(0, 0, 0, .4);
  border-radius: 50%;
}
.mal-farbe.gesperrt::after { display: none; }
.mal-farbe.gesperrt .mal-farbe-schloss { display: flex; }
.mal-farbe.gesperrt { cursor: pointer; }
.mal-farbe.aktiv {
  transform: scale(1.14);
  box-shadow: 0 0 0 3px #fff, 0 0 0 6px var(--he-akzent, #17233a);
}
.mal-farbe.fertig { opacity: 0.35; transform: scale(0.9); }
/* Große Paletten (freies Malen, 24 Farben): kleinere Tupfer, sonst frisst die
   Palette auf dem Handy den halben Bildschirm. */
.mal-palette.viele { gap: 7px; }
.mal-palette.viele .mal-farbe { width: 38px; height: 38px; font-size: 12px; border-width: 2px; }

/* --- Wort eintippen ------------------------------------------------------ */
.type-wrap {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 0 16px;
}
.type-input {
  width: 100%;
  font-size: 26px;
  font-weight: 700;
  text-align: center;
  padding: 12px;
  border: 3px solid var(--he-rand);
  border-radius: 14px;
  background: var(--he-flaeche);
  color: var(--he-text);
}
.type-input:focus { outline: none; border-color: var(--he-akzent); }
.type-input.correct { border-color: #4caf50; background: #e8f5e9; }
.type-input.wrong { border-color: #e53935; animation: he-shake 0.4s; }
@keyframes he-shake {
  25% { transform: translateX(-6px); }
  75% { transform: translateX(6px); }
}
.type-feedback { min-height: 26px; text-align: center; font-size: 16px; }
.type-feedback.ok { color: #2e7d32; font-weight: 700; }
.type-feedback.bad { color: #c62828; }
.type-feedback.hint { color: var(--he-text-leise); }
.type-compare { font-size: 24px; font-weight: 700; letter-spacing: 2px; }
.type-compare .ok { color: #2e7d32; }
.type-compare .bad { color: #c62828; text-decoration: underline wavy; }
.type-solution { margin-top: 6px; font-size: 16px; color: var(--he-text); }

/* --- Sortieren ----------------------------------------------------------- */
.sort-slot,
.sort-target {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: center;
  min-height: 54px;
  margin: 10px 16px;
  padding: 8px;
  border: 2px dashed var(--he-rand);
  border-radius: 14px;
}
.sort-slot.letters { gap: 3px; }
.sort-slot.correct { border-color: #4caf50; background: #e8f5e9; }
.sort-slot.wrong { border-color: #e53935; animation: he-shake 0.4s; }
.sort-pool {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
  padding: 0 16px;
}
.sort-chip {
  font-size: 19px;
  font-weight: 700;
  padding: 10px 14px;
  border-radius: 12px;
  border: 2px solid var(--he-rand);
  background: var(--he-flaeche);
  color: var(--he-text);
  cursor: pointer;
}
.sort-chip.placed { border-color: var(--he-akzent); }
.sort-chip.used { opacity: 0.35; pointer-events: none; }
.sort-pool.letters .sort-chip { padding: 10px 12px; }

/* --- Shop ---------------------------------------------------------------- */
.shop-content { padding: 12px; }
.shop-section { margin-bottom: 18px; }
.shop-section h3 { margin: 0 0 8px; font-size: 17px; color: var(--he-text); }
.shop-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: 10px;
}
.shop-item {
  border: 2px solid var(--he-rand);
  border-radius: var(--he-radius);
  background: var(--he-flaeche);
  padding: 10px 6px;
  text-align: center;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 4px;
  align-items: center;
}
.shop-item.active { border-color: var(--he-akzent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--he-akzent) 25%, transparent); }
.shop-item.owned { border-color: var(--he-akzent-dunkel); }
.shop-item.cant { opacity: 0.5; }
.si-icon { font-size: 34px; }
.si-name { font-size: 13px; font-weight: 700; color: var(--he-text); }
.si-price,
.si-status { font-size: 12px; color: var(--he-text-leise); }
.shop-coins { font-weight: 800; color: var(--he-text); }

/* --- Sticker-Album ------------------------------------------------------- */
.stickers-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(98px, 1fr));
  gap: 10px;
  padding: 12px;
}
.sticker-tile {
  border: 2px solid var(--he-rand);
  border-radius: var(--he-radius);
  background: var(--he-flaeche);
  padding: 12px 6px;
  text-align: center;
  display: flex;
  flex-direction: column;
  gap: 4px;
  align-items: center;
}
.sticker-tile.locked { opacity: 0.4; filter: grayscale(1); }
.stk-icon { font-size: 34px; }
.stk-name { font-size: 12px; font-weight: 600; color: var(--he-text); }

/* --- Einführung beim ersten Start ---------------------------------------- */
.onboarding-wrap {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 24px;
  text-align: center;
}
.onb-mascot { font-size: 84px; }
.onboarding-wrap h1 { font-size: 26px; margin: 0; color: var(--he-text); }
.onboarding-wrap p { font-size: 17px; color: var(--he-text-leise); margin: 0; max-width: 320px; }
.onb-dots { display: flex; gap: 8px; }
.onb-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--he-rand);
}
.onb-dot.active { background: var(--he-akzent); }
.onb-skip {
  background: none;
  border: none;
  color: var(--he-text-leise);
  font-size: 14px;
  cursor: pointer;
  text-decoration: underline;
}

/* --- Abzeichen im Eltern-Bereich ----------------------------------------- */
.badges-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.badge-tile {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 13px;
  padding: 6px 10px;
  border-radius: 20px;
  background: color-mix(in srgb, var(--he-akzent) 12%, #fff);
  color: var(--he-text);
}
.badge-icon { font-size: 15px; }
.badge-empty { font-size: 14px; color: var(--he-text-leise); }

/* --- Aufnahme-Studio ----------------------------------------------------- */
.audio-recorder-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: 20px;
}
.audio-recorder-modal {
  background: var(--he-flaeche);
  border-radius: 20px;
  padding: 20px;
  width: 100%;
  max-width: 360px;
  text-align: center;
  max-height: 84vh;
  overflow-y: auto;
}
.audio-recorder-modal h3 { margin: 0 0 8px; color: var(--he-text); }
.rec-text {
  padding: 10px;
  border-radius: 10px;
  border: 1px solid var(--he-rand);
  margin-bottom: 6px;
  cursor: pointer;
  font-size: 14px;
  text-align: left;
  color: var(--he-text);
}
.rec-button {
  width: 84px;
  height: 84px;
  border-radius: 50%;
  border: none;
  background: #e53935;
  color: #fff;
  font-size: 34px;
  cursor: pointer;
  margin: 10px auto;
  display: block;
}
.rec-button.recording { animation: he-puls 1s infinite; }
@keyframes he-puls {
  50% { transform: scale(1.1); opacity: 0.75; }
}
.rec-actions { display: flex; gap: 8px; }
.rec-actions .big-btn { flex: 1; }

/* --- Mengenbilder in Fünferblöcken --------------------------------------- */
/* Zählaufgaben liefern die Bilder als Fünfergruppen mit Leerzeichen dazwischen
   („🍎🍎🍎🍎🍎 🍎🍎"). Bei dieser Schriftgröße ist ein normales Leerzeichen zu
   schmal, um als Blockgrenze zu wirken – erst der größere Abstand macht aus der
   Reihe eine Struktur, die man auf einen Blick erfasst. */
/* Grundgröße der Mengenbilder. Ohne sie erben die Emojis die Textgröße der
   Karte und ein Erstklässler soll 14 Kirschen in 18-px-Bildchen abzählen.
   Apps mit eigener .bild-row-Regel (RechenHelden) überschreiben das. */
.bild-row {
  font-size: 30px;
  line-height: 1.4;
}
/* Ein Fünferblock bleibt zusammen; umgebrochen wird nur ZWISCHEN den Blöcken.
   Bei 20 Bildern ergibt das auf einem Handy zwei Reihen à zehn – dieselbe
   Struktur wie das Zwanzigerfeld im Mathebuch. */
.mengen-gruppe {
  display: inline-block;
  white-space: nowrap;
  margin: 0 0.45em 0.1em 0;
}
/* Der Abstand hinter dem LETZTEN Block zählt bei der Umbruchrechnung mit und
   drückte die Reihe über die Kante – zwei Blöcke, die zusammen hineinpassen,
   landeten dadurch untereinander. */
.mengen-gruppe:last-child { margin-right: 0; }
/* Die Bildgröße richtet sich nach der Menge, damit zwei Fünferblöcke
   nebeneinander passen und die Struktur „fünf und zwei" sichtbar bleibt. */
.mengen-block.viele { font-size: 0.68em; }
.mengen-block.sehr-viele { font-size: 0.45em; }
/* „Wovon siehst du mehr?": die zwei Mengen stehen untereinander und beginnen
   linksbündig an derselben Kante – dann ist die längere Reihe zu sehen, ohne
   sie abzuzählen. Nebeneinander wäre der Anfang der zweiten Menge erst zu
   suchen, und der Größenvergleich ginge verloren. */
.mengen-vergleich {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.25em;
}

/* --- Ansichten dürfen scrollen, nicht schrumpfen ------------------------- */
/* Die Ansichten sind flex-Container in voller Bildschirmhöhe. Wird der Inhalt
   höher als der Bildschirm, quetscht der Browser die Kinder zusammen, statt zu
   scrollen – auf einem 360-px-Handy schrumpfte die Banner-Reihe so von 60 px
   auf 8 px und war praktisch unsichtbar. flex-shrink:0 erzwingt stattdessen
   das Scrollen, das die Ansicht ohnehin erlaubt. */
.view > * { flex-shrink: 0; }

/* --- Karteninhalte ------------------------------------------------------- */
/* Die Engine baut die Inhalte von Klassen-, Welt- und Extra-Karten aus <span>.
   Ohne display:block fließen sie inline zusammen und ergeben Wortsalat
   („StarterErste Wörter"). Fällt nur auf schmalen Displays auf, weil breite
   Karten den Umbruch kaschieren – deshalb steht es hier und nicht im App-CSS. */
.class-card > .class-icon,
.class-card > .class-name,
.class-card > .class-age,
.class-card > .class-range,
.class-card > .class-progress,
.class-card > .class-stars,
.extra-card > .extra-icon,
.extra-card > .extra-title,
.extra-card > .extra-sub {
  display: block;
}

/* Mehrere Streak-Hinweise nebeneinander brauchen Luft, sonst steht dort
   „5 Tage in FolgeHeute: 12 Aufgaben". */
.streak-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
  padding: 0 12px;
}
.streak-pill { display: inline-block; }

/* --- Hilfsklassen -------------------------------------------------------- */
.hint-hidden { opacity: 0.18; pointer-events: none; }
.celebrate { animation: he-jump 0.6s ease; }
@keyframes he-jump {
  30% { transform: translateY(-16px) scale(1.1); }
  60% { transform: translateY(0) scale(1); }
}
.full-width { grid-column: 1 / -1; }


/* --- Ausmalen auf gemalter Vorlage ---------------------------------------
   Zwei Schichten: unten das Canvas mit der Farbe, darüber die Strichzeichnung
   mit `multiply`. Weiß im Bild lässt die Farbe durch, Schwarz bleibt Schwarz –
   so liegen die Linien immer obenauf und lassen sich nicht übermalen. */
.malbild-buehne {
  position: relative;
  width: 100%;
  /* Feste vh-Anteile (z.B. 62vh) reichen auf kurzen Querformat-Screens NICHT:
     Fragetext, Statuszeile, Werkzeugleiste und die angeklebten Knöpfe brauchen
     zusammen immer etwa 280px, egal wie hoch der Bildschirm ist - ohne das
     abzuziehen wandert die Werkzeugleiste unbemerkt unter den sichtbaren
     Bereich (nur die angeklebten Knöpfe blieben sichtbar, Farbe/Pinsel/
     Radierer waren nur durch Scrollen erreichbar). Auf hohen Handys bleibt es
     bei 420px wie bisher. */
  max-width: min(420px, max(90px, calc(100vh - 280px)));
  aspect-ratio: 1;
  background: #fff;
  border: 2px solid var(--he-rand);
  border-radius: 18px;
  overflow: hidden;
  line-height: 0;
  touch-action: none;          /* sonst scrollt die Seite beim Malen weg */
}
.malbild-farbe,
.malbild-linien {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
.malbild-farbe {
  touch-action: none;
  -webkit-tap-highlight-color: transparent;
  z-index: 1;
}
.malbild-linien {
  mix-blend-mode: multiply;
  pointer-events: none;        /* alle Finger gehen ans Canvas darunter */
  z-index: 2;
  image-rendering: -webkit-optimize-contrast;
}
.malbild-buehne.fueller .malbild-farbe { cursor: pointer; }
.malbild-buehne.stift .malbild-farbe,
.malbild-buehne.spray .malbild-farbe,
.malbild-buehne.muster .malbild-farbe { cursor: crosshair; }

.malbild-fertig {
  margin-top: 4px;
  padding: 12px 30px;
  border: none;
  border-radius: 999px;
  background: var(--he-akzent);
  color: #fff;
  font-size: 17px;
  font-weight: 800;
  cursor: pointer;
  box-shadow: 0 3px 0 var(--he-akzent-dunkel);
}
.malbild-fertig:active { transform: translateY(2px); box-shadow: none; }
.malbild-fertig:disabled { opacity: 0.4; box-shadow: none; cursor: default; }

/* Sicherheitsnetz gegen abgeschnittene Knöpfe: „Von vorn"/„Fertig!" bleiben
   am unteren Bildschirmrand kleben, auch wenn Vorlage+Blatt+Werkzeugleiste
   zusammen mehr Platz brauchen, als ein kleines Handy hoch ist. Der
   .view-Elternbereich ist bereits scrollbar (overflow-y:auto) – sticky
   braucht genau das. */
.malbild-knoepfe {
  display: flex;
  gap: 10px;
  align-items: center;
  justify-content: center;
  margin-top: 4px;
  padding: 8px 0 calc(8px + env(safe-area-inset-bottom, 0px));
  position: sticky;
  bottom: 0;
  background: var(--he-flaeche, #fff);
  z-index: 5;
}
.malbild-neu {
  padding: 11px 20px;
  border: 2px solid var(--he-rand);
  border-radius: 999px;
  background: var(--he-flaeche);
  color: var(--he-text-leise);
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
}
.malbild-neu:active { transform: translateY(1px); }

/* --- Pinselstärken (Mal-App) ------------------------------------------------
   Fünf Punkte in aufsteigender Größe. Bewusst ohne Beschriftung: Die Kinder
   können noch nicht lesen, die Größe ist selbsterklärend. Der Punkt trägt die
   gerade gewählte Farbe, damit vor dem ersten Strich klar ist, was passiert. */
.mal-pinsel {
  display: flex;
  gap: 10px;
  align-items: center;
  justify-content: center;
  margin-top: 8px;
}
.mal-pinselgroesse {
  width: 52px;
  height: 52px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 3px solid rgba(0, 0, 0, .12);
  border-radius: 50%;
  background: #fff;
  cursor: pointer;
  padding: 0;
  transition: transform .12s, border-color .12s;
}
.mal-pinselgroesse span {
  display: block;
  border-radius: 50%;
  background: #333;
  pointer-events: none;             /* sonst schluckt der Punkt den Tipp */
}
.mal-pinselgroesse.aktiv {
  border-color: var(--brand, #ec4899);
  transform: scale(1.12);
  box-shadow: 0 0 0 3px rgba(236, 72, 153, .18);
}

/* --- Stiftarten (Füller/Stift/Sprühdose/Muster) -----------------------------
   Vier Wege, wie Farbe aufs Bild kommt – der Füller füllt eine Fläche immer
   komplett (unabhängig von der Pinselgröße), der Stift malt wie bisher voll
   entlang des Strichs, Sprühdose und Muster geben zwei zusätzliche, sichtbar
   andere Texturen. Emoji statt Text, damit auch vorlesende Kinder die Wahl
   sofort erkennen. */
.mal-stiftart {
  display: flex;
  gap: 6px;
  align-items: center;
  justify-content: center;
}
.mal-stiftart-knopf {
  width: 42px;
  height: 42px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 3px solid rgba(0, 0, 0, .12);
  border-radius: 50%;
  background: #fff;
  font-size: 19px;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  transition: transform .12s, border-color .12s;
}
.mal-stiftart-knopf.aktiv {
  border-color: var(--brand, #ec4899);
  transform: scale(1.12);
  box-shadow: 0 0 0 3px rgba(236, 72, 153, .18);
}

/* --- Farbwähler als Bottom-Sheet --------------------------------------------
   Ersetzt die Dauerpalette (bis zu 24 Punkte, die immer offen unter dem Bild
   standen) durch einen einzigen Knopf. Ein Tipp klappt die Palette als Panel
   von unten hoch; ein Tipp auf eine Farbe wählt sie und schließt das Panel
   gleich wieder. So bleibt unter dem Bild Platz für Pinselgrößen und Knöpfe,
   statt dass drei Reihen um denselben schmalen Streifen konkurrieren. */
.mal-werkzeugleiste {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  flex-wrap: wrap;                    /* Sicherheitsnetz auf sehr schmalen Handys */
  gap: 12px;
  row-gap: 10px;
  margin: 8px 0 12px;                 /* unten Luft, bevor die klebende Knöpfeleiste beginnt */
}
/* ⚠️ Farbknopf (56px) + 5 Pinselgrößen + Radierer (56px) nebeneinander sind
   auf einem 375px-Handy in voller Größe zu breit (rechnerisch >440px) – das
   schob den Radiergummi unbemerkt aus dem sichtbaren Bereich, bis ein Klick
   darauf die Seite seitlich verschob. Innerhalb der Werkzeugleiste deshalb
   etwas kompakter als anderswo (z. B. im Abzeichnen-Blatt gäbe es die
   Pinselpunkte sonst nirgends anders). */
.mal-werkzeugleiste .mal-pinsel { margin-top: 0; gap: 6px; }
.mal-werkzeugleiste .mal-pinselgroesse { width: 42px; height: 42px; }

/* Jedes Werkzeug (Farbe/Größe/Radierer) mit einer kurzen Beschriftung
   darunter – ohne das wusste Markus beim Testen nicht auf Anhieb, dass der
   farbige Knopf die Palette öffnet oder wofür die Punktereihe steht. */
.werkzeug-eintrag {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.werkzeug-label {
  font-size: 11px;
  font-weight: 700;
  color: var(--he-text-leise, #6b7280);
}

.mal-radierer-knopf {
  width: 56px;
  height: 56px;
  flex: none;
  border-radius: 50%;
  border: 3px solid rgba(0, 0, 0, .18);
  background: #fff;
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  transition: transform .12s, border-color .12s;
}
.mal-radierer-knopf.aktiv {
  border-color: var(--brand, #ec4899);
  transform: scale(1.12);
  box-shadow: 0 0 0 3px rgba(236, 72, 153, .18);
}

.mal-undo-knopf {
  width: 56px;
  height: 56px;
  flex: none;
  border-radius: 50%;
  border: 3px solid rgba(0, 0, 0, .18);
  background: #fff;
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  transition: transform .12s, opacity .12s;
}
.mal-undo-knopf:active { transform: scale(0.92); }
.mal-undo-knopf:disabled { opacity: .35; cursor: default; }

.farbwahl-knopf {
  position: relative;
  width: 56px;
  height: 56px;
  flex: none;
  border-radius: 50%;
  border: 3px solid rgba(0, 0, 0, .18);
  padding: 0;
  cursor: pointer;
  background: #fff;
}
.farbwahl-punkt {
  position: absolute;
  inset: 4px;
  border-radius: 50%;
  background: #ccc;             /* bis zeigePalette()/zeigeAuswahl() die echte Farbe setzt */
  pointer-events: none;
}
/* Kleine feste Marke in der Ecke – sonst wüsste man nicht, dass hinter dem
   Farbklecks ein Knopf steckt und keine Farbfläche im Bild. */
.farbwahl-knopf::after {
  content: "🖌️";
  position: absolute;
  right: -6px;
  bottom: -6px;
  font-size: 20px;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, .35));
  pointer-events: none;
}

.farbwahl-scrim {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, .35);
  opacity: 0;
  pointer-events: none;
  transition: opacity .18s;
  z-index: 930;
}
.farbwahl-scrim.offen { opacity: 1; pointer-events: auto; }

.farbwahl-panel {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  background: var(--he-flaeche, #fff);
  border-radius: 22px 22px 0 0;
  padding: 10px 20px calc(20px + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 -8px 24px rgba(0, 0, 0, .18);
  transform: translateY(100%);
  transition: transform .22s ease;
  z-index: 931;
  max-height: 70vh;
  overflow-y: auto;
}
.farbwahl-panel.offen { transform: translateY(0); }
.farbwahl-griff {
  width: 40px;
  height: 5px;
  border-radius: 3px;
  background: rgba(0, 0, 0, .15);
  margin: 6px auto 14px;
}
/* Im Panel ist reichlich Platz – die Farbpunkte bleiben in voller Größe,
   auch bei 24 Farben (kein .viele-Gedränge wie in der alten Dauerpalette). */
.farbwahl-panel .mal-palette { max-width: none; }

/* --- Abzeichnen -------------------------------------------------------------
   Vorlage und eigenes Blatt nebeneinander. Auf dem Handy hochkant stehen sie
   untereinander, sonst wird beides zu klein zum Zeichnen. */
.abzeichnen-paar {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
  margin: 6px 0 10px;
}
@media (min-width: 620px) {
  .abzeichnen-paar { grid-template-columns: 1fr 1fr; }
}
.abzeichnen-paar figure {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.abzeichnen-paar figcaption {
  text-align: center;
  font-size: 14px;
  font-weight: 700;
  opacity: .65;
}
.abzeichnen-vorlage img {
  width: 100%;
  height: 100px;                      /* kompakt, damit alles auf den Bildschirm passt */
  display: block;
  background: #fff;
  border: 3px solid rgba(0, 0, 0, .10);
  border-radius: 14px;
  object-fit: contain;
  cursor: zoom-in;
}
.abzeichnen-vorlage.gross img { height: 58vh; cursor: zoom-out; }
/* Ab 620px Breite stehen Vorlage und Blatt nebeneinander (siehe .abzeichnen-paar
   weiter unten) – das greift für breite Handys im Querformat genauso wie für
   Tablets, ganz gleich ob quer oder hoch. Die 100px-Kompaktvorlage weicht dann
   einem vollen Quadrat, aber gedeckelt über die Viewporthöhe: ein Handy im
   Querformat ist zwar breit, aber oft nur 350-400px hoch – ohne Deckel würde
   allein die Vorlage schon nicht mehr passen. */
@media (min-width: 620px) {
  /* calc() statt fixem vh-Anteil: Fragetext, Bildunterschrift, Werkzeugleiste
     und die angeklebten Knöpfe brauchen zusammen immer etwa 260px, egal wie
     hoch der Bildschirm ist. Ohne den Abzug wanderte die Werkzeugleiste auf
     kurzen Querformat-Screens unbemerkt unter den sichtbaren Bereich. */
  .abzeichnen-vorlage img { height: auto; aspect-ratio: 1; width: min(100%, max(60px, calc(100vh - 280px))); margin: 0 auto; }
}
.abzeichnen-blatt canvas {
  width: 100%;
  aspect-ratio: 1;
  display: block;
  background: #fff;
  border: 3px solid rgba(0, 0, 0, .10);
  border-radius: 14px;
  object-fit: contain;
}
.abzeichnen-blatt canvas {
  touch-action: none;                 /* sonst scrollt die Seite beim Zeichnen */
  cursor: crosshair;
}
/* Das Blatt: weißes Papier, darauf (optional) die schwache Pausvorlage und
   ganz oben das durchsichtige Zeichen-Canvas. Reihenfolge ist wichtig – läge
   das Weiß im Canvas, wäre die Vorlage darunter nicht zu sehen. */
.abzeichnen-papier {
  position: relative;
  width: 100%;
  /* Bei quadratischem Seitenverhältnis bestimmt die Breite auch die Höhe –
     ohne Deckel würde das Blatt auf schmalen, hohen Handys allein schon fast
     den ganzen Bildschirm füllen und „Von vorn"/„Fertig!" nach unten aus dem
     sichtbaren Bereich drücken. 38vh lässt daneben noch Platz für Kopfzeile,
     Vorlage, Werkzeugleiste und Knöpfe. */
  max-width: min(100%, 38vh);
  margin: 0 auto;
  aspect-ratio: 1;
  background: #fff;
  border: 3px solid rgba(0, 0, 0, .10);
  border-radius: 14px;
  overflow: hidden;
}
/* Muss NACH der Grundregel oben stehen: gleiche Spezifität, also entscheidet
   bei ≥620px sonst die spätere Regel im Quelltext, nicht die Media Query. */
@media (min-width: 620px) {
  .abzeichnen-papier { max-width: min(100%, 480px, max(60px, calc(100vh - 280px))); }
}
.abzeichnen-papier canvas,
.abzeichnen-papier .abzeichnen-pausbild {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  border: 0;
  border-radius: 0;
  background: none;
  object-fit: contain;
}
.abzeichnen-papier .abzeichnen-pausbild {
  opacity: 0;                        /* aus, bis „Durchpausen" gedrückt wird */
  pointer-events: none;
  transition: opacity .15s;
}
.abzeichnen-papier.pausen .abzeichnen-pausbild { opacity: .16; }

.abzeichnen-pausen {
  border: 3px solid rgba(0, 0, 0, .12);
  background: #fff;
  border-radius: 999px;
  padding: 10px 18px;
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}
.abzeichnen-pausen.aktiv {
  border-color: var(--brand, #ec4899);
  background: rgba(236, 72, 153, .10);
}
.mal-radierer {
  background: #fff !important;
  font-size: 20px;
  line-height: 1;
}

/* --- Level-Kacheln mit Motiv ------------------------------------------------
   In einer Mal-App sagt eine Kachel-Nummer nichts: Das Kind sucht sich das Bild
   aus, das ihm gefällt, und lesen kann es noch nicht. Deshalb zeigt die Kachel
   das Motiv – auch bei gesperrten Bildern. Wer nicht sieht, was er bekäme,
   kauft es auch nicht. Statt die Kachel abzudunkeln, sitzt nur ein kleines
   Schloss in der Ecke. */
.level-tile.mit-bild {
  position: relative;
  padding: 0;
  overflow: hidden;
  background: #fff;
}
.level-tile .level-bild {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  padding: 3px;
}
.level-tile.mit-bild .level-stars {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 2px;
  text-align: center;
  font-size: 10px;
  text-shadow: 0 1px 2px #fff, 0 -1px 2px #fff;
}
.level-tile .level-schloss {
  position: absolute;
  top: 3px;
  right: 3px;
  font-size: 13px;
  line-height: 1;
  background: rgba(255, 255, 255, .85);
  border-radius: 999px;
  padding: 2px 3px;
}
/* Gesperrte Kacheln mit Bild nur leicht zurücknehmen – das Motiv muss erkennbar
   bleiben, sonst ist die Sperre wieder eine Abdeckung. */
.level-tile.mit-bild.locked { opacity: 0.82; }
.phase-section.locked { opacity: 0.45; }
.phase-section.locked:has(.mit-bild) { opacity: 0.85; }
