/* ============================================================
   PLAY SCROLL – core/style.css
   Globales Design-System: gilt für ALLE Spiele (Feed-Shell, Home,
   Sidebar, HUD, Sheets, Shop, Toast). Spiel-spezifisches CSS (z.B.
   für Schach oder Dog Defense) gehört NICHT hierher, sondern wird
   vom jeweiligen games/<id>/game.js selbst injiziert.
   ============================================================ */

/* Icons: gefuellte SVGs aus dem Sprite in app/index.html.
   Groesse = 1em, also die Schriftgroesse des Elternelements - dadurch sind
   sie ueberall genauso gross wie das Emoji vorher. Farbe = currentColor,
   dadurch faerben Zustaende wie .side-btn.liked .ic{color:...} das Icon
   automatisch mit. Benutzung: <svg class="i"><use href="#i-like"/></svg> */
.i{width:1em;height:1em;fill:currentColor;display:inline-block;
   vertical-align:-.14em;flex:none;pointer-events:none}

/* Die wenigen Icons, die bewusst NICHT die Textfarbe erben: Waehrung und
   Belohnungen. Sie stehen oft mitten im Fließtext ("Nicht genug Gold") und
   gehen dort unter, wenn sie grau sind. Alles andere bleibt einfarbig. */
.i.c-gold{color:var(--gold)}
.i.c-cyan{color:var(--cyan)}
.i.c-pink{color:var(--pink)}

/* Spiel-Logos (.gl) sind anders als die Bedienelemente (.i): sie bringen
   ihre eigenen Farben mit, damit man die Spiele in der Kachelansicht
   auseinanderhalten kann. Groesse wieder 1em, also genau so gross wie das
   Emoji vorher an derselben Stelle stand. Siehe gameIcon() in utils.js. */
.gl{width:1em;height:1em;display:inline-block;vertical-align:-.16em;
    flex:none;pointer-events:none}
/* Bild-Logos (logoBild) mit derselben Eckenrundung wie die gezeichneten
   Kacheln (rx 5.4 von 24 in #gc-kachel). */
.gl-bild{border-radius:22.5%;object-fit:cover}

/* Ein Logo mit eigener Flaeche braucht mehr Platz als ein Emoji: das Emoji
   nutzt seine 26px voll aus, bei einer Kachel steht das Motiv nur auf einem
   Teil davon. Deshalb sind die Logos ueberall deutlich groesser als die
   font-size der Stelle - und bekommen einen leichten Schatten, damit sie
   sich von der Kachel darunter abheben. */
.game-tile   .gi .gl{width:48px;height:48px}
.saved-item  .gi .gl{width:38px;height:38px}
.msg-head    .gi .gl{width:26px;height:26px}
.profile-top-item .gi .gl{width:28px;height:28px}
.featured-card .fc-icon .gl{width:58px;height:58px}
.game-title  .gl{width:24px;height:24px;vertical-align:-.32em}
.gl{filter:drop-shadow(0 1px 2px rgba(0,0,0,.28))}

:root{
  /* ---- Die App: DUNKEL ist der Standard (seit 1.24.0) ----
     Wer nichts einstellt, bekommt dunkel - unabhaengig von Geraet und
     Bildschirmbreite. Den hellen Satz bringt html.ps-hell weiter unten;
     dort steht jede Farbe, die sich unterscheidet, noch einmal.
     Die Spielbuehne ist von beidem ausgenommen (--buehne-* darunter). */
  --bg:#0b0b12; --bg2:#12121e; --pink:#ff8a00; --cyan:#ffc93c; --gold:#ffd54a;
  --txt:#fff; --txt-dim:rgba(255,255,255,.6);
  --glass:rgba(255,255,255,.08); --glass-border:rgba(255,255,255,.16);
  /* Trennlinien und Bildlaufleisten in Sheets, Shop und Avatar-Editor.
     Standen frueher als feste rgba-Werte an sieben Stellen - als
     Variable schalten sie mit, statt jede Regel zu verdoppeln. */
  --linie:rgba(255,255,255,.08);
  --rollbalken:rgba(255,255,255,.2);
  /* Die Handy-Pfeil-Buttons sitzen in eigenen Zonen NEBEN der Karte,
     ihr Grund ist also die Seite - nicht das Spiel. */
  --navbtn-bg:rgba(120,120,130,.32);
  --navbtn-bg-aktiv:rgba(140,140,150,.4);

  /* ---- Die Spielbuehne: bleibt dunkel ----
     Die 31 Spiele malen ihre Flaeche selbst dunkel (#111, #1a1a26, ...).
     Alles, was DARAUF liegt - Punktestand, Spieltitel, Hinweis-Pille,
     Pause-Overlay, die Leiste am Handy - braucht deshalb weiterhin
     helle Schrift auf dunklem Grund. Diese Elemente lesen --buehne-*
     statt --txt/--glass, sonst waeren sie nach dem Hellzug unsichtbar.
     Am PC steht die Leiste NEBEN der Buehne, dort gilt --seite* - das
     regelt der @media(min-width:1024px)-Block weiter unten. */
  --buehne:#0b0b12;
  --buehne-txt:#fff;
  --buehne-txt-dim:rgba(255,255,255,.6);
  --buehne-glass:rgba(255,255,255,.08);
  --buehne-glass-border:rgba(255,255,255,.16);
  --buehne-pille:rgba(10,10,20,.74);
  /* Gold auf der dunklen Buehne darf hell bleiben (Flecken-Anzeige). */
  --buehne-gold:#ffd54a;
  /* Goldener TEXT (Shop-Preise, Kontostand, Bestenliste). Auf dunklem
     Grund ist das helle Gold richtig; in der hellen Ansicht waere es
     praktisch unlesbar (Kontrast ~1.4:1) - siehe html.ps-hell. */
  --gold-txt:var(--gold);
  /* Dasselbe fuer --cyan: es traegt Hinweise im Shop, den Zaehler je
     Abschnitt, "Gespeichert"-Links und die Auswahl-Rahmen im
     Avatar-Editor. Im Orange-Thema ist das ein helles Gelb. */
  --cyan-txt:var(--cyan);
  /* Seiten-Ebene (Nav, Listen, Anmeldeformular, Rahmen um den Feed am PC).
     Zeigt auf dieselben Grundfarben - seit 1.23.0 also hell. Die eigenen
     Namen bleiben bestehen, weil saemtliche Geruest-Regeln im CSS sie
     lesen: eine spaetere Umstellung braucht wieder nur diese Stelle. */
  --seite:var(--bg); --seite-txt:var(--txt); --seite-txt-dim:var(--txt-dim);
  --seite-glass:var(--glass); --seite-glass-border:var(--glass-border);
  --nav-w:230px; --bottomnav-h:60px;
  /* Eigene, feste Zonen für die Handy-Pfeil-Buttons (oben/unten) - der
     Feed wird um genau diese Höhe verkürzt (siehe #feed weiter unten),
     damit die Buttons einen ECHTEN eigenen Bereich haben und nie über
     dem Spielinhalt liegen. Am PC werden beide auf 0 gesetzt (siehe
     @media min-width:1024px), dort gibt es diese Buttons ja gar nicht. */
  --navbtn-top-h:0px; --navbtn-bottom-h:0px;
  /* Hoehe der Handy-Kopfleiste. Bewusst EIGENE Variable und im Feed auf 0:
     #feed rechnet seine Hoehe aus 100dvh minus den Leisten - wuerde die
     Kopfleiste dort mitzaehlen, verloeren alle 31 Spiele oben Platz. */
  --topbar-h:0px;
  /* Flaechen, die vorher feste Farbwerte hatten. Ueber Variablen laesst
     sich das gesamte Erscheinungsbild an EINER Stelle umschalten -
     an EINER Stelle aendern statt an elf verstreuten. */
  --leiste:rgba(10,10,20,.92);      /* Kopf- und Fussleiste */
  --pille:var(--buehne-pille);      /* Hinweis-Pille - liegt auf dem Spiel */
  --abdunkeln:rgba(0,0,0,.55);      /* hinter Sheets und Overlays - in
                                       BEIDEN Ansichten dunkel, das ist auch
                                       bei hellen Apps das uebliche Mittel,
                                       um den Blick zu lenken. */
  --flaeche:#1c1c28;                /* erhabene Karten */
  --karte:var(--buehne);            /* Spielkarte im Feed - bleibt dunkel,
                                       am Handy IST sie die Spielflaeche. */
  /* Wie sich die dunkle Spielbuehne am PC vom Rahmen absetzt. Auf
     dunklem Grund ist ein schwarzer Schatten unsichtbar und der
     Buehnen-Verlauf endet unten bei genau der Hintergrundfarbe -
     dort braucht es den 1px-Ring. Auf Weiss genuegt der Schatten. */
  --buehne-schatten:0 0 0 1px var(--seite-glass-border),0 24px 70px rgba(0,0,0,.55);
}
/* Handy-Navigationseinstellung (siehe Profil, applyNavSettings() in
   core/feed.js): Standard ist der Sidebar-Button "Weiter" - dafür braucht
   #feed keine reservierten Zonen. Erst im Streifen-Modus kommen #navUp/
   #navDown zurück und brauchen wieder echten eigenen Platz. */
body.ps-nav-strips{--navbtn-top-h:44px;--navbtn-bottom-h:62px}

