/* ===================================================================
   SPÜRNASENCLUB – BAUKASTEN.CSS
   Gemeinsame, app-übergreifende Bausteine für alle Fall-Apps.
   Erstellt 06.08. nach Leo-Auftrag ("wenn wir bei jeder App wieder neu
   anfangen haben wir ein Problem") - fasst alles zusammen, was bisher in
   Mondkringel/Bibliotheksspuk parallel (und leicht unterschiedlich!)
   gebaut wurde: Los-geht's-Overlay, Sammelkarte, Turn-Banner, Farbwahl,
   Timer-Leiste.

   EINBINDEN: <link rel="stylesheet" href="baukasten.css"> VOR dem
   eigenen <style>-Block der jeweiligen App, damit App-eigene Regeln bei
   Bedarf überschreiben können.

   FARBTOKEN-KONVENTION: Diese Datei setzt die Kurzform-Variablennamen aus
   Mondkringel/Brieftaube/Flaschenpost/Tresor als Standard (--bg, --cyan,
   --yellow, --text, ...), weil 4 von 5 bestehenden Apps diese schon
   nutzen. NUR Bibliotheksspuk hat eigene Namen (--navy, --gold, --ink...)
   mit identischen Farbwerten - dort NICHT alles umbenennen (Risiko für
   bestehende Styles), sondern im App-eigenen <style> vor dem Baukasten-
   Import eine kleine Alias-Zeile ergänzen, z.B.:
     :root{ --navy:var(--bg); --gold:var(--cyan); --ink:var(--text); }
   (siehe Migrations-Notiz im Notion-Baukasten).
=================================================================== */

:root{
  --bg:#1a1a1a; --bg-panel:#232629; --bg-panel-2:#2c3033;
  --cyan:#42d4d4; --cyan-soft: rgba(66,212,212,.25);
  --magenta:#ff2bd6; --magenta-soft: rgba(255,43,214,.25);
  --yellow:#ffce54; --text:#f2f2f2; --muted:#9aa3a6;
  --steel: linear-gradient(145deg,#3a3f44,#1c1f21);
  --shadow: 0 8px 22px rgba(0,0,0,.5);
}
/* Kleines Utility, von mehreren Bausteinen genutzt (z.B. Abzeichen-Kleb-
   Szene unten) um Elemente per JS ein-/auszublenden. */
.hidden{ display:none !important; }

/* ---- Generisches Modal-System (Overlay+Panel), z.B. für Sammelkarte,
   Tipp-Panel, Detail-Puzzles. Version aus Mondkringel übernommen (etwas
   robuster als Bibliotheksspuks eigene Variante: max-height/overflow-y
   für lange Panel-Inhalte, echter Box-Shadow). z-index von Mondkringels
   150 auf 50 vereinheitlicht (geprüft: in Mondkringel kollidiert nichts
   dazwischen, einzig anderer z-index im Baukasten-Bereich ist 20 beim
   Los-geht's-Overlay). */
.overlay{position:fixed;inset:0;background:rgba(10,10,10,.82);display:none;align-items:center;justify-content:center;padding:16px;z-index:50;}
.overlay.active{display:flex;}
.panel{background:var(--bg-panel);border:1px solid #33383b;border-radius:20px;max-width:520px;width:100%;padding:22px;max-height:92vh;overflow-y:auto;box-shadow:0 20px 60px rgba(0,0,0,.6);color:var(--text);text-align:center;}
.panel h3{margin:0 0 4px;font-size:18px;}
.panel-close{float:right;background:none;border:none;color:var(--muted);font-size:20px;cursor:pointer;line-height:1;}
.panel-close:hover{color:var(--magenta);}

/* ---- "Los geht's"-Gating vor Minispielen -----------------------------
   Herkunft: Mondkringel, nach Kinder-UX-Recherche (NN/G-Quellen siehe
   Notion-Baukasten). Echtes Overlay (position:absolute) über dem
   gesperrten Spielfeld, NIE ein Button im normalen Textfluss danach -
   sonst muss man bei langen Feldern erst daran vorbeiscrollen.
   .game-area ist der positionierte Elternrahmen - absichtlich OHNE eigene
   Breite (nur position:relative), damit sie sich wie bisher an ihr
   Spielfeld anschmiegt (kein Risiko, bestehende Layouts zu verschieben).
   ACHTUNG (Lektion aus Bibliotheksspuk 06.08. "Proportionen"): wenn das
   Spielfeld selbst schmal ist (z.B. ein enges Tile-Grid, deutlich unter
   ~460px), hat der Overlay-Text zu wenig Zeilenbreite und bricht hässlich
   um. In dem Fall in der jeweiligen App PER ID override ergänzen, NICHT
   hier global, z.B.:
     #meinSchmalesGameArea{ width:100%; max-width:480px; margin:0 auto; } */
.game-area{position:relative;}
.game-start-overlay{
  position:absolute; top:0; left:0; right:0; min-height:100%; z-index:20; border-radius:16px;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:14px;
  background:rgba(10,10,10,.9); padding:24px; text-align:center;
}
.game-start-text{
  font-size:clamp(20px,5.5vw,26px); font-weight:900; color:#fff; line-height:1.35;
  margin:0; max-width:380px; text-shadow:0 2px 8px rgba(0,0,0,.6);
}
.game-start-turn{
  display:none; font-size:clamp(19px,5.5vw,24px); font-weight:900; color:#fff;
  margin:0; padding:10px 20px; border-radius:14px; text-shadow:0 1px 3px rgba(0,0,0,.4);
  box-shadow:0 4px 14px rgba(0,0,0,.3); max-width:380px; line-height:1.3;
}
.game-start-rule{
  font-size:clamp(14px,4vw,17px); font-weight:700; color:#fff; opacity:.95;
  margin:0; max-width:360px; line-height:1.4; text-shadow:0 1px 4px rgba(0,0,0,.5);
}
.rule-example{display:flex;flex-direction:column;gap:8px;}
.rule-pair{
  display:flex; align-items:center; justify-content:center; gap:8px;
  background:rgba(255,255,255,.07); border-radius:12px; padding:8px 14px;
}
.rule-card-icon{
  width:36px; height:36px; display:flex; align-items:center; justify-content:center;
  font-size:20px; background:var(--bg-panel-2); border:2px solid #3a3f43; border-radius:8px; flex-shrink:0;
}
.rule-verdict{font-size:13px;font-weight:800;margin-left:2px;white-space:nowrap;}
.rule-verdict.ok{color:#7CFC9E;}
.rule-verdict.bad{color:#ff6b9d;}
.game-start-overlay .btn{font-size:clamp(17px,4.5vw,20px);padding:20px 34px;min-height:64px;}
/* An .game-start-overlay angrenzende Spielfelder bekommen beim Sperren
   .locked - jede App fügt diese Klasse an IHR eigenes Spielfeld-Element
   an (z.B. .memory-grid.locked, .match3-board.locked, .race-field.locked). */

/* ---- Turn-Banner ("wer ist dran") -------------------------------------
   NOCH NICHT VEREINHEITLICHT (Stand 06.08.) - bewusst als offener Punkt
   stehen gelassen statt stillschweigend eine Version durchzusetzen:
   Mondkringel hat eine zweizeilige Variante mit Punktestand-Unterzeile
   (.turn-scores), min-height:112px, display:none als Grundzustand,
   eigenes turnPulse-Keyframe (35%-Sprung). Bibliotheksspuk hat eine
   einfachere einzeilige Variante, min-height:64px, .hidden-Klasse als
   Grundzustand. Beide wurden unabhängig gegen echten Layout-Sprung
   gefixt, aber mit unterschiedlichem Ergebnis - das ist eine Produkt-
   entscheidung (will Leo die Punktestand-Unterzeile überall?), keine
   rein technische. Unten die einfachere Bibliotheksspuk-Version als
   Platzhalter/Ausgangspunkt für künftige NEUE Apps ohne eigene Variante -
   NICHT in Mondkringel oder Bibliotheksspuk einsetzen, bis geklärt. */
.turn-banner{width:100%;max-width:480px;min-height:64px;box-sizing:border-box;display:flex;align-items:center;justify-content:center;text-align:center;color:#fff;font-weight:800;padding:10px;border-radius:12px;margin:8px 0;box-shadow:var(--shadow);text-shadow:0 1px 3px rgba(0,0,0,.4);}
@keyframes pulseBanner{0%{transform:scale(1);}50%{transform:scale(1.06);}100%{transform:scale(1);}}
.turn-banner.pulse{animation:pulseBanner .5s ease;}

/* ---- Timer-/Fortschrittsleiste (Zeitspiele) -----------------------------
   NOCH NICHT VEREINHEITLICHT (Stand 06.08.), selber Grund wie beim Turn-
   Banner: Mondkringel nutzt eine einzelne .timer-bar (Track+Füllung in
   einem Element), Bibliotheksspuk ein zweigeteiltes .timer-bar-wrap
   (Track) + .timer-bar (Füllung). Unten die Bibliotheksspuk-Version als
   Platzhalter für künftige NEUE Apps - NICHT in Mondkringel/Bibliotheksspuk
   einsetzen, bis geklärt. */
.timer-bar-wrap{width:100%;max-width:480px;background:#141617;border:1px solid #33383b;border-radius:999px;height:14px;overflow:hidden;margin:8px 0;}
.timer-bar{height:100%;background:linear-gradient(90deg,var(--yellow),var(--magenta));width:100%;transition:width .2s linear;}
.timer-bar.penalty{background:var(--magenta) !important;}
@keyframes flashPenalty{0%{box-shadow:0 0 0 0 rgba(255,43,214,.7);}100%{box-shadow:0 0 0 14px rgba(255,43,214,0);}}
.timer-bar-wrap.flash{animation:flashPenalty .4s;}

/* ---- Farbwahl (1-4 Spieler) ---------------------------------------------
   44px = Kinder-Touch-Ziel-Empfehlung (NN/G, ~2x2cm). War in mehreren
   Apps noch bei 34-38px, siehe Notion-Baukasten-Nachtrag 4 (Layout).
   Herkunft der .selected-Optik: Mondkringel-Version übernommen (Haken-
   Overlay + Glow in der jeweils gewählten Farbe über --c) - Bibliotheksspuk
   hatte hier eine einfachere, weiß-only Variante gebaut; beim Zusammenführen
   wird Bibliotheksspuk künftig auf DIESE Version umgestellt.
   Jeder Swatch braucht die Inline-Custom-Property --c mit dem Hex-Wert,
   z.B. style="--c:#ff5566" (siehe colorHex() in baukasten.js). */
.color-row{display:flex;gap:10px;justify-content:center;flex-wrap:wrap;margin:10px 0;}
.color-swatch{width:44px;height:44px;border-radius:50%;border:3px solid transparent;cursor:pointer;background:var(--c);padding:0;position:relative;transition:transform .12s ease;}
.color-swatch:hover{transform:scale(1.1);}
.color-swatch.selected{border-color:#fff;box-shadow:0 0 0 3px var(--c), 0 0 14px var(--c);}
.color-swatch.selected::after{content:"✓";position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:#fff;font-weight:900;text-shadow:0 1px 2px rgba(0,0,0,.5);}

/* ---- Fallübergreifende Sammelkarte ("Stempelkarte") --------------------
   Herkunft: Bibliotheksspuk-Variante (eigenständiges Overlay, nicht an
   ein anderes Puzzle-Panel gekoppelt) - robuster für Apps ohne
   generisches Puzzle-Overlay. Zugehöriges JS: siehe baukasten.js. */
.stamp-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:14px;margin:14px 0 6px;}
/* Update 08.08. (Leo-Wunsch): ungelöste Fälle sollen sich klarer von
   gelösten abheben - vorher unterschieden sie sich nur durch Rahmenfarbe,
   jetzt zusätzlich gedimmt/entsättigt. .done hebt das wieder auf. Der
   aktuelle Fall (.current, in der normalen Sammelkarte) und das
   Abzeichen-Ziel (.badge-target, in der Kleb-Szene) bleiben bewusst
   ungedimmt, auch bevor sie "gelöst" sind - beide sollen weiter einladend
   aussehen/leicht zu finden sein, nicht wie gesperrt wirken. */
.stamp-tile{background:var(--bg-panel-2);border:2px solid #3a3f43;border-radius:14px;padding:16px 10px;text-align:center;cursor:pointer;position:relative;color:var(--text);opacity:.5;filter:grayscale(85%);transition:transform .12s ease,border-color .12s ease,opacity .15s ease,filter .15s ease;}
.stamp-tile .stamp-icon{font-size:32px;margin-bottom:6px;}
.stamp-tile .stamp-name{font-size:12px;font-weight:700;}
.stamp-tile.done{border-color:var(--yellow);background:var(--cyan-soft);box-shadow:0 0 14px var(--cyan-soft);opacity:1;filter:none;}
.stamp-tile.done::after{content:"✔ gelöst";position:absolute;bottom:-18px;left:0;right:0;font-size:10px;color:var(--yellow);font-weight:800;}
.stamp-tile.current{border-style:dashed;opacity:1;filter:none;}
.stamp-tile.badge-target{opacity:1;filter:none;}

/* ---- Abzeichen-Reveal + Auf-Stempelkarte-kleben (Update 07.08., Leo-Idee;
   Drag am 08.08. entfernt, siehe baukasten.js für die Begründung) --
   Neue Szene NACH der Urkunde, VOR dem bisherigen Endscreen. Abzeichen dreht
   sich beim Erscheinen einmal per CSS um die Y-Achse (Pokémon-GO-artiger
   Reveal, Leo-Wunsch), landet dann normal. Danach per Tap (auf das Bild
   ODER den Fallback-Button, beide gleichwertig) auf die eigene Kachel
   geklebt.
   Update 08.08. (2, Leo-Wunsch): auch die ANDEREN Kacheln in dieser Szene
   sind jetzt anwählbar - Kinder können von hier aus gleich weitere, schon
   früher gelöste Fälle selbst markieren (identisches ehrliches
   Selbst-Antippen wie im "Meine Sammelkarte"-Überblick), nicht nur den
   aktuellen per Abzeichen-Tap.
   VERTRAG - HTML (eigener Screen zwischen Urkunde und Endscreen):
     <section class="screen" id="screen-badge-stick">
       <div class="card">
         <h2>Kleb dein Abzeichen auf deine Sammelkarte!</h2>
         <div class="badge-reveal-wrap">
           <img class="badge-reveal-img" id="badgeRevealImg" src="urkunde_XY.png"
                draggable="false" onerror="this.onerror=null; this.src='';
                this.outerHTML='<div class=badge-reveal-fallback>🏅</div>';">
         </div>
         <p class="badge-reveal-hint">Tipp auf dein Abzeichen, um es auf deine Sammelkarte zu kleben!</p>
         <div class="stamp-grid" id="badgeStickGrid"></div>
         <p class="badge-reveal-hint">Schon andere Fälle gelöst? Tipp sie auch an!</p>
         <button class="btn secondary" id="badgeStickFallback">🏅 Antippen zum Kleben</button>
         <div class="go-row"><button class="btn magenta hidden" id="badgeStickContinue" onclick="[APP-EIGENE WEITER-FUNKTION]">Weiter</button></div>
       </div>
     </section>
   JS-Aufruf beim Betreten dieser Szene: initBadgeStick() (siehe baukasten.js).
   Nutzt dieselben THIS_CASE_ID/CASE_LIST wie die Sammelkarte oben. */
.badge-reveal-wrap{ width:150px; height:150px; margin:16px auto; perspective:800px; }
.badge-reveal-img{
  width:100%; height:100%; object-fit:contain; cursor:pointer; display:block;
  filter:drop-shadow(0 0 16px rgba(255,206,84,.55));
  animation:badgeSpinIn 1.4s cubic-bezier(.16,.84,.44,1) 1 both;
}
.badge-reveal-fallback{ width:150px; height:150px; margin:16px auto; font-size:88px; display:flex; align-items:center; justify-content:center; }
@keyframes badgeSpinIn{
  0%{ transform:rotateY(0deg) scale(.3); opacity:0; }
  12%{ opacity:1; }
  100%{ transform:rotateY(1080deg) scale(1); opacity:1; }
}
.badge-reveal-img.placed{ visibility:hidden; }
.badge-reveal-hint{ text-align:center; color:var(--muted); font-size:13px; margin:6px 0 14px; }
.stamp-tile.badge-target{ animation:badgeTargetPulse 1.4s ease-in-out infinite; }
@keyframes badgeTargetPulse{ 0%,100%{ box-shadow:0 0 0 0 var(--cyan-soft); } 50%{ box-shadow:0 0 0 10px transparent; } }
.stamp-tile.stuck{ animation:stampStick .4s ease; }
@keyframes stampStick{ 0%{ transform:scale(1.3); } 60%{ transform:scale(.92); } 100%{ transform:scale(1); } }

/* ---- "Zufalls-Verdächtiger"-Übungsspiel (Beschreibungs-Trick) -----------
   Herkunft: Mondkringel, 06.08. (Leo-Idee) - Trainingsrunde direkt vor dem
   Phantombild. Kinder üben den Beschreibungs-Trick (Größe im Vergleich zu
   dir/Haare/Kleidung/Merkmal) an einer Quatsch-Figur, bevor es beim echten
   Phantombild ernst wird. Wie das Phantombild selbst: Stift+Papier, kein
   Zeichentool in der App.
   Update 06.08. (2. Durchgang, Leo-Korrektur): ursprünglich würfelte die App
   4 UNABHÄNGIGE Merkmale zusammen (Größe/Haare/Kleidung/Merkmal einzeln
   kombiniert, TRICK_CATEGORIES) - Leo-Einwand: das ergibt eine Merkmalsliste,
   keine zusammenhängende Person. VERTRAG jetzt stattdessen:
     var TRICK_CHARACTERS = [
       { name:"...", audio:"audio-trick-char-<1..6>",
         image:"trick-char-<1..6>.png", reveal:"...Kurztext für Auflösung" },
       ... 6 Einträge, jeweils EIN vollständiges, in sich stimmiges Bild +
       EIN zusammenhängender Audiotext (statt 4 einzeln kombinierten
       Bausteinen).
     ];
   Die App würfelt nur noch aus, WELCHER der 6 Einträge drankommt (1 Index).
   Die Zufallslogik (Auswahl, Glücksrad-Reihen-Animation, Audio-Wiedergabe)
   liegt generisch in baukasten.js (spinTrickReels/playAudioQueue) - die
   eigentlichen Inhalte (Figuren-Texte/-Bilder) bleiben pro App lokal.
   "Glücksrad"-Optik (Leo-Wunsch, weiterhin gewünscht auch mit nur noch 1
   Reihe): das Rechteck durchläuft kurz eine Farbanimation (.spinning),
   landet dann mit einem Pling auf "❓" (.locked). */
.trick-reels{display:flex;flex-direction:column;gap:10px;max-width:380px;margin:0 auto 18px;}
.trick-reel{
  min-height:52px;border-radius:12px;background:var(--bg-panel-2);border:2px solid #3a3f43;
  display:flex;align-items:center;justify-content:center;font-size:20px;font-weight:800;color:var(--muted);
  padding:8px 14px;text-align:center;transition:border-color .15s ease;
}
.trick-reel.spinning{animation:trickSpin .18s linear infinite;border-color:var(--cyan);}
@keyframes trickSpin{
  0%{background:var(--bg-panel-2);} 33%{background:var(--cyan-soft);}
  66%{background:var(--magenta-soft);} 100%{background:var(--bg-panel-2);}
}
.trick-reel.locked{color:var(--text);border-color:var(--yellow);}
.trick-reel.revealed{color:var(--text);border-color:var(--cyan);font-size:14px;font-weight:700;text-align:left;justify-content:flex-start;}

/* Quatsch-Figur (Bonus-Lacher bei "Auflösung ansehen") - seit dem
   Fest-Charaktere-Umbau (2. Durchgang) EIN vollständiges Bild pro Figur,
   kein Zusammensetzen aus Layern mehr nötig (siehe TRICK_CHARACTERS-
   VERTRAG oben). */
.trick-figure{position:relative;width:180px;height:180px;margin:0 auto 14px;}
.trick-figure img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:contain;
  /* Update 07.08. (Leo-Bugreport "Figuren tauchen bei der Zeichenaufgabe nicht
     auf"): zwei Ursachen. (1) trick-char-1..6.png fehlten schlicht noch als
     Dateien (App-seitig eingebunden, aber nie geliefert) - jetzt verarbeitet
     und ergänzt. (2) selbst mit Bild wären die Figuren vor dem dunklen
     Kartenhintergrund kaum zu erkennen gewesen, gleiches Problem wie schon bei
     den Verdächtigen-Portraits in Brieftaube/Bibliotheksspuk - gleicher
     Leucht-Filter jetzt auch hier. */
  filter:drop-shadow(0 0 10px rgba(255,255,255,.35)) drop-shadow(0 0 3px rgba(255,255,255,.5));
}
/* Update 07.08. (2. Durchgang): von "block" auf "absolute inset:0 + flex" umgestellt -
   liegt jetzt exakt wie das <img> im 180x180-Rahmen, wird per JS nur ein/ausgeblendet
   statt (wie vorher) das <img> permanent zu ersetzen (siehe Bugfix-Kommentar in
   mondkringel.html bei #trickFigureImg). */
.trick-figure-fallback{ position:absolute; inset:0; display:flex; align-items:center; justify-content:center; font-size:64px; }

/* ---- Mobile-Grundraster -------------------------------------------------
   Startpunkt für App-eigene Ergänzungen - jede App kann in ihrem eigenen
   <style> weitere Selektoren in derselben Media Query ergänzen. */
@media (max-width:400px){
  .screen{padding:16px 10px 50px;}
  .card-panel{padding:14px;}
}