/* ---------- Die helle Ansicht (Profil-Einstellung "Darstellung") ----------
   Dunkel ist der Standard (siehe :root). Wer im Profil auf hell stellt,
   bekommt die Klasse ps-hell - und zwar auf <html>, nicht auf <body>.
   Zwei Gruende dafuer:

   1. --seite/--seite-txt/... sind von --bg/--txt/... ABGELEITET. Custom
      Properties werden als bereits berechneter Wert vererbt: stuende der
      helle Satz auf <body>, haette --seite auf <html> laengst den dunklen
      Wert errechnet und body wuerde genau den erben. Deshalb wiederholt
      dieser Block die --seite*-Zeile - so wird sie im hellen Kontext
      neu ausgewertet.
   2. Ein Inline-Skript im <head> von app/index.html kann die Klasse
      setzen, bevor irgendetwas gemalt wird. <body> gibt es dort noch
      nicht - ohne das blitzt bei Hell-Nutzern kurz die dunkle Seite auf.

   Die Bildschirmbreite spielt bewusst KEINE Rolle mehr (bis 1.21.0 galt
   ohne eigene Wahl: PC hell, Handy dunkel). Es gilt allein die
   Einstellung, auf jedem Geraet gleich.

   NICHT enthalten: --buehne-*. Die Spielflaeche und alles, was darauf
   liegt, bleibt in beiden Ansichten dunkel - die 31 Spiele malen ihren
   Hintergrund selbst. */
html.ps-hell{
  --bg:#fff; --bg2:#f4f4f7;
  --txt:#16130e; --txt-dim:rgba(22,19,14,.6);
  --glass:rgba(0,0,0,.045); --glass-border:rgba(0,0,0,.1);
  --linie:rgba(0,0,0,.08);
  --rollbalken:rgba(0,0,0,.2);
  --navbtn-bg:rgba(0,0,0,.06);
  --navbtn-bg-aktiv:rgba(0,0,0,.12);
  --gold-txt:#8a5a00;
  --cyan-txt:#0a8f8a;
  --leiste:rgba(255,255,255,.92);
  --flaeche:#fff;
  --buehne-schatten:0 24px 70px rgba(0,0,0,.18);
  /* Muss wiederholt werden - siehe Grund 1 oben. */
  --seite:var(--bg); --seite-txt:var(--txt); --seite-txt-dim:var(--txt-dim);
  --seite-glass:var(--glass); --seite-glass-border:var(--glass-border);
}

/* ---------- Farbthema "Gelb/Orange" (Versuch) ----------
   Ersetzt nur die Akzentfarben, nicht --bg/--bg2 (die Spiele-Kartenoptik
   bleibt dunkel) - betrifft Buttons, Logo, aktive Icons, Nav-Markierung.
   body.theme-orange schaltet es ein; ohne die Klasse bleibt alles beim
   bisherigen Pink/Cyan. */
body.theme-orange{
  --pink:#ff8a00; --cyan:#ffc93c; --gold:#ff8a00;
  /* Auf der dunklen Buehne bleibt das kraeftige Orange richtig. */
  --buehne-gold:#ff8a00;
  --gold-txt:#ff8a00;
  --cyan-txt:#ffc93c;
}
/* In der hellen Ansicht ist #ff8a00 als TEXT zu blass (Kontrast ~2.3:1) -
   dafuer ein abgedunkelter Ton derselben Farbe. Der Selektor nennt beide
   Klassen, weil body.theme-orange sonst den Wert von html.ps-hell wieder
   ueberschreiben wuerde (body ist spezifischer als html). */
html.ps-hell body.theme-orange{
  --gold-txt:#a35c00;
  --cyan-txt:#8a6a00;
}
body.theme-orange .logo{
  background:linear-gradient(90deg,#ff8a00,#ffc93c);
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;
  filter:drop-shadow(0 4px 24px rgba(255,138,0,.35));
}
*{margin:0;padding:0;box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{height:100%;background:var(--bg);color:var(--txt);overflow:hidden;
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  overscroll-behavior:none;}
button{font-family:inherit;border:none;background:none;color:inherit;cursor:pointer}

/* ---------- App-Gerüst: Nav + Ansichten ----------
   Drei Ansichten (Feed/Games/Profil) leben nebeneinander im Markup,
   aber nur eine ist je "active" (display:block) - kein Router nötig. */
.app-shell{height:100%;display:flex;background:var(--seite)}
.app-stage{flex:1;position:relative;min-width:0;height:100%;background:var(--seite)}
.view{display:none;height:100%}
.view.active{display:block}

/* Unteres Menü: Handy/Tablet. Der Feed zieht sich um dessen Höhe
   zusammen (--bottomnav-h), damit am Kartenrand nichts verdeckt wird -
   am PC wird die Variable weiter unten auf 0 gesetzt. */
.app-bottomnav{position:fixed;left:0;right:0;bottom:0;z-index:45;
  display:flex;justify-content:space-around;align-items:stretch;
  height:calc(var(--bottomnav-h) + env(safe-area-inset-bottom));
  padding-bottom:env(safe-area-inset-bottom);
  background:var(--seite);border-top:1px solid var(--seite-glass-border);
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px)}
.bn-item{flex:1;min-width:0;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:2px;color:var(--seite-txt-dim);font-size:10px;font-weight:700;background:none}
/* Fuenf Eintraege statt drei (Feed, Games, Gespeichert, Nachrichten,
   Profil): auf 360px Breite bleiben je Knopf nur rund 72px. Ohne nowrap
   bricht "Gespeichert" um und die Leiste wird zweizeilig. */
.bn-item span:last-child{white-space:nowrap;font-size:9px;letter-spacing:-.2px;
  max-width:100%;overflow:hidden;text-overflow:ellipsis}
.bn-item .ni{font-size:22px;line-height:0;display:flex;align-items:center;justify-content:center}
/* Zwei Fassungen je Eintrag - Kontur oder gefuellt, nie beide. Der Wechsel
   laeuft rein ueber CSS, deshalb kein Flackern beim Umschalten. */
.bn-item .bn-f{display:none}
.bn-item.active .bn-o{display:none}
.bn-item.active .bn-f{display:inline-block}
.bn-item.active{color:var(--pink);font-weight:800}
.bn-item:active{transform:scale(.92)}
.bn-item{transition:color .18s ease,transform .12s ease}

/* Games ist der Mittelpunkt der Leiste: rund ein Viertel groesser und in
   Akzentfarbe - aber ohne eigenen Kreis und auf derselben Grundlinie wie
   die anderen vier. Ein aufgesetzter Knopf wirkte hier zu laut. */
.bn-games .ni{font-size:28px}
.bn-games{color:var(--pink);opacity:.75}
.bn-games.active{opacity:1}

/* Linkes Menü: nur am PC sichtbar (siehe @media weiter unten). */
.app-nav{display:none}

/* ---------- Feed (Wisch-Bahn wie TikTok) ----------
   Der Feed ist ein ECHTER Scroll-Container mit Scroll-Snap, kein
   selbstgebautes Gezieh per transform. Der Grund: nur so bekommt man
   Schwung, Gummiband und "halb durchziehen und zurückfedern" geschenkt -
   genau das, was Wischen auf dem Handy natürlich anfühlen lässt.
   Nachgeahmtes Scrollen fühlt sich immer selbstgebaut an.

   Im Container liegen immer GENAU DREI Karten (voriges / aktuelles /
   nächstes), die Ruhelage ist die Mitte. Nach jedem Schnappen hängt
   core/feed.js die Karten um und korrigiert scrollTop um eine
   Kartenhöhe - unsichtbar, weil es genau ein Raster weit ist (siehe
   railShift()). Deshalb bleibt die Bahn endlos, ohne dass Karten
   endlos auflaufen.

   scroll-snap-stop:always ist wichtig: ohne das wischt ein kräftiger
   Schwung über mehrere Karten hinweg und man landet irgendwo - mit ihm
   rückt immer genau EIN Spiel weiter, wie bei TikTok.
   margin-top/height sind um --navbtn-top-h/--navbtn-bottom-h verkürzt -
   das schafft oben und unten einen ECHTEN, freien Bereich für die
   Handy-Pfeil-Buttons, statt dass die als Overlay über dem Spielinhalt
   schweben (genau das lag vorher über dem Hangman-Tastenfeld etc.). */
#feed{position:relative;margin-top:var(--navbtn-top-h);
  height:calc(100vh - var(--bottomnav-h) - var(--navbtn-top-h) - var(--navbtn-bottom-h));
  height:calc(100dvh - var(--bottomnav-h) - var(--navbtn-top-h) - var(--navbtn-bottom-h));
  overflow-x:hidden;overflow-y:scroll;
  scroll-snap-type:y mandatory;
  -webkit-overflow-scrolling:touch;
  /* Kein Weiterreichen an die Seite dahinter: sonst zieht ein Wischen am
     Ende der Bahn das ganze Fenster mit (Pull-to-Refresh auf
     Android-Chrome, Gummiband der Seite auf iOS). */
  overscroll-behavior-y:contain;
  /* Rollbalken weg - er würde über dem Spiel liegen. */
  scrollbar-width:none;-ms-overflow-style:none;}
#feed::-webkit-scrollbar{width:0;height:0;display:none}
/* Beim programmatischen Umhängen (railShift) darf NICHT gesnappt und
   nicht animiert werden, sonst ruckelt der Ausgleichsschritt sichtbar. */
#feed.rail-umbau{scroll-snap-type:none;scroll-behavior:auto}
/* Während gespielt wird, ist der Feed für FINGER nicht scrollbar - per
   Skript (der Wisch-Griff über navigate()) weiterhin sehr wohl, denn
   scrollTo/scrollTop wirken auch bei overflow:hidden.

   Das ist der zweite und entscheidende Riegel neben touch-action. Gemessen:
   touch-action:none auf der Bühne reicht NICHT, wenn ein Spiel in seinem
   Shadow DOM ein Element auf "pan-x pan-y" setzt (nachgewiesen bei minenfeld
   und pizzeria) - dann wischte der Feed mitten im Zug weiter. Spiele wie
   flappy fielen nicht auf, weil sie zusätzlich preventDefault() aufrufen;
   darauf kann man sich bei 31 Spielen aber nicht verlassen.

   Ist der Feed gar nicht scrollbar, kann keine Fingergeste ihn bewegen,
   unabhängig davon, was ein Spiel mitbringt.
   Gesetzt von engage()/disengage() in core/feed.js. */
#feed.spielt{overflow-y:hidden}
/* Dieselbe Regel noch einmal, aber aus dem DOM abgeleitet statt von Hand
   gesetzt. Grund: Die Klasse .spielt ist Buchhaltung, und Buchhaltung kann
   man vergessen - genau das ist passiert (armGame räumte 'engaged' von der
   Karte, ohne .spielt vom Feed zu nehmen; der Feed blieb unscrollbar und
   Wischen war ab da tot, ohne sichtbaren Grund). :has() fragt direkt, ob
   eine Karte gerade gespielt wird, und kann deshalb nicht veralten.
   Die Klasse oben bleibt als Rückfallebene für ältere Browser ohne :has(). */
#feed:has(.card.engaged){overflow-y:hidden}
#feed:not(:has(.card.engaged)){overflow-y:scroll}
/* Die Karte traegt die Textfarbe fuer ALLES, was auf dem Spiel liegt.
   Ohne dieses color: wuerde hier das schwarze --txt von html/body
   durchschlagen - Punktestand und Spieltitel waeren auf der dunklen
   Spielflaeche unsichtbar. */
.card{position:relative;height:100%;overflow:hidden;background:var(--karte);
  color:var(--buehne-txt);
  /* Jede Karte ist ein Schnapppunkt und hält den Schwung an (siehe
     #feed oben) - eine Karte je Wischer, nie zwei. */
  scroll-snap-align:start;scroll-snap-stop:always}

/* ---------- Sprung an eine andere Stelle der Bahn ----------
   Normales Weiterwischen braucht KEINE Animation - das macht der
   Scroll-Container selbst (siehe #feed). Diese Blende hier ist nur für
   den harten Sprung von aussen: aus Gespeichert/Geliket/Profil zu einem
   bestimmten Spiel (goToGame) oder ein Neuaufbau nach dem Anmelden
   (neuStartAktivesSpiel). Dabei wird die ganze Bahn neu gebaut - ohne
   Blende würde das hart umschalten.

   Die frühere Karussell-Animation (zwei Karten absolut übereinander,
   --dir, cardSlideIn/Out) ist entfallen: in einem Scroll-Container darf
   eine Karte nicht absolut positioniert werden, sonst fällt sie aus der
   Bahn und das Schnappen verrutscht. */
#feed.bahn-blende{animation:bahnBlende .34s ease}
@keyframes bahnBlende{from{opacity:.25}to{opacity:1}}
@media (prefers-reduced-motion:reduce){
  #feed.bahn-blende{animation:none}
}

/* ---------- Nachbarkarten in der Bahn ----------
   Von den drei Karten im Feed trägt nur die mittlere ein echtes Spiel.
   Die Nachbarn sind Vorschauen - sonst müssten drei Spiele gleichzeitig
   laufen (Speicher, Timer, Töne). Damit man beim Wischen aber nicht in
   ein leeres Feld schaut, zeigen sie gross Symbol und Namen. Sobald eine
   Karte in die Mitte schnappt, entsteht ihr Spiel und .hat-spiel blendet
   die Vorschau aus (siehe railAktivieren() in core/feed.js). */
.karten-vorschau{position:absolute;inset:0;z-index:3;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;
  pointer-events:none;transition:opacity .2s ease}
.card.hat-spiel .karten-vorschau{opacity:0}
.karten-vorschau .kv-symbol{font-size:64px;line-height:1;filter:drop-shadow(0 6px 20px rgba(0,0,0,.45))}
.karten-vorschau .kv-name{font-size:22px;font-weight:800;text-align:center;padding:0 40px;
  text-shadow:0 2px 10px rgba(0,0,0,.6)}
.karten-vorschau .kv-lade{font-size:12px;font-weight:700;letter-spacing:.4px;
  color:var(--buehne-txt-dim)}

/* ---------- Startseite ---------- */
.home{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:24px;
  background:radial-gradient(60% 45% at 15% 10%, rgba(255,138,0,.28), transparent 60%),
    radial-gradient(55% 45% at 88% 85%, rgba(255,201,60,.20), transparent 60%),
    linear-gradient(160deg,#0b0b12,#12121e 60%,#0b0b12);}
.logo{font-size:clamp(38px,9.5vw,80px);font-weight:900;letter-spacing:2px;
  background:linear-gradient(90deg,var(--pink),var(--cyan));
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;
  filter:drop-shadow(0 4px 24px rgba(255,138,0,.35));}
.tagline{margin-top:6px;color:var(--txt-dim);font-size:clamp(13px,3.4vw,17px);letter-spacing:1px}
.stats{display:flex;gap:12px;margin:28px 0 20px;flex-wrap:wrap;justify-content:center}
.stat{background:var(--glass);border:1px solid var(--glass-border);border-radius:18px;
  padding:14px 18px;min-width:96px;backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}
.stat b{display:block;font-size:24px;font-weight:800}
.stat span{font-size:11px;color:var(--txt-dim);text-transform:uppercase;letter-spacing:1px}
.home-btn{display:inline-flex;align-items:center;gap:8px;margin-top:10px;padding:13px 24px;border-radius:999px;
  font-weight:700;font-size:15px;background:linear-gradient(135deg,var(--pink),#ffb020);color:#1c0f00;
  box-shadow:0 8px 26px rgba(255,138,0,.4);transition:transform .15s ease}
.home-btn:active{transform:scale(.95)}
.home-btn.ghost{background:var(--glass);border:1px solid var(--glass-border);box-shadow:none}
/* Feld und Knopf muessen exakt gleich hoch sein und exakt gleich sitzen.
   Philipp hat auf dem echten Handy einen Versatz von ein paar Pixeln
   gesehen (in der Emulation nicht reproduzierbar, dort waren es 0,0 px).
   Wahrscheinliche Ursache auf echten Geraeten: der Knopf hatte keine eigene
   Hoehe und keine feste Zeilenhoehe - er hing damit an den Schriftmetriken
   der jeweils verfuegbaren Systemschrift, und die sind auf Android anders
   als in der Emulation.

   Deshalb jetzt festgenagelt statt dem Zufall ueberlassen: gleiche
   Mindesthoehe, feste Zeilenhoehe, Inhalt zentriert, align-items:stretch
   ausgeschrieben. Das kostet nichts und laesst dem Versatz keinen Raum
   mehr - unabhaengig davon, welche Schrift ein Geraet nimmt. */
.code-row{display:flex;gap:8px;margin-top:18px;max-width:320px;width:100%;
  align-items:stretch}
.code-row input,.code-row button{min-height:42px;line-height:1;
  box-sizing:border-box;font-family:inherit}
/* min-width:0 ist hier das Entscheidende - und war die Ursache von Philipps
   Fund: Ein Flex-Element schrumpft standardmaessig NICHT unter die Breite
   seines Inhalts (min-width:auto). Der Platzhalter "CODE EINGEBEN..." ist
   in Grossbuchstaben mit Sperrung ziemlich breit; stellt jemand am Handy
   eine groessere Systemschrift ein, passen Feld und Knopf nicht mehr
   nebeneinander - und statt zu schrumpfen liefen sie nach RECHTS ueber die
   Fluchtlinie der anderen Knoepfe hinaus. Genau das war auf seinem Bild zu
   sehen; bei Standardschrift trat es nie auf (gemessen: 0,0 px bei 12px
   Schrift, 35 px bei 15px, 79 px bei 18px).

   Mit min-width:0 darf das Feld schmaler werden, und flex-wrap sorgt dafuer,
   dass der Knopf lieber in die naechste Zeile rutscht als ueberzulaufen.
   Die Grundbreite von 140px ist die Grenze, ab der umgebrochen wird. */
.code-row{flex-wrap:wrap}
.code-row input{flex:1 1 140px;min-width:0}
.code-row button{flex:0 1 auto;min-width:0;max-width:100%;
  display:inline-flex;align-items:center;justify-content:center;
  white-space:nowrap}
.code-row input{flex:1;background:var(--glass);border:1px solid var(--glass-border);border-radius:999px;
  padding:11px 16px;color:var(--txt);font-size:14px;outline:none;text-transform:uppercase;letter-spacing:1px}
.code-row input:focus{border-color:var(--gold)}
.code-row button{background:linear-gradient(90deg,var(--gold),#ffb020);color:#221a00;border-radius:999px;
  padding:0 18px;font-weight:800;font-size:13px}
/* ---------- Spiel-Karten (generischer Rahmen für jedes Spiel) ---------- */
.game-card{background:linear-gradient(170deg,#101020,#0b0b12)}
.game-stage{position:absolute;inset:0;isolation:isolate}   /* isolate (2026-10-17): Ebenen eines Spiels (z. B. Startschicht z-index 30 in Das letzte Klopfen) bleiben unter der Seitenleiste (z-index 10) */
.game-body{position:absolute;inset:0}

/* ---------- Vollbild-Spielmodus (aus dem Games-Tab) ----------
   Bewusst eigenständig, komplett ohne Sidebar/HUD/Feed-Kartenoptik -
   das Spiel bekommt den ganzen Bildschirm. Siehe openGameFullscreen()/
   closeGameFullscreen() in core/feed.js. */
/* Solange das Vollbild offen ist, muessen Blaetter (Shop, Kommentare)
   DARUEBER liegen. Sonst oeffnet sich der Shop unsichtbar hinter dem
   Spiel - die Blaetter stehen normal auf z-index 50, das Vollbild auf 200. */
body.gf-offen .sheet{z-index:260}
body.gf-offen #backdrop{z-index:255}
.game-fullscreen{position:fixed;inset:0;z-index:200;background:var(--buehne);
  color:var(--buehne-txt);display:none}
.game-fullscreen.open{display:block}
.game-fs-stage{position:absolute;inset:0;--ps-touch:none}
/* Spiele-Update 2026-09 (Punkt 1.10): eigene PlayScroll-Leiste OBEN im Vollbild. Vorher lagen Zurück-Knopf
   und Gold/Dias ÜBER den Spielen und verdeckten in ~18 Spielen deren Anzeige oben links/rechts. Jetzt
   beginnt das Spiel unter der Leiste - es kann nichts mehr überlappen. */
.game-fullscreen{--gf-leiste:calc(52px + env(safe-area-inset-top))}
.game-fullscreen::before{content:"";position:absolute;left:0;right:0;top:0;height:var(--gf-leiste);
  background:rgba(8,10,18,.92);border-bottom:1px solid rgba(255,255,255,.08);z-index:55}
.game-fullscreen .game-fs-stage{top:var(--gf-leiste)}
/* Oben links sitzt hier der Zurück-Button. Das HUD (Punktestand, Gold)
   würde sonst darunter liegen - im Vollbild sammelt es sich deshalb
   rechts, statt wie in der Karte über die ganze Breite zu spannen. */
.game-fs-stage .game-hud{left:auto;
  right:calc(14px + env(safe-area-inset-right));justify-content:flex-end}
.game-fullscreen .game-fs-stage .game-hud{position:fixed;top:calc(8px + env(safe-area-inset-top));z-index:61}
.gf-back{position:absolute;top:calc(6px + env(safe-area-inset-top));
  left:calc(10px + env(safe-area-inset-left));z-index:60;   /* ueber jeder Spiel-Anzeige (Pizzeria-Leiste lag sonst darueber) */
  background:rgba(120,120,130,.32);border:1px solid rgba(255,255,255,.22);
  color:#fff;border-radius:50%;width:40px;height:40px;padding:0;display:grid;place-items:center;
  cursor:pointer;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
  box-shadow:0 4px 14px rgba(0,0,0,.3)}
.gf-back .i{width:20px;height:20px}
.gf-back:active{transform:scale(.94)}
/* Shop-Knopf im Vollbild, in Goldton, damit man ihn als Laden erkennt.
   Er sitzt am RECHTEN RAND MITTIG - nicht oben rechts und nicht unten:
   oben haben die Spiele ihre eigene Kopfzeile (bei Dog Defense Knochen,
   Leben, Welle, Tempo und Info - die wurden verdeckt), unten liegen die
   Bedienelemente. Der rechte Rand mittig ist die Stelle, an der im Feed
   die Seitenleiste liegt; dort halten die Spiele ohnehin Platz frei. */
.gf-shop{position:absolute;top:50%;transform:translateY(-50%);
  right:calc(8px + env(safe-area-inset-right));z-index:60;
  display:flex;flex-direction:column;align-items:center;gap:2px;
  background:rgba(255,213,74,.20);border:1px solid rgba(255,213,74,.55);
  color:var(--gold-txt,#ffd54a);border-radius:16px;padding:9px 8px;
  font-size:10px;font-weight:800;letter-spacing:.04em;cursor:pointer;
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
  box-shadow:0 4px 14px rgba(0,0,0,.3)}
.gf-shop .i{width:22px;height:22px}
.gf-shop:active{transform:translateY(-50%) scale(.94)}
/* Rangliste im Vollbild (grosses September-Update) - gleiche Bauart wie der
   Shop-Knopf, direkt DARUEBER am rechten Rand, damit beide nie ueber den
   Kopfzeilen oder Bedienelementen der Spiele liegen. */
.gf-rang{position:absolute;top:calc(50% - 74px);transform:translateY(-50%);
  right:calc(8px + env(safe-area-inset-right));z-index:60;
  display:flex;flex-direction:column;align-items:center;gap:2px;
  background:rgba(255,138,0,.18);border:1px solid rgba(255,170,60,.55);color:#ffc36b;
  border-radius:14px;padding:8px 7px;font-size:10.5px;font-weight:800;cursor:pointer;
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);box-shadow:0 4px 14px rgba(0,0,0,.3)}
.gf-rang[hidden]{display:none}
.gf-rang .i{width:22px;height:22px}
.gf-rang:active{transform:translateY(-50%) scale(.94)}
/* Spiele-Update 2026-09: Seit es die Leiste oben gibt, sitzen Shop und Rangliste DORT - links neben dem
   Zurück-Knopf, als runde Symbole wie dieser. Am rechten Rand mittig lagen sie bei Irrgarten, Frosch u. a.
   auf dem Spielfeld. Rechts in der Leiste steht das HUD des Spiels, links ist Platz. */
.game-fullscreen .gf-shop,.game-fullscreen .gf-rang{top:calc(6px + env(safe-area-inset-top));right:auto;transform:none;
  width:40px;height:40px;padding:0;border-radius:50%;display:grid;place-items:center;font-size:0;gap:0}
.game-fullscreen .gf-shop{left:calc(58px + env(safe-area-inset-left))}
.game-fullscreen .gf-rang{left:calc(106px + env(safe-area-inset-left))}
.game-fullscreen .gf-shop[hidden]~.gf-rang{left:calc(58px + env(safe-area-inset-left))}
.game-fullscreen .gf-shop .i,.game-fullscreen .gf-rang .i{width:20px;height:20px}
.game-fullscreen .gf-shop:active,.game-fullscreen .gf-rang:active{transform:scale(.94)}
.game-fullscreen .gf-shop[hidden],.game-fullscreen .gf-rang[hidden]{display:none}
/* Pokal/Wagen genau mittig (Philipp 2026-10-09, PC): Das unsichtbare Wort "Top"/"Shop"
   belegte im Raster eine zweite Zeile und schob das Symbol nach oben, dazu kam das
   vertical-align der .i-Symbole. Wort im Rundknopf ganz raus, Symbol als Block. */
.game-fullscreen .gf-shop .gf-lb,.game-fullscreen .gf-rang .gf-lb{display:none}
.game-fullscreen .gf-shop .i,.game-fullscreen .gf-rang .i,.gf-back .i,.ko-btn .i,.gf-aufgaben .i{display:block;vertical-align:0;margin:0}
.rang-unter{margin:0 0 12px}
/* Reiter bei Spielen mit mehreren Ranglisten-Ansichten (seit 2026-10-05, Perfect Timing) */
.rang-reiter{display:flex;gap:6px;margin:0 0 12px;padding:4px;border-radius:999px;background:var(--glass);border:1px solid var(--glass-border)}
.rang-reiter button{flex:1;border:0;border-radius:999px;padding:8px 10px;background:transparent;color:var(--txt-dim);
  font-weight:800;font-size:12.5px;cursor:pointer}
.rang-reiter button.an{background:var(--pink);color:#1c0f00}
.rang-anmelden{display:inline-block;margin-left:6px;padding:5px 12px;border-radius:999px;border:0;
  background:var(--pink);color:#1c0f00;font-weight:800;font-size:12px;cursor:pointer}
.gf-shop[hidden]{display:none}
/* ---------- Wer bekommt die Geste: Feed oder Spiel? ----------
   Das ist die Kernregel des Wischens, und sie hängt am Zustand der
   Karte - nicht an einer festen Einstellung:

   WARTET die Karte (ready) oder ist sie PAUSIERT, wird gerade nicht
   gespielt. Dann gehört der ganze Bildschirm dem Feed: touch-action
   pan-y, der Browser scrollt nativ, man wischt durch wie bei TikTok.

   WIRD GESPIELT (engaged), gehört jede Berührung dem Spiel:
   touch-action none, damit Ziehen und Zielen sofort und ohne Verzögerung
   ankommen. Zum Weiterwischen gibt es dann den Griff unten links
   (.wisch-griff) - siehe unten.

   Das war schon immer der Plan (der Umwandler in _build_games.js schreibt
   touch-action:none in den Spielen deshalb auf var(--ps-touch) um), nur
   stand hier lange ein festes "none" - damit war Scrollen unmöglich.

   Der bekannte Preis von pan-y: iOS Safari wartet bei einer Berührung
   kurz ab, ob daraus eine Scroll-Geste wird. Das betrifft jetzt nur noch
   den EINEN Tipp, mit dem man ein wartendes Spiel startet - sobald
   gespielt wird, steht touch-action auf none und alles kommt sofort an.
   Ohne dieses Zugeständnis gibt es kein natives Scrollen, und
   nachgeahmtes fühlt sich schlechter an als ein kurzer Moment Geduld
   beim Starten. */
.game-card{--ps-touch:pan-y}
.game-card.engaged{--ps-touch:none}
.game-body canvas{display:block;width:100%;height:100%;
  touch-action:var(--ps-touch,pan-y)}
/* ENTSCHEIDEND, und in zwei Anlaeufen schrittweise gelernt:

   1. --ps-touch ist nur eine VARIABLE. Sie wirkt ausschliesslich dort, wo
      wirklich touch-action:var(--ps-touch) steht - auf dem Canvas oben und
      in den Spielen, deren Quell-CSS ein touch-action:none mitbrachte (das
      schreibt _build_games.js um). Ein Spiel ohne solche Regel hatte damit
      effektiv touch-action:auto, und der Feed nahm ihm mitten im Spielen
      die Geste weg: wischen statt spielen.

   2. Die Sperre auf .game-body zu setzen reichte NICHT. Mehrere Spiele
      haengen Overlays (Pause, Sieg, Bedienleisten) nicht in .game-body,
      sondern direkt an .game-stage - landete der Finger darauf, scrollte
      der Feed trotzdem. Auffaellig war das nur zeitweise, weil der Feed
      bei jedem Start andere Spiele zufaellig auswaehlt.

   Deshalb wird die ganze BUEHNE gesperrt, sobald gespielt wird. Damit ist
   es unabhaengig davon, was ein einzelnes Spiel mitbringt oder wohin es
   seine Overlays haengt.

   Der Preis, den .wisch-griff dafuer zahlt: touch-action wirkt als
   Schnittmenge entlang der Elternkette - ein Kind kann sich nicht mehr
   erlauben als sein Elternteil. Der Griff liegt deshalb AUSSERHALB der
   Buehne, als Geschwister, genau wie die Seitenleiste (die aus demselben
   Grund immer funktioniert hat). Siehe buildCardShell() in core/feed.js. */
.game-card.engaged .game-stage{touch-action:none}

/* ---------- Wisch-Griff (nur während gespielt wird) ----------
   Solange gespielt wird, blockiert das Spiel die Gesten. Damit man
   trotzdem weiterkommt, ohne erst Pause zu drücken, liegt unten links
   ein Griff mit touch-action:pan-y - dort scrollt der Browser die Bahn
   wieder nativ.

   Warum UNTEN LINKS und nicht über die ganze Höhe: der Griff nimmt dem
   Spiel die Fläche weg, die er bedeckt, also darf er nur ein Streifen
   sein. Rechts wäre die Seitenleiste im Weg, bleibt also links.

   Er saß zuerst oben links - aus der Überlegung heraus, dass unten und
   mittig die Spiele steuern (Schläger bei Ziegelbruch/Ballduell/
   Alienabwehr, Zielkreise bei Minigolf/Bubbleshooter). Philipps Test auf
   dem Handy hat das am 2026-09-12 widerlegt, und sein Einwand wiegt
   schwerer: oben kommt der Daumen im Halten gar nicht hin. Gewischt wird
   unten, nicht oben - ein Griff, den niemand erreicht, nützt nichts, auch
   wenn er keinem Spiel im Weg ist.

   Er ist sichtbar (dezente Pille), nicht unsichtbar: einen Griff, den
   man erraten muss, findet niemand. */
/* touch-action:none, und das Blaettern macht hier JavaScript selbst
   (griffZug in core/feed.js) - anders als auf der grossen Flaeche, wo der
   Browser nativ scrollt.

   Der Grund, gemessen und nicht geraten: Ein Snap-Container rueckt nur
   weiter, wenn Strecke ODER Schwung reichen. Der Griff ist absichtlich nur
   ein Streifen - auf 42% der Hoehe bleibt jede normale Wischbewegung unter
   der Schwelle und federt zurueck. Es sah kaputt aus, obwohl alles richtig
   verdrahtet war. Den Griff ueber die ganze Hoehe zu ziehen war keine
   Option: er nimmt dem Spiel genau die Flaeche weg, die er bedeckt.

   Ein kleines Bedienelement braucht auch keinen nativen Schwung, sondern
   eine verlaessliche Reaktion: ab ein paar Pixeln Bewegung loest es ein
   weiches scrollTo aus - dieselbe Animation wie bei den Pfeil-Knoepfen. */
.wisch-griff{position:absolute;left:0;bottom:0;width:44px;height:42%;
  /* 60 statt 8 (1.67.1): Spiele wie Pizzeria, Idle Clicker und Das letzte
     Klopfen legen eigene Ebenen bis z-index 50 an - die lagen über dem
     Griff, man konnte nicht mehr weiterwischen. Unter .game-fullscreen (200). */
  z-index:60;display:none;touch-action:none;
  align-items:center;justify-content:center;
  /* Nicht ganz durchsichtig, aber sehr zurückhaltend - es soll auffindbar
     sein, ohne mit dem Spiel zu konkurrieren. */
  background:linear-gradient(90deg,var(--buehne-glass),transparent);
  border:none;color:var(--buehne-txt-dim);cursor:grab}
.card.engaged .wisch-griff{display:flex}
.wisch-griff .gr{display:flex;flex-direction:column;align-items:center;gap:3px;
  font-size:11px;opacity:.75;pointer-events:none}
.wisch-griff .gr .i{width:14px;height:14px}
/* Beim ersten Spielen einer Sitzung blinkt der Griff zweimal auf, damit
   man ihn überhaupt bemerkt. Danach bleibt er still (siehe
   griffEinmalZeigen() in core/feed.js). */
@keyframes griffWink{0%,100%{opacity:.75}50%{opacity:1;transform:translateX(3px)}}
.wisch-griff.wink .gr{animation:griffWink 1.1s ease 2}
@media (prefers-reduced-motion:reduce){.wisch-griff.wink .gr{animation:none}}
/* Am PC braucht es den Griff nicht - dort gibt es Mausrad und
   Tastatur (siehe core/feed.js). */
@media (min-width:1024px){.card.engaged .wisch-griff{display:none}}

/* ---------- Deckel über der Spielfläche (solange nicht gespielt wird) ----------
   Liegt über dem Spiel, wann immer die Karte NICHT "engaged" ist - also im
   Wartezustand ("Zum Spielen tippen"), in der Pause und immer sonst, wenn
   der Feed die Geste haben soll. Ein Tipp darauf startet das Spiel
   (pointerup-Handler in core/feed.js), gewischt wird nativ: touch-action
   pan-y, und der Browser scrollt den Feed.

   WARUM er nötig ist - von Philipp am 2026-09-12 auf dem echten Handy
   gefunden und danach nachgemessen: Bei Spielen mit "Zum Spielen tippen"
   ließ sich teilweise gar nicht wischen. Die touch-action-Kette war dabei
   nachweislich korrekt (pan-y bis zum Canvas) - blockiert haben die SPIELE
   SELBST, per preventDefault bzw. Zeiger-Übernahme in ihren eigenen
   Handlern. Die laufen nämlich ab dem Erzeugen der Karte, nicht erst ab
   dem Start.

   Deshalb wirkte es zufällig: es hing davon ab, ob man ein Spielelement
   traf. Gemessen blockierten stapelturm links-unten und rechts-mitte,
   alienabwehr mittig, ziegelbruch rechts-mitte - jedes Spiel woanders.
   Gegen so etwas hilft keine CSS-Regel, nur: das Spiel bekommt die
   Berührung gar nicht erst.

   BEKANNTE EINSCHRÄNKUNG: Bedienelemente, die ein Spiel im Wartezustand
   anbietet (z.B. .chess-reset, .td-bar), liegen unter dem Deckel und sind
   dort nicht mehr anklickbar - ein Tipp startet stattdessen das Spiel.
   Bewusst in Kauf genommen: verlässliches Wischen ist in jedem Spiel
   wichtiger als ein Knopf in zweien, und nach dem Start ist der Deckel weg. */
.spiel-deckel{position:absolute;inset:0;z-index:7;background:transparent;
  touch-action:pan-y}
.card.engaged .spiel-deckel{display:none}
/* Seit 2026-10-13 (Tester Smaragd: kein Hover, kein Hand-Zeiger): Der Deckel
   fängt die Maus ab, bevor die Knöpfe des Spiels sie sehen - also zeigt er
   selbst, dass ein Klick das Spiel startet, und der Hinweis leuchtet auf. */
@media (hover:hover){
  .spiel-deckel{cursor:pointer}
  .card:has(.spiel-deckel:hover) .tap-hint{border-color:var(--cyan);transform:translateX(-50%) scale(1.06)}
}

/* Knöpfe in der Titelzeile der Karte (2026-10-09): Shop, Rangliste,
   Testaufgaben. Die Zeile (.game-hud) liegt dafür ÜBER dem Deckel
   (z-index 8 statt 5), sonst zählt ein Tipp als "aufs Spielfeld getippt"
   und startet das Spiel. Lange Spielnamen werden dann gekürzt. */
.karte-oben{display:flex;gap:6px;margin-right:auto;pointer-events:none;flex:none}
.game-hud .ko-btn{width:31px;height:31px}
.game-hud .ko-btn .i{width:17px;height:17px}
.game-hud .game-title{min-width:0;overflow:hidden;text-overflow:ellipsis;flex:0 1 auto}
/* Spiele mit eigener Oberfläche (Titelzeile aus): als Gruppe oben in der Seitenleiste */
.karte-oben.ko-frei{flex-direction:column;align-items:center;gap:10px;margin:0 0 6px;padding-bottom:10px;
  border-bottom:1px solid var(--buehne-glass-border)}
.karte-oben.ko-frei .ko-btn{width:36px;height:36px}
.karte-oben.ko-frei:not(:has(.ko-btn:not([hidden]))){display:none}
.ko-btn,.gf-aufgaben{position:relative;width:36px;height:36px;border-radius:50%;display:grid;place-items:center;padding:0;
  background:var(--buehne-glass);border:1px solid var(--buehne-glass-border);color:var(--buehne-txt);cursor:pointer;
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);box-shadow:0 3px 10px rgba(0,0,0,.35);pointer-events:auto}
.ko-btn[hidden],.gf-aufgaben[hidden]{display:none}
.ko-btn .i,.gf-aufgaben .i{width:19px;height:19px}
.ko-btn:active,.gf-aufgaben:active{transform:scale(.92)}
.ko-aufgaben,.gf-aufgaben{color:#7fe3c4;border-color:rgba(127,227,196,.5)}
/* Farben wie die Vollbild-Knöpfe: Shop gold, Rangliste orange */
.ko-shop{color:var(--gold-txt,#ffd54a);background:rgba(255,213,74,.20);border-color:rgba(255,213,74,.55)}
.ko-rang{color:#ffc36b;background:rgba(255,138,0,.18);border-color:rgba(255,170,60,.55)}
.ko-zahl{position:absolute;top:-5px;right:-5px;min-width:17px;height:17px;padding:0 4px;border-radius:999px;
  background:var(--pink);color:#1c0f00;font-size:10px;font-weight:800;line-height:17px;text-align:center}
.ko-zahl[hidden]{display:none}
/* Im Vollbild in der oberen Reihe hinter Zurück/Shop/Rangliste - die
   genaue Stelle setzt psTaVollbild() je nachdem, welche davon sichtbar
   sind. Unter dem Zurück-Knopf lag er bei Dorfreich auf der Rohstoffleiste. */
.gf-aufgaben{position:absolute;top:calc(6px + env(safe-area-inset-top));left:calc(58px + env(safe-area-inset-left));
  width:40px;height:40px;z-index:60}
.gf-aufgaben .i{width:20px;height:20px}

/* Testaufgaben-Blatt (core/testaufgaben.js) */
.ta-aufgabe{border:1px solid var(--glass-border);border-radius:14px;padding:12px;margin-bottom:12px;background:var(--glass)}
.ta-aufgabe.fertig{opacity:.75}
.ta-kopf{display:flex;gap:10px;align-items:flex-start;cursor:pointer}
.ta-kopf input{width:20px;height:20px;margin-top:2px;flex:none;accent-color:#3ecf8e}
.ta-kopf b{display:block;font-size:14.5px}
.ta-aufgabe.fertig .ta-kopf b{text-decoration:line-through}
.ta-kopf small{color:var(--txt-dim);font-size:11.5px}
/* Dringlichkeit "!8" und Rang "C" vor dem Titel (2026-10-09) */
.ta-mk{display:inline-block;font-style:normal;font-size:11px;font-weight:800;padding:1px 6px;border-radius:999px;margin-right:5px;
  background:var(--glass);border:1px solid var(--glass-border);vertical-align:1px}
.ta-mk.hoch{background:rgba(255,138,0,.2);border-color:rgba(255,138,0,.6);color:#ffae42}
.ta-mk.rang{background:rgba(155,107,255,.18);border-color:rgba(155,107,255,.5);color:#c9b6ff}
.ta-text{margin:8px 0 0 30px;font-size:13.5px;line-height:1.45;color:var(--txt-dim)}
.ta-kommentare{margin:8px 0 0 30px}
.ta-kom{border-left:3px solid rgba(127,227,196,.5);padding:4px 0 4px 10px;margin-top:8px}
.ta-kom small{color:var(--txt-dim);font-size:11px}
.ta-kom p{margin:2px 0 0;font-size:13.5px;white-space:pre-wrap;word-break:break-word}
.ta-form{display:flex;gap:8px;margin:10px 0 0 30px}
.ta-form textarea{flex:1;min-height:38px;max-height:120px;resize:vertical;border-radius:12px;border:1px solid var(--glass-border);
  background:transparent;color:inherit;padding:8px 10px;font:inherit;font-size:13.5px}
.ta-form button{width:40px;border-radius:12px;border:0;background:var(--pink);color:#1c0f00;display:grid;place-items:center;cursor:pointer}
.ta-form button .i{width:18px;height:18px}
.ta-foto{width:40px;border-radius:12px;border:1px solid var(--glass-border);display:grid;place-items:center;cursor:pointer;font-size:17px}
.ta-foto.an{border-color:#3ecf8e;background:rgba(62,207,142,.18)}
.ta-bildknopf{margin-top:6px;border:1px solid var(--glass-border);background:transparent;color:inherit;border-radius:999px;padding:5px 10px;font-size:12px;cursor:pointer}
.ta-bild{display:block;max-width:100%;max-height:420px;border-radius:10px;margin-top:6px}
.ta-leer,.ta-hinweis{color:var(--txt-dim);font-size:13px;text-align:center;margin:14px 0}

/* Hinweis, solange eine Karte noch wartet oder gerade nicht gespielt wird. */
.tap-hint{position:absolute;left:50%;bottom:calc(86px + env(safe-area-inset-bottom));
  transform:translateX(-50%);z-index:7;pointer-events:none;white-space:nowrap;
  background:var(--buehne-pille);border:1px solid var(--buehne-glass-border);
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  border-radius:999px;padding:7px 15px;font-size:12px;font-weight:700;
  opacity:0;transition:opacity .25s ease}
.card.ready .tap-hint,
.card.live:not(.engaged) .tap-hint{opacity:1}
.game-hud{position:absolute;top:calc(12px + env(safe-area-inset-top));left:14px;right:14px;
  display:flex;justify-content:space-between;align-items:center;pointer-events:none;z-index:8;gap:8px}   /* 8 = über dem Deckel, siehe .karte-oben */
.game-title,.game-score,.flecks-hud{font-weight:800;font-size:13px;letter-spacing:.5px;font-variant-numeric:tabular-nums;
  background:var(--buehne-glass);border:1px solid var(--buehne-glass-border);border-radius:999px;padding:6px 12px;
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);white-space:nowrap}
.flecks-hud{color:var(--buehne-gold)}
.game-info{position:absolute;left:14px;right:76px;bottom:calc(14px + env(safe-area-inset-bottom));z-index:5;pointer-events:none}
.game-info h2{font-size:17px;font-weight:800;text-shadow:0 2px 8px rgba(0,0,0,.6)}
.game-info p{font-size:12px;color:var(--buehne-txt-dim);margin-top:3px;text-shadow:0 2px 6px rgba(0,0,0,.6)}

/* ---------- Pause-Overlay ---------- */
.pause-overlay{position:absolute;inset:0;display:flex;flex-direction:column;gap:8px;align-items:center;justify-content:center;
  z-index:6;pointer-events:none;background:rgba(5,5,12,.55);backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);
  opacity:0;transition:opacity .2s ease}
.card.paused .pause-overlay{opacity:1}
.pause-overlay .big{font-size:48px}
.pause-overlay .txt{font-weight:800;font-size:20px}
.pause-overlay .sub{font-size:12px;color:var(--buehne-txt-dim);text-align:center;padding:0 30px}

/* ---------- Seitenleiste: klein, monochrome bis benutzt ---------- */
.sidebar{position:absolute;right:8px;top:50%;transform:translateY(-50%);
  display:flex;flex-direction:column;gap:12px;z-index:10;align-items:center}
.side-btn{display:flex;flex-direction:column;align-items:center;gap:2px;transition:transform .12s ease}
.side-btn:active{transform:scale(.85)}
.side-btn .ic{width:40px;height:40px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  font-size:17px;background:var(--buehne-glass);border:1px solid var(--buehne-glass-border);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  box-shadow:0 3px 10px rgba(0,0,0,.35);
  color:var(--buehne-txt-dim);opacity:.85;transition:opacity .2s ease,color .2s ease}
.side-btn .ic .i{width:21px;height:21px}
.side-btn .ct,.side-btn .lb{font-size:10px;font-weight:700;color:var(--buehne-txt-dim);text-shadow:0 1px 4px rgba(0,0,0,.6)}
/* Benutzte Buttons werden farbig */
.side-btn.liked .ic{filter:none;opacity:1;color:var(--pink);border-color:rgba(255,138,0,.6);box-shadow:0 0 14px rgba(255,138,0,.5)}
.side-btn.disliked .ic{filter:none;opacity:1;color:#c9c9d4;border-color:rgba(201,201,212,.5)}
.side-btn.saved .ic{filter:none;opacity:1;color:var(--buehne-gold);border-color:rgba(255,213,74,.6);box-shadow:0 0 14px rgba(255,213,74,.4)}
.card.paused .pause-btn .ic{filter:none;opacity:1;color:var(--cyan);border-color:rgba(255,201,60,.6);box-shadow:0 0 14px rgba(255,201,60,.4)}
@keyframes pop{0%{transform:scale(1)}40%{transform:scale(1.3)}100%{transform:scale(1)}}
.side-btn.pop .ic{animation:pop .3s ease}

/* "Weiter" (früher 🔀 Zufall) ist jetzt auf PC UND Handy sichtbar - auf
   dem Handy per Profil-Einstellung ggf. durch die Streifen ersetzt (siehe
   body.ps-nav-strips weiter unten). "Zurück" ist neu und standardmäßig
   überall ausgeblendet - erscheint nur über die Handy-Einstellung
   "Zurück-Button zeigen" (siehe core/auth.js navSettingsHtml()). */
.side-btn[data-action="back"]{display:none}
/* Pause- und Dislike-Button: nur am Handy ausgeblendet, am PC bleiben
   sie (siehe @media min-width:1024px weiter unten). */
.side-btn[data-action="pause"],
.side-btn[data-action="dislike"]{display:none}

/* ---------- Handy-Navigationsstil (Profil-Einstellung) ----------
   Standard ("button"): der Sidebar-Button "Weiter" (und optional
   "Zurück") übernimmt die Navigation, die Streifen bleiben aus.
   "strips": die beiden alten Streifen oben/unten kommen zurück, dafür
   verschwinden die Sidebar-Buttons "Weiter"/"Zurück" (sonst doppelt).
   Gilt ausdrücklich NUR am Handy - am PC (siehe @media min-width:1024px)
   bleibt "Weiter" immer sichtbar, unabhängig von dieser Einstellung. */
/* Shop sitzt seit 2026-10-09 oben in der Karte (.karte-oben), nicht mehr in der Seitenleiste. */
.side-btn[data-action="shop"]{display:none}
@media (max-width:1023.98px){
  /* Profil-Einstellung "Pause und Dislike auch am Handy zeigen" (2026-10-09) */
  body.ps-seite-extra .side-btn[data-action="pause"],
  body.ps-seite-extra .side-btn[data-action="dislike"]{display:flex}
  /* Standard "wischen" (2026-10-09): an der Seite nur Like, Kommentar, Speichern, Teilen */
  body.ps-nav-wischen .side-btn[data-action="next"]{display:none}
  body.ps-nav-strips .side-btn[data-action="next"]{display:none}
  body.ps-nav-back:not(.ps-nav-strips) .side-btn[data-action="back"]{display:flex}
  body.ps-nav-strips #navUp,body.ps-nav-strips #navDown{display:flex}
}

/* ---------- Handy: Pfeil-Buttons statt Wischen ----------
   Bewusst KEIN Wischen/Scrollen mehr am Handy - stattdessen zwei feste,
   klar sichtbare Knöpfe. Oben (klein, ▲) geht zurück zum vorherigen
   Spiel, unten (länglich, ▼) holt ein neues Zufallsspiel. Grau/dezent,
   damit sie nicht mit dem Spielinhalt konkurrieren. Nur am Handy
   sichtbar - am PC bleibt alles wie gewohnt (Mausrad + Zufalls-Button). */
.mobile-nav-btn{
  position:fixed;left:50%;transform:translateX(-50%);z-index:44;
  display:flex;align-items:center;justify-content:center;
  /* Diese Buttons sitzen in ihrer EIGENEN Zone ueber/unter der Karte,
     nicht auf dem Spiel - ihr Grund ist die Seite. Sie gehen deshalb
     mit der Darstellung mit, statt fest hell auf dunkel zu sein. */
  background:var(--navbtn-bg);border:1px solid var(--glass-border);
  color:var(--txt-dim);
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
  box-shadow:0 2px 8px rgba(0,0,0,.18);
  transition:transform .12s ease,background .15s ease;
}
.mobile-nav-btn:active{transform:translateX(-50%) scale(.94);background:var(--navbtn-bg-aktiv)}
.mobile-nav-btn .arrow{line-height:1}
/* Beide sitzen jetzt mittig in ihrer eigenen, freien Zone (siehe
   --navbtn-top-h/--navbtn-bottom-h bei #feed) - kein Overlay mehr über
   Tastatur/Zielkreis/Hinweistext einzelner Spiele. */
#navUp{top:calc(8px + env(safe-area-inset-top));width:60px;height:28px;border-radius:999px;display:none}
#navDown{bottom:calc(var(--bottomnav-h) + 14px + env(safe-area-inset-bottom));
  width:min(260px,68vw);height:34px;border-radius:999px;display:none}
/* Beide Streifen erscheinen NUR im Handy-Einstellung "strips" (siehe
   @media max-width:1023.98px weiter oben) - Standard ist der
   Sidebar-Button "Weiter" (siehe .side-btn[data-action="next"]). */
#navUp .arrow{font-size:13px}
#navDown .arrow{font-size:15px}

/* ---------- Sheets ---------- */
#backdrop{position:fixed;inset:0;background:var(--abdunkeln);opacity:0;pointer-events:none;transition:opacity .25s ease;z-index:40}
#backdrop.open{opacity:1;pointer-events:auto}
.sheet{position:fixed;left:0;right:0;bottom:0;z-index:50;max-width:640px;margin:0 auto;background:var(--bg2);
  border:1px solid var(--glass-border);border-bottom:none;border-radius:22px 22px 0 0;height:70vh;
  display:flex;flex-direction:column;transform:translateY(105%);transition:transform .3s cubic-bezier(.2,.9,.25,1)}
.sheet.open{transform:translateY(0)}
.sheet-head{display:flex;align-items:center;justify-content:space-between;padding:16px 18px;
  border-bottom:1px solid var(--linie);font-weight:800}
.sheet-head button{font-size:18px;color:var(--txt-dim);padding:4px 8px}
.sheet-body{flex:1;overflow-y:auto;padding:14px 18px}
.sheet-body::-webkit-scrollbar{width:4px}
.sheet-body::-webkit-scrollbar-thumb{background:var(--rollbalken);border-radius:2px}
.empty{color:var(--txt-dim);text-align:center;margin-top:40px;font-size:14px}
.comment{display:flex;gap:10px;margin-bottom:16px}
.comment .av{width:36px;height:36px;border-radius:50%;flex-shrink:0;display:flex;align-items:center;justify-content:center;
  background:linear-gradient(135deg,var(--pink),var(--cyan));font-weight:800;font-size:15px}
.comment .cb .meta{font-size:12px;color:var(--txt-dim);margin-bottom:2px}
.comment .cb .tx{font-size:14px;line-height:1.4;word-break:break-word}
/* Loesch-Knopf nur bei eigenen Kommentaren (seit 1.31.0). Bewusst
   zurueckhaltend: Er soll erreichbar sein, aber nicht schreien. */
.comment{position:relative}
.comment .cm-del{flex-shrink:0;align-self:flex-start;margin-left:auto;opacity:.45;
  padding:4px;line-height:0;border-radius:8px;background:transparent}
.comment .cm-del:hover,.comment .cm-del:active{opacity:1;background:var(--glass)}
.comment .cm-del .i{width:16px;height:16px}
/* Statt Eingabefeld fuer Gaeste */
.cs-hinweis{flex:1;background:var(--glass);border:1px solid var(--glass-border);
  border-radius:999px;padding:12px 18px;color:var(--txt-dim);font-size:14px;text-align:center}
.msg-head .msg-del{margin-left:auto;opacity:.45;padding:4px;line-height:0;border-radius:8px}
.msg-head .msg-del:hover{opacity:1;background:var(--glass)}
.msg-head .msg-del .i{width:15px;height:15px}
/* ---------- Prüfliste (nur beim Betreiber sichtbar) ---------- */
.admin-eintrag{background:var(--glass);border:1px solid var(--glass-border);border-radius:12px;
  padding:10px 12px;margin-top:10px}
.admin-kopf{font-size:12px;color:var(--txt-dim);margin-bottom:4px}
.admin-grund{display:inline-block;margin-left:6px;padding:1px 6px;border-radius:999px;
  background:rgba(255,90,90,.18);color:#ff8a8a;font-size:11px}
.admin-text{font-size:14px;line-height:1.4;word-break:break-word;margin-bottom:8px}
.admin-fuss{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--txt-dim);flex-wrap:wrap}
.admin-fuss button{margin-left:auto;border-radius:999px;padding:6px 14px;font-size:13px;font-weight:700}
.admin-ok{background:var(--glass);border:1px solid var(--glass-border)}
.admin-weg,.admin-frei{background:linear-gradient(90deg,var(--pink),#ffb020);margin-left:0!important}
/* Rückgängig-Leiste nach dem Verwerfen (seit 1.34.0) */
#admin-rueck{position:fixed;left:50%;bottom:calc(78px + env(safe-area-inset-bottom));transform:translate(-50%,20px);
  display:none;align-items:center;gap:12px;z-index:300;max-width:92vw;
  background:#1b1b22;color:#fff;border:1px solid rgba(255,255,255,.14);
  border-radius:999px;padding:10px 12px 10px 18px;font-size:13px;
  box-shadow:0 10px 30px rgba(0,0,0,.45);opacity:0;transition:opacity .18s ease,transform .18s ease}
#admin-rueck.show{display:flex;opacity:1;transform:translate(-50%,0)}
#admin-rueck button{background:var(--cyan);color:#08131a;font-weight:800;
  border-radius:999px;padding:6px 14px;font-size:13px}
.sheet-form{display:flex;gap:10px;padding:12px 14px calc(12px + env(safe-area-inset-bottom));border-top:1px solid var(--linie)}
.sheet-form input{flex:1;background:var(--glass);border:1px solid var(--glass-border);border-radius:999px;
  padding:12px 18px;color:var(--txt);font-size:15px;outline:none}
.sheet-form input:focus{border-color:var(--cyan-txt)}
.sheet-form button{background:linear-gradient(90deg,var(--pink),#ffb020);border-radius:999px;padding:0 20px;font-weight:800;font-size:14px}
.saved-item{display:flex;align-items:center;gap:14px;width:100%;text-align:left;background:var(--glass);
  border:1px solid var(--glass-border);border-radius:16px;padding:14px 16px;margin-bottom:12px;transition:transform .12s ease}
.saved-item:active{transform:scale(.97)}
.saved-item .gi{font-size:30px}
.saved-item .gn{font-weight:800;font-size:16px}
.saved-item .gd{font-size:12px;color:var(--txt-dim);margin-top:2px}
.saved-item .go{margin-left:auto;color:var(--cyan-txt);font-weight:800;font-size:13px}

/* ---------- Shop ---------- */
.shop-balance{position:sticky;top:-14px;background:var(--bg2);padding:4px 0 12px;font-weight:800;color:var(--gold-txt);z-index:2}
.shop-sec{font-size:12px;font-weight:800;text-transform:uppercase;letter-spacing:1px;color:var(--txt-dim);
  margin:18px 0 8px;display:flex;align-items:center;gap:8px}
/* Wie viel von einem Abschnitt schon freigeschaltet ist. */
.shop-sec .cnt{margin-left:auto;letter-spacing:0;font-size:11px;font-weight:700;
  color:var(--cyan-txt);background:rgba(255,201,60,.12);border:1px solid rgba(255,201,60,.3);
  border-radius:999px;padding:1px 8px;text-transform:none}
.shop-note.sub{margin:-4px 0 10px}
.shop-item{display:flex;align-items:center;gap:12px;background:var(--glass);border:1px solid var(--glass-border);
  border-radius:14px;padding:10px 12px;margin-bottom:8px}
.shop-item .sw{width:34px;height:34px;border-radius:50%;flex-shrink:0;display:flex;align-items:center;justify-content:center;
  font-size:20px;border:1px solid var(--glass-border)}
.shop-item .nm{flex:1;font-weight:700;font-size:14px}
.shop-item .pr{font-weight:800;font-size:13px;color:var(--gold-txt)}
.shop-item button{padding:8px 14px;border-radius:999px;font-weight:800;font-size:12px;
  background:linear-gradient(90deg,var(--pink),#ffb020)}
.shop-item button.eq{background:rgba(255,201,60,.15);border:1px solid var(--cyan-txt);color:var(--cyan-txt)}
.shop-item button.own{background:var(--glass);border:1px solid var(--glass-border)}

/* Kopf des Spiel-Ladens, erklärende Zeilen und Verbesserungen */
.shop-head{font-size:19px;font-weight:900;letter-spacing:-.02em;padding:2px 0 2px}
.shop-note{font-size:12px;color:var(--txt-dim);line-height:1.55;margin:2px 0 10px}
.shop-note.ver{margin-top:16px;text-align:center;opacity:.6;font-size:11px}
.shop-item.perk .sw{background:rgba(255,213,74,.16);border-color:rgba(255,213,74,.5);color:var(--gold)}
.shop-item.perk .sw.bild{width:46px;height:46px;border-radius:12px;background-color:rgba(20,16,40,.6);background-repeat:no-repeat;border-color:rgba(255,213,74,.35)}
.shop-item .nm small{display:block;font-weight:500;font-size:11.5px;color:var(--txt-dim);margin-top:2px}
.shop-item .nm em{display:block;font-style:normal;font-weight:700;font-size:11px;color:var(--cyan-txt);margin-top:3px}

/* Lane Rush: große Garage statt fünf schmaler Listenzeilen. */
.vehicle-carousel{overflow:hidden;background:linear-gradient(160deg,rgba(255,255,255,.1),rgba(255,255,255,.035));border:1px solid var(--glass-border);border-radius:22px;padding:12px;margin-bottom:12px}
.vc-nav{display:grid;grid-template-columns:48px 1fr 48px;align-items:center;gap:8px}
.vc-arrow{height:44px;border-radius:13px;background:rgba(255,255,255,.08);border:1px solid var(--glass-border);font-size:32px;line-height:1;color:var(--txt)}
.vc-arrow:active{transform:scale(.92)}
.vc-title{text-align:center}.vc-title b{display:block;font-size:20px}.vc-title span{font-size:11px;color:var(--txt-dim)}
.vc-preview{height:220px;margin:10px 0 14px;border-radius:17px;display:grid;place-items:center;overflow:hidden;position:relative;background:linear-gradient(90deg,#8f432d 0 18%,#30343d 18% 82%,#8f432d 82%)}
.vc-preview:before{content:"";position:absolute;inset:0;background:linear-gradient(90deg,transparent 49%,rgba(255,255,255,.75) 49% 51%,transparent 51%);background-size:100% 54px;opacity:.55}
.vc-car{position:relative;width:92px;height:174px;filter:drop-shadow(0 14px 12px rgba(0,0,0,.5));z-index:1}
.vc-body{position:absolute;inset:7px 10px;border-radius:24px;background:var(--car-body);border:3px solid rgba(5,8,14,.85);overflow:hidden}
.vc-glass{position:absolute;left:17px;right:17px;top:29px;height:50px;background:linear-gradient(#18304a,#315675);clip-path:polygon(15% 0,85% 0,100% 100%,0 100%)}
.vc-accent{position:absolute;left:50%;top:3px;bottom:3px;width:9px;transform:translateX(-50%);background:var(--car-accent);opacity:.92}
.vc-light{position:absolute;top:8px;width:17px;height:8px;border-radius:5px;background:#fff4b0}.vc-light.l1{left:8px}.vc-light.l2{right:8px}
.vc-wheel{position:absolute;width:15px;height:38px;border-radius:6px;background:#090b10}.vc-wheel.w1{left:1px;top:25px}.vc-wheel.w2{right:1px;top:25px}.vc-wheel.w3{left:1px;bottom:24px}.vc-wheel.w4{right:1px;bottom:24px}
.vc-car.vortex{width:82px}.vc-car.vortex .vc-accent{left:17px;width:6px;box-shadow:42px 0 var(--car-accent)}
.vc-car.iron{width:106px}.vc-car.iron .vc-body{border-radius:12px;border-width:5px}.vc-car.iron .vc-accent{left:8px;right:8px;top:82px;bottom:auto;width:auto;height:16px;transform:none}
.vc-car.volt .vc-accent{width:28px;clip-path:polygon(40% 0,75% 0,52% 42%,80% 42%,25% 100%,43% 54%,18% 54%)}
.vc-car.apex{height:188px}.vc-car.apex .vc-body{border-radius:29px}.vc-car.apex .vc-accent{width:10px;box-shadow:-25px 72px 0 -2px var(--car-accent),25px 72px 0 -2px var(--car-accent)}
.vc-stats{display:grid;gap:9px}.vc-stat{display:grid;grid-template-columns:90px 34px 1fr;align-items:center;gap:8px;font-size:12px}.vc-stat>span{font-weight:750}.vc-stat>b{text-align:right;color:var(--gold-txt)}.vc-stat>i{height:10px;border-radius:999px;background:rgba(255,255,255,.09);overflow:hidden}.vc-stat>i>em{display:block;height:100%;border-radius:inherit;background:linear-gradient(90deg,var(--pink),var(--gold));box-shadow:0 0 10px rgba(255,213,74,.25)}
.vc-action{display:flex;justify-content:flex-end;align-items:center;gap:13px;margin-top:16px}.vc-action strong{color:var(--gold-txt);font-size:15px}.vc-action button{padding:10px 18px;border-radius:999px;font-weight:850;background:linear-gradient(90deg,var(--pink),#ffb020)}.vc-action button.eq{background:rgba(255,201,60,.15);border:1px solid var(--cyan-txt);color:var(--cyan-txt)}.vc-action button.own{background:rgba(255,255,255,.1);border:1px solid var(--glass-border)}

/* ---------- Willkommens-Popup ----------
   Ersetzt die frühere grosse Startkarte: kleines, zentriertes,
   graues Popup statt einer eigenen Feed-Karte. */
.ov{position:fixed;inset:0;display:none;place-items:center;padding:16px;
  background:var(--abdunkeln);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);z-index:80}
.ov.show{display:grid}
.welcome-card{width:100%;max-width:320px;text-align:center;background:var(--flaeche);
  border:1px solid var(--glass-border);border-radius:22px;padding:26px 22px;
  display:flex;flex-direction:column;gap:12px}
.welcome-card .logo.small{font-size:26px;font-weight:900;letter-spacing:.5px;
  background:linear-gradient(90deg,var(--pink),var(--cyan));
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
.welcome-card p{font-size:13px;color:var(--txt-dim);line-height:1.5;margin-bottom:4px}
/* Dieselbe Absicherung fuer die Fassung im Willkommen-Fenster - sie hat
   eigene, dezentere Farben (der Knopf ist hier bewusst grau statt golden),
   aber dieselben Anforderungen an die Ausrichtung. */
.welcome-card .code-row{display:flex;gap:8px;align-items:stretch}
.welcome-card .code-row{flex-wrap:wrap}
.welcome-card .code-row input,.welcome-card .code-row button{
  min-height:42px;line-height:1;box-sizing:border-box}
.welcome-card .code-row input{flex:1 1 140px;min-width:0}
.welcome-card .code-row button{flex:0 1 auto;min-width:0;max-width:100%;
  display:inline-flex;align-items:center;justify-content:center;
  white-space:nowrap}
.welcome-card .code-row input{flex:1;background:var(--glass);border:1px solid var(--glass-border);
  border-radius:999px;padding:11px 16px;color:var(--txt);font-size:13px;outline:none;
  text-transform:uppercase;letter-spacing:1px}
.welcome-card .code-row button{background:var(--glass);border:1px solid var(--glass-border);
  border-radius:999px;padding:0 16px;font-weight:800;font-size:12px;color:var(--txt)}

/* Aktiver Creator-Code im Profil (siehe codeToolsHtml in core/auth.js).
   Laeuft gerade einer, steht statt des Eingabefelds der Code selbst da -
   gross genug, um ihn vorlesen zu koennen. */
.code-aktiv{margin:8px 0 0;font-size:20px;font-weight:800;letter-spacing:1px;
  color:var(--gold)}

/* Weiter in style_ansichten.css, style_pc.css, style_profil.css und
   style_rangliste.css (aufgeteilt am 2026-10-10, Reihenfolge zaehlt). */

/* Fehlerliste 14.10. (Nr. 17): Handy quer - die Seitenleiste (Shop, Rangliste, Like ...) war hoeher als die Karte,
   ragte oben/unten raus und lag ueber den Spielknoepfen. Jetzt steht sie NEBEN dem Spiel und ist kompakter. */
@media (max-width:1023.98px) and (orientation:landscape) and (max-height:520px){
  .card.hat-spiel .game-stage{right:58px}
  .sidebar{right:6px;gap:6px}
  .side-btn .ic{width:34px;height:34px}
  .side-btn .ic .i{width:18px;height:18px}
  .side-btn .lb{display:none}
  .karte-oben.ko-frei{gap:6px;margin:0 0 2px;padding-bottom:6px}
  .karte-oben.ko-frei .ko-btn{width:32px;height:32px}
}
/* Testaufgaben im Spiel: Bereich „Erledigt“ (2026-10-17) */
.ta-erledigt-bereich{margin:6px 0 12px}
.ta-erledigt-bereich>summary{cursor:pointer;font-weight:800;font-size:14px;padding:8px 2px;color:var(--txt-dim)}
