/* games-703 · shared shell (Neubau #709)
   ------------------------------------------------------------------------
   THESIS: Ein Reveal ist eine Zahl, die man versteht, bevor man liest. Alles
   darunter ist eine ruhige Liste, keine Sammlung von Karten. Refused: der
   Hero-Metrik-Baukasten (grosse Zahl, Label, Stat-Kacheln, Akzent ueberall)
   und das Blatt, das hochgeschoben wird und dann einfach dasteht.
   OWN-WORLD: Weisses Blatt mit Griff, eine Schrift (Onest), drei Tinten,
   ein Akzent je Spiel aus einem Farbton gerechnet, Haarlinien statt Kaesten,
   Ziffern tabellarisch, Ecken 28/16/10.
   STORY: Der Spieler sieht sofort, wie weit er daneben lag; liest im zweiten
   Blick, was die Wahrheit ist; im dritten, wie er selbst haette rechnen
   koennen. Dann drueckt er den einen Knopf.
   FIRST VIEWPORT (Reveal): Blatt faehrt aus dem Fuss, Griff oben, die Zahl
   zaehlt in 640 ms hoch, das Richtungswort erscheint daneben, dann kommen
   die Zeilen im Abstand von 55 ms von unten: der Satz mit der Wahrheit, die
   Verteilung, der Rechenweg, der Fakt, die Quelle. Der Knopf sitzt am Fuss.
   FORM: Mobile-App-Onboarding, vom Auftraggeber gepinnt (#709); der Wurf
   c472e83b (impeccable concept-seed) tritt hinter das Pinning zurueck.
   FINISH: unreviewed and undocumented is unfinished; this build ends with
   the finish review, the verdict, DESIGN.md, and every shipping raster
   carrying its provenance.
   ------------------------------------------------------------------------
   Jedes Spiel lebt in .stage und darf dort alles. Ausserhalb von .stage
   nichts umbauen. Die Reveal-Bausteine unten sind die EINE Rangfolge; ein
   Spiel fuellt sie, keins baut sie neu. */

*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; }
html:has(body > .app), body:has(> .app) { overflow: hidden; overscroll-behavior: none; }   /* #751: Spielseiten scrollen nie; Seiten mit body.page (About/Serie/Plus) bleiben rollbar */
html[data-hero]:has(body > .app), html[data-hero] body { overscroll-behavior: auto; }
/* #787 (Esteban: im Reveal lieber scrollen als das Bild verdecken): NUR solange das Netz in game.js das Blatt nach unten
   geschoben hat, darf die Spielseite senkrecht rollen; beim naechsten Zug ist sie wieder genau ein Bildschirm (#751). */
html[data-rv-scroll]:has(body > .app) { overflow-x: hidden; overflow-y: auto; }
html[data-rv-scroll] body:has(> .app) { overflow: visible; height: auto; }
html[data-rv-scroll] .app { max-height: none !important; }   /* die Obergrenze (#751, howmany/who) gilt im Roll-Zustand nicht */   /* #758: im Landing-Hero rollt das Rad/der Finger aus dem Rahmen hinaus auf die Landing (Esteban: «man kann nicht mehr scrollen»); Rad-Eingaben der Spiele nur noch mit Ctrl/Cmd (G.wheelOwn) */
body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--t-md);
  line-height: 1.45;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-feature-settings: "tnum" 1;
  overscroll-behavior: none;
  -webkit-tap-highlight-color: transparent;
  caret-color: var(--accent);
  accent-color: var(--accent);
}
img, svg, canvas { display: block; max-width: 100%; }
button { font: inherit; color: inherit; }
a { color: inherit; }
::selection { background: var(--accent-line); color: var(--ink); }
* { scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent; }
::-webkit-scrollbar { width: 4px; height: 4px; }
::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 2px; }

/* ---- App-Rahmen -------------------------------------------------------- */
.app {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 460px;
  /* #751 (Esteban): NIE vertikal scrollen, auf keiner Bildhoehe. Vorher min-height: die App wuchs mit dem
     Inhalt und die Seite scrollte (gemessen: Where?/Where from? auf Laptop-Hoehen 560-730 px um 16-134 px).
     Jetzt ist die App genau ein Bildschirm hoch; die Buehne (flex 1, min-height 0) und ihre Kinder muessen
     schrumpfen statt die Seite zu verlaengern. Waechter: node _ops/fit751.mjs (over = 0 UND clip = 0). */
  height: 100vh;
  height: 100dvh;
  max-height: 100dvh;
  margin-inline: auto;
  padding:
    max(var(--s3), env(safe-area-inset-top))
    max(var(--s5), env(safe-area-inset-right))
    max(var(--s4), env(safe-area-inset-bottom))
    max(var(--s5), env(safe-area-inset-left));
  overflow: hidden;
}

/* ---- Topbar: Name links, Zustand rechts ------------------------------- */
/* ---- Zeile 2 = das Spiel (#760): Day N · Punkte · ‹ Archive ›. Spielname + alte Meta bleiben im DOM (Spiele haengen an
   #meta/#dayno), sind aber aus (.topbar__old). Grid mit echter Mitte, wie die Marken-Zeile darueber. */
.topbar {
  display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center;
  gap: var(--s3);
  min-height: 32px;
  flex: 0 0 auto;
}
.topbar__old, .topbar > .topbar__name { display: none !important; }
.topbar__name {
  font-size: var(--t-md);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.topbar__meta {
  display: flex; align-items: center; gap: var(--s3);
  font-size: var(--t-xs);
  font-weight: 500;
  color: var(--ink-3);
}
/* #761 (Esteban an der Klick-Seite kopf-demo761, Endstand): Tages-Zeile leise und leicht: 13 px, Gewicht 400, Tinte 3, Laufweite
   -0.02em, proportionale Ziffern; nur die ZAHL traegt 700. «Archive» dieselbe Schrift. Rechner 15 px (unten). */
.topbar__day { justify-self: start; font-size: 13px; font-weight: 400; color: var(--ink-3); letter-spacing: -0.02em; white-space: nowrap; }
/* #761 (Esteban: «die Schrift vom Tag ist komisch, die Abstaende zwischen den Nummern»): die Tagesnummer zaehlt nicht hoch, sie
   braucht keine Tabellenziffern; mit dem globalen tnum standen «2 6 3» auseinander. Proportionale Ziffern wie im Wort daneben. */
.topbar__day, .topbar__day .brandbar__day { font-variant-numeric: proportional-nums; font-feature-settings: "tnum" 0; }
.topbar__day .brandbar__day { font-weight: 700; color: inherit; }
.topbar__day[data-empty] { visibility: hidden; }   /* Everything setzt den Tag erst am Schluss: bis dahin kein einsames «Day». #765: Attribut statt :has(:empty), das Safari am Handy nach dem Setzen nicht zuverlaessig neu auswertet (Esteban: «Day» fehlte aus der Mail heraus) */
.topbar__nav { justify-self: end; display: inline-flex; align-items: center; justify-content: space-between; gap: 4px; }
.topbar__nav[hidden] { display: none; }
.topbar__arch { font-size: 13px; font-weight: 400; color: var(--ink-3); letter-spacing: -0.02em; white-space: nowrap; text-decoration: none; }   /* #761: eine Schrift mit «Day N» · #762: Link auf die Archiv-Seite */
.topbar__arch:hover, .topbar__arch:focus-visible { color: var(--ink); outline: none; }
.topbar__nav .brandbar__step { position: relative; width: 7px; height: 22px; padding: 0; font-size: 16px; color: var(--ink-3); }
.topbar__nav .brandbar__step:first-child { justify-items: start; }
.topbar__nav .brandbar__step:last-child { justify-items: end; }
.topbar__nav .brandbar__step::before { content: ""; position: absolute; inset: -6px -10px; }   /* Trefferflaeche 27 x 34 px, die Luft bleibt (Esteban #760) */
.topbar__nav a.brandbar__step:hover, .topbar__nav a.brandbar__step:focus-visible { background: transparent; color: var(--ink); }
/* Rechner (Esteban #760: «die ganze Navigation darf groesser sein»): eine Stufe hoch, die Luft rechnet game.js (G.fitNav) */
@media (min-width: 900px) {
  .brandbar, .topbar { min-height: 38px; }
  /* Groessen der Zeile 1 am Rechner stehen UNTEN nach den Grundregeln (#761: hier standen sie vor den Grundregeln und verloren
     bei gleicher Spezifitaet; Logo 22 statt 27, Konto 16 statt 19, Mond 14 statt 17 waren live so, nur die Flamme griff). */
  .brandbar__set .flame__n { font-size: var(--t-sm); }
  .topbar__day, .topbar__arch { font-size: 15px; }
  .topbar__nav .brandbar__step { width: 8px; height: 26px; font-size: 19px; }
  .pips--brand { gap: 7px; --pip: 14px; }   /* Esteban #761 */
}

/* ---- Zeile 1 = die Familie (#760, Esteban; loest #721/#725/#744 «roughly.is · More games» ab):
   roughly± (Wortmarke = Link auf alle Spiele, Plusminus huepft) · [Play with friends] · Flamme · Konto · Mond.
   Handy-first (390 px), dieselbe Zeile am Rechner. Wird von game.js autoBrand() VOR die Topbar gesetzt. */
@media (min-width: 900px) and (min-height: 700px) {
  .app { max-width: calc(var(--col, 1120px) + 48px); }   /* #831 (Esteban: «so breit wie die Navigation der Startseite»): Inhalt 1120 statt 732, nur breiter, nicht groesser */
  .dock { max-width: 460px; margin-inline: auto; width: 100%; }
  body[data-dayend] .dock { max-width: 732px; }   /* #765 (Esteban): am Tagesende so breit wie Tomorrow + Mail (game.js setzt die Marke); #831: alte Breite */
  /* #831 (Esteban: «oben das Spiel breit, unten nur das, was am Tagesende kommt, in der alten Breite»): Tagesende-Block 732 px Inhalt,
     mittig. Spiele mit Blatt (Where?, Where from?): das ganze Blatt wird wieder 780 px breit; das Spiel darueber bleibt 1120. */
  body[data-dayend] .dayend { max-width: 732px; margin-inline: auto; }
  /* #831 Regel (Esteban): breit wird nur die Spielflaeche; Text + Knoepfe bleiben in der alten Breite. Das Blatt von unten (Ergebnis
     nach jedem Tipp UND Tagesende) ist 780 px, mittig; Knoepfe darin hoechstens 460 px wie in der Knopfleiste. Landing-Held ausgenommen. */
  html:not([data-hero]) .sheet { left: 50%; right: auto; width: 780px; margin-left: -390px; }
  html:not([data-hero]) .sheet .btn { max-width: 460px; margin-inline: auto; }

}
.brandbar {
  display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center;
  gap: var(--s3); min-height: 32px; margin: 0;   /* #761 Esteban: keine Luft zur Spiel-Zeile (war 2 px) */
  flex: 0 0 auto;
  font-size: var(--t-xs); font-weight: 500; color: var(--ink-3);
}
.brandbar__mark { justify-self: start; display: inline-flex; align-items: center; color: var(--ink); text-decoration: none; position: relative; }
.brandbar__mark::before { content: ""; position: absolute; inset: -11px -10px; }   /* #761 (Esteban: «Logo am Handy manchmal nicht anklickbar»): die Wortmarke war 22 px hoch, die Trefferflaeche auch; jetzt 44 px, die Luft bleibt */
.brandbar__mark:hover, .brandbar__mark:focus-visible { color: var(--ink); outline: none; }
.brandbar__logo { height: 24px; width: auto; display: block; margin-left: calc(24px * -0.227); }   /* #761 Esteban: 24 Handy, 30 Rechner */   /* Wort «roughly» beginnt an der Spaltenkante (wie nav.css .brand__logo) */
.brandbar__logo path { transform-box: fill-box; transform-origin: center; }
.brandbar__mark:hover .brandbar__logo path, .brandbar__mark:focus-visible .brandbar__logo path { animation: brand-pm .62s var(--ease-o); }
@keyframes brand-pm { 0% { transform: translateY(0) } 28% { transform: translateY(-22%) } 58% { transform: translateY(9%) } 80% { transform: translateY(-3%) } 100% { transform: translateY(0) } }
@media (prefers-reduced-motion: reduce) { .brandbar__mark:hover .brandbar__logo path { animation: none; } }
.brandbar__mid { justify-self: center; display: inline-flex; align-items: center; }
.brandbar__mid .roombtn--lbl { height: 28px; padding: 0 11px 0 8px; gap: 6px; background: var(--paper-2); color: var(--ink-2); }
.brandbar__mid .roombtn--lbl:hover, .brandbar__mid .roombtn--lbl:focus-visible { color: var(--ink); background: var(--paper-3); }
.brandbar__mid .roombtn--lbl svg { width: 15px; height: 15px; }
/* #772 eingebettet (fremde Seite): «Play on roughly.is» ist dieselbe Pille, Pfeil rechts statt Zeichen links; ein Link, darum ohne Unterstrich */
.brandbar__mid .roombtn--out { padding: 0 9px 0 11px; gap: 5px; text-decoration: none; }
.brandbar__mid .roombtn--out svg { width: 13px; height: 13px; }
/* Rechts: gleiche TINTE-Luft (9 px) zwischen Flamme-Zahl, Konto und Mond. Die Zeichen sind kastenlos (Breite = ihr SVG),
   die Kaesten-Luft ist aus der Tinte-Messung an der Klick-Seite abgeleitet (#760: Konto 6.7 px, Mond 5.3 px).
   Trefferflaechen per ::before groesser, ohne die Luft zu aendern. */
/* #761 (Esteban: «Flamme, Konto und Mond sind nicht gleich hoch»): gemessen 15 / 11.4 / 10.9 px Tinte (die Kaesten waren
   16 / 16 / 14, aber jedes Zeichen fuellt seinen 24er-Kasten anders: Flamme 22.5 von 24 Einheiten, Konto 17.1, Mond 18.7).
   Jetzt hat jedes Zeichen dieselbe TINTE-Hoehe --ico; die Kastenhoehe folgt aus dem Fuellgrad des Zeichens. Aendert sich ein
   Zeichen, aendert man seinen Faktor hier, nichts sonst. Esteban #761 an der Klick-Seite: Handy 11 px, Rechner 14 px (unten). */
.brandbar__set { justify-self: end; display: inline-flex; align-items: center; gap: 0; --ico: 11px; }   /* Esteban #761: 11 Handy, 14 Rechner */
/* #761 (Esteban: «bei null Flammen ist der Umriss duenner als das Konto»): die Umriss-Flamme (Serie 0) bekommt in Pixeln denselben
   Strich wie Konto und Mond (2 Einheiten in deren Kasten = 2 * 1.404 / 1.067 Einheiten im Flammen-Kasten). Gefuellte Flamme unveraendert. */
.brandbar__set .flame--zero .flame__p { stroke-width: 2.63; }
.brandbar__set .flame__svg { width: calc(var(--ico) * 1.067); height: calc(var(--ico) * 1.067); flex-basis: calc(var(--ico) * 1.067); margin-top: 1px; }   /* margin: die Flammen-Tinte sitzt 0.5 px hoeher in ihrem Kasten als Konto/Mond, so liegen die Tinte-Mitten auf einer Linie */
.brandbar__set .streakbadge, .brandbar__set a.streakbadge { background: transparent; padding: 0; min-height: 26px; position: relative; }
.brandbar__set .streakbadge:hover, .brandbar__set a.streakbadge:hover { background: transparent; }
.brandbar__set .streakbadge::before { content: ""; position: absolute; inset: -6px -4px; }
.brandbar__set .flame--zero { color: var(--ink-3); }
.brandbar__acct { position: relative; display: inline-grid; place-items: center; width: calc(var(--ico) * 1.404); height: 26px; color: var(--ink-3); }
.brandbar__acct svg { width: calc(var(--ico) * 1.404); height: calc(var(--ico) * 1.404); display: block; }
.brandbar__acct::before { content: ""; position: absolute; inset: -6px -5px; }
.brandbar__acct:hover, .brandbar__acct:focus-visible { color: var(--ink); outline: none; }
.brandbar__set .themebtn { position: relative; min-width: 0; width: calc(var(--ico) * 1.284); height: 26px; padding: 0; border-radius: 6px; }
.brandbar__set .themebtn svg { width: calc(var(--ico) * 1.284); height: calc(var(--ico) * 1.284); }
.brandbar__set .themebtn::before { content: ""; position: absolute; inset: -6px -5px; }
.brandbar__set .themebtn:hover, .brandbar__set .themebtn:focus-visible { background: transparent; color: var(--ink); }
/* Rechner (Esteban #760: «die ganze Navigation darf groesser sein»): eine Stufe hoch. Steht NACH den Grundregeln (#761). */
@media (min-width: 900px) {
  .brandbar__logo { height: 30px; margin-left: calc(30px * -0.227); }
  .brandbar__mid .roombtn--lbl { height: 34px; padding: 0 14px 0 11px; font-size: var(--t-sm); gap: 7px; }
  .brandbar__mid .roombtn--lbl svg { width: 17px; height: 17px; }
  .brandbar__mid .roombtn--out { padding: 0 12px 0 14px; }
  .brandbar__mid .roombtn--out svg { width: 15px; height: 15px; }
  .brandbar__set { --ico: 14px; }
  .brandbar__acct, .brandbar__set .themebtn { height: 30px; }
}
.brandbar__day { font-variant-numeric: tabular-nums; }
/* #740: Credit-Zeile unter der Marken-Zeile (games.js credit:), leise, ein Link */
.credit { margin: 2px 0 0; flex: 0 0 auto; font-size: var(--t-xs); font-weight: 500; color: var(--ink-3); text-align: center; }
.credit a { color: inherit; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--line-strong); }
.credit a:hover, .credit a:focus-visible { color: var(--ink); text-decoration-color: var(--ink); outline: none; }
html[data-hero] .credit { display: none !important; }
/* Die fuenf Punkte in der Spiel-Zeile: doppelt so gross wie frueher in der Topbar (Esteban #725) */
.pips--brand { gap: 7px; justify-self: center; --pip: 11px; }
.pips--brand .pip { width: var(--pip); height: var(--pip); }
/* #761 (Esteban: «die Abstaende zwischen den Punkten»): der aktuelle Punkt ist per transform 1.25x gross, transform nimmt keinen
   Platz: die Luft zu seinen Nachbarn war 3.9 statt 5 px. Der Rand gleicht die halbe Vergroesserung aus, alle Luecken sind gleich. */
.pips--brand .pip[data-now] { transform: scale(1.25); margin-inline: calc(var(--pip) * .125); }
.topbar__tools { display: inline-flex; align-items: center; gap: 2px; }
.topbar__tools .langbtn, .topbar__tools .themebtn, .topbar__tools .roombtn { height: 30px; min-width: 30px; }
/* #760: die Grundform des Freunde-Knopfs gehoert HIERHER, nicht nur in room.css: room.css laedt erst beim Klick (game.js
   G.roomLoad), bis dahin zeigte der Knopf das Browser-Standard-Chrom (grauer Kasten mit Rand, Esteban: «komische Farbe»). */
.roombtn { appearance: none; border: 0; background: transparent; cursor: pointer; color: var(--ink-3); display: inline-grid; grid-auto-flow: column; align-items: center; gap: 4px; padding: 0 6px; border-radius: var(--r-full); font: inherit; font-size: var(--t-xs); font-weight: 600; }
.roombtn:hover, .roombtn:focus-visible { color: var(--ink); background: var(--paper-2); outline: none; }
.roombtn svg { display: block; }
.brandbar__step {
  display: inline-grid; place-items: center; width: 22px; height: 22px;
  border-radius: var(--r-full); color: var(--ink-3); text-decoration: none;
  font-size: 17px; line-height: 1;
  transition: color var(--d-fast) var(--ease), background var(--d-fast) var(--ease);
}
a.brandbar__step:hover, a.brandbar__step:focus-visible { color: var(--ink); background: var(--paper-2); outline: none; }
.brandbar__step[data-off] { opacity: .25; }
/* Schalter Sprache + Thema (Esteban #724), dieselbe Stille wie die Tages-Pfeile */

.themebtn, .langbtn {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  display: inline-grid; place-items: center; min-width: 26px; height: 26px; padding: 0 5px;
  border-radius: var(--r-full); color: var(--ink-3);
  font: inherit; font-size: var(--t-xs); font-weight: 600; letter-spacing: .02em;
  transition: color var(--d-fast) var(--ease), background var(--d-fast) var(--ease);
}
.themebtn:hover, .langbtn:hover, .themebtn:focus-visible, .langbtn:focus-visible { color: var(--ink); background: var(--paper-2); outline: none; }
.themebtn svg { display: block; }
/* Sprach-Menue (#725): Knopf mit Code + Winkel, Liste als kleines Blatt darunter. */
.langmenu { position: relative; display: inline-flex; }
.langbtn { grid-auto-flow: column; gap: 3px; }
.langbtn__chev { width: 10px; height: 10px; display: block; }
.langmenu__list {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 40; min-width: 150px; padding: 4px;
  background: var(--paper); border: 1px solid var(--line); border-radius: 14px;
  box-shadow: 0 10px 28px rgba(0, 0, 0, .12);
}
.langmenu__list[hidden] { display: none; }
.langmenu__item {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  display: flex; align-items: center; gap: 10px; width: 100%; min-height: 40px; padding: 0 12px;
  border-radius: 10px; font: inherit; font-size: var(--t-sm); font-weight: 500; color: var(--ink-2); text-align: left;
}
.langmenu__item:hover, .langmenu__item:focus-visible { background: var(--paper-2); color: var(--ink); outline: none; }
.langmenu__item[aria-checked="true"] { color: var(--ink); font-weight: 600; }
.langmenu__code { font-size: var(--t-xs); font-weight: 600; letter-spacing: .02em; color: var(--ink-3); min-width: 22px; }
/* Zwei Sprachen im selben HTML: nur die eine ist sichtbar (boot.js setzt <html lang>). */
html[lang="de"] [data-l="en"], html:not([lang="de"]) [data-l="de"] { display: none !important; }
/* Challenge- oder Archiv-Zeile unter der Marke */
.challenge {
  margin: var(--s2) 0 0; padding: var(--s2) var(--s4);
  border-radius: var(--r-full); background: var(--accent-soft); color: var(--accent);
  font-size: var(--t-sm); font-weight: 500; text-align: center;
  flex: 0 0 auto;
}
.challenge b { font-weight: 700; }

/* ---- roughly+ (#728): das Wort traegt den Regenbogen der zehn Spiel-Farbtoene und er LAEUFT (Esteban:
   animiert), dieselbe Bewegung wie .rb__over auf der Landing (Verlauf 200 % breit, faehrt durch, 3.2 s).
   --acl/--acc = dieselbe Formel wie --accent in tokens.css (hell/dunkel). Der Verlauf endet mit seiner
   Startfarbe, darum ist der Lauf nahtlos. */
:root { --acl: 50%; --acc: 0.17; --rb: linear-gradient(90deg, oklch(var(--acl) var(--acc) 40), oklch(var(--acl) var(--acc) 262), oklch(var(--acl) var(--acc) 150), oklch(var(--acl) var(--acc) 300), oklch(var(--acl) var(--acc) 75), oklch(var(--acl) var(--acc) 350), oklch(var(--acl) var(--acc) 235), oklch(var(--acl) var(--acc) 178), oklch(var(--acl) var(--acc) 205), oklch(var(--acl) var(--acc) 320), oklch(var(--acl) var(--acc) 40)); }
@media (prefers-color-scheme: dark) { html:not([data-theme="light"]) { --acl: 78%; --acc: 0.14; } }
html[data-theme="dark"] { --acl: 78%; --acc: 0.14; }
@media (prefers-color-scheme: dark) { html:not([data-theme="light"]) .sheet { box-shadow: 0 -1px 0 rgba(255,255,255,.05), 0 -14px 28px -12px rgba(0,0,0,.55); } }
html[data-theme="dark"] .sheet { box-shadow: 0 -1px 0 rgba(255,255,255,.05), 0 -14px 28px -12px rgba(0,0,0,.55); }
@keyframes rb-run { from { background-position: 0 0; } to { background-position: -200% 0; } }
.plus {
  font-weight: 700; white-space: nowrap;
  display: inline-block; line-height: 1.25; padding: 0 .04em .06em; margin: 0 -.04em -.06em;   /* Unterlaengen (g, y) bleiben im Farbbereich */
  background: var(--rb); background-size: 200% 100%;
  -webkit-background-clip: text; background-clip: text; color: transparent; -webkit-text-fill-color: transparent;
  animation: rb-run 3.2s linear infinite;
}
/* SUPPORTER (#737, Esteban): das Wort «Supporter» hat eine EIGENE Farbe, nicht den Regenbogen, damit sich
   die Support-Stufe ueber roughly+ hebt und das Wort einen Grund gibt, hinzuklicken (fuehrt auf plus.html#t2).
   Standard = Gold UND Silber im Wechsel (--sup, Esteban-Entscheid #737 «C ganz klar»); Gold (--sup-gold) und Silber (--sup-silver) bleiben als Alternativen. Gleiche Mechanik wie .plus
   (Verlauf im Text, langsamer Zug), bewusst langsamer als der Regenbogen: edler, nicht bunter. */
:root {
  --sup-gold: linear-gradient(90deg, oklch(66% 0.13 74), oklch(84% 0.12 90), oklch(60% 0.12 66), oklch(88% 0.10 94), oklch(70% 0.13 78), oklch(66% 0.13 74));
  --sup-silver: linear-gradient(90deg, oklch(52% 0.02 255), oklch(84% 0.01 240), oklch(44% 0.02 262), oklch(90% 0.008 245), oklch(60% 0.02 255), oklch(52% 0.02 255));
  --sup: linear-gradient(90deg, oklch(66% 0.13 74), oklch(86% 0.10 92), oklch(58% 0.02 255), oklch(88% 0.008 245), oklch(62% 0.12 68), oklch(90% 0.09 94), oklch(50% 0.02 260), oklch(84% 0.01 240), oklch(66% 0.13 74));
}
@media (prefers-color-scheme: dark) { html:not([data-theme="light"]) {
  --sup-gold: linear-gradient(90deg, oklch(80% 0.13 82), oklch(93% 0.09 95), oklch(72% 0.13 72), oklch(95% 0.07 98), oklch(84% 0.12 86), oklch(80% 0.13 82));
  --sup-silver: linear-gradient(90deg, oklch(78% 0.012 250), oklch(97% 0.005 240), oklch(66% 0.015 260), oklch(99% 0.003 245), oklch(82% 0.01 250), oklch(78% 0.012 250));
  --sup: linear-gradient(90deg, oklch(80% 0.13 82), oklch(94% 0.08 95), oklch(80% 0.012 250), oklch(98% 0.004 245), oklch(74% 0.13 72), oklch(95% 0.07 98), oklch(70% 0.015 260), oklch(96% 0.006 240), oklch(80% 0.13 82));
} }
html[data-theme="dark"] {
  --sup-gold: linear-gradient(90deg, oklch(80% 0.13 82), oklch(93% 0.09 95), oklch(72% 0.13 72), oklch(95% 0.07 98), oklch(84% 0.12 86), oklch(80% 0.13 82));
  --sup-silver: linear-gradient(90deg, oklch(78% 0.012 250), oklch(97% 0.005 240), oklch(66% 0.015 260), oklch(99% 0.003 245), oklch(82% 0.01 250), oklch(78% 0.012 250));
  --sup: linear-gradient(90deg, oklch(80% 0.13 82), oklch(94% 0.08 95), oklch(80% 0.012 250), oklch(98% 0.004 245), oklch(74% 0.13 72), oklch(95% 0.07 98), oklch(70% 0.015 260), oklch(96% 0.006 240), oklch(80% 0.13 82));
}
.sup {
  font-weight: 700; white-space: nowrap;
  display: inline-block; line-height: 1.25; padding: 0 .04em .06em; margin: 0 -.04em -.06em;
  background: var(--sup); background-size: 200% 100%;
  -webkit-background-clip: text; background-clip: text; color: transparent; -webkit-text-fill-color: transparent;
  animation: rb-run 5.5s linear infinite;
}
.sup--gold { background-image: var(--sup-gold); }
.sup--silver { background-image: var(--sup-silver); }
.sup--mix { background-image: var(--sup); }   /* = Standard, Klasse bleibt fuer die Vergleichsseite */
a.sup { text-decoration: none; }
a.sup:hover, a.sup:focus-visible { animation-duration: 2.2s; outline: none; }
@media (prefers-reduced-motion: reduce) { .sup { animation: none; } }
/* Supporter mit Wirkung (.supfx, Esteban #737: «so geil wie bei roughly+»): dieselbe Mechanik wie .plusfx,
   nur mit dem Supporter-Verlauf: Farbe in Ruhe, beim Hover Halo + schnellerer Zug, beides weich ueberblendet. */
.supfx { position: relative; display: inline-block; isolation: isolate; background: none; color: var(--ink); -webkit-text-fill-color: currentColor; animation: none; line-height: 1.25; padding: 0 .04em .06em; margin: 0 -.04em -.06em; }
.supfx .sup__ink { position: relative; opacity: 0; }
.supfx .sup__rb, .supfx .sup__rb2 {
  position: absolute; inset: 0; pointer-events: none; white-space: nowrap;
  padding: 0 .04em .06em;
  background: var(--sup); background-size: 200% 100%;
  -webkit-background-clip: text; background-clip: text; color: transparent; -webkit-text-fill-color: transparent;
  animation: rb-run 5.5s linear infinite;
}
.supfx .sup__rb2 { animation-duration: 3s; opacity: 0;   /* #737: schneller als Ruhe (5.5 s), ohne Hast */ transition: opacity .45s cubic-bezier(.5, 0, .15, 1); }
.supfx::after {
  content: ""; position: absolute; inset: -4px -10px; z-index: -1; border-radius: var(--r-full);
  background: var(--sup); background-size: 200% 100%; filter: blur(12px); opacity: 0;
  transform: scale(.35); transform-origin: center;
  animation: rb-run 5.5s linear infinite;
  transition: opacity .45s cubic-bezier(.5, 0, .15, 1), transform .45s cubic-bezier(.5, 0, .15, 1);
}
.supfx:hover::after, .supfx:focus-visible::after { opacity: .16; transform: scale(1); }   /* #737 kein Halo -> #740 (Esteban): Halo zurueck, sonst merkt man nicht, dass es klickbar ist */
html[data-theme="light"] .supfx:hover::after, html[data-theme="light"] .supfx:focus-visible::after { opacity: .11; }
.supfx:hover .sup__rb2, .supfx:focus-visible .sup__rb2 { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .supfx .sup__rb, .supfx .sup__rb2, .supfx::after { animation: none; } }
/* #740 (Esteban, Vergleichsseite _ops/_hover_review.html): kein Halo, nirgends. Verlinkte Supporter-Woerter (Namen,
   «Supporters» im Fuss, «supporters page») = W-D: in Ruhe Tinte, beim Hover faehrt Gold+Silber von links ins Wort.
   Nicht verlinkte Woerter (Titel, Kartenname) bleiben still in Gold+Silber, ohne Hover-Reaktion. */
.supfx::after, .plusfx::after { display: none; }
span.supfx:hover .sup__rb2 { opacity: 0; }
a.supfx .sup__ink { opacity: 1; }
a.supfx .sup__rb2 { display: none; }
a.supfx .sup__rb {
  -webkit-mask-image: linear-gradient(90deg, #000 0 40%, transparent 60% 100%); mask-image: linear-gradient(90deg, #000 0 40%, transparent 60% 100%);
  -webkit-mask-size: 250% 100%; mask-size: 250% 100%; -webkit-mask-position: 100% 0; mask-position: 100% 0;
  transition: -webkit-mask-position .8s cubic-bezier(.45, .05, .2, 1), mask-position .8s cubic-bezier(.45, .05, .2, 1);
}
a.supfx:hover .sup__rb, a.supfx:focus-visible .sup__rb { -webkit-mask-position: 0 0; mask-position: 0 0; }
a.supfx:focus-visible { outline: none; }
/* #779 (Esteban: «Mr_Butzemann wie die Supporter: erst beim Drueberfahren kommt die Animation»): .vipfx = dieselbe Mechanik wie
   a.supfx, mit dem VIP-Verlauf. In Ruhe Tinte, beim Hover faehrt Rot-Violett von links ins Wort. */
.vipfx { position: relative; display: inline-block; color: var(--ink); line-height: 1.25; padding: 0 .04em .06em; margin: 0 -.04em -.06em; }
.vipfx .vip__ink { position: relative; }
.vipfx .vip__rb { position: absolute; inset: 0; pointer-events: none; white-space: nowrap; padding: 0 .04em .06em;
  background: var(--vip); background-size: 200% 100%; -webkit-background-clip: text; background-clip: text; color: transparent; -webkit-text-fill-color: transparent;
  animation: rb-run 4.5s linear infinite;
  -webkit-mask-image: linear-gradient(90deg, #000 0 40%, transparent 60% 100%); mask-image: linear-gradient(90deg, #000 0 40%, transparent 60% 100%);
  -webkit-mask-size: 250% 100%; mask-size: 250% 100%; -webkit-mask-position: 100% 0; mask-position: 100% 0;
  transition: -webkit-mask-position .8s cubic-bezier(.45, .05, .2, 1), mask-position .8s cubic-bezier(.45, .05, .2, 1); }
a:hover .vipfx .vip__rb, a:focus-visible .vipfx .vip__rb, a.vipfx:hover .vip__rb { -webkit-mask-position: 0 0; mask-position: 0 0; }
@media (prefers-reduced-motion: reduce) { .vipfx .vip__rb { animation: none; } }
/* Regenbogen-Rand (Ring wie auf der Landing, hier als Linie): Flaeche in Papier, Rand im Verlauf, laeuft mit. */
.rbring {
  border: 1.5px solid transparent;
  background: linear-gradient(var(--paper), var(--paper)) padding-box, var(--rb) border-box;
  background-size: auto, 200% 100%;
  animation: rb-run 9s linear infinite;   /* Esteban #728: der Rand laeuft langsam, das Wort behaelt sein Tempo */
}
/* #774 Rang am Namen im Raum (Esteban-Entscheid; Quelle room_players.tier, SQL v10; room.js rkName). roughly+ = das «+» der
   Marke HINTER dem Namen im Regenbogen (--rb, rb-run wie .plus), Supporter = Goldrahmen um den Namen (--sup, Mechanik .rbring),
   Entwickler = «±» der Wortmarke DAVOR in Tinte (currentColor). Der Name selbst bleibt Tinte und behaelt sein Gewicht:
   der eigene Name ist fett, egal welcher Rang. Hell/dunkel ueber --rb/--sup/--paper. */
.rk { display: inline-block; max-width: 100%; vertical-align: baseline; }
.rk__mark { display: inline-block; width: .72em; height: .9em; vertical-align: -.08em; margin-right: .2em; }
.rk__plus {
  display: inline-block; font-style: normal; font-weight: 800; line-height: 1; margin-left: .2em; padding: 0 .04em .06em; margin-bottom: -.06em;   /* #779 K: gleicher Abstand wie Raute/Stern/± */
  background: var(--rb); background-size: 200% 100%;
  -webkit-background-clip: text; background-clip: text; color: transparent; -webkit-text-fill-color: transparent;
  animation: rb-run 3.2s linear infinite;
}
.rk--supporter { }   /* #779: kein Rahmen mehr (schob den Namen nach rechts); das Zeichen steht dahinter, siehe unten */
@media (prefers-reduced-motion: reduce) { .rk__plus { animation: none; } }
/* #779 VIP (Esteban: «ein Tier fuer die engsten Freunde, glaenzend violett»): eigener Verlauf --vip, tiefes Violett mit einem hellen
   Glanz, der langsam durchzieht (wie Lack). Name im Raum = violett glaenzende Schrift, keine Pille (Supporter hat den Rahmen). */
:root { --vip: linear-gradient(100deg, oklch(50% 0.21 25) 0%, oklch(55% 0.25 305) 30%, oklch(90% 0.06 340) 38%, oklch(48% 0.24 300) 46%, oklch(56% 0.23 20) 72%, oklch(48% 0.24 300) 90%, oklch(50% 0.21 25) 100%); }   /* #779 Esteban: ein Verlauf von Rot nach Violett (nicht die Mischfarbe), mit hellem Glanz */
html[data-theme="dark"] { --vip: linear-gradient(100deg, oklch(64% 0.21 25) 0%, oklch(66% 0.21 300) 30%, oklch(95% 0.04 340) 38%, oklch(66% 0.21 300) 46%, oklch(64% 0.21 25) 72%, oklch(66% 0.21 300) 90%, oklch(64% 0.21 25) 100%); }
/* #779 KENNZEICHEN K (Esteban-Entscheid, Klick-Seite _ops/kennzeichen779.html): der Name beginnt IMMER ganz links in Tinte, das
   Zeichen steht dahinter, auf der Mitte der Kleinbuchstaben. roughly+ = Regenbogen-Plus (.rk__plus), Supporter = Gold-Raute,
   VIP = Rot-Violett-Stern, Entwickler = das ± (ohne Kreis, hinter dem Namen). Die Farbe laeuft von links nach rechts (rb-run),
   die Zeichen selbst stehen still. Per CSS an den Rang-Klassen, damit jede Stelle (Raum, Konto, Duell, roughly+-Seite) es traegt. */
.rk--supporter::after, .rk--vip::after {
  content: ""; display: inline-block; width: .72em; height: .72em; margin-left: .26em; vertical-align: -.08em;
  background-size: 200% 100%; animation: rb-run 5s linear infinite;
  -webkit-mask: var(--rkm) center / contain no-repeat; mask: var(--rkm) center / contain no-repeat;
}
.rk--supporter::after { background-image: var(--sup); --rkm: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M10 1.8 18.2 10 10 18.2 1.8 10Z'/%3E%3C/svg%3E"); animation-duration: 5.5s; }
.rk--vip::after { background-image: var(--vip); --rkm: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M10 1.8l2.4 5.1 5.6.7-4.1 3.8 1.1 5.5L10 14.1l-5 2.8 1.1-5.5L2 7.6l5.6-.7z'/%3E%3C/svg%3E"); animation-duration: 4.5s; }
.rk--dev { display: inline-flex; flex-direction: row-reverse; justify-content: flex-end; align-items: center; gap: .24em; }   /* das ± steht hinter dem Namen, der Name links */
.rk--dev > .rk__mark { margin: 0; width: .6em; height: .75em; vertical-align: 0; flex: 0 0 auto; }
@media (prefers-reduced-motion: reduce) { .rk--supporter::after, .rk--vip::after { animation: none; } }
.vipw { font-weight: 700; white-space: nowrap; background: var(--vip); background-size: 200% 100%; -webkit-background-clip: text; background-clip: text; color: transparent; -webkit-text-fill-color: transparent; animation: rb-run 4.5s linear infinite; }
@media (prefers-reduced-motion: reduce) { .rk--vip, .vipw { animation: none; } }
/* #779 Geschenk-Rahmen (Esteban: «bei roughly+ der Regenbogen, bei Supporter die Supporter-Farben rund um den Bildschirmrand;
   eine einmalige Animation, danach bleibt der Rahmen stehen, bis man wegklickt»): zieht einmal im Kreis ein (dieselbe Kegel-Maske
   wie .rimrun), bleibt dann, seine Farben laufen ruhig weiter. Geht mit der Karte (data-out). */
.giftrim { position: fixed; inset: 0; z-index: 89; pointer-events: none; --sweep: 0deg; transition: opacity .5s var(--ease);
  -webkit-mask: conic-gradient(from -90deg at 50% 50%, #000 var(--sweep), transparent 0); mask: conic-gradient(from -90deg at 50% 50%, #000 var(--sweep), transparent 0); }
.giftrim[data-on] { animation: rim-sweep 2.2s cubic-bezier(.3, .1, .2, 1) forwards; }
.giftrim[data-out] { opacity: 0; }
.giftrim__ring { position: absolute; inset: 8px; border-radius: 26px; padding: 5px; display: block; background: var(--rim, var(--rb)); background-size: 200% 100%; animation: rb-run 4s linear infinite;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask-composite: exclude; }
.giftrim--plus { --rim: var(--rb); }
.giftrim--supporter { --rim: var(--sup); }
.giftrim--supporter .giftrim__ring { animation-duration: 5.5s; }
/* VIP: ein Kegel-Verlauf um den ganzen Rahmen (kein Stoss oben in der Mitte wie beim waagrechten Verlauf), zwei helle Glanzstellen
   ziehen langsam im Kreis - Lack statt Regenbogen */
@property --vga { syntax: '<angle>'; inherits: false; initial-value: 0deg; }
@keyframes vip-spin { to { --vga: 360deg; } }
.giftrim--vip .giftrim__ring { background: conic-gradient(from var(--vga), oklch(50% 0.21 25), oklch(48% 0.24 300) 25%, oklch(90% 0.06 340) 31%, oklch(48% 0.24 300) 37%, oklch(50% 0.21 25) 50%, oklch(56% 0.23 20) 58%, oklch(48% 0.24 300) 75%, oklch(90% 0.06 340) 81%, oklch(48% 0.24 300) 87%, oklch(50% 0.21 25)); background-size: auto; animation: vip-spin 7s linear infinite; }
html[data-theme="dark"] .giftrim--vip .giftrim__ring { background: conic-gradient(from var(--vga), oklch(64% 0.21 25), oklch(66% 0.21 300) 25%, oklch(95% 0.04 340) 31%, oklch(66% 0.21 300) 37%, oklch(64% 0.21 25) 50%, oklch(66% 0.21 300) 75%, oklch(95% 0.04 340) 81%, oklch(66% 0.21 300) 87%, oklch(64% 0.21 25)); }
@media (prefers-reduced-motion: reduce) { .giftrim { -webkit-mask: none; mask: none; } .giftrim[data-on] { animation: none; } .giftrim__ring { animation: none; } }
/* Das Wort ohne Regenbogen, wo schon einer im Bild ist (Esteban: nicht viermal). */
.plusq { font-weight: 700; white-space: nowrap; color: var(--ink); }
a.plus, a.plusq { text-decoration: none; }
/* roughly+ mit Wirkung (.plusfx, an einem <a> oder an einem <span>): Regenbogen in Ruhe (Variante B). Hover = Halo + schnellere Farben, beides
   WEICH: die schnelle Schicht liegt als zweite Kopie darueber und blendet ein/aus (Tempo kann man nicht
   ueberblenden, zwei Kopien schon), der Halo blendet mit. Zurueck ebenso sanft. */
.plusfx { position: relative; display: inline-block; isolation: isolate; background: none; color: var(--ink); -webkit-text-fill-color: currentColor; animation: none; line-height: 1.25; padding: 0 .04em .06em; margin: 0 -.04em -.06em; }
.plusfx .plus__ink { position: relative; opacity: 0; }
.plusfx .plus__rb, .plusfx .plus__rb2 {
  position: absolute; inset: 0; pointer-events: none; white-space: nowrap;
  padding: 0 .04em .06em;
  background: var(--rb); background-size: 200% 100%;
  -webkit-background-clip: text; background-clip: text; color: transparent; -webkit-text-fill-color: transparent;
  animation: rb-run 3.2s linear infinite;
}
/* Einfahrt wie bei der weissen Pille: dieselbe Kurve (langsamer Start, dann Zug), 1.1 s, hin und zurueck */
/* Hinein und hinaus dieselbe Kurve (0.45 s, kurzer Moment, dann Zug), damit das Weggehen so weich ist wie das
   Kommen. Der Halo waechst aus der MITTE des Worts heraus (Skalierung von 35 % auf 100 %), nicht als Flaeche. */
.plusfx .plus__rb2 { animation-duration: 1.9s; opacity: 0;   /* #737: schneller als Ruhe (3.2 s), aber nicht mehr 1.1 s */ transition: opacity .45s cubic-bezier(.5, 0, .15, 1); }
.plusfx::after {
  content: ""; position: absolute; inset: -4px -10px; z-index: -1; border-radius: var(--r-full);
  background: var(--rb); background-size: 200% 100%; filter: blur(12px); opacity: 0;
  transform: scale(.35); transform-origin: center;
  animation: rb-run 3.2s linear infinite;
  transition: opacity .45s cubic-bezier(.5, 0, .15, 1), transform .45s cubic-bezier(.5, 0, .15, 1);
}
.plusfx:hover::after, .plusfx:focus-visible::after { opacity: .16; transform: scale(1); }   /* #737 kein Halo -> #740 (Esteban): Halo zurueck */
html[data-theme="light"] .plusfx:hover::after, html[data-theme="light"] .plusfx:focus-visible::after { opacity: .11; }
.plusfx:hover .plus__rb2, .plusfx:focus-visible .plus__rb2 { opacity: 1; }
.plusfx:focus-visible { outline: none; }
/* roughly+ in Tinte (wo schon ein Regenbogen im Bild ist): Hover = der Regenbogen faehrt langsam von links
   ins Wort, wie auf der Pille «roughly+ entdecken» und in der Landing-Navigation; Verlassen = faehrt hinaus. */
a.plusq { position: relative; display: inline-block; color: var(--ink); line-height: 1.25; padding: 0 .04em .06em; margin: 0 -.04em -.06em; }
a.plusq .plusq__rb {
  position: absolute; inset: 0; pointer-events: none; white-space: nowrap; padding: 0 .04em .06em;
  background: var(--rb); background-size: 200% 100%;
  -webkit-background-clip: text; background-clip: text; color: transparent; -webkit-text-fill-color: transparent;
  animation: rb-run 3.2s linear infinite;
  -webkit-mask-image: linear-gradient(90deg, #000 0 40%, transparent 60% 100%); mask-image: linear-gradient(90deg, #000 0 40%, transparent 60% 100%);
  -webkit-mask-size: 250% 100%; mask-size: 250% 100%; -webkit-mask-position: 100% 0; mask-position: 100% 0;
  transition: -webkit-mask-position 1.1s cubic-bezier(.45, .05, .2, 1), mask-position 1.1s cubic-bezier(.45, .05, .2, 1);
}
a.plusq .plusq__ink {
  position: relative;
  -webkit-mask-image: linear-gradient(90deg, transparent 0 40%, #000 60% 100%); mask-image: linear-gradient(90deg, transparent 0 40%, #000 60% 100%);
  -webkit-mask-size: 250% 100%; mask-size: 250% 100%; -webkit-mask-position: 100% 0; mask-position: 100% 0;
  transition: -webkit-mask-position 1.1s cubic-bezier(.45, .05, .2, 1), mask-position 1.1s cubic-bezier(.45, .05, .2, 1);
}
a.plusq:hover .plusq__rb, a.plusq:focus-visible .plusq__rb, a.plusq:hover .plusq__ink, a.plusq:focus-visible .plusq__ink { -webkit-mask-position: 0 0; mask-position: 0 0; }
a.plusq:focus-visible { outline: none; }
@media (prefers-reduced-motion: reduce) { .plusfx .plus__rb, .plusfx .plus__rb2, .plusfx::after, a.plusq .plusq__rb, a.plusq .plusq__ink { transition: none; animation: none !important; } }
/* Regenbogen-Rand (Ring wie auf der Landing, hier als Linie): Flaeche in Papier, Rand im Verlauf, laeuft mit. */
/* ---- Archiv-Zeile (#728, Esteban dritte Runde: etwas groesser, schoener): eine Pille mit Regenbogen-Rand
   unter der Marken-Zeile. Datum in Tinte, Satz in Tinte 2, roughly+ laeuft. ---- */
.archline {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
  margin: var(--s3) auto 0; padding: 8px 16px 9px; width: fit-content; max-width: 100%;
  border-radius: var(--r-full); flex: 0 0 auto;
  font-size: var(--t-sm); font-weight: 500; color: var(--ink-2); line-height: 1.3; text-align: center;
}
.archline b { font-weight: 600; color: var(--ink); }
/* Zeile 2 (Esteban #728): grau, eine Stufe kleiner, das Wort bleibt am Stueck */
.archline > span { font-size: var(--t-xs); color: var(--ink-2); white-space: normal; }
.archline > span .plus { white-space: nowrap; }
/* Am gesperrten Archivtag: nur EIN Regenbogen (das Wort), die Pille bleibt still. */
.archline--quiet { background: var(--paper-2); flex-direction: row; gap: 6px; }
.archline .plus { font-size: 1.02em; }

/* ---- Archiv-Feldchen (#728, Esteban: wie die Batterie-Warnung, Spiel dahinter sichtbar, kein Schleier).
   Dritte Runde: schoener. Weiche Karte, roughly+ gross und laufend, der Weg zu roughly+ als Pille mit
   Regenbogen-Rand, «Lieber heute spielen» leise darunter. Der Rahmen faengt Tipps neben dem Feld ab. ---- */
.gate { position: fixed; inset: 0; z-index: 62; display: flex; align-items: center; justify-content: center; padding: var(--s5); }   /* #762: ueber dem «?» der Buehne (.infodot 61), das stach vorher durch die Schranke */
.gate__card {
  width: 344px; max-width: 100%; padding: var(--s6) var(--s5) var(--s5);
  background: var(--paper); border-radius: var(--r-lg);
  box-shadow: 0 0 0 1px var(--line), 0 24px 60px rgba(14, 14, 17, .22), 0 4px 14px rgba(14, 14, 17, .08);
  display: flex; flex-direction: column; align-items: center; gap: var(--s2);
  text-align: center;
  animation: gate-in var(--d-mid) var(--ease-o) both;
}
.gate__card:focus { outline: none; }
@keyframes gate-in { from { opacity: 0; transform: translateY(8px) scale(.96); } to { opacity: 1; transform: none; } }
.gate__kicker { margin: 0; font-size: var(--t-xs); font-weight: 500; color: var(--ink-3); letter-spacing: .01em; }
.gate__title { margin: 0; font-size: 2.1rem; letter-spacing: -0.035em; line-height: 1.05; }
.gate__text { margin: 2px 0 var(--s4); font-size: var(--t-md); line-height: 1.4; color: var(--ink-2); }
.gate__more {
  position: relative; overflow: hidden; isolation: isolate;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-height: 52px; padding: 0 28px; border-radius: var(--r-full);
  background: var(--ink); color: var(--paper);
  font-size: var(--t-md); font-weight: 600; text-decoration: none; cursor: pointer;
  transition: transform var(--d-fast) var(--ease);
}
/* Hover (Esteban #728): der Regenbogen faehrt langsam von links in die Pille, wie beim Abschluss-Knopf
   der Blog-Posts (Maske gleitet 1.1 s, der Verlauf laeuft darunter durch); Verlassen = Zug faehrt hinaus. */
.gate__more::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: var(--rb); background-size: 200% 100%;
  animation: rb-run 3.2s linear infinite;
  -webkit-mask-image: linear-gradient(90deg, #000 0 40%, transparent 60% 100%); mask-image: linear-gradient(90deg, #000 0 40%, transparent 60% 100%);
  -webkit-mask-size: 250% 100%; mask-size: 250% 100%;
  -webkit-mask-position: 100% 0; mask-position: 100% 0;
  transition: -webkit-mask-position 1.1s cubic-bezier(.45, .05, .2, 1), mask-position 1.1s cubic-bezier(.45, .05, .2, 1);
}
.gate__more:hover::before, .gate__more:focus-visible::before { -webkit-mask-position: 0 0; mask-position: 0 0; }
.gate__more:hover, .gate__more:focus-visible { transform: translateY(-1px); outline: none; }
.gate__more:active { transform: scale(.98); }
.gate__more .plusq { color: inherit; }
@media (prefers-reduced-motion: reduce) { .gate__more::before { animation: none; transition: none; } }
.gate__gift { display: inline-flex; align-items: center; justify-content: center; min-height: 48px; padding: 0 22px; margin: 0 0 var(--s2); border: 0; border-radius: var(--r-full); background: var(--ink); color: var(--paper); font: inherit; font-size: var(--t-md); font-weight: 600; cursor: pointer; }   /* #748: der verdiente Archivtag (Tag 14) vor dem Plus-Hinweis */
.gate__ok {
  display: inline-flex; align-items: center; justify-content: center; min-height: 40px; padding: 0 var(--s4);
  border-radius: var(--r-full); font-size: var(--t-sm); font-weight: 500; color: var(--ink-3); text-decoration: none; cursor: pointer;
}
.gate__ok:hover, .gate__ok:focus-visible { color: var(--ink); background: var(--paper-2); outline: none; }
/* #760 Streamer-Popup (Esteban): dieselbe Karte wie die Archiv-Schranke, dazu ein X und ein Schleier, der auf Klick daneben schliesst */
.gate--stream { background: rgba(14, 14, 17, .28); cursor: default; }
.gate--stream .gate__card { position: relative; }
.gate__x {
  position: absolute; top: var(--s3); right: var(--s3); width: 36px; height: 36px; border: 0; border-radius: var(--r-full);
  background: var(--paper-2); color: var(--ink-2); font: inherit; font-size: 22px; line-height: 1; cursor: pointer;
}
.gate__x:hover, .gate__x:focus-visible { color: var(--ink); outline: none; }
.gate__go { border: 0; font: inherit; font-size: var(--t-md); font-weight: 600; min-width: 220px; }
.gate__go::before { animation-duration: 6.4s; transition-duration: 2.2s; }   /* Esteban #760: der Regenbogen halb so schnell wie an der Archiv-Schranke */
.gate__go:disabled { opacity: .6; cursor: default; }
button.gate__ok { border: 0; background: transparent; font: inherit; }
/* #762 Archiv-Wand (Esteban, an der Klick-Seite entschieden): Schleier ueber der Buehne, Karte linksbuendig, Titel 700 in Tinte,
   ein Satz in Tinte-2, Knopf voll breit mit Preis, darunter zwei leise Pillen (heute spielen / alle Tage). Kein Kicker, ein roughly+. */
.gate--wall { background: rgba(14, 14, 17, .26); cursor: default; }
html[data-wall] .infodot { visibility: hidden; }
/* #767: Raum-Modus, bis der Raum-Zustand da ist (boot.js setzt es vor dem Paint, room.js nimmt es weg, sobald das Spiel laeuft):
   Buehne, Dock und Blatt unsichtbar, sonst blitzt Frage 1 auf, bevor die Lobby sie deckt. */
html[data-room-wait] .stage, html[data-room-wait] .dock, html[data-room-wait] .sheet, html[data-room-wait] .infodot { visibility: hidden; }
/* #770: waehrend der Raum-Pause tritt das Reveal-Blatt des Spiels zurueck; die Buehne bleibt stehen,
   darueber liegt das Pause-Blatt des Raums. Das Blatt bleibt im DOM (der Raum braucht seinen Weiter-Knopf). */
html[data-room-pause] .sheet, html[data-room-pause] .infodot { visibility: hidden; }   /* das «?» sitzt in einem eigenen Stapel und stach durch den Schleier */
.gate--wall .gate__card { width: 352px; padding: 26px 24px 20px; align-items: center; text-align: center; gap: 0; border-radius: 24px; box-shadow: 0 0 0 1px var(--line), 0 30px 70px -20px rgba(14, 14, 17, .45); }
.gate--wall .gate__title { font-size: 1.45rem; font-weight: 700; letter-spacing: -0.03em; line-height: 1.15; margin: 0 0 10px; color: var(--ink); }
.gate--wall .gate__title .plus { font-size: 1em; }
.gate--wall .gate__text { margin: 0 0 18px; font-size: var(--t-md); line-height: 1.4; color: var(--ink-2); }
.gate--wall .gate__gift { align-self: stretch; }
.gate--wall .gate__more { align-self: stretch; justify-content: center; min-height: 52px; }
.gate--wall .gate__links { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; width: 100%; margin: 10px 0 0; font-size: var(--t-sm); font-weight: 600; }
.gate--wall .gate__links a { display: inline-flex; align-items: center; justify-content: center; min-height: 42px; padding: 0 10px; border-radius: var(--r-full); background: var(--paper-2); color: var(--ink); font-weight: 600; font-size: var(--t-sm); text-decoration: none; white-space: nowrap; }
.gate--wall .gate__links a:hover, .gate--wall .gate__links a:focus-visible { background: var(--paper-3); color: var(--ink); outline: none; }
/* #777 (Esteban: die Karten zu simpel, Rand im Regenbogen, Flamme zurueck wie Tag 30, beim Riss ein Herzbruch).
   Die Momente tragen die Gestalt der Wand, dazu: laufender Regenbogen-Rand (.rbring, 2 px), echter Schatten mit Versatz,
   und oben ein Bild, das den Moment ERZAEHLT (elf Zeichen, sieben Tage, 24-h-Ring, die brechende Flamme). */
.gate--prompt { animation: pm-in .3s var(--ease-o) both; }
.gate--prompt .gate__card { align-items: center; text-align: center; border: 2px solid transparent; background: linear-gradient(var(--paper), var(--paper)) padding-box, var(--rb) border-box; background-size: auto, 200% 100%;box-shadow: 0 28px 64px -28px rgba(14, 14, 17, .55), 0 6px 16px -8px rgba(14, 14, 17, .18); animation: pm-card .55s var(--ease-o) both, rb-run 9s linear infinite; }
.gate--prompt .gate__title { text-wrap: balance; }
.gate--prompt .gate__text { text-wrap: pretty; }
.gate--prompt .gate__links { grid-template-columns: 1fr; }
.gate--prompt[data-out] { opacity: 0; transition: opacity .24s ease; }
@keyframes pm-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes pm-card { 0% { opacity: 0; transform: translateY(18px) scale(.94); } 60% { opacity: 1; } 100% { opacity: 1; transform: none; } }
.pmart { display: flex; align-items: center; justify-content: center; margin: 2px 0 18px; min-height: 56px; }
/* alldone: die elf Spiele leuchten nacheinander in ihrer Farbe auf */
.pmart--eleven { flex-wrap: wrap; gap: 6px; max-width: 224px; }   /* elf Zeichen = sechs + fuenf, mittig */
.pmart--eleven i { display: grid; place-items: center; width: 32px; height: 32px; border-radius: var(--r-full); background: var(--paper-2); color: var(--ink-3); animation: pm-lit .5s var(--ease-o) calc(.35s + var(--i) * .08s) both; }
.pmart--eleven svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
@keyframes pm-lit { 0% { transform: scale(.5); opacity: 0; } 55% { transform: scale(1.18); opacity: 1; background: oklch(var(--acl) var(--acc) var(--h)); color: #fff; } 100% { transform: none; opacity: 1; background: oklch(94% 0.05 var(--h)); color: oklch(var(--acl) var(--acc) var(--h)); } }
/* week: sieben Tage fuellen sich im Regenbogen, der siebte pulsiert */
.pmart--week { gap: 10px; }
.pmart--week i { width: 14px; height: 14px; border-radius: var(--r-full); background: var(--paper-3); animation: pm-day .4s var(--ease-o) calc(.3s + var(--i) * .11s) both; }
.pmart--week i:last-child { animation: pm-day .4s var(--ease-o) 1.07s both, pm-pulse 1.6s ease-in-out 1.6s infinite; }
@keyframes pm-day { 0% { transform: scale(.4); background: var(--paper-3); } 60% { transform: scale(1.35); } 100% { transform: none; background: oklch(var(--acl) var(--acc) var(--h)); } }
@keyframes pm-pulse { 0%, 100% { box-shadow: 0 0 0 0 oklch(var(--acl) var(--acc) var(--h) / .45); } 50% { box-shadow: 0 0 0 7px oklch(var(--acl) var(--acc) var(--h) / 0); } }
/* gift: der 24-h-Ring laeuft leer */
.pmart--gift { position: relative; width: 64px; height: 64px; }
.pmart--gift svg { position: absolute; inset: 0; width: 64px; height: 64px; transform: rotate(-90deg); }
.pmart--gift circle { fill: none; stroke-width: 5; stroke-linecap: round; }
.pmart__track { stroke: var(--paper-3); }
.pmart__left { stroke: oklch(var(--acl) var(--acc) 262); stroke-dasharray: 100 100; animation: pm-drain 1.8s cubic-bezier(.6, .05, .3, 1) .35s both; }
.pmart--gift b { position: relative; font-size: var(--t-sm); font-weight: 700; color: var(--ink-2); font-variant-numeric: tabular-nums; animation: pm-fade 1.8s ease .35s both; }
@keyframes pm-drain { from { stroke-dashoffset: 0; } to { stroke-dashoffset: 100; } }
@keyframes pm-fade { from { opacity: 1; } to { opacity: .35; } }
/* flame: Herzbruch. Die Flamme flackert, reisst entlang einer Zacke, die Haelften kippen auseinander und werden Asche, Rauch steigt */
.pmart--broken, .pmback { position: relative; width: 96px; height: 96px; margin: 0 auto 14px; }
.pmart--broken .flame, .pmback .flame { position: absolute; inset: 0; display: grid; place-items: center; }
.gate--prompt .pmart--broken .flame__svg, .pmback .flame__svg { width: 84px; height: 84px; flex-basis: 84px; }
.pmart--broken .flame__n, .pmback .flame__n { display: none; }
.pmart__half { position: absolute; inset: 0; }
.pmart__half--l { clip-path: polygon(0 0, 53% 0, 46% 20%, 56% 38%, 44% 56%, 55% 74%, 48% 100%, 0 100%); }
.pmart__half--r { clip-path: polygon(53% 0, 100% 0, 100% 100%, 48% 100%, 55% 74%, 44% 56%, 56% 38%, 46% 20%); }
.pmart--broken .pmart__half--l { animation: pm-flick .9s ease-in-out .3s, pm-split-l 1.1s cubic-bezier(.5, 0, .2, 1) 1.2s both; }
.pmart--broken .pmart__half--r { animation: pm-flick .9s ease-in-out .3s, pm-split-r 1.1s cubic-bezier(.5, 0, .2, 1) 1.2s both; }
@keyframes pm-flick { 0%, 100% { transform: none; } 20% { transform: scaleY(1.08) skewX(-2deg); } 45% { transform: scaleY(.9) skewX(3deg); } 70% { transform: scaleY(1.04); } }
@keyframes pm-split-l { 0% { transform: none; filter: none; opacity: 1; } 12% { transform: translateX(-1px); } 100% { transform: translate(-9px, 6px) rotate(-11deg); filter: grayscale(1) brightness(.72); opacity: .6; } }
@keyframes pm-split-r { 0% { transform: none; filter: none; opacity: 1; } 12% { transform: translateX(1px); } 100% { transform: translate(9px, 8px) rotate(12deg); filter: grayscale(1) brightness(.72); opacity: .6; } }
.pmart__smoke { position: absolute; left: 50%; top: 6px; width: 0; height: 0; }
.pmart__smoke i { position: absolute; left: -6px; top: 0; width: 12px; height: 12px; border-radius: 50%; background: var(--ink-3); filter: blur(4px); opacity: 0; animation: pm-smoke 2.4s ease-out 1.6s infinite; }
.pmart__smoke i:nth-child(2) { left: -12px; animation-delay: 2.2s; animation-duration: 2.8s; }
.pmart__smoke i:nth-child(3) { left: 2px; animation-delay: 2.7s; animation-duration: 2.6s; }
@keyframes pm-smoke { 0% { opacity: 0; transform: translate(0, 0) scale(.6); } 20% { opacity: .35; } 100% { opacity: 0; transform: translate(6px, -46px) scale(2.1); } }
.gate--prompt[data-kind="flame"] .gate__card { animation: pm-card .55s var(--ease-o) both, pm-shake .42s ease-in-out 1.25s, rb-run 9s linear infinite; }
@keyframes pm-shake { 0%, 100% { transform: none; } 25% { transform: translateX(-4px) rotate(-.4deg); } 55% { transform: translateX(3px) rotate(.3deg); } 80% { transform: translateX(-1px); } }
/* Die Feier (roughly+ holt die Flamme zurueck): Asche-Haelften fahren zusammen, Blitz, die ganze Flamme zuendet in Farbe */
.mile--back .mile__card { gap: 4px; }
.pmback { width: 132px; height: 132px; margin-bottom: 8px; }
.mile .pmback .flame__svg { width: 120px; height: 120px; flex-basis: 120px; }
.pmback .pmart__half--l { animation: pm-join-l .9s cubic-bezier(.6, 0, .2, 1) .15s both; }
.pmback .pmart__half--r { animation: pm-join-r .9s cubic-bezier(.6, 0, .2, 1) .15s both; }
.pmback__whole { position: absolute; inset: 0; animation: pm-ignite 1.3s var(--ease-o) 1s both; }
@keyframes pm-join-l { 0% { transform: translate(-16px, 10px) rotate(-14deg); filter: grayscale(1) brightness(.7); opacity: .55; } 88% { transform: none; filter: grayscale(1) brightness(.8); opacity: .9; } 100% { transform: none; filter: grayscale(1); opacity: 0; } }
@keyframes pm-join-r { 0% { transform: translate(16px, 12px) rotate(14deg); filter: grayscale(1) brightness(.7); opacity: .55; } 88% { transform: none; filter: grayscale(1) brightness(.8); opacity: .9; } 100% { transform: none; filter: grayscale(1); opacity: 0; } }
@keyframes pm-ignite { 0% { opacity: 0; transform: scale(.9); filter: grayscale(1) brightness(2.4); } 18% { opacity: 1; filter: grayscale(.4) brightness(2.2); } 45% { transform: scale(1.22) rotate(-3deg); filter: brightness(1.5) saturate(1.4); } 70% { transform: scale(.96) rotate(2deg); } 100% { opacity: 1; transform: none; filter: none; } }
.mile--back .mile__ring { animation-delay: 1.05s; }
.mile--back .mile__ring--2 { animation-delay: 1.45s !important; }
.mile--back .mile__t { animation-delay: 1.5s; }
.mile--back .mile__s { animation-delay: 1.7s; max-width: 30ch; text-wrap: balance; }
.mile--back .mile__tap { animation-delay: 2.4s; }
/* #777 Monat: 50 % ab Tag 30. In der Laufbahn eine Regenbogen-Marke an der Stufe 30 (von Anfang an sichtbar), im Meilenstein-Blatt
   ein Satz + der Kauf-Knopf in Wand-Gestalt, auf der Serie-Seite eine wartende Zeile bei der Hall. */
.path__deal { display: block; position: relative; left: 50%; transform: translateX(-50%); margin-top: 4px; width: max-content; max-width: none; padding: 2px 8px; border-radius: var(--r-full); font-size: var(--t-xs); font-weight: 700; color: var(--ink); border: 1.5px solid transparent; background: linear-gradient(var(--paper), var(--paper)) padding-box, var(--rb) border-box; background-size: auto, 200% 100%; animation: rb-run 9s linear infinite; white-space: nowrap; }
.mile__deal { margin: var(--s4) 0 0; font-size: var(--t-md); font-weight: 600; color: var(--ink); animation: mile-in .4s var(--ease-o) .8s both; }
.mile__dealgo { margin: var(--s3) 0 0; min-height: 52px; padding: 0 26px; animation: mile-in .4s var(--ease-o) .95s both; }
.halldeal { margin: var(--s4) 0 0; padding: 12px 16px; border-radius: 16px; border: 1.5px solid transparent; background: linear-gradient(var(--paper), var(--paper)) padding-box, var(--rb) border-box; background-size: auto, 200% 100%; animation: rb-run 9s linear infinite; font-weight: 600; }
.halldeal a { margin-left: 4px; font-weight: 700; }
/* #777 Konto-Momente: Willkommen (Handy und Computer verbinden sich mit der Flamme in der Mitte) und «Flamme sichern» (Flamme mit
   Schild). Gestalt der Plus-Blaetter, aber als Feier, ohne Kaufangebot. */
.accart { position: relative; display: flex; align-items: center; justify-content: center; gap: 0; margin: 2px 0 16px; height: 84px; }
.accart__flame { position: relative; display: grid; place-items: center; width: 76px; height: 76px; }
.accart__flame .flame { display: grid; place-items: center; }
.gate--acc .accart__flame .flame__svg { width: 64px; height: 64px; flex-basis: 64px; }
.accart__flame .flame__n { display: none; }
.accart__flame { animation: acc-flame .8s var(--ease-o) .15s both; }
.accart__dev { display: grid; place-items: center; width: 42px; height: 42px; border-radius: var(--r-full); background: var(--paper-2); color: var(--ink-2); animation: acc-dev .5s var(--ease-o) both; }
.accart__dev svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.accart__dev--l { animation-delay: .45s; }
.accart__dev--r { animation-delay: .55s; }
.accart__wire { position: relative; width: 38px; height: 2px; border-radius: 2px; background: var(--paper-3); overflow: hidden; }
.accart__wire::after { content: ''; position: absolute; inset: 0; background: var(--rb); background-size: 200% 100%; transform-origin: left center; animation: acc-wire .6s var(--ease-o) .75s both, rb-run 6s linear infinite; }
.accart__wire--l::after { transform-origin: right center; }
@keyframes acc-flame { 0% { opacity: 0; transform: scale(.6); } 60% { transform: scale(1.12); } 100% { opacity: 1; transform: none; } }
@keyframes acc-dev { from { opacity: 0; transform: scale(.7); } to { opacity: 1; transform: none; } }
@keyframes acc-wire { from { transform: scaleX(0); } to { transform: scaleX(1); } }
.accart--save .accart__shield { position: absolute; left: calc(50% + 14px); top: 44px; display: grid; place-items: center; width: 34px; height: 34px; border-radius: var(--r-full); background: var(--paper); box-shadow: 0 6px 14px -6px rgba(14, 14, 17, .35), 0 0 0 1px var(--line); color: oklch(var(--acl) var(--acc) 150); animation: acc-dev .5s var(--ease-o) .7s both; }
.accart--save .accart__shield svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
@media (prefers-reduced-motion: reduce) { .accart__flame, .accart__dev, .accart__wire::after, .accart__shield { animation: none !important; } }
/* #777 Runde 4 (Esteban): Knopf immer EINE Zeile; Streichpreis animiert; zwoelf Duotone-Zeichen; 24-h-Ring im Regenbogen, der
   leerlaeuft und erlischt; Woche = das eigene Spiel mit seiner Archivzahl. */
.gate--prompt .gate__more span, .gate--wall .gate__more span, .mile__dealgo span { white-space: nowrap; }
.gate--prompt .gate__more, .gate--wall .gate__more, .mile__dealgo { font-size: clamp(.92rem, 3.9vw, 1.02rem); }
.pmwas { position: relative; text-decoration: none; opacity: .62; font-weight: 600; margin: 0 .12em; }
.pmwas::after { content: ''; position: absolute; left: -2px; right: -2px; top: 52%; height: 2px; border-radius: 2px; background: currentColor; transform: scaleX(0) rotate(-8deg); transform-origin: left center; animation: pm-strike .45s var(--ease-o) .7s both; }
.pmnow { display: inline-block; font-weight: 800; animation: pm-now .5s var(--ease-o) 1.05s both; }
@keyframes pm-strike { to { transform: scaleX(1) rotate(-8deg); } }
@keyframes pm-now { 0% { opacity: 0; transform: translateY(6px) scale(.8); } 60% { transform: scale(1.15); } 100% { opacity: 1; transform: none; } }
.tier__num .pmwas { font-size: .55em; vertical-align: .3em; }
.pmart--eleven { max-width: 236px; }
.pmart--eleven i { width: 34px; height: 34px; }
.pmart--eleven svg.pk-duo { width: 22px; height: 22px; }
.pmart__mix { display: grid !important; place-items: center; }
.pmart__mix > * { transform: scale(.72); }
.pmart__left { stroke-width: 6; animation: pm-drain 2.4s cubic-bezier(.55, .05, .35, 1) 1s both, pm-dim .6s ease 3.3s both; }   /* #777: erst voll im Regenbogen, dann leer, dann erlischt er */
.pmart--gift b { display: grid; }
.pmart--gift b span { grid-area: 1 / 1; }
.pmart__h24 { animation: pm-fadeout .3s ease 3.2s both; }
.pmart__h0 { opacity: 0; color: var(--ink-3); animation: pm-fadein .3s ease 3.35s both; }
@keyframes pm-dim { 0%, 40%, 70% { opacity: 1; } 20%, 55%, 100% { opacity: 0; } }
@keyframes pm-fadeout { to { opacity: 0; } }
@keyframes pm-fadein { to { opacity: 1; } }
.pmart--fav { position: relative; flex-direction: column; gap: 6px; }
.pmart--fav i { display: grid; place-items: center; width: 64px; height: 64px; border-radius: var(--r-full); background: oklch(94% 0.05 var(--h)); color: oklch(var(--acl) var(--acc) var(--h)); animation: pm-lit .6s var(--ease-o) .3s both; --i: 0; }
.pmart--fav svg.pk-duo { width: 38px; height: 38px; }
.pmart--fav b { font-size: var(--t-sm); font-weight: 800; color: oklch(var(--acl) var(--acc) var(--h)); font-variant-numeric: tabular-nums; animation: pm-now .5s var(--ease-o) .7s both; }
.pmart--fav b::after { content: ' days'; font-weight: 600; color: var(--ink-3); }
:root[lang="de"] .pmart--fav b::after, html[lang="de"] .pmart--fav b::after { content: ' Tage'; }
@media (prefers-reduced-motion: reduce) { .pmwas::after { animation: none; transform: scaleX(1) rotate(-8deg); } .pmnow, .pmart__h24, .pmart__h0 { animation: none !important; } .pmart__h24 { opacity: 0; } .pmart__h0 { opacity: 1; } }
/* #777: Spielname mit seinem Duotone-Piktogramm im Fliesstext; Archiv-Ende zeigt das Spiel + das gespielte Datum */
.pmgame { display: inline-flex; align-items: center; gap: 3px; white-space: nowrap; color: oklch(var(--acl) var(--acc) var(--h)); }
.pmgame svg.pk-duo { width: 1.15em; height: 1.15em; flex: none; }
.pmgame b { font-weight: 700; }
.pmart--arch b::after, html[lang="de"] .pmart--arch b::after, :root[lang="de"] .pmart--arch b::after { content: none; }
.pmart--arch b { display: none; }   /* das Datum steht schon im Titel */
/* #777 (Esteban: «das Archiv-Ende muss geil animiert sein»): das ganze Archiv dieses Spiels als Raster, ein Feld je Tag. Der gespielte
   Tag leuchtet zuerst in der Farbe des Spiels, von ihm aus laeuft eine Welle, bis alle Tage da sind (so gross ist das Archiv), dann
   faehrt der Regenbogen einmal ueber alle Felder und sie bleiben leise getoent: das alles kann offen sein. */
.pmart--grid { position: relative; flex-direction: column; gap: 10px; margin-bottom: 16px; }
.pmgrid__ico { display: grid; place-items: center; width: 40px; height: 40px; border-radius: var(--r-full); background: oklch(94% 0.05 var(--h)); color: oklch(var(--acl) var(--acc) var(--h)); animation: pm-lit .5s var(--ease-o) .1s both; --i: 0; }
.pmgrid__ico svg.pk-duo { width: 24px; height: 24px; }
.pmgrid { display: grid; grid-template-columns: repeat(70, 3px); gap: 1px; }
.pmgrid i { width: 3px; height: 3px; border-radius: .5px; background: var(--line-strong); opacity: 0; transform: scale(.2); animation: pm-cell .3s var(--ease-o) calc(.6s + var(--d)) forwards; }
.pmgrid i.is-own { background: oklch(80% 0.09 var(--h)); }
.pmgrid i.is-me { background: oklch(var(--acl) var(--acc) var(--h)); opacity: 1; transform: none; border-radius: 1px; animation: pm-me 1.4s ease-in-out .35s infinite; box-shadow: 0 0 0 2px oklch(var(--acl) var(--acc) var(--h) / .3); z-index: 1; }
@keyframes pm-cell { 0% { opacity: 0; transform: scale(.2); } 60% { opacity: 1; transform: scale(1.6); } 100% { opacity: 1; transform: none; } }
@keyframes pm-me { 0%, 100% { transform: scale(1.4); } 50% { transform: scale(2.4); } }
@media (max-width: 360px) { .pmgrid { grid-template-columns: repeat(70, 2.6px); } .pmgrid i { width: 2.6px; height: 2.6px; } }
@media (prefers-reduced-motion: reduce) { .pmgrid i { animation: none !important; opacity: 1; transform: none; } }
/* #777 (Esteban): der Ausweg ist ein schlichter Textlink, keine Pille, nicht unterstrichen; der Kauf-Knopf ist der einzige Knopf */
.gate--prompt .gate__links { margin-top: 6px; }
.gate--prompt .gate__links a, .gate--prompt .gate__links a:hover, .gate--prompt .gate__links a:focus-visible { min-height: 40px; background: transparent; color: var(--ink-2); font-weight: 600; text-decoration: none; border-radius: var(--r-full); }
.gate--prompt .gate__links a:hover, .gate--prompt .gate__links a:focus-visible { color: var(--ink); }
.gate--prompt .gate__links a:focus-visible { box-shadow: 0 0 0 2px var(--line-strong); }
.scin { display: flex; flex-direction: column; align-items: stretch; gap: 10px; width: 100%; max-width: 440px; margin: 4px auto 18px; animation: pm-card .55s var(--ease-o) both; }
.scin .sc__img { border-radius: 18px; border: 2px solid transparent; background: linear-gradient(var(--paper), var(--paper)) padding-box, var(--rb) border-box; background-size: auto, 200% 100%; animation: rb-run 9s linear infinite; box-shadow: 0 18px 40px -24px rgba(14, 14, 17, .45); }
.scin--demo { position: relative; z-index: 5; padding: 0 16px; }
/* #820 Teilen-Karte in drei Gestalten (Vergleich _ops/teilen820.html). Gemeinsam: das Bild randlos oben, darunter Teilen,
   der Rueckkanal-Satz und ein leises «Nicht jetzt» (kein X an der Ecke: das X war der Reflex, 84 % schlossen damit, Median 2.2 s).
   Kein Regenbogen-Rahmen mehr um die Karte: er machte sie zur Werbe-Einblendung. */
.sc__card { position: relative; display: flex; flex-direction: column; align-items: stretch; gap: 10px; width: min(92vw, 400px); padding: 0 0 6px; border-radius: 28px; background: var(--paper); overflow: hidden; }
.sc__media { margin: 0 0 4px; line-height: 0; }
.sc__img { display: block; width: 100%; height: auto; }
.sc__card > .sc__go { align-self: stretch; margin: 0 16px; width: auto; }
.sc__card > .sc__note { margin: 2px 20px 0; }
.sc__later { align-self: center; min-height: 44px; padding: 0 20px; border: 0; background: transparent; color: var(--ink-2); font: inherit; font-size: var(--t-sm); font-weight: 600; cursor: pointer; border-radius: var(--r-full); transition: color var(--d-fast) var(--ease); }
.sc__later:hover, .sc__later:focus-visible { color: var(--ink); outline: none; }
.sc__later:focus-visible { box-shadow: 0 0 0 2px var(--line-strong); }
.sc__card:focus { outline: none; }
.sc[data-out] { opacity: 0; transition: opacity .24s ease, transform .3s var(--ease-o); }
/* Das Blatt (#820): kommt 3 s nach dem Tagesende von unten, kein Abdunkeln, die Seite darueber bleibt bedienbar. Es steht immer
   an der Unterkante und laeuft unten aus dem Bild (Esteban: «erst dann sieht es aus, als waere es eine geswiped»). Papier und
   Regenbogen-Rand liegen auf ::before, damit sie beim Flug zur Vorschau ausblenden koennen, waehrend das Bild bleibt. */
.sc--a { position: fixed; left: 50%; bottom: 0; z-index: 64; isolation: isolate; width: min(100%, 440px); margin-left: max(-50%, -220px); padding: 12px 0 calc(10px + env(safe-area-inset-bottom)); border-radius: 28px 28px 0 0; touch-action: none; cursor: grab; animation: sc-up .6s var(--ease-o) backwards; transition: transform .45s cubic-bezier(.3, 1.4, .5, 1); will-change: transform; }
.sc--a::before { content: ""; position: absolute; inset: 0 0 -40px; z-index: -1; border: 2px solid transparent; border-bottom: 0; border-radius: inherit; background: linear-gradient(var(--paper), var(--paper)) padding-box, var(--rb) border-box; background-size: auto, 200% 100%; box-shadow: 0 -18px 50px -20px rgba(14, 14, 17, .42); animation: rb-run 9s linear infinite; transition: opacity .3s ease; }
.sc--a[data-drag] { cursor: grabbing; transition: none; }
.sc--a[data-out] { opacity: 0; transition: opacity .24s ease; }
.sc--a[data-fly] { transition: none; pointer-events: none; }
.sc--a[data-fly]::before, .sc--a[data-fly] .sc__grip, .sc--a[data-fly] .sc__card > :not(.sc__media) { opacity: 0; transition: opacity .22s ease; }
/* #820 (Esteban: «waehrend sie fliegt verliert sie Schatten und Regenbogenrand»): die fliegende Karte traegt beides selbst, wie die
   Vorschau, in der sie landet. Der Ring liegt hinter dem Bild (::before), blendet beim Abflug ein; Masse bleiben gleich (kein Sprung). */
.sc--a .sc__media { position: relative; isolation: isolate; }
.sc--a .sc__media::before { content: ""; position: absolute; inset: -5px; z-index: -1; border-radius: 25px; background: var(--rb); background-size: 200% 100%; animation: rb-run 9s linear infinite; opacity: 0; transition: opacity .2s ease; }
.sc--a[data-fly] .sc__media::before { opacity: 1; }
.sc--a[data-fly] .sc__img { box-shadow: 0 0 0 1px var(--line), 0 26px 50px -18px rgba(14, 14, 17, .55); transition: box-shadow .2s ease; }
.sc--a .sc__grip { width: 44px; height: 5px; margin: 0 auto 10px; border-radius: 3px; background: var(--line-strong); cursor: grab; }
.sc--a .sc__card { width: 100%; border-radius: 0; gap: 8px; background: transparent; overflow: visible; }
.sc--a .sc__img { border-radius: 20px; box-shadow: 0 0 0 1px var(--line), 0 10px 24px -16px rgba(14, 14, 17, .4); }
@keyframes sc-up { from { transform: translateY(105%); } to { transform: none; } }
.sc--a .sc__media { margin: 0 auto 4px; width: min(calc(100% - 32px), 300px); }   /* ein halbes Blatt: das Bild kleiner, oben bleibt der Endscreen sichtbar */
@media (max-height: 760px) { .sc--a .sc__media { width: min(calc(100% - 32px), 250px); } .sc--a .sc__note { display: none; } }
/* Kopf des Blatts: drei Worte + Teilen direkt daneben (#820 R3); der Rueckkanal-Satz nur am Rechner (ruhiger am Handy) */
/* Duell-Ende (#820): Namensfeld im Blatt (kein eigenes Blatt mehr) und «Revanche live» als Link */
.sc__name { display: flex; align-items: center; gap: 10px; min-width: 0; margin: 2px 16px 0; padding: 0 8px 0 18px; min-height: 50px; border-radius: var(--r-full); background: var(--paper-2, #f3f3f6); cursor: text; }
.sc__name span { flex: 0 0 auto; font-size: var(--t-sm, .9375rem); color: var(--ink-2); white-space: nowrap; }
.sc__name input { flex: 1; min-width: 0; width: 100%; height: 46px; border: 0; background: transparent; color: var(--ink); font: inherit; font-weight: 700; outline: none; }
.sc__name input::placeholder { color: var(--ink-3); font-weight: 500; }
.sc__name:focus-within { box-shadow: 0 0 0 2px var(--line-strong); }
.sc__live { align-self: center; display: inline-flex; align-items: center; min-height: 44px; color: var(--ink); font-weight: 700; text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 4px; }
.sc__live:hover, .sc__live:focus-visible { color: var(--accent, var(--ink)); outline: none; }
.sc__top { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 0 16px 6px; }
.sc__top .sc__head.sc__head--big { font-size: clamp(1.625rem, 7.4vw, 2.125rem); letter-spacing: -.035em; }   /* #820: «Du gewinnst 3:1» gross */
.sc__top .sc__head { margin: 0; font-size: 1.3125rem; font-weight: 700; letter-spacing: -.025em; line-height: 1.15; }
.sc__card > .sc__top > .sc__go { flex: 0 0 auto; width: auto; min-height: 46px; margin: 0; padding: 0 20px; font-size: var(--t-sm, .9375rem); }
@media (max-width: 899px) { .sc--a .sc__note { display: none; } }
/* Rechner: das Blatt wird quer (Bild links gross, rechts Titel + Teilen), sonst war die Karte schmal (Esteban #820) */
@media (min-width: 900px) and (min-height: 600px) {
  .sc--a { width: 760px; margin-left: -380px; padding: 14px 0 36px; }
  .sc--a .sc__card { display: grid; grid-template-columns: 400px minmax(0, 1fr); grid-template-rows: 1fr auto auto auto auto auto auto 1fr; column-gap: 32px; row-gap: 12px; padding: 0 32px; }
  .sc--a .sc__media { grid-column: 1; grid-row: 1 / -1; width: 400px; margin: 0; }
  .sc--a .sc__top { display: contents; }
  .sc--a .sc__card > .sc__top > .sc__go { width: 100%; min-height: 52px; padding: 0 24px; font-size: var(--t-md, 1.0625rem); }
  .sc--a .sc__top .sc__head.sc__head--big { font-size: 2.5rem; }
  .sc--a .sc__head { display: block; grid-column: 2; grid-row: 2; margin: 0 0 6px; font-size: var(--t-xl, 1.75rem); font-weight: 700; letter-spacing: -.035em; line-height: 1.1; text-wrap: balance; }
  .sc--a .sc__go { grid-column: 2; grid-row: 3; margin: 0; }
  .sc--a .sc__msg { grid-column: 2; grid-row: 4; }
  .sc--a .sc__note { grid-column: 2; grid-row: 5; display: block; margin: 0; text-align: left; }
  .sc--a .sc__later { grid-column: 2; grid-row: 7; justify-self: start; padding: 0; }
  .sc--a .sc__name { grid-column: 2; grid-row: 5; margin: 0; }
  .sc--a .sc__live { grid-column: 2; grid-row: 6; justify-self: start; }
}
/* Die Vorschau (#820 R3): eine verkleinerte Kopie genau des fliegenden Bilds (Ring + Schatten wie .sc--a[data-fly] .sc__media),
   oben rechts unter der Kopfzeile, ohne Text. Das x sitzt ausserhalb der Skalierung und geht beim Hover mit. */
.scchip { position: fixed; right: max(16px, env(safe-area-inset-right)); top: 120px; z-index: 63; width: 96px; height: 96px; transition: translate .3s var(--ease-o); }
.scchip:not([data-land]) { animation: scchip-in .6s var(--ease-o) both; }
.scchip { rotate: 6deg; transition: translate .3s var(--ease-o), rotate .3s var(--ease-o); }   /* #831 (Esteban): die Vorschau haengt schraeg wie ein hingelegtes Foto */
.scchip:hover, .scchip:focus-within { translate: 0 -3px; }
.scchip:hover, .scchip:focus-within { rotate: 3deg; }
.scchip[data-out] { opacity: 0; translate: 24px 0; transition: opacity .25s ease, translate .3s var(--ease-o); }
.scchip__open { position: absolute; inset: 0; padding: 0; border: 0; background: none; cursor: pointer; border-radius: 8px; }
.scchip__open:focus-visible { outline: 2px solid var(--ink); outline-offset: 4px; }
.scchip__card { position: absolute; left: 0; top: 0; isolation: isolate; transform-origin: 0 0; }
.scchip__card::before { content: ""; position: absolute; inset: -5px; z-index: -1; border-radius: 25px; background: var(--rb); background-size: 200% 100%; animation: rb-run 9s linear infinite; }
.scchip__card img { display: block; width: 100%; height: 100%; border-radius: 20px; box-shadow: 0 0 0 1px var(--line), 0 26px 50px -18px rgba(14, 14, 17, .55); }
.scchip:hover .scchip__card img { box-shadow: 0 0 0 1px var(--line-strong), 0 34px 60px -18px rgba(14, 14, 17, .6); }
.scchip__x { position: absolute; top: -18px; left: -18px; display: grid; place-items: center; width: 44px; height: 44px; padding: 0; border: 0; background: transparent; cursor: pointer; }
.scchip[data-land] .scchip__x { animation: pm-in .3s ease .15s both; }
.scchip__x svg { width: 24px; height: 24px; padding: 5px; box-sizing: border-box; border-radius: var(--r-full); background: var(--paper); fill: none; stroke: var(--ink-2); stroke-width: 2.6; stroke-linecap: round; box-shadow: 0 2px 8px -2px rgba(14, 14, 17, .4), 0 0 0 1px var(--line); }
.scchip__x:hover svg, .scchip__x:focus-visible svg { stroke: var(--ink); }
.scchip__x:focus-visible { outline: none; }
@keyframes scchip-in { from { opacity: 0; transform: translateX(40px) scale(.8); } to { opacity: 1; transform: none; } }
@media (min-width: 600px) { .scchip { right: 24px; width: 124px; height: 124px; } }
@media (prefers-reduced-motion: reduce) { .sc--a, .scchip, .scchip[data-land] .scchip__x { animation: none; } }
.sc__row { display: flex; width: 100%; }
.sc__go { flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 10px; min-height: 52px; border: 0; border-radius: var(--r-full); background: var(--ink); color: var(--paper); font: inherit; font-size: var(--t-md); font-weight: 700; cursor: pointer; transition: transform var(--d-fast) var(--ease); }
.sc__go:hover, .sc__go:focus-visible { transform: translateY(-1px); outline: none; }
/* #783 (Esteban: «wenn man mit der Maus ueber den Teilen-Knopf geht, soll die Regenbogen-Animation kommen»): der Knopf fuellt sich mit
   dem laufenden Regenbogen (--rb, rb-run wie Rand und Plus), Schrift weiss. */
/* #788 (Esteban: «der falsche Hover - es soll der sein, der langsam von links nach rechts hineinkommt, den haben wir schon oft»):
   derselbe Zug wie .gate__more / Abschluss-Knopf der Blog-Posts: der Regenbogen laeuft unter einer Maske, die 1.1 s von links
   hereingleitet; Verlassen = er faehrt wieder hinaus. Schrift bleibt hell. */
.sc__go { position: relative; overflow: hidden; isolation: isolate; }
.sc__go::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: var(--rb); background-size: 200% 100%;
  animation: rb-run 3.2s linear infinite;
  -webkit-mask-image: linear-gradient(90deg, #000 0 40%, transparent 60% 100%); mask-image: linear-gradient(90deg, #000 0 40%, transparent 60% 100%);
  -webkit-mask-size: 250% 100%; mask-size: 250% 100%;
  -webkit-mask-position: 100% 0; mask-position: 100% 0;
  transition: -webkit-mask-position 1.1s cubic-bezier(.45, .05, .2, 1), mask-position 1.1s cubic-bezier(.45, .05, .2, 1);
}
.sc__go:hover::before, .sc__go:focus-visible::before { -webkit-mask-position: 0 0; mask-position: 0 0; }
.sc__go:hover, .sc__go:focus-visible { box-shadow: 0 12px 26px -14px rgba(14, 14, 17, .55); }
@media (prefers-reduced-motion: reduce) { .sc__go::before { animation: none; transition: none; } }
.sc__go svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.sc__next { min-height: 40px; padding: 0 16px; border: 0; background: transparent; color: var(--ink-2); font: inherit; font-weight: 600; cursor: pointer; }
.sc__next:hover, .sc__next:focus-visible { color: var(--ink); outline: none; }
.sc__msg { margin: 0; font-size: var(--t-sm); color: var(--ink-2); text-align: center; }
.sc__msg:empty { display: none; }
.sc__msg a { color: var(--ink); font-weight: 700; }
@media (prefers-reduced-motion: reduce) {
  .gate--prompt, .gate--prompt .gate__card, .pmart i, .pmart b, .pmart__left, .pmart__half, .pmart__smoke i, .pmback__whole { animation: none !important; }
  .pmart--broken .pmart__half { filter: grayscale(1) brightness(.72); opacity: .6; }
  .pmart--broken .pmart__half--l { transform: translate(-9px, 6px) rotate(-11deg); }
  .pmart--broken .pmart__half--r { transform: translate(9px, 8px) rotate(12deg); }
  .pmback .pmart__half { display: none; }
  .pmart--week i { background: oklch(var(--acl) var(--acc) var(--h)); }
  .pmart__left { stroke-dashoffset: 100; }
}

/* ---- Werkzeugzeile ------------------------------------------------------ */
.tools {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s3); width: 100%;
  padding-bottom: var(--s3);
}
.tools:empty { display: none; }
.tools > :only-child { margin-inline: auto; }

/* ---- Nochmal spielen ---------------------------------------------------- */
.replay {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  display: grid; place-items: center;
  width: 32px; height: 32px; margin-right: -6px;
  border-radius: var(--r-full);
  color: var(--ink-3);
  transition: color var(--d-fast) var(--ease), background var(--d-fast) var(--ease);
}
.replay:hover, .replay:focus-visible { color: var(--ink); background: var(--paper-2); outline: none; }
.replay:active { transform: rotate(-90deg); transition: transform var(--d-mid) var(--ease-o); }

/* ---- Fortschritt: Punkte ---------------------------------------------- */
.pips { display: flex; gap: 5px; }
.pip {
  width: 6px; height: 6px; border-radius: var(--r-full);
  background: var(--paper-3);
  transition: background var(--d-fast) var(--ease), transform var(--d-fast) var(--ease);
}
.pip[data-on]  { background: var(--line-strong); }
.pip[data-now] { background: var(--accent); transform: scale(1.4); }
/* #725: Abschluss = Aufblitzen im Akzent + Ring, der nach aussen laeuft; der naechste Punkt federt herein */
.pip { position: relative; }
.pip[data-done] { animation: pipdone .55s var(--ease) both; }
.pip[data-done]::after {
  content: ""; position: absolute; inset: -2px; border-radius: inherit;
  border: 2px solid var(--accent); opacity: 0; animation: pipring .7s cubic-bezier(.2, .7, .2, 1) both;
}
.pip[data-enter] { animation: pipenter .5s cubic-bezier(.2, 1.2, .3, 1.4) both; }
@keyframes pipdone { 0% { background: var(--accent); transform: scale(1.4); } 45% { background: var(--accent); transform: scale(1.9); } 100% { background: var(--line-strong); transform: scale(1); } }
@keyframes pipring { 0% { opacity: .9; transform: scale(1); } 100% { opacity: 0; transform: scale(3.2); } }
@keyframes pipenter { 0% { transform: scale(.4); opacity: .4; } 100% { transform: scale(1.4); opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .pip[data-done], .pip[data-done]::after, .pip[data-enter] { animation: none; } }

/* ---- Buehne ------------------------------------------------------------ */
.stage {
  position: relative;
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: var(--s4);
  min-height: 0;
  padding-block: var(--s4);
}
.stage > .play { flex: 1 1 auto; width: 100%; min-height: 0; }

/* ---- Prompt: EIN kurzer Satz ------------------------------------------- */
.prompt {
  flex: 0 0 auto;
  text-align: center;
  font-size: var(--t-lg);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.25;
  text-wrap: balance;
  max-width: 24ch;
  margin-inline: auto;
}
.prompt small {
  display: block;
  margin-top: var(--s1);
  font-size: var(--t-sm);
  font-weight: 400;
  letter-spacing: 0;
  color: var(--ink-3);
}

/* #742 (Esteban): der gestufte Formel-Satz (G.satz in game.js): Spielname in der Spielfarbe, «, roughly, is»
   leise und kleiner, der Rest normal. Im Landing-Hero bleibt der Satz ungestuft (dort #737 abgenommen). */
.prompt.satz { max-width: 100%; min-width: 0; width: 100%; }   /* die Formel nutzt die volle Buehnenbreite */
html:not([data-hero]) .prompt .satz__name { display: block; color: var(--accent); font-weight: 700; font-size: 1.45em; line-height: 1.05; letter-spacing: -0.03em; margin-bottom: .14em; }
html:not([data-hero]) .prompt .satz__mid  { color: var(--ink); font-weight: 600; }   /* #843 (Esteban: «so grau und kleiner ... gleich Schrift wie das schwarze, cleaner»): «roughly, is» liest wie der Rest des Satzes, alle Spiele */
html:not([data-hero]) .prompt .satz__rest { color: var(--ink); font-weight: 600; }
html:not([data-hero]) .prompt .satz__line { display: block; font-size: .88em; line-height: 1.25; text-wrap: balance; }   /* feste Groesse, kein Pressen; zu lang = Umbruch in derselben Groesse */
html:not([data-hero]) .prompt .satz__sub  { display: block; margin-top: .3em; color: var(--ink-2); font-weight: 500; font-size: .88em; letter-spacing: -0.01em; text-wrap: balance; }
/* ---- Die eine grosse Zahl --------------------------------------------- */
.mega {
  font-size: var(--t-mega);
  font-weight: 700;
  letter-spacing: var(--tight);
  line-height: .95;
  font-variant-numeric: tabular-nums;
}
.unit { font-size: .32em; font-weight: 500; color: var(--ink-2); letter-spacing: 0; }

/* ---- Dock: genau EIN Primaerknopf ------------------------------------- */
.dock {
  position: relative;
  z-index: 10;
  flex: 0 0 auto;
  display: flex; flex-direction: column; gap: var(--s2);
  padding-top: var(--s3);
}
[hidden] { display: none !important; }

.btn {
  appearance: none; border: 0; cursor: pointer;
  min-height: 52px;
  padding: var(--s3) var(--s5);
  border-radius: var(--r-full);
  background: var(--accent); color: var(--accent-ink);
  font-size: var(--t-md); font-weight: 600; letter-spacing: -0.01em;
  transition: transform var(--d-fast) var(--ease), opacity var(--d-fast) var(--ease),
              background var(--d-fast) var(--ease);
}
.btn:active { transform: scale(.98); }
.btn:disabled { opacity: .35; pointer-events: none; }
.btn--ghost {
  background: transparent; color: var(--ink-2);
  font-weight: 500; min-height: 44px; padding: var(--s2) var(--s4);
}
.btn--quiet { background: var(--paper-2); color: var(--ink); }
:where(.btn, .share, .hintbtn, .numfield, .replay):focus-visible {
  outline: 2px solid var(--accent); outline-offset: 3px;
}

/* ---- Info je Ding (#751, Stand Runde 10) -------------------------------
   Punkt «?» exakt an der rechten oberen Ecke der Zeichnung (fixed, Treffflaeche
   48 px). Desktop: Papier-Karte haengt am Punkt, oeffnet nach rechts. Handy: das
   Bild schrumpft nach oben, die Karte liegt als Auflage eng darunter (Nase zum
   «?»), Frage und Spielflaeche bleiben stehen. Nichts steht im Fluss. */
.infoname { cursor: help; outline: none; text-decoration: none; }
.infoname:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }
.infopict { cursor: help; }
.infodot {
  appearance: none; position: fixed; z-index: 61; transform: translate(-50%, -50%);
  width: 20px; height: 20px; padding: 0; border-radius: 50%; cursor: help;
  display: grid; place-items: center;
  background: var(--paper); color: var(--ink-2); border: 1.5px solid var(--ink-3);
  font: 700 12px/1 var(--font); letter-spacing: 0; box-shadow: 0 0 0 2px var(--paper);
  transition: color var(--d-fast) var(--ease), background var(--d-fast) var(--ease), border-color var(--d-fast) var(--ease);
}
.infodot::before { content: ''; position: absolute; inset: -14px; border-radius: 50%; }
.infodot:hover, .infodot[data-on] { background: var(--ink); color: var(--paper); border-color: var(--ink); }
/* die reservierte Zeile (Handy): genau zwei Zeilen, immer gleich hoch, mittig unter der Frage */
/* Desktop-Karte */
.infobubble {
  position: fixed; z-index: 60; box-sizing: border-box;
  width: max-content; max-width: min(36ch, calc(100vw - 24px));
  padding: .7em .95em; border-radius: var(--r-md);
  background: var(--paper); color: var(--ink); border: 1px solid var(--line); box-shadow: var(--shadow-2);
  font-size: var(--t-sm); font-weight: 500; line-height: 1.4; letter-spacing: 0;
  text-align: left; text-wrap: pretty; pointer-events: none;
  opacity: 0; transform: scale(.97); transform-origin: 0 0; transition: opacity var(--d-fast) var(--ease), transform var(--d-fast) var(--ease);
}
.infobubble[data-on] { opacity: 1; transform: none; }
.infobubble[data-seite="pin"] { border-top-left-radius: 6px; }   /* haengt am «?» wie an einem Pin */
/* Handy (Runde 10): Auflage eng unter dem geschrumpften Bild, mittig, Nase oben zum «?» */
.infobubble[data-seite="handy"] { text-align: center; text-wrap: balance; transform-origin: 50% 0; }
.infobubble[data-seite="handy"]::before {
  content: ''; position: absolute; top: -6px; left: var(--nase, 80%); width: 11px; height: 11px;
  transform: rotate(45deg); background: var(--paper); border-left: 1px solid var(--line); border-top: 1px solid var(--line); border-radius: 2px;
}
/* #768: dieselbe Blase, aber die Nase zeigt nach UNTEN - wenn unter dem «?»
   kein Platz mehr ist, steht die Blase darueber. */
.infobubble[data-seite="oben"] { text-align: center; text-wrap: balance; transform-origin: 50% 100%; }
.infobubble[data-seite="oben"]::after {
  content: ''; position: absolute; bottom: -6px; left: var(--nase, 80%); width: 11px; height: 11px;
  transform: rotate(45deg); background: var(--paper); border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); border-radius: 2px;
}
.infopict { will-change: transform; }
.infobubble[data-seite="unten"] { text-align: center; text-wrap: balance; }   /* Spiele ohne eigenes Bild: mittig, ohne Nase */
html[data-hero] .infoname { cursor: default; }
html[data-hero] .infodot, html[data-hero] .infobubble { display: none; }   /* die Landing bleibt, wie sie ist */

/* ======================================================================
   DAS BLATT (Reveal-Sheet): faehrt aus dem Fuss, traegt einen Griff
   ====================================================================== */
.sheet {
  position: absolute; top: auto; right: 0; bottom: 0; left: 0; z-index: 20;
  padding: var(--s6) var(--s5) max(var(--s5), env(safe-area-inset-bottom));
  background: var(--paper);
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  /* #737 (Paul): der Schatten bleibt innerhalb der Blatt-Breite (negativer Spread), sonst schneidet ihn
     die Buehne am Rand ab und das Blatt sieht wie ein abgeschnittener Kasten aus. */
  box-shadow: 0 -1px 0 rgba(14,14,17,.04), 0 -14px 28px -12px rgba(14,14,17,.16);
  transform: translateY(102%);
  transition: transform var(--d-slow) var(--ease-o);
}
.sheet[data-open] { transform: translateY(0); }
/* Der Griff: sagt "das ist ein Blatt, das kam von unten". #737 (Paul, Desktop): NUR auf Touch-Geraeten.
   Mit der Maus verspricht der Balken ein Ziehen, das es nicht gibt ("Drawer, aber nicht interaktiv"). */
@media (pointer: coarse) {
  .sheet::after {
    content: ""; position: absolute; top: 10px; left: 50%;
    width: 36px; height: 5px; margin-left: -18px;
    border-radius: var(--r-full); background: var(--line);
  }
}

/* ---- Gestaffelter Auftritt der Zeilen ----------------------------------
   Die Zeilen kommen NACH dem Blatt, im Abstand von 55 ms, 10 px von unten.
   Ohne JS, ohne Eingriff ins Spiel. Bloecke mit [data-stage] steuern ihren
   Auftritt selbst (WHERE) und werden hier uebersprungen. */
.sheet[data-open] > :not(.sheet__scroll, .sheet__body, .sheet__fade, .sheet__foot, [data-stage], [hidden]),
.sheet[data-open] :is(.sheet__scroll, .sheet__body, #roundBlock, #doneBlock) > :not([data-stage], [hidden]) {
  animation: rv-in 460ms var(--ease-o) both;
  animation-delay: calc(140ms + var(--rv-i, 0) * 55ms);
}
.sheet[data-open] :nth-child(1) { --rv-i: 0; }
.sheet[data-open] :nth-child(2) { --rv-i: 1; }
.sheet[data-open] :nth-child(3) { --rv-i: 2; }
.sheet[data-open] :nth-child(4) { --rv-i: 3; }
.sheet[data-open] :nth-child(5) { --rv-i: 4; }
.sheet[data-open] :nth-child(6) { --rv-i: 5; }
.sheet[data-open] :nth-child(7) { --rv-i: 6; }
.sheet[data-open] :nth-child(8) { --rv-i: 7; }
.sheet[data-open] :nth-child(9) { --rv-i: 8; }
.sheet[data-open] :nth-child(n+10) { --rv-i: 9; }
@keyframes rv-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

/* ======================================================================
   DIE RANGFOLGE IM BLATT (Squint-Test: man sieht genau EINS, die Zahl)
     1  .factor        die Zahl mit dem Wort daneben
     2  der Satz       .sheet__verdict / .said / .sheet__line / .rv__truth
     3  .beat + .dist  wo man unter den anderen liegt, mit Kurve
     4  .napkin        der Rechenweg, als Zeile, ohne Kasten
     5  .sheet__fact   der Fakt, leiser
     6  .sheet__src    die Quelle, eine tippbare Zeile
   FARB-REGEL: Text nur in --ink / --ink-2 / --ink-3. Der Akzent gehoert
   im Blatt genau EINER Sache: der eigenen Marke in der Kurve.
   ====================================================================== */

/* 1 · Die Zahl. */
.factor {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 0 var(--s3);
  margin: 0 0 var(--s2);
  font-size: var(--t-mega); font-weight: 700; letter-spacing: var(--tight);
  line-height: .95; font-variant-numeric: tabular-nums;
  color: var(--ink);
}
/* Unter der Zahl gibt es GENAU EINE Textbehandlung: 17 px, normal, Tinte 2.
   Kein Fett im Satz, keine zweite Groesse, keine Farbe. Die Hierarchie ist
   der Sprung von der Zahl zum Rest, nichts sonst (Esteban #709). */
.factor__dir, .sheet__verdict, .said, .sheet__line, .rv__truth, .truthline, .belong,
.sg-said, .crowdline, .beat, .sheet__fact, .napkin, .introline {
  font-size: var(--t-md); font-weight: 400; letter-spacing: 0; line-height: 1.4;
  color: var(--ink-2); text-wrap: pretty;
}
/* Das Urteil ist die eine Zeile in voller Tinte. */
.sheet__verdict, .rv__truth, .truthline { color: var(--ink); font-weight: 500; }
/* Der Fakt-Absatz ist aus dem Blatt raus (Esteban #709): die Quelle ist ein
   Link mit dem Artikelnamen, wer mehr will, tippt. */
.sheet__fact { display: none; }
:is(.sheet__verdict, .said, .sheet__line, .rv__truth, .belong, .sg-said, .beat, .napkin) b {
  font-weight: 400; color: inherit;
}
.factor--spot { color: var(--good); }
.factor--spot .factor__dir { color: var(--good); }

/* 2 · Der Satz: die eigene Antwort neben der Wahrheit. */
.sheet__verdict, .said, .sheet__line, .rv__truth, .truthline, .belong, .sg-said, .crowdline {
  margin: 0 0 var(--s2);
}

/* 3 · Die Einordnung und die Kurve. */
.beat { margin: 0; font-variant-numeric: tabular-nums; }
.dist { position: relative; width: 100%; margin: var(--s3) 0 var(--s4); }
/* #768: die Kurve rechnet in Pixeln (1 Einheit = 1 px) und setzt width/height
   selbst. Kein `preserveAspectRatio: none` mehr - das zog die Striche in die
   Breite, und auf dem Rechner war die 0.7-px-Kontur ein ungleicher Faden. */
.dist__svg { width: 100%; height: auto; display: block; overflow: visible; }
.dist__area { fill: var(--accent-soft); stroke: var(--accent-line); stroke-width: 1.2; stroke-linejoin: round; }
/* #768 Runde 2: zwei weitere Gestalten derselben Zahlen (Wahl per [data-kurve]).
   SCHWARM: jeder echte Tipp ein Punkt, die Stapelhoehe IST die Anzahl.
   KAMM: ein Haarstrich je Tipp, die glatte Flaeche steht nur noch als Schatten
   dahinter, damit man die Form erkennt und trotzdem die Luecken sieht. */
.dist__schwarm circle { fill: var(--accent); opacity: .32; }
.dist__kamm line { stroke: var(--accent); stroke-width: .8; opacity: .45; }
.dist__ghost { fill: var(--accent-soft); stroke: none; opacity: .55; }
.dist__base { stroke: var(--line); stroke-width: 1; }
/* #803 HUEGEL (Vorgabe): weiche Dichte mit Verlauf, die Strecke zwischen Tipp und Wahrheit ist dichter getoent
   und ihre Kante kraeftiger, der eigene Tipp ein Punkt auf der Kurve. Woerter stehen UEBER dem Bild an den Stielen. */
.dist__st1 { stop-color: var(--accent); stop-opacity: .2; }
.dist__st0 { stop-color: var(--accent); stop-opacity: .03; }
.dist__gap { fill: var(--accent); opacity: .16; }
.dist__edge { fill: none; stroke: var(--accent-line); stroke-width: 1.5; stroke-linejoin: round; stroke-linecap: round; }
.dist__edge.is-gap { stroke: var(--accent); stroke-width: 2; }
.dist__fig--huegel .dist__base { stroke: var(--line-strong); }
.dist__fig--huegel .dist__truth { stroke-width: 1.5; }
.dist__fig--huegel .dist__mine { stroke-width: 1.25; stroke-dasharray: 3 2.5; }
.dist__dot { fill: var(--accent); stroke: var(--paper); stroke-width: 2.5; paint-order: stroke; }
.dist__dot.is-spot { fill: var(--good); }
.dist__fig--huegel.is-spot .dist__mark.is-mine,
.dist__fig--huegel.is-spot .dist__mark.is-mine b { color: var(--good); }
/* Woerter oben: die erste Zeile sitzt direkt ueber dem Bild, eine ausweichende Marke steigt EINE Zeile hoeher
   und zieht ihren Stiel als Haarlinie mit. */
.dist__fig--huegel .dist__marks { margin: 0 0 3px; }
.dist__fig--huegel .dist__marks:has(.is-row2) .dist__mark { top: 1.25em; }
.dist__fig--huegel .dist__marks:has(.is-row2) .dist__mark.is-row2 { top: 0; }
.dist__fig--huegel .dist__mark.is-row2::after {
  content: ""; position: absolute; top: 100%; height: 1.4em; width: 1px;
  left: var(--stiel, 50%); background: currentColor; opacity: .5;
}
/* Auftritt: der Huegel waechst aus der Grundlinie, danach setzen sich Punkt und Woerter. Einmal je Runde. */
.dist__fig--huegel.is-anim .dist__hill {
  transform-box: fill-box; transform-origin: 50% 100%;
  animation: dist-grow 720ms var(--ease-o) 260ms both;
}
.dist__fig--huegel.is-anim :is(.dist__dot, .dist__mine, .dist__truth, .dist__mark) {
  animation: dist-set 360ms var(--ease-o) 760ms both;
}
@keyframes dist-grow { from { transform: scaleY(0); } to { transform: none; } }
@keyframes dist-set { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .dist__fig--huegel.is-anim :is(.dist__hill, .dist__dot, .dist__mine, .dist__truth, .dist__mark) { animation: none; }
}
/* #768 Runde 3 (Esteban: «die Linien sind da total zu dick»). 1.75 px war der
   Ausgleich fuer die alte, in die Breite gezogene Zeichnung; seit die Kurve in
   echten Pixeln rechnet, braucht es das nicht mehr. Die Wahrheit bleibt eine
   Spur kraeftiger als die eigene Marke - sie ist der Anker. */
.dist__truth { stroke: var(--ink); stroke-width: 1.15; }
.dist__mine  { stroke: var(--accent); stroke-width: 1; stroke-dasharray: 2.6 2.2; }
/* #770: der Strich eines Mitspielers. Duenn und grau, damit Wahrheit (Tinte) und ich (Spielfarbe) lesbar bleiben. */
.dist__peer  { stroke: var(--line-strong); stroke-width: 1; }
/* Die Spange unter der Grundlinie: der Abstand zwischen Tipp und Wahrheit als
   Strecke. Sie erklaert den Faktor, ohne ihn ein zweites Mal hinzuschreiben. */
.dist__span { fill: none; stroke: var(--line-strong); stroke-width: .8; }

/* Die zwei Marken-Woerter ueber der Kurve. «real 73 m» / «you 318 m»: erst das
   Wort, dann die Zahl - vorher stand da «73» und «you 270», und niemand wusste,
   welche der beiden Zahlen die Wahrheit ist. */
.dist__marks { position: relative; height: 1.45em; margin-bottom: 2px; font-size: var(--t-xs); }
.dist__mark {
  position: absolute; top: 0; transform: translateX(-50%);
  white-space: nowrap; font-variant-numeric: tabular-nums;
  color: var(--ink-2); line-height: 1.2;
}
.dist__mark b { font-weight: 600; margin-right: .35em; }
.dist__mark.is-truth { color: var(--ink); }
.dist__mark.is-truth b { color: var(--ink); }
.dist__mark.is-mine { color: var(--accent); }
.dist__mark.is-mine b { color: var(--accent); }
/* #770: die Mitspieler im Raum. Leiser als Wahrheit und eigene Marke: sie sind der Vergleich,
   nicht die Aussage. Der Strich steht auf der Kurve, der Name darueber. */
.dist__mark.is-peer { color: var(--ink-3); }
.dist__mark.is-peer b { font-weight: 500; margin-right: 0; }
/* Weicht die eigene Marke aus, faellt sie eine Zeile tiefer; die Hoehe ist
   immer reserviert, damit beim Oeffnen des Blatts nichts springt. */
.dist__marks:has(.is-row2) { height: 2.7em; }
.dist__mark.is-row2 { top: 1.25em; }
@media (min-width: 900px) { .dist__marks { font-size: var(--t-sm); } }
/* Zwei Zeilen Platz: die eigene Marke weicht in die zweite, wenn sie sonst
   auf einer Quantil-Marke laege. Die Hoehe ist immer da, damit nichts springt. */
.dist__axis { position: relative; height: 2.4em; margin-top: 4px; }
.dist__tick {
  position: absolute; transform: translateX(-50%);
  font-size: var(--t-xs); color: var(--ink-3);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.dist__tick.is-truth, .dist__tick.is-mine { color: var(--ink-2); }
.dist__tick.is-row2 { top: 1.15em; }
.dist__note { display: none; }   /* kein Simulations-Hinweis (Esteban #709) */

/* 4 · Der Rechenweg: eine Zeile mit Haarlinie darueber, kein Kasten. */
.napkin { display: none; }   /* der Rechenweg ist aus dem Blatt raus (Esteban #709) */
.napkin__label { display: none; }

/* 5 · Der Fakt: leiser, derselbe Rhythmus. */
.sheet__fact { margin: 0; padding: var(--s2) 0 var(--s3); }
.napkin + .sheet__fact { padding-top: 0; }

/* 6 · Die Quelle: eine tippbare Zeile mit Winkel rechts. */
.sheet__src {
  display: inline-block; width: auto; min-height: 32px; padding: var(--s2) 0 0;   /* #737 (Paul): nur so breit wie der Text, nicht die ganze Zeile klickbar */
  font-size: var(--t-xs); font-weight: 500; letter-spacing: 0;
  color: var(--ink-3); text-decoration: none;
  transition: color var(--d-fast) var(--ease);
}
.sheet__src::after { content: " \203A"; }
.sheet__src:hover, .sheet__src:focus-visible { color: var(--ink); outline: none; }

/* Knopf im Blatt: volle Breite, am Fuss. */
.sheet .btn { display: block; width: 100%; margin-top: var(--s3); flex: 0 0 auto; }
.sheet__fade {
  flex: 0 0 auto; position: relative; z-index: 1;
  height: 28px; margin-top: -28px; pointer-events: none;
  background: linear-gradient(to bottom, rgba(255,255,255,0), var(--paper));
}

/* ---- Tipp: einer pro Tag --------------------------------------------- */
/* #768 (Esteban: «von der Pille her muessen Tipp pro Tag und die Meteranzahl
   gleich gross sein, das sind sie nicht - die Tipp-Pille ist vertikal kleiner»).
   Gemessen: Tipp 36 px, Zahlenfeld 44 px. Beide stehen in mehreren Spielen in
   DERSELBEN Zeile; ungleich hohe Pillen nebeneinander sind ein Bruch. Die
   Aenderung steht hier in der geteilten Schicht, damit sie ueberall gilt. */
.hintbtn {
  appearance: none; cursor: pointer; border: 0;
  padding: 0 var(--s4); min-height: 44px;
  border-radius: var(--r-full);
  background: var(--paper-2); color: var(--ink-2);
  font-size: var(--t-sm); font-weight: 500;
  transition: color var(--d-fast) var(--ease), background var(--d-fast) var(--ease);
}
.hintbtn:hover:not(:disabled) { color: var(--ink); }
.hintbtn:disabled { opacity: .5; cursor: default; }
.hintbox, .hint {
  margin: var(--s2) 0 0; padding: 0;
  font-size: var(--t-sm); color: var(--ink-2); line-height: 1.45;
  text-align: center; text-wrap: balance;
}

/* ---- Zahleneingabe neben der Geste ------------------------------------ */
.numfield {
  display: inline-flex; align-items: baseline; gap: var(--s2);
  min-height: 44px; padding: var(--s2) var(--s4);
  background: var(--paper-2);
  border: 0; border-radius: var(--r-full);
  transition: box-shadow var(--d-fast) var(--ease), background var(--d-fast) var(--ease);
}
.numfield:focus-within { box-shadow: 0 0 0 2px var(--accent); }
.numfield__in {
  appearance: none; border: 0; background: transparent; padding: 0;
  width: 6ch; min-width: 6ch; max-width: 11ch; field-sizing: content;
  color: var(--ink); font: inherit; font-weight: 600;
  font-variant-numeric: tabular-nums; text-align: right;
}
.numfield__in:focus { outline: none; }
.numfield__in::placeholder { color: var(--ink-3); font-weight: 400; }
.numfield__unit { font-size: var(--t-sm); color: var(--ink-3); font-weight: 500; }

/* ---- Teilen ------------------------------------------------------------- */
.share {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  appearance: none; cursor: pointer;
  min-height: 52px; padding: var(--s3) var(--s5);
  border: 0; border-radius: var(--r-full);
  background: var(--ink); color: var(--paper);
  font-size: var(--t-md); font-weight: 600;
  transition: transform var(--d-fast) var(--ease), opacity var(--d-fast) var(--ease);
}
.share:active { transform: scale(.98); }
/* #744 R8 (Esteban): Hover wie der Heimweg-Knopf: fuellt sich mit dem Akzent des Spiels, hebt sich, das Symbol springt kurz hoch */
.share { transition: transform var(--d-fast) var(--ease), opacity var(--d-fast) var(--ease), background var(--d-mid) var(--ease), color var(--d-mid) var(--ease), box-shadow var(--d-mid) var(--ease); }
.share:hover, .share:focus-visible { background: var(--accent); color: var(--accent-ink); transform: translateY(-1px); box-shadow: 0 10px 22px -10px var(--accent), 0 1px 0 var(--accent-line); }
.share svg { transition: transform .34s cubic-bezier(.2, 1.1, .25, 1.35); }
.share:hover svg, .share:focus-visible svg { transform: translateY(-2px); }
@media (min-width: 900px) { .share { min-height: 60px; padding: 0 var(--s6); font-size: var(--t-lg); } }   /* #744 R8: am Rechner groesser */
.share svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2;
             stroke-linecap: round; stroke-linejoin: round; }
.share[data-done] { background: var(--good); color: var(--good-ink); }

/* ---- Tagesabschluss: alle Runden als Liste ----------------------------- */
.summary { display: flex; flex-direction: column; width: 100%; }
.srow {
  display: grid; grid-template-columns: 1fr auto; align-items: center; gap: var(--s3);
  padding: var(--s3) 0; border-top: 1px solid var(--line);
}
.srow:last-child { border-bottom: 1px solid var(--line); }
.srow__what { font-size: var(--t-md); color: var(--ink); line-height: 1.3; }
.srow__f {
  font-size: var(--t-md); font-weight: 600; font-variant-numeric: tabular-nums;
  white-space: nowrap; color: var(--ink);
}
.srow__f[data-dir="low"]::before  { content: '‹ '; color: var(--ink-3); font-weight: 400; }
.srow__f[data-dir="high"]::before { content: '› '; color: var(--ink-3); font-weight: 400; }
.srow__f[data-dir="spot"] { color: var(--good); }

/* ---- Regel-Linie mit Beschriftung --------------------------------------- */
.rule { position: relative; width: 100%; border-top: 1px dashed var(--line-strong); }
.rule::after {
  content: attr(data-label);
  position: absolute; top: -.75em; left: 0;
  font-size: var(--t-xs); font-weight: 500; color: var(--ink-3);
  background: var(--paper); padding-right: var(--s2);
}

/* ---- Kleinteile ---------------------------------------------------------- */
.chip {
  display: inline-flex; align-items: center; gap: var(--s1);
  padding: 4px var(--s3); border-radius: var(--r-full);
  background: var(--paper-2); color: var(--ink-2);
  font-size: var(--t-xs); font-weight: 500;
}
.chip--accent { background: var(--accent-soft); color: var(--accent); }
.label { font-size: var(--t-xs); font-weight: 500; color: var(--ink-3); }
.sr { position:absolute; width:1px; height:1px; padding:0; margin:-1px;
      overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0; }

/* ---- Motion-Respekt ------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
}

/* ---- Kurze Buehne (Landscape-Handy) -------------------------------------- */
@media (max-height: 620px) {
  :root { --t-mega: 2.75rem; }
  .stage { gap: var(--s3); padding-block: var(--s2); }
  .prompt { font-size: var(--t-md); }
  .sheet { padding-top: var(--s5); }
}

/* Alte Reveal-Klassen aus #703, damit nichts bricht */
.rv { display: flex; flex-direction: column; gap: var(--s2); }
.rv__head { display: flex; align-items: baseline; gap: var(--s3); flex-wrap: wrap; }
.rv__num { font-size: var(--t-mega); font-weight: 700; letter-spacing: var(--tight); line-height: .95;
           font-variant-numeric: tabular-nums; color: var(--ink); }
.rv__num--spot { color: var(--good); }
.rv__dir { font-size: var(--t-md); font-weight: 500; color: var(--ink-2); }
.rv__mine { font-size: var(--t-sm); color: var(--ink-3); }
.rv__rule { height: 1px; background: var(--line); margin: var(--s4) 0 0; }

/* ---- Geister-Hand (#721): zeigt die Geste vor, bis der Spieler anfasst ---- */
.ghost {
  position: fixed; left: 0; top: 0; z-index: 60; pointer-events: none;
  width: 0; height: 0; opacity: 0;
  transition: opacity var(--d-mid) var(--ease);
}
.ghost[data-on] { opacity: 1; }
.ghost svg {
  position: absolute; left: -10px; top: -6px; width: 44px !important; height: 52px !important; max-width: none;
  filter: drop-shadow(0 2px 6px rgba(0,0,0,.35));
  transition: transform var(--d-fast) var(--ease);
  transform-origin: 30% 20%;
}
.ghost__hand { fill: var(--paper); stroke: var(--ink); stroke-width: 2.4; stroke-linejoin: round; }
.ghost[data-press] svg { transform: scale(.88) translate(2px, 3px); }
.ghost__ring {
  position: absolute; left: -22px; top: -22px; width: 44px; height: 44px;
  border-radius: var(--r-full); border: 2px solid var(--accent);
  opacity: 0; transform: scale(.4);
  transition: opacity var(--d-fast) var(--ease), transform var(--d-mid) var(--ease-o);
}
.ghost[data-press] .ghost__ring { opacity: .9; transform: scale(1); }
@media (prefers-reduced-motion: reduce) { .ghost { display: none; } }

/* Easter Egg (#721): eine leise Zeile unter der Zahl */
.egg { margin: calc(-1 * var(--s2)) 0 var(--s2); font-size: var(--t-sm); font-weight: 600; color: var(--accent); }


/* Einheiten-/Waehrungs-Knopf (#730). Bleibt fuer Spiele, die spaeter doch einen
   eigenen Knopf wollen; How expensive? nutzt stattdessen die Anzeigen selbst. */
.unithost { display: inline-flex; align-items: center; }
.unitbtn {
  font: inherit; font-size: .72rem; font-variant-numeric: tabular-nums;
  line-height: 1; padding: .32em .55em; min-width: 2.9em;
  border: 1px solid var(--line); border-radius: .5em;
  background: transparent; color: var(--ink-2); cursor: pointer; opacity: .8;
  transition: opacity .15s ease, border-color .15s ease;
}
.unitbtn:hover, .unitbtn:focus-visible { opacity: 1; border-color: var(--accent); }

/* ----------------------------------------------------------------------
   Waehrungs-Menue (#730). Direktwahl statt Durchklicken: Esteban wollte die
   Waehrung SEHEN und WAEHLEN, nicht viermal tippen, bis die richtige kommt.
   `position: fixed` ist Absicht, nicht Bequemlichkeit: die Anker sitzen im
   Regler und im Ergebnis-Blatt, beide mit eigenem Ueberlauf und z-index.
   Ein absolut positioniertes Menue wuerde dort abgeschnitten.
   ---------------------------------------------------------------------- */
.moneymenu {
  position: fixed;
  z-index: 60;                        /* ueber dem Blatt (20) */
  min-width: 12.5rem;
  padding: .3rem;
  display: flex; flex-direction: column; gap: 1px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-md, .6rem);
  box-shadow: 0 10px 30px rgba(0,0,0,.14), 0 2px 6px rgba(0,0,0,.06);
}
.moneymenu[hidden] { display: none; }
.moneymenu__item {
  display: grid;
  grid-template-columns: 2.9rem 1fr auto;
  align-items: baseline;
  gap: .5rem;
  padding: .5rem .6rem;
  border: 0; border-radius: .4rem;
  background: transparent;
  color: var(--ink-2);
  font: inherit; font-size: var(--t-sm);
  text-align: left; cursor: pointer;
}
.moneymenu__item:hover, .moneymenu__item:focus-visible { background: var(--paper-2); color: var(--ink); outline: none; }
.moneymenu__item[aria-checked="true"] { color: var(--ink); font-weight: 600; }
.moneymenu__item[aria-checked="true"] .moneymenu__code { color: var(--accent); }
.moneymenu__code { font-weight: 600; letter-spacing: .02em; font-variant-numeric: tabular-nums; }
.moneymenu__name { color: inherit; }
.moneymenu__src { font-size: var(--t-xs); color: var(--ink-3); white-space: nowrap; }

/* HERO-MODUS (#737, Esteban: «der Hero ist Runde 1 des Tages-Mix»): das Spiel laeuft bildfuellend im Landing-Hero
   (roughly.is) als erste Runde des Mix (?mix=0&n=5&hero=1). Kein Kopf, keine Marken-Zeile, keine Punkte: die Landing
   traegt die Zeile «Today's mix · Round 1 of 5 · Where?» darueber. Alles andere ist das Spiel, unveraendert.
   Ein Spiel hero-tauglich machen heisst: hier nichts, nur dort, wo es im Hero-Rahmen schlecht sitzt. */
html[data-hero] .topbar, html[data-hero] .brandbar, html[data-hero] .challenge, html[data-hero] .archline { display: none !important; }   /* #744: die Archiv-Pille zeigt die Landing ueber dem Rahmen */
/* #744 (Esteban): hinter der Schranke bleibt «Weitere Spiele» klickbar, die Buehne und der Spiel-Knopf nicht. Die Schranke
   selbst laesst im Hero Zeiger durch (nur die Karte faengt), gesperrt wird das Spiel darunter direkt. */
html[data-hero] .gate { pointer-events: none; }
html[data-hero] .gate .gate__card { pointer-events: auto; }
html[data-hero] body:has(.gate) .stage, html[data-hero] body:has(.gate) .mapwrap, html[data-hero] body:has(.gate) .dock > .btn, html[data-hero] body:has(.gate) .subject { pointer-events: none; }
html[data-hero] .app { max-width: none; padding-top: max(var(--s6), env(safe-area-inset-top)); }   /* R6 (Esteban): «jetzt zu nah an der Navigation» */
/* Die Frage in Display-Stufe wie der alte Landing-Hero (clamp 2.25rem..4.5rem), die Buehne bekommt die ganze Breite. */
html[data-hero] .prompt { max-width: 14ch; margin-inline: auto; font-size: clamp(2.125rem, 9vw, 4.5rem); font-weight: 700; letter-spacing: -0.035em; line-height: .98; text-align: center; }   /* #744 R11: am Handy eine Stufe kleiner (2.5 -> 2.125 rem), die Karte bekommt den Platz */
html[data-hero] .prompt small { display: block; margin-top: .35em; font-size: clamp(.95rem, 2vw, 1.15rem); font-weight: 500; letter-spacing: 0; line-height: 1.35; color: var(--ink-2); }
/* Rechner (>= 900 px): wie der alte Landing-Hero stand das Motiv NEBEN der Frage, nicht darueber; das spart die Hoehe,
   die die Buehne braucht, damit der Knopf im Rahmen bleibt (Where? mass 808 px in einem 728er Rahmen). */
@media (min-width: 900px) {
  html[data-hero] .prompt { max-width: 16ch; font-size: clamp(3rem, 7.6vw, 6rem); }   /* R6: «noch groesser»; 6rem ist die Display-Decke der Familie */
  html[data-hero] .subject { flex-direction: row; justify-content: center; align-items: center; gap: var(--s7); }
  html[data-hero] .subject .prompt { text-align: left; margin-inline: 0; }
  html[data-hero] .subject .sil, html[data-hero] .subject .logo { flex: 0 0 auto; }
  html[data-hero] .subject .prompt { flex: 0 1 auto; min-width: 0; }   /* R6: der Satz bricht in der Spalte um, statt das Motiv links hinauszuschieben (gemessen: Nintendo-Logo bei x = -71) */
}

/* Hero-Modus, das Dock (#737, Esteban): links mittig das Dock des Spiels (Tipp, Eingabe, Knopf, so wie es ist),
   rechts der Weg zu den Besten mit dem drehenden Zehn-Farben-Ring des alten Landing-Heros. */
/* Kein Tipp im Hero (Esteban #737): den gibt es erst im Mix selbst.
   R5 (Esteban: «zu viel Luft zwischen Satz und Navigation»): der Block haengt OBEN, die Buehne nimmt die Hoehe, die
   der Rahmen hergibt (Where?/Where from? lassen die Karte mitwachsen, where.css), das Dock sitzt direkt darunter. */
html[data-hero] .hintrow, html[data-hero] .hintbtn, html[data-hero] .dock .hint { display: none !important; }
html[data-hero] .app { justify-content: flex-start; }
/* R6: die Restluft des Rahmens teilt sich 1:2 (ein Drittel ueber dem Satz, zwei Drittel unter dem Dock): nicht an der Pille
   kleben, nicht mittig schwimmen. Auf kurzen Rahmen (680 px) gibt es keine Restluft, dann greifen nur die Abstaende. */
html[data-hero] .app::before { content: ""; display: block; flex: 1 1 0; min-height: 0; }
html[data-hero] .app::after { content: ""; display: block; flex: 2 1 0; min-height: 0; }
html[data-hero] .stage { flex: 0 0 auto; min-height: 0; justify-content: flex-start; }   /* R6: die Buehne ist so hoch wie ihr Inhalt; die Karte misst ihre Hoehe selbst (game.js heroFit -> --herofree), die Restluft liegt UNTER dem Dock */

/* DAS HERO-DOCK (Esteban #737, R5: «mehr visuelle Hierarchie: Mix prominenter als Where? weiterspielen, Weitere Spiele
   ein bisschen auf die Seite»): die Knoepfe des Spiels stehen MITTIG (Spacer ::before links, .dock__gap rechts, beide
   gleich elastisch), «Weitere Spiele» sitzt am rechten Rand. Vor dem Reveal: [Pin setzen] .... [o Weitere Spiele].
   Nach dem Reveal: [MIX VON HEUTE WEITERSPIELEN] [Where? weiterspielen] .... [o Weitere Spiele].
   Mix = 60 px, grosse Schrift, Tinte + Regenbogen. Where? = 52 px, nur Haarlinie, beim Hover gruen. Handy: untereinander. */
html[data-hero] .dock { display: flex; flex-direction: row; flex-wrap: nowrap; justify-content: center; align-items: center; gap: var(--s3); padding-top: var(--s5); width: 100%; max-width: none; margin-inline: 0; }   /* Where? haelt sein Dock sonst in Handy-Breite (460 px) */
html[data-hero] .dock::before, html[data-hero] .dock > .dock__gap { content: ""; display: block; flex: 1 1 0; min-width: 0; }
/* R8 (Esteban: «Drop pin ist nicht mittig»): ab 900 px haengt «Weitere Spiele» absolut am rechten Rand, die Spiel-Knoepfe
   stehen exakt in der Mitte der Spalte, also mittig unter der Karte. Darunter (640-900) bleibt die Zeile mit Spacern. */
@media (min-width: 900px) {
  html[data-hero] .dock { position: relative; }
  html[data-hero] .dock::before, html[data-hero] .dock > .dock__gap { display: none; }
  html[data-hero] .dock > .heromore { position: absolute; right: 0; top: var(--s5); bottom: 0; margin-block: auto; height: 56px; transition: top .7s var(--ease-o); }
  html[data-hero] body.is-revealed .dock > .heromore, html[data-hero] body.is-done .dock > .heromore { top: var(--s3); }
}
html[data-hero] .dock > .btn, html[data-hero] .dock > .herostay, html[data-hero] .dock > .heromix, html[data-hero] .dock > .heromore {
  flex: 0 1 auto; min-width: 0; margin: 0;
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  border-radius: var(--r-full);
  font-weight: 600; letter-spacing: -0.01em; line-height: 1.15; text-align: center; text-decoration: none;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
html[data-hero] .dock > .btn { min-height: 72px; min-width: 360px; padding: 0 var(--s8); font-size: 1.375rem; font-weight: 700; letter-spacing: -0.02em; }   /* R6/R9: «Pin setzen ist zu klein, breiter und groesser» */
html[data-hero] .dock > .herostay { min-height: 72px; padding: 0 var(--s7); font-size: 1.25rem; font-weight: 700; letter-spacing: -0.02em; }   /* #744: der EINE Knopf nach dem Reveal (R2: ohne Untertitel) */
html[data-hero] .dock > .heromore { min-height: 56px; }
/* DIE FORMEL (R11, Esteban am Koala abgenommen, gilt fuer jedes hero-taugliche Spiel): das Blatt ist im Hero KEIN Overlay,
   sondern ein Block im Fluss zwischen Buehne und Knoepfen. Die Buehne bleibt ganz sichtbar, die Zahl steht direkt unter der
   Buehne, die Knoepfe direkt unter der Zahl, «Weitere Spiele» rechts. Vor dem Reveal ist das Blatt nicht da. Der Rahmen
   bleibt immer ein Schirm. Das Spiel gibt seiner Buehne nach dem Reveal eine Deckel-Hoehe (Spiel-CSS), damit der Block passt. */
html[data-hero] .sheet { position: static; order: 1; transform: none !important; box-shadow: none; background: transparent; border-radius: 0; padding: var(--s4) 0 0 !important; max-height: none; overflow: visible; }
html[data-hero] .sheet:not([data-open]) { display: none; }
html[data-hero] .sheet::after { display: none; }
html[data-hero] .dock { order: 2; }
html[data-hero] .app::before { order: -1; }
html[data-hero] .app::after { order: 3; }
@media (min-width: 900px) {
  html[data-hero] body.is-revealed .dock, html[data-hero] body.is-done .dock { justify-content: flex-start; }
}
@media (max-width: 640px) {
  /* Handy: Satz und Motiv werden nach dem Reveal eine Zeile */
  html[data-hero] body.is-revealed .subject, html[data-hero] body.is-done .subject { flex-direction: row; gap: var(--s3); animation: hero-cross .5s var(--ease-o) both; }   /* #744: der Umbruch Spalte -> Zeile laesst sich nicht animieren, darum ueberblenden */
  html[data-hero] body.is-revealed .prompt, html[data-hero] body.is-done .prompt { text-align: left; flex: 1 1 auto; min-width: 0; max-width: none !important; }
  html[data-hero] body.is-revealed .sil, html[data-hero] body.is-done .sil, html[data-hero] body.is-revealed .logo, html[data-hero] body.is-done .logo { flex: 0 0 auto; width: 44px !important; height: auto !important; }
}
/* R7 (Esteban): nach dem Reveal bleibt der Satz, wird klein und rutscht hoch (Titel-Stufe); weil er im Fluss steht, ruecken
   Karte, Blatt und Knoepfe um seine Differenz nach oben. Kein Uebergang: game.js misst die Luft unter dem Dock direkt danach. */
html[data-hero] body.is-revealed .prompt, html[data-hero] body.is-done .prompt { font-size: clamp(1.375rem, 2.4vw, 2rem) !important; max-width: none !important; line-height: 1.1; letter-spacing: -0.025em; }
html[data-hero] body.is-revealed .subject, html[data-hero] body.is-done .subject { gap: var(--s4); }
html[data-hero] body.is-revealed .dock, html[data-hero] body.is-done .dock { padding-top: var(--s3); }
html[data-hero] body.is-revealed .app::before, html[data-hero] body.is-done .app::before { flex-grow: 0; }   /* nach dem Reveal rutscht alles hoch, die Restluft liegt ganz unten */
/* R8 (Esteban: «ruckig, auf einmal kleiner»): der Satz schrumpft und rutscht in EINER weichen Bewegung (700 ms, dieselbe
   Kurve wie die Buehne); die Karte, das Blatt und die Knoepfe fahren mit, weil sie im Fluss stehen. where.js haelt das Blatt
   waehrenddessen pro Frame am Dock (heroGap). */
html[data-hero] .prompt { transition: font-size .7s var(--ease-o), letter-spacing .7s var(--ease-o), line-height .7s var(--ease-o); }
html[data-hero] .subject { transition: gap .7s var(--ease-o); }
html[data-hero] .dock { transition: padding-top .7s var(--ease-o); }
html[data-hero] .app::before { transition: flex-grow .7s var(--ease-o); }
html[data-hero] .sil, html[data-hero] .logo { transition: width .7s var(--ease-o), height .7s var(--ease-o), opacity var(--d-mid) var(--ease); }
@media (prefers-reduced-motion: reduce) { html[data-hero] .prompt, html[data-hero] .subject, html[data-hero] .dock, html[data-hero] .app::before, html[data-hero] .sil, html[data-hero] .logo { transition: none; } }
/* «Where? weiterspielen» (#744, Esteban): der ERSTE Knopf nach dem Reveal, gefuellt in der Spielfarbe (gruen), mit
   Untertitel «Fünf neue Tiere». Vorher (#737 R5) still mit Haarlinie und erst beim Hover gruen. */
html[data-hero] .dock > .herostay { background: var(--accent); color: var(--accent-ink); box-shadow: none; transition: transform var(--d-fast) var(--ease), filter var(--d-fast) var(--ease); }
html[data-hero] .dock > .herostay:hover, html[data-hero] .dock > .herostay:focus-visible { filter: brightness(1.08); transform: translateY(-1px); }
html[data-hero] .dock > .herostay:active { transform: scale(.98); }
/* «Weitere Spiele»: KEINE Pille, nur Ring + Wort, in derselben Hoehe wie die Knoepfe */
html[data-hero] .dock > .heromore { background: transparent; color: var(--ink); padding: 0 0 0 var(--s2); justify-content: center; }
/* «Mix von heute weiterspielen» (#744, Esteban: «drei Knoepfe sind zu viel»): nach dem Reveal gibt es EINEN Knopf
   («Where? weiterspielen», gruen) und EINEN stillen Textweg zum Mix (Tinte, darunter die fuenf Tagesfarben als
   Linie, Pfeil). «Weitere Spiele» verschwindet nach dem Reveal (unten). Vorher (#737 R5): Mix als Regenbogen-CTA
   neben Where?, dazu der Ring, alle drei gleich laut. */
html[data-hero] .dock > .heromix {
  background: transparent; color: var(--ink); border: 0; font-family: inherit; cursor: pointer;
  min-height: 72px; padding: 0 var(--s3); font-size: var(--t-md); font-weight: 600; gap: 8px;
  transition: transform var(--d-fast) var(--ease), color var(--d-fast) var(--ease);
}
.heromix__txt { position: relative; display: inline-block; padding-bottom: 7px; }
.heromix__line { position: absolute; left: 0; right: 0; bottom: 0; display: flex; gap: 3px; height: 3px; }
.heromix__line i { flex: 1 1 0; height: 100%; border-radius: 3px; background: oklch(78% 0.14 var(--h)); transition: height var(--d-fast) var(--ease); }
.heromix__arrow { display: inline-block; transition: transform var(--d-fast) var(--ease); }
html[data-hero] .dock > .heromix:hover, html[data-hero] .dock > .heromix:focus-visible { outline: none; }
html[data-hero] .dock > .heromix:hover .heromix__line, html[data-hero] .dock > .heromix:focus-visible .heromix__line { height: 4px; }
html[data-hero] .dock > .heromix:hover .heromix__arrow, html[data-hero] .dock > .heromix:focus-visible .heromix__arrow { transform: translateX(4px); }
html[data-hero] .dock > .heromix:active { transform: scale(.98); }
/* #744 R2 (Esteban): «Weitere Spiele» bleibt auch nach dem Reveal stehen. */
.heromix:hover .hrb__over, .heromix:focus-visible .hrb__over, .heromix:hover .hrb__ink, .heromix:focus-visible .hrb__ink { -webkit-mask-position: 0 0; mask-position: 0 0; }   /* #744 R2: Regenbogen der Mix-Spiele faehrt in den Text (wie Nav-Mix) */
html[data-hero] .sheet .sheet__src { display: none; }   /* #744 R2 (Esteban): im Hero kein Wikipedia-Link, cleaner */
/* #744 (Esteban: «Reveal am Handy ruckelt, Knoepfe ploppen»): das Blatt und die zwei Wege kommen als EINE Bewegung von
   unten herauf, waehrend Satz und Karte ihre 700-ms-Fahrt machen (where.js setzt is-revealed jetzt am Anfang der Fahrt). */
@keyframes hero-cross { 0% { opacity: 1; } 35% { opacity: 0; } 100% { opacity: 1; } }
@keyframes hero-in { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
html[data-hero] .sheet[data-open] { animation: hero-in .6s var(--ease-o) .1s both; }
html[data-hero] .dock > .herostay, html[data-hero] .dock > .heromix { animation: hero-in .55s var(--ease-o) .25s both; }
@media (prefers-reduced-motion: reduce) { html[data-hero] .sheet[data-open], html[data-hero] .dock > .herostay, html[data-hero] .dock > .heromix, html[data-hero] body.is-revealed .subject { animation: none; } }
.heromore {
  --ring: conic-gradient(from 0deg, oklch(var(--acl) var(--acc) 40), oklch(var(--acl) var(--acc) 262), oklch(var(--acl) var(--acc) 150), oklch(var(--acl) var(--acc) 300), oklch(var(--acl) var(--acc) 75), oklch(var(--acl) var(--acc) 350), oklch(var(--acl) var(--acc) 235), oklch(var(--acl) var(--acc) 178), oklch(var(--acl) var(--acc) 205), oklch(var(--acl) var(--acc) 320), oklch(var(--acl) var(--acc) 40));
}
.heromore__ring { position: relative; flex: 0 0 auto; width: 44px; height: 44px; border-radius: var(--r-full); background: var(--ring); padding: 2.5px; display: grid; animation: heromore-spin 7s linear infinite; }
.heromore__in { display: grid; place-items: center; width: 100%; height: 100%; border-radius: var(--r-full); background: var(--paper); animation: heromore-spin 7s linear infinite reverse; }
.heromore__in svg { width: 21px; height: 21px; fill: none; stroke: var(--ink); stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.heromore__txt { display: inline-flex; min-width: 0; }
.heromore__small { display: none; }
.heromore:focus-visible, .herostay:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
@keyframes heromore-spin { to { transform: rotate(360deg); } }
/* Der Regenbogen-Zug durch das Wort beim Hover (Mechanik wie .rb in nav.css: Tinte darunter, Farbe darueber, Maske als Zug) */
.hrb { position: relative; display: inline-block; }
.hrb__over {
  position: absolute; inset: 0; pointer-events: none; white-space: nowrap;
  background: var(--rb); background-size: 200% 100%; background-position: 0 0;
  -webkit-background-clip: text; background-clip: text; color: transparent; -webkit-text-fill-color: transparent;
  animation: rb-run 3.2s linear infinite;
  -webkit-mask-image: linear-gradient(90deg, #000 0 40%, transparent 60% 100%); mask-image: linear-gradient(90deg, #000 0 40%, transparent 60% 100%);
  -webkit-mask-size: 250% 100%; mask-size: 250% 100%; -webkit-mask-position: 100% 0; mask-position: 100% 0;
  transition: -webkit-mask-position 1.1s cubic-bezier(.45, .05, .2, 1), mask-position 1.1s cubic-bezier(.45, .05, .2, 1);
}
.hrb__ink {
  -webkit-mask-image: linear-gradient(90deg, transparent 0 40%, #000 60% 100%); mask-image: linear-gradient(90deg, transparent 0 40%, #000 60% 100%);
  -webkit-mask-size: 250% 100%; mask-size: 250% 100%; -webkit-mask-position: 100% 0; mask-position: 100% 0;
  transition: -webkit-mask-position 1.1s cubic-bezier(.45, .05, .2, 1), mask-position 1.1s cubic-bezier(.45, .05, .2, 1);
}
.heromore:hover .hrb__over, .heromore:focus-visible .hrb__over, .heromore:hover .hrb__ink, .heromore:focus-visible .hrb__ink { -webkit-mask-position: 0 0; mask-position: 0 0; }
@media (max-width: 640px) {
  /* Handy: der grosse Knopf allein in der ersten Zeile, «Where? weiterspielen» und «Weitere Spiele» teilen sich die zweite
     (R6: drei Zeilen ragten nach dem Reveal 22 px aus dem Rahmen) */
  html[data-hero] .dock { flex-wrap: wrap; align-items: stretch; gap: var(--s2); }
  html[data-hero] .dock::before, html[data-hero] .dock > .dock__gap { display: none; }
  html[data-hero] .dock > .btn { flex: 1 1 auto; max-width: none; min-width: 0; min-height: 64px; font-size: 1.25rem; padding-inline: var(--s4); }   /* #744 R11: vor dem Reveal teilt sich der Knopf die Zeile mit «More games» (spart 44 px fuer die Karte) */
  html[data-hero] .dock > .herostay { flex: 1 1 100%; max-width: none; min-height: 64px; padding-inline: var(--s3); font-size: 1.125rem; }   /* eigene Zeile (#744: der EINE Knopf, voll, mit Untertitel) */
  html[data-hero] .dock > .heromix { flex: 1 1 100%; min-height: 48px; }   /* #744: der stille Mix-Weg mittig darunter */
}
/* #779 (Esteban: «Continue with today's mix im Hero wegnehmen, stattdessen Where? weiterspielen unten mittig, Weitere Spiele bleibt»):
   PostHog 7 T: 43 von 450 Hero-Spielern nahmen den Mix-Weg, 270 «Where? weiterspielen». Der Mix-Weg entfaellt im Hero ganz; der
   Weiterspielen-Knopf steht mittig an der Stelle des «Pin setzen», «Weitere Spiele» wie gehabt daneben. */
html[data-hero] .dock > .heromix { display: none !important; }
@media (max-width: 640px) { html[data-hero] .dock > .herostay { flex: 1 1 auto; min-width: 0; } }
/* nach dem Reveal steht «Where? weiterspielen» mittig unter der Karte, wie vorher «Pin setzen» (gemessen: das Dock stand nach dem
   Reveal auf flex-start, der Knopf klebte links) */
@media (min-width: 900px) { html[data-hero] body.is-revealed .dock, html[data-hero] body.is-done .dock { justify-content: center !important; } }   /* am Handy teilen sich Weiterspielen und «Weitere Spiele» eine Zeile, wie vorher «Pin setzen» */
@media (max-width: 640px) {
  html[data-hero] .dock > .heromore { flex: 0 0 auto; align-self: center; max-width: none; min-height: 52px; padding-inline: var(--s3); }
}
@media (prefers-reduced-motion: reduce) { .heromore__ring, .heromore__in, .hrb__over { animation: none; } .hrb__over, .hrb__ink { transition: none; } }

/* #744 R3 (Esteban): am Rechner steht «Naeher als x % der Spieler» in Zeile 1 neben Zahl und Band-Wort; am Handy
   rueckt das Blatt vertikal enger zusammen und «Weitere Spiele» wird kleiner. Nur im Hero. */
@media (min-width: 900px) {
  html[data-hero] .sheet #roundBlock { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: var(--s3); row-gap: 0; }
  html[data-hero] .sheet #roundBlock > .factor { margin: 0; flex: 0 1 auto; }
  html[data-hero] .sheet #roundBlock > .factor .factor__dir { flex: 0 1 auto; }
  html[data-hero] .sheet #roundBlock > .crowdline { margin: 0; flex: 0 1 auto; }
  /* #779 R2 (Esteban): «Naeher als x % der Spieler» direkt UNTER der Kilometer-Zahl, und auf derselben Hoehe rechts der Knopf
     «Keep playing Where?» und «More games». Kein Band-Spruch im Hero (where.js). Das Blatt ist nur so breit wie sein Inhalt,
     das Dock rueckt um die Blatt-Hoehe (--sheeth, where.js) hoch und stellt seine Knoepfe rechts auf. */
  html[data-hero] .sheet #roundBlock { flex-direction: column; align-items: flex-start; }
  html[data-hero] body.is-revealed .sheet, html[data-hero] body.is-done .sheet { align-self: flex-start; width: auto; max-width: 55%; }
  html[data-hero] body.is-revealed .dock, html[data-hero] body.is-done .dock { margin-top: calc(-1 * var(--sheeth, 0px)); min-height: var(--sheeth, 0px); padding-top: 0; justify-content: flex-end !important; align-items: center; gap: var(--s4); pointer-events: none; }
  html[data-hero] body.is-revealed .dock > *, html[data-hero] body.is-done .dock > * { pointer-events: auto; }
  html[data-hero] body.is-revealed .dock > .heromore, html[data-hero] body.is-done .dock > .heromore { position: static; height: auto; }
  /* Esteban: «Keep playing Where? in der Mitte des Bildschirms, nicht rechts beim More games» - der Knopf steht exakt mittig im Dock
     (= mittig unter der Karte), «More games» bleibt rechts, beide auf der Hoehe der Kilometer-Zahl */
  html[data-hero] body.is-revealed .dock > .herostay, html[data-hero] body.is-done .dock > .herostay { position: absolute; left: 50%; top: 50%; translate: -50% -50%; }   /* translate statt transform: die Einblend-Animation (hero-in) belegt transform */
}
@media (max-width: 640px) {
  html[data-hero] .sheet { padding-top: var(--s3) !important; }
  html[data-hero] .sheet .factor { margin-bottom: 2px; row-gap: 0; }
  html[data-hero] .sheet .crowdline { margin-bottom: 0; }
  html[data-hero] body.is-revealed .dock, html[data-hero] body.is-done .dock { padding-top: var(--s2); }
  html[data-hero] .dock > .heromore { min-height: 36px; font-size: var(--t-sm); }
  html[data-hero] .dock > .heromore .heromore__ring { width: 30px; height: 30px; padding: 2px; }
  html[data-hero] .dock > .heromore .heromore__in svg { width: 15px; height: 15px; }
}

/* ---- «All games ->» im Tagesabschluss (#744, Esteban: rechts unten, still; gross bleibt der Teilen-Knopf) ------------------ */
.allgames { display: flex; justify-content: flex-end; align-items: center; gap: 6px; width: 100%; margin: var(--s3) 0 0; font-size: var(--t-sm); font-weight: 600; color: var(--ink-2); text-decoration: none; transition: color var(--d-fast) var(--ease); }
/* #744 R7 (Esteban: «Come back tomorrow und All games auf die gleiche Linie wie Challenge a friend, Knopf kleiner, alles
   muss ohne Scrollen auf einen Schirm»): die Fuss-Zeile (where/wherefrom) ist EINE Linie: Knopf (kompakt) links, Tages-Zeile
   daneben, «All games ->» rechts. Handy: Knopf und «All games» in einer Zeile, «Come back tomorrow» darunter links. */
.donefoot { flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s3); }
.donefoot .share { flex: 0 0 auto; min-height: 44px; padding: 0 var(--s4); font-size: var(--t-sm); }
@media (min-width: 900px) { .donefoot .share { min-height: 56px; padding: 0 var(--s6); font-size: var(--t-md); } }   /* #744 R8: am Rechner groesser, bleibt auf der einen Linie */
.donefoot .daytag { flex: 1 1 auto; text-align: left; }
.donefoot .allgames { width: auto; flex: 0 0 auto; margin: 0 0 0 auto; }
a.daytag { text-decoration: none; }   /* R14 (Esteban): «Come back tomorrow» fuehrt auf die Serien-Seite (Countdown, Historie) */
a.daytag:hover, a.daytag:focus-visible { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; outline: none; }
@media (max-width: 640px) {
  .donefoot .share { order: 1; }
  .donefoot .allgames { order: 2; }
  .donefoot .daytag { order: 3; flex: 1 1 100%; }
}
.allgames__arrow { display: inline-block; transition: transform var(--d-fast) var(--ease); }
/* #761: die Kachel zum naechsten Spiel (ersetzt «More games», wenn heute noch eines offen ist); --nh = dessen Farbton */
.nextgame { justify-content: flex-start; width: auto; gap: 10px; margin: 0; padding: 6px 14px 6px 6px; border-radius: var(--r-full); background: var(--paper-2); color: var(--ink); }
.nextgame:hover, .nextgame:focus-visible { background: var(--paper-3); color: var(--ink); }
.nextgame__pk { flex: 0 0 auto; width: 36px; height: 36px; border-radius: var(--r-full); display: grid; place-items: center; color: oklch(50% 0.17 var(--nh, 255)); background: var(--paper); }
:root[data-theme="dark"] .nextgame__pk { color: oklch(78% 0.14 var(--nh, 255)); }
.nextgame__pk svg { width: 22px; height: 22px; }
.nextgame__t { display: flex; flex-direction: column; gap: 0; min-width: 0; line-height: 1.2; }
.nextgame__k { font-size: 11px; font-weight: 600; color: var(--ink-3); letter-spacing: .02em; text-transform: uppercase; }
.nextgame__n { font-size: var(--t-sm); font-weight: 700; color: var(--ink); white-space: nowrap; }
/* #761: Hierarchie am Tagesende, ALLE Spiele: Next up = Primaer (volle Breite, Farbe des naechsten Spiels), Teilen + Freunde =
   zwei stille Pillen in einer Zeile (.done__acts, game.js moreGames; where/wherefrom: .donefoot mit denselben Regeln). */
.allgames.nextgame { width: 100%; justify-content: center; height: 52px; padding: 0 18px 0 8px; margin: var(--s3) 0 0; border-radius: var(--r-full); background: oklch(50% 0.17 var(--nh, 255)); color: #fff; }
.allgames.nextgame:hover, .allgames.nextgame:focus-visible { background: oklch(44% 0.17 var(--nh, 255)); color: #fff; }
.allgames.nextgame .nextgame__pk { background: rgba(255, 255, 255, .92); }
.allgames.nextgame .nextgame__k { color: rgba(255, 255, 255, .78); }
.allgames.nextgame .nextgame__n { color: #fff; font-size: var(--t-md); }
:root[data-theme="dark"] .allgames.nextgame { background: oklch(78% 0.14 var(--nh, 255)); color: var(--paper); }
:root[data-theme="dark"] .allgames.nextgame .nextgame__n { color: var(--paper); } :root[data-theme="dark"] .allgames.nextgame .nextgame__k { color: rgba(0, 0, 0, .6); }
.done__acts { display: flex; gap: var(--s2); margin: var(--s2) 0 0; width: 100%; }
/* #836 B: die leise Zeile unter Gestern + Next up (ersetzt Morgen-Kachel + Mail-Feld) */
.dayend--line { display: block; width: 100%; margin: var(--s4) 0 0; text-align: center; }
.dayend.dayend--line { text-align: center; align-items: center; border-top: 0; padding-top: 0; }   /* #836 Esteban: mittig, ohne Trennlinie */
.dayend--line .dayend__next { text-align: center; }
.ydaywrap__side { display: flex; flex-direction: column; align-items: stretch; min-width: 0; }
.ydaywrap__side > .allgames.nextgame { margin-top: var(--s2); }
.ydaywrap__side > .dayend--line { margin: 12px 0 0; }
.dayend--line .remindme--line { margin: 10px auto 0; max-width: 380px; border-top: 0; padding-top: 0; }
.dayend--line .remindme--line .remindme__q { display: none; }   /* #836: kompakt, die Zeile darueber sagt es schon */
.dayend__next { margin: 0; font-size: var(--t-sm); color: var(--ink-3); }
.dayend__remind { border: 0; background: none; padding: 4px 2px; font: inherit; font-weight: 600; color: var(--ink-2); text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--line-strong); cursor: pointer; }
.dayend__remind:hover, .dayend__remind:focus-visible { color: var(--ink); text-decoration-color: var(--ink); outline: none; }
.dayend__on { color: var(--ink-2); font-weight: 600; }
.dayend--line [data-part="remind"] { margin-top: var(--s2); }
/* #836 (Esteban): die Gestern-Karte am Tagesende. Unscharfes Bild von gestern als Koeder, Text, Preis; ab dem dritten Spieltag
   die grosse Karte (Regenbogen-Rand wie die Kauf-Momente) ueber «Next up», das dann zur leisen Pille wird. */
.ydaycard { display: flex; align-items: center; gap: 14px; width: 100%; margin: var(--s2) 0 0; padding: 10px 16px 10px 10px; border-radius: 20px; background: var(--paper-2); color: var(--ink); text-decoration: none; transition: background var(--d-fast) var(--ease), transform var(--d-fast) var(--ease); }
.ydaycard:hover, .ydaycard:focus-visible { background: var(--paper-3); outline: none; transform: translateY(-1px); }
.ydaycard__sil { position: relative; flex: 0 0 auto; width: 60px; height: 50px; display: grid; place-items: center; border-radius: 14px; background: oklch(94% 0.05 var(--nh, 255)); overflow: visible; }
.ydaycard__img { width: 100%; height: 100%; display: grid; place-items: center; filter: blur(3px); opacity: .85; }
.ydaycard__img svg { width: 78%; height: 78%; fill: oklch(50% 0.17 var(--nh, 255)); }
.ydaycard__q { position: absolute; right: -5px; top: -5px; width: 20px; height: 20px; display: grid; place-items: center; border-radius: 50%; background: var(--ink); color: var(--paper); font-size: 12px; font-style: normal; font-weight: 700; }
:root[data-theme="dark"] .ydaycard__sil { background: oklch(28% 0.05 var(--nh, 255)); }
:root[data-theme="dark"] .ydaycard__img svg { fill: oklch(78% 0.14 var(--nh, 255)); }
.ydaycard__sil img { max-width: 52px; max-height: 32px; width: auto; height: auto; }
.ydaycard__sil--icon { filter: none; opacity: 1; background: oklch(94% 0.05 var(--nh, 255)); }
.ydaycard__sil--icon svg { width: 30px; height: 30px; }
.ydaycard__txt { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; text-align: left; }
.ydaycard__txt b { font-size: var(--t-md); font-weight: 700; letter-spacing: -0.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ydaycard__txt > span { font-size: var(--t-sm); color: var(--ink-2); line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }   /* #836 Esteban: jede Zeile EINE Zeile, drei Zeilen statt fuenf */
.ydaycard__p { margin-top: 2px; font-variant-numeric: tabular-nums; }
.ydaycard__p s { color: var(--ink-3); margin-right: 4px; }
.ydaycard__p b { font-size: var(--t-sm); color: var(--ink); font-weight: 700; }
.ydaycard__go { flex: 0 0 auto; order: -1; margin-left: 4px; font-size: 1.25rem; color: var(--ink-2); transition: transform var(--d-fast) var(--ease); }
.ydaycard:hover .ydaycard__go, .ydaycard:focus-visible .ydaycard__go { transform: translateX(-3px); }
.ydaycard--lead { margin: var(--s3) 0 0; padding: 10px 14px 10px 10px; border: 2px solid transparent; background: linear-gradient(var(--paper), var(--paper)) padding-box, var(--rb) border-box; background-size: auto, 200% 100%; box-shadow: 0 14px 34px -20px rgba(14, 14, 17, .4); }
.ydaycard--lead:hover, .ydaycard--lead:focus-visible { background: linear-gradient(var(--paper-2), var(--paper-2)) padding-box, var(--rb) border-box; background-size: auto, 200% 100%; }
.ydaycard--lead .ydaycard__sil { width: 64px; height: 52px; }
.ydaywrap { display: flex; flex-direction: column; width: 100%; }
.ydaywrap > .ydaycard, .ydaywrap > .allgames { margin-top: var(--s2); }
@media (min-width: 700px) {   /* #836 Esteban: am Rechner nebeneinander, kein Leerraum rechts */
  .ydaywrap { flex-direction: row; gap: var(--s3); align-items: stretch; margin-top: var(--s3); }
  .ydaywrap > .ydaycard, .ydaywrap > .allgames { margin: 0; }
  .ydaywrap > .ydaycard { flex: 3 1 0; min-width: 0; }
  .ydaywrap > .ydaywrap__side { flex: 2 1 0; }
  .ydaywrap__side > .allgames.nextgame { margin: 0; width: 100%; }
  .ydaywrap__side > .dayend--line { margin: 10px 0 0; }
  .ydaywrap__side .dayend__next { font-size: var(--t-xs); white-space: nowrap; }   /* am Rechner eine Zeile unter Next up */
}
.allgames.nextgame.nextgame--quiet { height: 46px; margin: var(--s2) 0 0; background: var(--paper-2); color: var(--ink); }
.allgames.nextgame.nextgame--quiet .nextgame__k { color: var(--ink-3); }
.allgames.nextgame.nextgame--quiet .nextgame__n, .allgames.nextgame.nextgame--quiet .allgames__arrow { color: var(--ink); }
:root[data-theme="dark"] .allgames.nextgame.nextgame--quiet { background: var(--paper-2); color: var(--ink); }
/* #838 (Esteban am Where?-Tagesende, Variante B: «Next up viel zu gross, falsche Schriftfarbe, man sieht es gar nicht; man kann scrollen»):
   - Next up erbte aus where.css .donefoot .allgames {flex: 1 0 100%}: am Rechner auf die volle Zeilenhoehe gestreckt (94 px),
     am Handy auf 36 px gequetscht, und der Ueberhang liess das Blatt rollen (Rand unten und «New rounds» abgeschnitten).
     Jetzt feste Hoehe, nie gestreckt, Seite mittig neben der Gestern-Karte.
   - Dunkel: die Regel fuer den farbigen Knopf (Schrift = Papier) schlug die leise Pille -> dunkel auf dunkel. Eigene Farben.
   - Die leise Zeile «New rounds at midnight UTC · Remind me» bleibt unter Next up (#836), hat jetzt Platz. */
.ydaywrap__side { display: flex; flex-direction: column; justify-content: center; min-width: 0; }
:root body .donefoot .ydaywrap__side > .allgames.nextgame { flex: 0 0 auto; width: 100%; height: 48px; min-height: 0; margin: 0; }
@media (min-width: 700px) { :root body .donefoot .ydaywrap__side > .allgames.nextgame { height: 56px; } }
:root body .ydaywrap .allgames.nextgame--quiet .nextgame__k { color: var(--ink-2); }
:root body .ydaywrap .allgames.nextgame--quiet .nextgame__n, :root body .ydaywrap .allgames.nextgame--quiet .allgames__arrow { color: var(--ink); }
:root body .ydaywrap .allgames.nextgame--quiet .nextgame__pk { background: var(--paper); }
:root[data-theme="dark"] body .ydaywrap .allgames.nextgame--quiet { background: var(--paper-2); color: var(--ink); }
:root[data-theme="dark"] body .ydaywrap .allgames.nextgame--quiet:hover { background: var(--paper-3); }
:root body .ydaywrap__side .dayend__next { white-space: normal; text-wrap: balance; text-align: center; }   /* #838 (Esteban): eine Zeile ohne Umbruch ragte links in die Gestern-Karte */
/* #836 (Esteban): im Flammen-Fenster ist «mit 2 Freunden zurueckholen» der erste Knopf, roughly+ der zweite */
.gate__friends.gate__friends--main { background: var(--ink); color: var(--paper); margin: 0 0 8px; }
.gate__friends.gate__friends--main:hover, .gate__friends.gate__friends--main:focus-visible { background: var(--ink); opacity: .92; }
.gate__more.gate__more--second { background: var(--paper-2); color: var(--ink); min-height: 48px; }
.done__acts .share { flex: 1 1 0; min-width: 0; width: auto; justify-content: center; padding: 0 10px; min-height: 44px; font-size: 14px; background: var(--paper-2); color: var(--ink); }
.done__acts .share:hover, .done__acts .share:focus-visible, .donefoot .share:hover, .donefoot .share:focus-visible { background: var(--accent); color: var(--accent-ink); }   /* #783 (Esteban: Hover verbuggt): vorher nur grauer Grund, aber helle Schrift + Akzent-Schatten aus .share:hover, Text verschwand. Jetzt fuellt sich die Pille sauber mit dem Akzent. */
/* #783 (Esteban: «dass das Share-Symbol sich ein bisschen bewegt, dass es die Leute catcht»): alle 3.2 s hebt sich das Zeichen
   kurz an und wippt (Stupser), beim Hover steht es oben. Ohne Bewegungswunsch still. */
@keyframes share-nudge { 0%, 58%, 100% { transform: none; } 64% { transform: translateY(-8px) rotate(-12deg); } 70% { transform: translateY(0) scale(1.08, .9); } 76% { transform: translateY(-5px) rotate(8deg); } 82% { transform: translateY(0) scale(1.04, .95); } 88% { transform: translateY(-2px); } 93% { transform: none; } }   /* #783 R2 (Esteban: «das Zeichen muss huepfen»): zwei echte Spruenge statt Wippen */
.done__acts .share svg, .donefoot .share svg { animation: share-nudge 2.6s ease-in-out .8s infinite; transform-origin: 50% 100%; }
.done__acts .share:hover svg, .done__acts .share:focus-visible svg, .donefoot .share:hover svg, .donefoot .share:focus-visible svg { animation: none; transform: translateY(-2px); }
@media (prefers-reduced-motion: reduce) { .done__acts .share svg, .donefoot .share svg { animation: none; } }
.done__acts .share svg { stroke: currentColor; }
.done__acts .roombtn--done { flex: 1 1 0; min-width: 0; height: 44px; padding: 0 10px; border-radius: var(--r-full); background: var(--paper-2); color: var(--ink); font-size: 14px; font-weight: 600; gap: 6px; justify-content: center; white-space: nowrap; }
.done__acts .roombtn--done:hover { background: var(--paper-3); }
.done__acts .roombtn--done svg { width: 16px; height: 16px; }
@media (min-width: 900px) { .done__acts .share, .done__acts .roombtn--done { font-size: var(--t-sm); padding: 0 var(--s4); min-height: 48px; height: 48px; } .allgames.nextgame { height: 56px; } }
.allgames:hover, .allgames:focus-visible { color: var(--ink); outline: none; }
.allgames:hover .allgames__arrow, .allgames:focus-visible .allgames__arrow { transform: translateX(4px); }
/* Bild vor dem Namen in den Abschluss-Zeilen (#744, Esteban: «ueberall, wo echte Umrisse da sind»): Where? Tier-Umriss,
   Where from? Logo, How big? / How many? / How expensive? Objekt-Umriss. Which way? hat seine gezeichnete Form schon. */
.srow--pikto { grid-template-columns: auto 1fr auto; }
.srow__pikto { width: 32px; height: 26px; display: grid; place-items: center; }
.srow__pikto svg { width: 100%; height: 100%; fill: var(--ink); }
.srow__pikto--logo { width: 56px; }
.srow__pikto--logo img { display: block; max-width: 56px; max-height: 24px; width: auto; height: auto; object-fit: contain; }
html[data-theme="dark"] .srow__pikto--logo img[data-frame~="d"], html[data-theme="dark"] .srow__pikto--logo img[data-frame="dl"] { background: var(--logo-paper, #fff); padding: 3px 5px; border-radius: 4px; }
html:not([data-theme="dark"]) .srow__pikto--logo img[data-frame~="l"], html:not([data-theme="dark"]) .srow__pikto--logo img[data-frame="dl"] { background: var(--ink-3); padding: 3px 5px; border-radius: 4px; }

/* #744 R8: «roughly.is · More games» ist breiter; auf dem Handy die Pille eine Stufe kleiner (11 px) und die Punkte 9 px, damit
   die Punkte ECHT mittig bleiben (Esteban). Gemessen 390 px: Pille EN 140 / DE 138 px, Punkte 65 px mittig auf 195, keine Kollision. Steht am Dateiende, weil die Grundregeln weiter oben stehen. */
@media (max-width: 420px) {
  .pips--brand { gap: 4px; --pip: 11px; }   /* Esteban #761: Punkt 11, Luecke 4 */
}

/* ---- Tagesende: die Tagesnummer wird Regenbogen, der Pfeil «‹» winkt nach links (#744 R10, Esteban: «damit man versteht, man
   kann ins Archiv zurueck»). game.js setzt .brandbar[data-done] beim day_done-Moment. Der Regenbogen laeuft wie ueberall (rb-run),
   der Pfeil winkt dreimal und bleibt dann in voller Tinte. */
/* #761 (Esteban: «die Zahl ist manchmal regenbogenfarbig, keine Ahnung warum»): der Regenbogen auf der Tagesnummer am Tagesende
   (#744 R10) ist RAUS, das Signal wurde nicht verstanden. Der Pfeil «‹» winkt weiter. */
/* #761 (Esteban: «oben sind die Punkte auf einmal grau statt in der Spielfarbe»): am Tagesende tragen alle fuenf Punkte die
   Spielfarbe, das liest sich als «fertig gespielt». */
.topbar[data-done] .pips--brand .pip[data-on], body.is-done .pips--brand .pip[data-on] { background: var(--accent); }
.pips--brand .pip[data-hot] { transform: scale(1.8); }   /* #761: Runde des angetippten Tiers, nur groesser (Esteban: kein Ring) */
/* ---- #761 Tagesende-Feuer (Esteban: «nach jedem Guess kommt der kleine Funke, wenn der Tag fertig ist, soll er riesig sein»):
   ein Komet steigt von der Tageszahl zur Flamme im Kopf, dort platzt ein Funkenschwarm in Spielfarbe + Tinte, die Flamme
   zuengelt gross und «+1» steigt auf (game.js G.dayBurst, aus G.dayPlus). Reduced motion: nur das stille +1. ---- */
.dayburst { position: fixed; z-index: 70; width: 0; height: 0; pointer-events: none; }
.dayburst__comet { position: absolute; left: -6px; top: -6px; width: 12px; height: 12px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 3px var(--paper), 0 0 18px 2px var(--accent-line); transform: translate(var(--fx), var(--fy)) scale(1); animation: dayburst-fly .78s cubic-bezier(.45, 0, .2, 1) both; }
@keyframes dayburst-fly { 0% { opacity: 0; transform: translate(var(--fx), var(--fy)) scale(.6); } 12% { opacity: 1; transform: translate(calc(var(--fx) * .92), calc(var(--fy) * .92 - 26px)) scale(1.1); } 100% { opacity: 1; transform: translate(0, 0) scale(.35); } }
.dayburst__sp { position: absolute; left: calc(var(--r) * -.5); top: calc(var(--r) * -.5); width: var(--r); height: var(--r); border-radius: 50%; background: var(--c); opacity: 0; animation: dayburst-sp var(--dur) cubic-bezier(.1, .7, .3, 1) var(--del) both; }
@keyframes dayburst-sp { 0% { opacity: 0; transform: translate(0, 0) scale(.4); } 10% { opacity: 1; transform: translate(calc(var(--tx) * .18), calc(var(--ty) * .18)) scale(1.15); } 100% { opacity: 0; transform: translate(var(--tx), calc(var(--ty) + 18px)) scale(.25); } }
.dayburst__ring { position: absolute; left: -8px; top: -8px; width: 16px; height: 16px; border-radius: 50%; border: 2px solid var(--accent); opacity: 0; animation: dayburst-ring .9s cubic-bezier(.2, .7, .2, 1) var(--del) both; }
@keyframes dayburst-ring { 0% { opacity: .9; transform: scale(.6); } 100% { opacity: 0; transform: scale(7); border-width: .5px; } }
@media (prefers-reduced-motion: reduce) { .dayburst { display: none; } }
.flame--upbig .flame__svg { animation: flame-upbig 1.1s cubic-bezier(.2, .8, .2, 1) both; }
.flame--upbig .flame__up { font-size: var(--t-lg); top: -18px; }
@keyframes flame-upbig { 0% { transform: scale(1); } 30% { transform: scale(1.9) rotate(-5deg); } 55% { transform: scale(.9) rotate(3deg); } 100% { transform: none; } }
@media (prefers-reduced-motion: reduce) { .flame--upbig .flame__svg { animation: none; } }
.topbar[data-done] .topbar__nav > a.brandbar__step:first-child { color: var(--ink); animation: step-wink 2.4s cubic-bezier(.45, .05, .2, 1) .4s 3 both; }
/* #744 R12 (Esteban: «springt zu rasch, soll langsam gleiten und trotzdem zeigen, dass man zurueck kann»): ein langsames Gleiten
   nach links (12 px, 2.4 s, weiche Kurve), Pause, dreimal.
   #779 (Esteban: «der Pfeil springt viel zu weit, soll sich nur ein bisschen bewegen»): 4 px statt 12. */
@keyframes step-wink { 0%, 100% { transform: translateX(0); } 45% { transform: translateX(-4px); } 60% { transform: translateX(-4px); } }
@media (prefers-reduced-motion: reduce) { .brandbar[data-done] .brandbar__nav > a.brandbar__step:first-child { animation: none; } }

/* ---- Serie: EIN Abzeichen in allen Spielen (#744 R11, Esteban; Regel in game.js G.streak). Stille Pille in der Meta-Zeile. ---- */
.streakbadge { display: inline-flex; align-items: center; min-height: 26px; padding: 0 10px; border-radius: var(--r-full); background: var(--paper-2); color: var(--ink-2); font-size: var(--t-xs); font-weight: 600; letter-spacing: 0; white-space: nowrap; font-variant-numeric: tabular-nums; }
/* die alten, je Spiel verschiedenen Anzeigen sind aus (Where?/Where from? km-Total, How big? «Streak 1», When?/How expensive?/How sweet? Streak-Chips) */
.topbar__meta > #dayno, .topbar__meta > #meta.meta-score, .topbar__meta > #streak, .topbar__meta > .streak { display: none !important; }

/* ---- Flamme = die Familien-Serie (#744 R12/R13, Esteban): Flamme + Zahl, ueberall gleich (Spiel-Zeile, Landing-Nav,
   Serien-Seite). Beim ersten Laden zeichnet sich der Umriss von der Kante her (flame-draw), dann fuellt sie sich (flame-fill);
   danach steht sie still, die Zahl wird nur nachgezogen. Mit roughly+ traegt sie die Farben der zuletzt gespielten Spiele
   (game.js G.flameHues, Verlauf im SVG); ohne roughly+ Tinte. ---- */
.flame { display: inline-flex; align-items: center; gap: 4px; color: var(--ink); font-weight: 700; font-variant-numeric: tabular-nums; text-decoration: none; }
.flame__svg { width: 16px; height: 16px; flex: 0 0 16px; overflow: visible; }
.flame__p { stroke-width: 1.6; stroke-linejoin: round; stroke-linecap: round; fill-opacity: 1; transform-origin: 50% 88%; }
/* R21: bis Stufe 3 steht die Flamme still; ab Stufe 3 (flame--alive) zeichnet sie sich bei jedem Laden und zuengelt leise */
/* #758 (Esteban, Ende): die alte Ankunft bleibt, ueberall: der Umriss zeichnet sich einmal rundherum, dann fuellt sie sich, dann
   erwachen die Zungen (0.4 s nach der Fuellung). Nur die ERSTE Zeichnung einer Seite; jede weitere traegt flame--pv (keine Animation). */
.flame--alive .flame__p { fill-opacity: 0; stroke-dasharray: 100; stroke-dashoffset: 100;
  animation: flame-draw 1.1s cubic-bezier(.35, .1, .25, 1) .15s forwards, flame-fill .5s ease-out 1.05s forwards; }
.flame--alive:not(.flame--pv) .flame__wake { opacity: 0; animation: flame-fxin .5s ease-out 1.5s forwards; }   /* eigener Rahmen um die Zungen: seine Animation kollidiert nicht mit Atmen/Hover */
/* ---- #758 (Esteban, sieben Musterbogen-Runden, Entscheid flammebogen758g): die Flamme LEBT. Kontur immer scharf, kein Filter.
   RUHE: im Umriss liegen drei kleinere Zungen (derselbe Pfad, 60/40/22 %), die sich gleichsinnig als Welle von aussen nach innen
   bewegen (versetzt, innen staerker) plus ein langsamer gemeinsamer Atem; dazu Funken, die unregelmaessig (eigene Groesse, Start,
   Dauer, Hoehe, seitliches Wackeln) von der Spitze weit ueber die Flamme hinaus steigen. Zungen-Ton je Fassung: Tinte hell auf Ink /
   dunkel auf der weissen Dunkel-Flamme, Plus weiss, Glut warm, Aurora mint, Gold gold, Neon magenta mit cyan-Kern.
   HOVER (.flame--hov, nav.js): zwei Laeufer starten am Fuss, fahren links und rechts an der Kontur hoch, treffen sich an der
   Spitze, und dort spruehen dann zwoelf Funken. Die alte Ruhe-Bewegung (scaleY/skew der ganzen Flamme, R21) ist raus. ---- */
.flame .flame__svg { overflow: visible; }
.flame__tongue { transform-origin: 12px 20.5px; transform-box: view-box; animation: flame-lick 1.6s ease-in-out infinite; }
.flame__tongue--1 { --fa: 1; animation-delay: 0s; } .flame__tongue--2 { --fa: 1.35; animation-delay: -.16s; } .flame__tongue--3 { --fa: 1.8; animation-delay: -.3s; }
@keyframes flame-lick { 0%, 100% { transform: scaleY(1) skewX(0); } 28% { transform: scaleY(calc(1 + .09 * var(--fa))) skewX(calc(-3.5deg * var(--fa))); } 62% { transform: scaleY(calc(1 - .04 * var(--fa))) skewX(calc(3deg * var(--fa))); } }
.flame__tongues { transform-origin: 12px 20.5px; transform-box: view-box; animation: flame-breathe 4.3s ease-in-out infinite; }
@keyframes flame-breathe { 0%, 100% { transform: scaleY(1); } 50% { transform: scaleY(1.05); } }
.flame--plus .flame__tongue path { fill: var(--ftg, rgba(255, 255, 255, .42)); }
.flame[data-fx="ember"] .flame__tongue path { fill: var(--ftg, rgba(255, 224, 150, .5)); }
.flame[data-fx="aurora"] .flame__tongue path { fill: var(--ftg, rgba(220, 255, 240, .42)); }
.flame[data-fx="gold"] .flame__tongue path { fill: var(--ftg, rgba(255, 246, 200, .55)); }
.flame[data-fx="neon"] .flame__tongue path { fill: var(--ftg, rgba(255, 210, 250, .5)); }
.flame[data-fx="neon"] .flame__tongue--3 path { fill: var(--ftg, rgba(200, 255, 255, .6)); }
.flame--paperfill .flame__p { stroke-width: 1.7; }   /* #758: Fuellung «weiss» = Papier-Flamme, die Kontur traegt sie (game.js setzt Tinte-Kontur, wenn keine gewaehlt) */
.flame--zero .flame__tongues, .flame--notongue .flame__tongues { display: none; }
.flame--nosweep .flame__trace, .flame--nospark .flame__burst { display: none; }   /* #758: Flitzer / Funken abschaltbar (Serien-Seite) */   /* Esteban #758: Zungen sind ein Schalter (game.js notongue); Tinte ohne Wahl = ohne Zungen; ohne Serie sowieso nur Umriss */
.flame:not(.flame--plus) .flame__tongue path { fill: var(--ftg, rgba(255, 255, 255, .16)); }   /* Tinte mit Zungen: hell auf Ink */
:root[data-theme="dark"] .flame:not(.flame--plus) .flame__tongue path { fill: var(--ftg, rgba(0, 0, 0, .2)); }   /* dunkel: die Tinten-Flamme ist weiss, die Zungen dunkel */
  /* ohne Serie ist die Flamme nur Umriss, da gibt es kein Innen */
/* Funken: je Funke eigene Werte (game.js setzt --dx --dy --dur --del --wob --wdur). Kein Dauerzustand (Esteban #758): sie spruehen
   nur als Ereignis, bei jeder geschafften Runde (.flame--spark, G.flameSpark) und beim Hover an der Spitze (.flame--hov). */
.flame__sp { transform-box: view-box; transform-origin: 12px 3px; opacity: 0; }
.flame__sp circle { fill: var(--fsk, currentColor); transform-box: view-box; transform-origin: center; }   /* --fsk = eigene Funkenfarbe (game.js), sonst folgt sie den Flitzern, sonst Fassung */
.flame--spark .flame__burst .flame__sp { animation: flame-rise var(--dur) cubic-bezier(.15, .6, .35, 1) var(--del) both; }
.flame--spark .flame__burst .flame__sp circle, .flame--hov .flame__burst .flame__sp circle { animation: flame-wob var(--wdur) ease-in-out var(--del) infinite; }
.flame--spark .flame__tongues { animation: flame-breathe 4.3s ease-in-out infinite, flame-surge .7s ease-out both; }
.flame--plus .flame__sp circle { fill: var(--fsk, var(--fsp, currentColor)); }   /* Plus: Farbe des ersten Spiels der Flamme (game.js setzt --fsp), gesaettigt, auf Weiss UND Schwarz sichtbar */
.flame[data-fx="ember"] .flame__sp circle { fill: var(--fsk, #ff7a2a); } .flame[data-fx="gold"] .flame__sp circle { fill: var(--fsk, #d99a00); } .flame[data-fx="neon"] .flame__sp circle { fill: var(--fsk, #ff2fd0); } .flame[data-fx="aurora"] .flame__sp circle { fill: var(--fsk, #14b36d); }
@keyframes flame-rise { 0% { opacity: 0; transform: translate(0, 0) scale(.5); } 5% { opacity: .95; transform: translate(calc(var(--dx) * .15), -1.5px) scale(1); } 60% { opacity: .7; } 100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(.25); } }
@keyframes flame-wob { 0%, 100% { transform: translateX(calc(-1 * var(--wob))); } 50% { transform: translateX(var(--wob)); } }
/* Hover: Laeufer (Papier, halb IN der Flamme, darum auf jeder Fassung sichtbar) und Funkenschwarm 0.7 s spaeter an der Spitze */
.flame__trace { fill: none; stroke: var(--ftr, var(--ink)); stroke-width: 2.8; stroke-linecap: round; opacity: 0; pointer-events: none; }   /* Esteban #758: Laeufer hell SCHWARZ, dunkel WEISS (Tinte), breit: buendig bis zur Kante */
.flame:not(.flame--plus) .flame__trace { stroke: var(--ftr, var(--ink-3)); }   /* auf der Tinten-Flamme waere Tinte unsichtbar: dort Grau (ink-3), auf Schwarz wie auf Weiss lesbar */
.flame__trace--tail { stroke-width: 4; }
.flame--hov .flame__trace--a { stroke-dasharray: 9 91; animation: flame-traceA 1.05s cubic-bezier(.3, 0, .2, 1) both; }
.flame--hov .flame__trace--b { stroke-dasharray: 9 91; animation: flame-traceB 1.05s cubic-bezier(.3, 0, .2, 1) both; }
.flame--hov .flame__trace--tail.flame__trace--a { stroke-dasharray: 16 84; animation: flame-traceTailA 1.05s cubic-bezier(.3, 0, .2, 1) .06s both; }
.flame--hov .flame__trace--tail.flame__trace--b { stroke-dasharray: 16 84; animation: flame-traceTailB 1.05s cubic-bezier(.3, 0, .2, 1) .06s both; }
/* der Pfad beginnt an der Spitze (0), laeuft rechts hinunter (Fuss ~50) und links wieder hoch (100): A rechts hoch = Offset -50 -> 0, B links hoch = -50 -> -100 */
@keyframes flame-traceA { 0% { stroke-dashoffset: -50; opacity: 0; } 8% { opacity: 1; } 85% { opacity: 1; } 100% { stroke-dashoffset: 0; opacity: 0; } }
@keyframes flame-traceB { 0% { stroke-dashoffset: -50; opacity: 0; } 8% { opacity: 1; } 85% { opacity: 1; } 100% { stroke-dashoffset: -100; opacity: 0; } }
@keyframes flame-traceTailA { 0% { stroke-dashoffset: -50; opacity: 0; } 8% { opacity: .28; } 85% { opacity: .28; } 100% { stroke-dashoffset: 0; opacity: 0; } }
@keyframes flame-traceTailB { 0% { stroke-dashoffset: -50; opacity: 0; } 8% { opacity: .28; } 85% { opacity: .28; } 100% { stroke-dashoffset: -100; opacity: 0; } }
.flame--hov .flame__burst .flame__sp { animation: flame-rise var(--dur) cubic-bezier(.15, .6, .35, 1) calc(var(--del) + .7s) both; }
.flame--hov .flame__tongues { animation: flame-breathe 4.3s ease-in-out infinite, flame-surge .7s ease-out .7s both; }
@keyframes flame-surge { 0% { transform: scaleY(1); } 35% { transform: scaleY(1.24) skewX(-3deg); } 100% { transform: scaleY(1); } }
/* R28: mit Farben ist der Pfad nur die Linie, die Flaeche kommt aus den Farbflecken (.flame__fx), die beim Zeichnen einblenden */
.flame__p--line { fill: none !important; }
.flame__fx { opacity: 1; }
.flame--alive .flame__fx { opacity: 0; animation: flame-fxin .6s ease-out 1s forwards; }   /* Rueckfall (nicht bei Plus-Mix/fx, die haben eigene Ankunft, unten) */
/* #758 (Esteban, vierte Fassung: «nicht zu vorsichtig, jede Flamme ihre eigene Sprache, Zungen frueh»): das Einzeichnen des Umrisses
   gehoert der TINTE. Jede farbige Fassung kommt mit ihrem eigenen, klar sichtbaren Motiv an; die Zungen sind ab 0.3 s da:
     Your games: die Farben WIRBELN herein (die Flecken drehen eine halbe Runde und legen sich), der Mix deiner Spiele.
     Glut:   die Glut wacht auf und FLAMMT AUF: dunkel, ein Atemzug, dann ein heller Schub, aus dem die Funken hochschiessen.
     Aurora: der Vorhang STEIGT: die Lichter ziehen von unten hoch und legen sich, wie Nordlicht, das aufgeht.
     Gold:   ein warmer Glanz faehrt einmal um die Kontur (Esteban: die Referenz).
     Neon:   die Roehre ZUENDET: drei kurze Fehlzuendungen, dann Licht mit einem Schub im Lichthof.
   Ankunft nur ohne .flame--pv. Alles endet im Normalzustand (fill-mode backwards, wo ein SVG-Attribut weiterlaeuft).
   clip-path/transform nie auf .flame__fx selbst (SVG-clip = Flammenform), nur auf die Kinder. */
.flame--plus.flame--alive .flame__fx { opacity: 1; }
.flame--plus.flame--alive:not(.flame--pv) .flame__wake { animation-delay: .3s !important; }   /* farbige Flammen: Zungen frueh */
/* Your games */
.flame--plus.flame--alive:not([data-fx]):not(.flame--pv) .flame__fx > rect { animation: flame-fxin .5s ease-out .05s both; }
.flame--plus.flame--alive:not([data-fx]):not(.flame--pv) .flame__fx > g { transform-box: view-box; transform-origin: 12px 12px; animation: flame-swirl 1.1s cubic-bezier(.2, .7, .2, 1) .1s both; }
@keyframes flame-swirl { 0% { opacity: 0; rotate: -200deg; scale: .6; } 60% { opacity: 1; } 100% { opacity: 1; rotate: 0deg; scale: 1; } }
/* Glut */
.flame[data-fx="ember"].flame--alive:not(.flame--pv) .flame__fx > rect, .flame[data-fx="ember"].flame--alive:not(.flame--pv) .flame__fx > g { animation: flame-flare 1.3s cubic-bezier(.4, 0, .3, 1) .05s both; }
@keyframes flame-flare { 0% { filter: brightness(.3) saturate(.6); } 40% { filter: brightness(.6) saturate(.85); } 55% { filter: brightness(.5) saturate(.8); } 75% { filter: brightness(1.7) saturate(1.3); } 100% { filter: none; } }
.flame[data-fx="ember"].flame--alive:not(.flame--pv) .flame__fx > circle { animation: flame-fxin .3s ease-out .95s backwards; }
/* Aurora (fuenfte Fassung, Esteban: «mach Aurora neu, ich vertraue dir»): ein helles Lichtband faehrt EINMAL schnell von unten durch die
   Flamme hindurch (das eigene Band der Aurora, nur heller und schneller), dahinter kommen die Lichter in einer weichen Welle von
   links her, Fleck fuer Fleck; danach laeuft das Band wieder in seinem langsamen Takt. */
.flame[data-fx="aurora"].flame--alive:not(.flame--pv) .flame__fx > rect:first-of-type { animation: flame-fxin .7s ease-out .05s both; }
.flame[data-fx="aurora"].flame--alive:not(.flame--pv) .flame__fx > rect:nth-of-type(2) { transform-box: view-box; animation: flame-aurora-sweep 1s cubic-bezier(.45, 0, .2, 1) .15s none; }
@keyframes flame-aurora-sweep { 0% { translate: 0 30px; opacity: 1; filter: brightness(2.2); } 100% { translate: 0 -30px; opacity: 1; filter: brightness(2.2); } }
.flame[data-fx="aurora"].flame--alive:not(.flame--pv) .flame__fx > g > g { transform-box: view-box; animation: flame-aurora-wave 1.2s cubic-bezier(.3, 0, .2, 1) both; }
.flame[data-fx="aurora"].flame--alive:not(.flame--pv) .flame__fx > g > g:nth-child(1) { animation-delay: .3s; } .flame[data-fx="aurora"].flame--alive:not(.flame--pv) .flame__fx > g > g:nth-child(2) { animation-delay: .42s; }
.flame[data-fx="aurora"].flame--alive:not(.flame--pv) .flame__fx > g > g:nth-child(3) { animation-delay: .54s; } .flame[data-fx="aurora"].flame--alive:not(.flame--pv) .flame__fx > g > g:nth-child(4) { animation-delay: .66s; }
.flame[data-fx="aurora"].flame--alive:not(.flame--pv) .flame__fx > g > g:nth-child(5) { animation-delay: .78s; } .flame[data-fx="aurora"].flame--alive:not(.flame--pv) .flame__fx > g > g:nth-child(n+6) { animation-delay: .9s; }
@keyframes flame-aurora-wave { 0% { opacity: 0; translate: -6px 3px; } 100% { opacity: 1; translate: 0 0; } }
/* Gold (Referenz) */
.flame[data-fx="gold"].flame--alive:not(.flame--pv) .flame__fx > * { animation: flame-fxin .5s ease-out .1s both; }
.flame[data-fx="gold"].flame--alive:not(.flame--pv) .flame__p--line:not(.flame__p--ink) { stroke: #fff8d0 !important; stroke-width: 1.6; stroke-dasharray: 18 82; stroke-dashoffset: 100; animation: flame-gleam 1s cubic-bezier(.3, 0, .2, 1) .3s both; }
@keyframes flame-gleam { 0% { stroke-dashoffset: 100; stroke-opacity: 0; } 15% { stroke-opacity: 1; } 85% { stroke-opacity: 1; } 100% { stroke-dashoffset: -18; stroke-opacity: 0; } }
/* Neon */
.flame[data-fx="neon"].flame--alive:not(.flame--pv) .flame__fx > * { animation: flame-neon-on .8s steps(1, end) 0s backwards; }
.flame[data-fx="neon"].flame--alive:not(.flame--pv) .flame__svg > path[filter] { transform-box: view-box; transform-origin: 12px 13px; animation: flame-neon-on .8s steps(1, end) 0s backwards, flame-neon-halo .5s ease-out .8s none; }   /* Halo: fill none, sonst stuende der grosse Schein schon vor dem Start (backwards) oder bliebe danach (forwards) */
@keyframes flame-neon-on { 0% { opacity: 0; } 10% { opacity: .8; } 18% { opacity: 0; } 32% { opacity: .6; } 40% { opacity: 0; } 52% { opacity: 1; } 60% { opacity: .2; } 68% { opacity: 1; } 100% { opacity: 1; } }
@keyframes flame-neon-halo { 0% { scale: 1.45; opacity: 1; } 100% { scale: 1; opacity: .55; } }
@keyframes flame-fxin { to { opacity: 1; } }
@keyframes flame-live { 0%, 100% { transform: scaleY(1) skewX(0); } 30% { transform: scaleY(1.07) skewX(-3.5deg); } 60% { transform: scaleY(.965) skewX(2.5deg); } 80% { transform: scaleY(1.05) skewX(-1.5deg); } }   /* #758: kraeftiger (war 1.04 / 2 Grad) */
.flame__n { font-size: var(--t-xs); line-height: 1; }
.flame__p--ink { stroke-width: 1.4; }   /* #748: gewaehlte Tinten-Kontur ueber einer farbigen Flamme */
/* #750 (Esteban): auch ohne Serie zeichnet sich der Umriss bei jedem Laden ein (nur die Fuellung bleibt weg) */
.flame--zero .flame__p { fill-opacity: 0; stroke-dasharray: 100; stroke-dashoffset: 100; animation: flame-draw 1.1s cubic-bezier(.35, .1, .25, 1) .15s forwards; }
.flame--pv.flame--zero .flame__p { animation: none; stroke-dashoffset: 0; }
/* #758 (Esteban): jede Neuzeichnung, die keine Ankunft ist (Regler, Kontur-Wechsel, Hub-Sync), traegt flame--pv: keine Start-Animation, nichts blendet ein */
.flame--pv .flame__svg, .flame--pv .flame__p, .flame--pv .flame__fx, .flame--pv .flame__fx > * { animation: none !important; opacity: 1; fill-opacity: 1; stroke-dashoffset: 0; }
.flame--pv .flame__wake { opacity: 1; }
.flame--big .flame__svg { width: 64px; height: 64px; flex-basis: 64px; }
.flame--big .flame__p { stroke-width: 1; }
.flame--big .flame__n { font-size: 3rem; letter-spacing: -0.04em; }
/* #748: die +1-Rueckmeldung (game.js G.dayPlus): die Flamme zuengelt einmal kraeftig, «+1» steigt neben ihr auf und verblasst.
   Kein Schleier, kein Ring; der normale Tag ist leise (t-1934), der Meilenstein hat sein eigenes Overlay. */
.flame { position: relative; }
.flame--up .flame__svg { animation: flame-up 1.1s cubic-bezier(.2, .8, .2, 1) both; }
.flame__up { position: absolute; left: calc(100% - 6px); top: -12px; font-size: var(--t-sm); font-weight: 700; color: var(--ink); pointer-events: none; animation: flame-plus 1.5s cubic-bezier(.2, .7, .2, 1) both; }
.flame--big .flame__up { font-size: var(--t-lg); }
@keyframes flame-up { 0% { transform: scale(1); } 30% { transform: scale(1.35) rotate(-4deg); } 55% { transform: scale(.94) rotate(3deg); } 100% { transform: none; } }
@keyframes flame-plus { 0% { opacity: 0; transform: translateY(6px); } 20% { opacity: 1; transform: translateY(-2px); } 70% { opacity: 1; transform: translateY(-10px); } 100% { opacity: 0; transform: translateY(-18px); } }
@media (prefers-reduced-motion: reduce) { .flame--up .flame__svg { animation: none; } .flame__up { animation: flame-plus-still 1.5s both; } }
@keyframes flame-plus-still { 0%, 80% { opacity: 1; } 100% { opacity: 0; } }
@keyframes flame-draw { to { stroke-dashoffset: 0; } }
@keyframes flame-fill { to { fill-opacity: 1; } }
a.streakbadge { text-decoration: none; padding: 0 9px 0 7px; }
a.streakbadge:hover, a.streakbadge:focus-visible { background: var(--paper-3); outline: none; }
@media (prefers-reduced-motion: reduce) { .flame__p, .flame--alive .flame__p { animation: none; fill-opacity: 1; stroke-dashoffset: 0; } .flame__tongue, .flame__tongues, .flame__sp, .flame__sp circle, .flame__trace { animation: none !important; } }

/* ---- Tagesabschluss: Vergleich + 7 Tage + Morgen (#744 R12, game.js G.dayEnd) --------------------------------------------- */
.dayend { width: 100%; margin: var(--s3) 0 0; padding-top: var(--s3); border-top: 1px solid var(--line); display: flex; flex-direction: column; gap: var(--s2); text-align: left; }
.daybeat { margin: -2px 0 var(--s2); font-size: var(--t-md); font-weight: 600; color: var(--ink); }   /* R13: direkt unter der Hauptzahl */
.dayend__row { display: flex; align-items: center; justify-content: space-between; gap: var(--s3); flex-wrap: wrap; }
.dayend__label { font-size: var(--t-xs); font-weight: 600; color: var(--ink-2); }
.week { display: inline-flex; gap: 7px; }
.week__d { display: inline-flex; flex-direction: column; align-items: center; gap: 3px; }
.week__d i { width: 14px; height: 14px; border-radius: var(--r-full); background: var(--paper-3); }
.week__d small { font-size: 9px; line-height: 1; font-weight: 600; color: var(--ink-3); }
.week__d.is-on i { background: var(--accent); }
.week__d.is-on small { color: var(--ink); }
.week__d.is-today i { box-shadow: 0 0 0 2px var(--paper), 0 0 0 3.5px var(--accent-line); }
/* #748: zwei weitere Zustaende im Streifen: nur gespielt (Ring, kein erfuellter Tag), geschuetzt (Tinte-3 mit Kerbe) */
.week__d.is-part i { background: transparent; box-shadow: inset 0 0 0 2px var(--accent-line); }
.week__d.is-shield i { background: var(--ink-3); -webkit-mask: radial-gradient(circle at 50% 40%, transparent 27%, #000 30%); mask: radial-gradient(circle at 50% 40%, transparent 27%, #000 30%); }
.week__d.is-shield small { color: var(--ink-2); }
.dayend__shield { margin: -2px 0 0; font-size: var(--t-xs); font-weight: 600; color: var(--ink-2); }
/* #748: die Erinnerung am Tagesende (game.js G.remindBlock): eine Frage, ein Feld, ein Knopf, ein stilles Nein */
.remindme { display: flex; flex-direction: column; gap: 8px; margin: var(--s2) 0 0; padding: var(--s3) 0 0; border-top: 1px solid var(--line); }
.remindme__q { margin: 0; font-size: var(--t-sm); font-weight: 600; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }   /* #803 (Esteban: «muss in DE und EN bei allen Spielen auf EINE Zeile, sonst ist die Sektion zu breit»): Text gekuerzt + nie Umbruch */
.remindme__row { display: flex; gap: 8px; }
.remindme__mail { flex: 1 1 auto; min-width: 0; height: 44px; padding: 0 14px; border: 1px solid var(--line-strong); border-radius: var(--r-full); background: var(--paper); color: var(--ink); font: inherit; font-size: var(--t-sm); }
.remindme__mail:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--accent); }
.remindme__mail[aria-invalid="true"] { box-shadow: 0 0 0 2px var(--bad); }
.remindme__go { flex: 0 0 auto; height: 44px; padding: 0 16px; border: 0; border-radius: var(--r-full); background: var(--ink); color: var(--paper); font: inherit; font-size: var(--t-sm); font-weight: 600; cursor: pointer; white-space: nowrap; }
.remindme__go:disabled { opacity: .5; }
.remindme__no { align-self: flex-start; background: none; border: 0; padding: 2px 0; color: var(--ink-3); font: inherit; font-size: var(--t-xs); cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }
.remindme__err { margin: 0; font-size: var(--t-xs); color: var(--bad); }
/* #749: die Frage nach der Nutzungsmessung am Tagesabschluss (game.js consentBlock) und auf der Serien-Seite. Gleiche Stimme wie die Erinnerung. */
/* #750 (Esteban): der Cookie-Banner auf den Seiten ohne Spiel (_shared/consent.js). Ein weisses Blatt am unteren Rand, das wie das
   Reveal-Blatt aufsteigt; am Handy volle Breite, am Rechner links unten. Eine Frage, ein Satz, zwei gleich grosse Pillen, der Link. */
.cb { position: fixed; left: 0; right: 0; bottom: 0; z-index: 60; padding: 0 var(--s3) max(var(--s3), env(safe-area-inset-bottom)); transform: translateY(110%); transition: transform var(--d-slow) var(--ease-o), opacity var(--d-mid) var(--ease); pointer-events: none; }
.cb.is-in { transform: translateY(0); pointer-events: auto; }
.cb.is-away { transform: translateY(110%); opacity: 0; pointer-events: none; }
.cb__in { max-width: 460px; margin: 0 auto; padding: var(--s4) var(--s5) var(--s4); background: var(--paper); border-radius: var(--r-lg); box-shadow: 0 -1px 0 rgba(14,14,17,.04), 0 -14px 28px -12px rgba(14,14,17,.16), 0 0 0 1px var(--line); }
@media (min-width: 720px) { .cb { left: auto; right: var(--s5); bottom: var(--s5); padding: 0; } .cb__in { width: 420px; } }   /* #750 (Esteban): am Rechner rechts unten */
/* #750 (Esteban, dritte Runde): die Karte bleibt, nur der SATZ steht am Rechner auf einer Zeile (Karte so breit wie der Satz) */
@media (min-width: 720px) { .cb__in { width: 420px; } .cb__t { white-space: nowrap; } }   /* Satz gekuerzt, damit er in 420 px auf eine Zeile passt */
.cb__q { margin: 0 0 4px; font-size: var(--t-md); font-weight: 700; color: var(--ink); letter-spacing: -0.01em; }
.cb__t { margin: 0 0 var(--s3); font-size: var(--t-sm); color: var(--ink-2); line-height: 1.4; text-wrap: pretty; }
.cb__row { display: flex; align-items: center; gap: 8px; }
.cb__yes, .cb__no { flex: 0 0 auto; border: 0; border-radius: var(--r-full); font: inherit; font-weight: 600; cursor: pointer; transition: transform var(--d-fast) var(--ease); }
/* #750 (Esteban): «Allow» deutlich groesser als «Not now» */
.cb__yes { height: 52px; padding: 0 30px; font-size: var(--t-md); background: var(--ink); color: var(--paper); }
.cb__no { height: 38px; padding: 0 14px; font-size: var(--t-xs); background: transparent; color: var(--ink-2); box-shadow: inset 0 0 0 1.5px var(--line-strong); }
.cb__yes:hover, .cb__no:hover, .cb__yes:focus-visible, .cb__no:focus-visible { transform: translateY(-1px); outline: none; }
.cb__yes:focus-visible, .cb__no:focus-visible { box-shadow: 0 0 0 3px var(--accent-line); }
.cb__link { margin-left: auto; font-size: var(--t-xs); font-weight: 500; color: var(--ink-3); text-decoration: underline; text-underline-offset: 3px; }
.cb__link:hover { color: var(--ink); }
@media (prefers-color-scheme: dark) { html:not([data-theme="light"]) .cb__in { box-shadow: 0 -1px 0 rgba(255,255,255,.05), 0 -14px 28px -12px rgba(0,0,0,.55), 0 0 0 1px var(--line); } }
html[data-theme="dark"] .cb__in { box-shadow: 0 -1px 0 rgba(255,255,255,.05), 0 -14px 28px -12px rgba(0,0,0,.55), 0 0 0 1px var(--line); }
/* #822 Landing-Varianten (Esteban: auf der Homepage fuer EU-Nutzer groesser, Spiele bleiben). Gemeinsam: grosse Schrift,
   zwei gleich grosse Knoepfe (Allow gefuellt, Not now umrandet), Datenschutz-Link bleibt sichtbar. */
.cb__ico { display: inline-grid; place-items: center; flex: 0 0 auto; width: 48px; height: 48px; border-radius: 14px; background: var(--accent-soft); color: var(--accent); }
.cb__ico svg { fill: currentColor; }
.cb--a .cb__q, .cb--b .cb__q { font-size: var(--t-lg); margin-bottom: 6px; }
.cb--a .cb__t, .cb--b .cb__t, .cb--c .cb__t { font-size: var(--t-md); white-space: normal; }
.cb--a .cb__yes, .cb--a .cb__no, .cb--b .cb__yes, .cb--b .cb__no, .cb--c .cb__yes, .cb--c .cb__no { height: 52px; padding: 0 28px; font-size: var(--t-md); }
.cb--a .cb__no, .cb--b .cb__no, .cb--c .cb__no { color: var(--ink); }
/* A · Grosse Karte: Ort wie heute (Handy unten, Rechner rechts unten), alles groesser, Knoepfe teilen die Breite */
.cb--a .cb__in { max-width: 560px; padding: var(--s5) var(--s5) var(--s4); }
.cb--a .cb__row { flex-wrap: wrap; }
.cb--a .cb__yes, .cb--a .cb__no { flex: 1 1 0; white-space: nowrap; }
.cb--a .cb__link { flex: 1 0 100%; margin: 4px 0 0; text-align: center; }
@media (min-width: 720px) { .cb--a .cb__in { width: 500px; } }
/* B · Leiste unten: Handy randlos am unteren Rand (Griff oben), Rechner breite Leiste mittig, Text links, Knoepfe rechts */
.cb--b { padding: 0; }
.cb--b .cb__in { max-width: none; display: grid; grid-template-columns: auto 1fr; gap: var(--s3) var(--s4); align-items: start; border-radius: 22px 22px 0 0; padding: var(--s5) var(--s4) max(var(--s4), env(safe-area-inset-bottom)); position: relative; }
.cb--b .cb__in::before { content: ''; position: absolute; top: 8px; left: 50%; width: 36px; height: 4px; margin-left: -18px; border-radius: 4px; background: var(--line-strong); }
.cb--b .cb__t { margin-bottom: 0; }
.cb--b .cb__row { grid-column: 1 / -1; flex-wrap: wrap; }
.cb--b .cb__yes, .cb--b .cb__no { flex: 1 1 0; white-space: nowrap; }
.cb--b .cb__link { flex: 1 0 100%; margin: 4px 0 0; text-align: center; }
@media (min-width: 720px) {
  .cb--b { left: 0; right: 0; bottom: var(--s5); padding: 0 var(--s5); }
  .cb--b .cb__in { width: auto; max-width: 900px; margin: 0 auto; grid-template-columns: auto 1fr auto; align-items: center; border-radius: var(--r-lg); padding: var(--s4) var(--s5); }
  .cb--b .cb__in::before { display: none; }
  .cb--b .cb__row { grid-column: auto; flex-wrap: nowrap; }
  .cb--b .cb__yes, .cb--b .cb__no { flex: 0 0 auto; width: 150px; padding: 0; }
  .cb--b .cb__link { flex: 0 0 auto; margin: 0 0 0 8px; }
}
/* C · Mitte: Karte in der Mitte ueber leichtem Schleier, Symbol oben, Knoepfe untereinander; Klick daneben = Not now */
/* C · Mitte, Glas (#822 Esteban: Glassmorphism, Piktogramm animiert, erst nach dem Hero). Das Glas hat einen Grund: die Karte
   schwebt ueber der echten Seite, man sieht sie unscharf dahinter. Schleier = leichte Unschaerfe statt Abdunkeln.
   Rand = Regenbogen-Linie als eigene Ebene (::after mit Maske), weil eine durchscheinende Flaeche den Verlauf sonst durchliesse. */
.cb--c { top: 0; display: grid; place-items: center; padding: var(--s4); background: rgba(14,14,17,0); transform: none; opacity: 1; transition: background-color 420ms var(--ease-o); }   /* #822: nie opacity am Elternteil, sonst setzt das Glas der Karte waehrend des Einblendens aus und springt am Ende ein */
.cb--c.is-in { background: rgba(14,14,17,.10); transform: none; }
.cb--c.is-away { background: rgba(14,14,17,0); opacity: 1; transform: none; transition-duration: 260ms; }
.cb--c .cb__in { position: relative; isolation: isolate; width: 100%; max-width: 420px; margin: 0; text-align: center; padding: var(--s5) var(--s4) var(--s4); border-radius: 28px;
  background: color-mix(in oklab, var(--paper) 82%, transparent); -webkit-backdrop-filter: blur(14px) saturate(1.15); backdrop-filter: blur(14px) saturate(1.15);   /* wie die Navigation (nav.css .nav__pill) */
  box-shadow: var(--shadow-2), 0 24px 48px -28px rgba(14,14,17,.28);
  opacity: 0; transform: translateY(16px) scale(.97); transition: opacity 320ms var(--ease-o), transform 560ms var(--ease-o); will-change: transform, opacity; }
.cb--c.is-in .cb__in { opacity: 1; transform: none; }
.cb--c.is-away .cb__in { opacity: 0; transform: translateY(10px) scale(.98); transition-duration: 220ms; }
.cb--c .cb__in::after { content: ''; position: absolute; inset: 0; z-index: -1; border-radius: inherit; padding: 2px; pointer-events: none;
  background: conic-gradient(from var(--vga), oklch(var(--acl) var(--acc) 40), oklch(var(--acl) var(--acc) 262), oklch(var(--acl) var(--acc) 150), oklch(var(--acl) var(--acc) 300), oklch(var(--acl) var(--acc) 75), oklch(var(--acl) var(--acc) 350), oklch(var(--acl) var(--acc) 235), oklch(var(--acl) var(--acc) 178), oklch(var(--acl) var(--acc) 205), oklch(var(--acl) var(--acc) 320), oklch(var(--acl) var(--acc) 40)); 
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); mask-composite: exclude; }
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) { .cb--c .cb__in { background: var(--paper); } .cb--c { background: rgba(14,14,17,.28); } }
.cb--c .cb__ico { display: block; width: 64px; height: 48px; margin: 0 auto var(--s4); border-radius: 0; background: none; }
.cb--c .cb__q { white-space: nowrap; font-size: clamp(1.25rem, 6.2vw, 1.75rem); line-height: 1.15; margin-bottom: var(--s2); letter-spacing: -0.03em; }
.cb--c .cb__t { margin-bottom: var(--s5); color: var(--ink-2); }
.cb--c .cb__row { flex-direction: column; align-items: stretch; gap: 10px; }
.cb--c .cb__no { background: transparent; box-shadow: inset 0 0 0 1.5px var(--line-strong); }
.cb--c .cb__no:hover { background: var(--paper); }
.cb--c .cb__link { margin: 8px auto 0; }
@media (min-width: 720px) { .cb--c { left: 0; right: 0; bottom: 0; padding: var(--s5); } .cb--c .cb__in { width: 420px; padding: var(--s6) var(--s6) var(--s5); } .cb--c .cb__t { white-space: normal; } }
@media (prefers-reduced-motion: reduce) { .cb--c .cb__in { transform: none; transition: opacity 200ms linear; } }
.cb__wm { display: inline-flex; align-items: flex-start; font-family: Onest, ui-sans-serif, system-ui, sans-serif; font-weight: 700; letter-spacing: -0.035em; }
.cb__wm svg { width: .36em; height: .36em; margin: .02em 0 0 .03em; }
/* Piktogramm C: steigende Linie (Spielfarben), zeichnet sich einmal nach dem Auftritt der Karte, dann setzt sich der Punkt. */
.cbl { width: 64px; height: 48px; overflow: visible; }
.cbl__l { stroke-dasharray: 1 1; stroke-dashoffset: 1; opacity: 0; animation: cbl-draw 900ms cubic-bezier(.65,0,.35,1) .5s both; }   /* opacity: sonst zeigt die runde Kappe vorab einen Punkt */
.cbl__d { fill: oklch(66% 0.17 40); transform-box: fill-box; transform-origin: center; transform: scale(0); animation: cbl-dot 420ms var(--ease-o) 1.32s both; }
@keyframes cbl-draw { 0% { opacity: 0; stroke-dashoffset: 1; } 1% { opacity: 1; } 100% { opacity: 1; stroke-dashoffset: 0; } }
@keyframes cbl-dot { 60% { transform: scale(1.25); } to { transform: none; } }
@media (prefers-reduced-motion: reduce) { .cbl__l { animation: none; stroke-dashoffset: 0; opacity: 1; } .cbl__d { animation: none; transform: none; } }
@media (prefers-reduced-motion: reduce) { .cb { transition: none; } }
.consentq { display: flex; flex-direction: column; gap: 6px; margin: var(--s2) 0 0; padding: var(--s3) 0 0; border-top: 1px solid var(--line); }
.consentq__q { margin: 0; font-size: var(--t-sm); font-weight: 600; color: var(--ink); }
.consentq__t { margin: 0; font-size: var(--t-xs); color: var(--ink-2); line-height: 1.4; max-width: 60ch; text-wrap: pretty; }
.consentq__row { display: flex; gap: 8px; align-items: center; margin-top: 4px; }
.consentq__yes { height: 40px; padding: 0 16px; border: 0; border-radius: var(--r-full); background: var(--ink); color: var(--paper); font: inherit; font-size: var(--t-sm); font-weight: 600; cursor: pointer; }
.consentq__no { height: 40px; padding: 0 14px; border: 0; border-radius: var(--r-full); background: transparent; box-shadow: inset 0 0 0 1.5px var(--line-strong); color: var(--ink); font: inherit; font-size: var(--t-sm); font-weight: 600; cursor: pointer; }
.consentq__state { display: inline-flex; align-items: center; gap: 10px; font-size: var(--t-sm); color: var(--ink-2); }
.consentq__state button { background: none; border: 0; padding: 0; color: var(--ink); font: inherit; font-size: var(--t-sm); cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }
/* #761: Morgen-Kachel + Erinnerung nebeneinander (Rechner), untereinander (Handy) */
.dayend__grid { display: grid; grid-template-columns: 1fr; gap: var(--s2); align-items: stretch; }
@media (min-width: 600px) { .dayend__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--s3); } }
.dayend__grid .remindme { margin: 0; padding: var(--s2) var(--s3); border: 0; border-radius: var(--r-md, 12px); background: var(--paper-2); gap: 6px; justify-content: center; }
.dayend__grid .remindme__q { font-size: var(--t-xs); font-weight: 600; color: var(--ink); }
.dayend__grid .remindme__row { flex-wrap: wrap; }   /* schmale Spalte (Rechner mit Zoom): Feld und Knopf untereinander statt zerquetscht */
.dayend__grid .remindme__mail { height: 38px; padding: 0 12px; font-size: var(--t-xs); flex: 1 1 150px; }
.dayend__grid .remindme__go { flex: 1 1 auto; }
.dayend__grid .remindme__go { height: 38px; padding: 0 12px; font-size: var(--t-xs); }
.remindme--in { display: grid; place-items: center; font-size: var(--t-sm); font-weight: 600; color: var(--ink-2); }
.dayend__tomorrow { display: flex; align-items: center; gap: var(--s3); padding: var(--s2) var(--s3); border-radius: var(--r-md, 12px); background: var(--paper-2); }
.dayend__sil { flex: 0 0 auto; width: 84px; height: 60px; display: grid; place-items: center; filter: blur(5px); opacity: .6; }   /* #761 Esteban: das Tier von morgen groesser, bleibt unscharf */
.dayend__sil svg { width: 100%; height: 100%; fill: var(--ink); }
.dayend__sil img { max-width: 56px; max-height: 32px; width: auto; height: auto; }
.dayend__txt { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
/* #761: Gestern-Kachel (Archiv-Einstieg), gleiche Form wie Morgen; als Link */
a.dayend__yday { text-decoration: none; color: inherit; transition: background var(--d-fast) var(--ease); }
a.dayend__yday:hover, a.dayend__yday:focus-visible { background: var(--paper-3); outline: none; }
.dayend__yday .dayend__txt > span { color: var(--ink); font-weight: 600; }
.dayend__mailok { font-size: .8em; font-weight: 700; color: var(--good); }   /* #803: nur ein Haekchen am Titel «Morgen», die Kachel waechst nicht */
/* #803 (Esteban, gewaehlt «zwei halbe Kacheln», dann: «links Gestern, rechts Morgen, am Computer gleich»): Gestern | Morgen nebeneinander,
   niedrig; ohne Mail-Eintrag darunter das Mail-Feld in EINER Zeile (Frage im Feld). Ohne Gestern-Kachel nimmt Morgen die ganze Breite. */
:root body .dayend .dayend__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 8px; }
:root body .dayend .dayend__grid:not(:has([data-part="yday"])) [data-part="tomorrow"] { grid-column: 1 / -1; }
:root body .dayend .dayend__grid [data-part="remind"] { grid-column: 1 / -1; padding: 0; background: none; }
:root body .dayend .dayend__grid .remindme__q { display: none; }
:root body .dayend .dayend__grid [data-part="remind"] > .remindme__q:only-child { display: block; white-space: normal; font-size: var(--t-xs); font-weight: 600; color: var(--ink-2); padding: 2px 4px; }
:root body .dayend .dayend__grid .remindme__row { flex-wrap: nowrap; }
:root body .dayend .dayend__grid .remindme__mail { height: 40px; flex: 1 1 auto; font-size: var(--t-sm); }
:root body .dayend .dayend__grid .remindme__go { height: 40px; flex: 0 0 auto; padding: 0 22px; font-size: var(--t-sm); }
:root body .dayend .dayend__grid .dayend__tomorrow { gap: 10px; padding: 8px 12px; min-width: 0; }
:root body .dayend .dayend__grid .dayend__sil { width: 48px; height: 36px; filter: blur(3px); }
:root body .dayend .dayend__grid .dayend__sil img { max-width: 40px; max-height: 28px; }
:root body .dayend .dayend__grid .dayend__txt b { font-size: var(--t-sm); white-space: nowrap; }
:root body .dayend .dayend__grid .dayend__txt span { font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 599px) { :root body .dayend .dayend__grid [data-part="yday"] .dayend__txt b { white-space: normal; line-height: 1.15; } }   /* «Gestern verpasst» bricht am Handy in zwei Zeilen statt abgeschnitten */
/* #803 (Esteban): am Rechner steht die Mail-Frage RECHTS neben «Morgen» in derselben Reihe (Gestern | Morgen | Mail), am Handy darunter */
@media (min-width: 600px) {
  :root body .dayend .dayend__grid { display: flex; gap: 8px; }
  :root body .dayend .dayend__grid > * { flex: 1 1 0; min-width: 0; }
  :root body .dayend .dayend__grid > [data-part="tomorrow"]:has([data-part="remind"]) { flex: 2.2 1 0; }
  :root body .dayend .dayend__grid [data-part="tomorrow"] > [data-part="remind"] { flex: 1 1 auto; max-width: 340px; margin: 0 0 0 auto; padding: 0; background: none; border: 0; align-self: center; }
  :root body .dayend .dayend__grid [data-part="tomorrow"] > [data-part="remind"] .remindme__q { display: none; }
  :root body .dayend .dayend__grid [data-part="tomorrow"] > [data-part="remind"] > .remindme__q:only-child { display: block; white-space: normal; font-size: var(--t-xs); font-weight: 600; color: var(--ink-2); }
  :root body .dayend .dayend__grid [data-part="tomorrow"] > [data-part="remind"] .remindme__mail { background: var(--paper); }
}

.dayend__txt b { font-size: var(--t-md); font-weight: 700; color: var(--ink); }
.dayend__txt span { font-size: var(--t-xs); color: var(--ink-2); }

/* ---- Meilenstein-Overlay (#744 R17, Esteban: «Tag 7 muss eine geile Animation haben»): game.js G.milestone ------------------
   Papier mit Schleier, zwei Ringe in den Spielfarben laufen nach aussen, die grosse Flamme waechst aus der Mitte (mile-pop),
   dann Zahl und Satz. Tippen schliesst (is-out). ---- */
.mile { position: fixed; inset: 0; z-index: 70; display: grid; place-items: center; background: color-mix(in oklab, var(--paper) 86%, transparent); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); animation: mile-in .4s var(--ease-o) both; cursor: pointer; overflow: hidden; }
.mile.is-out { animation: mile-out .4s var(--ease) both; }
/* #748 Rand-Lauf (G.rimRun): der Regenbogen als Rahmen um den Schirm, oeffnet sich im Kreis (--sweep), verblasst. Zwei Masken
   auf zwei Elementen wie plus.html (.unlock), hier geteilt fuer Meilensteine und den Archivtag. */
@property --sweep { syntax: '<angle>'; inherits: false; initial-value: 0deg; }
.rimrun { position: fixed; inset: 0; z-index: 80; pointer-events: none; --sweep: 0deg; opacity: 1; transition: opacity .7s var(--ease);
  -webkit-mask: conic-gradient(from -90deg at 50% 50%, #000 var(--sweep), transparent 0); mask: conic-gradient(from -90deg at 50% 50%, #000 var(--sweep), transparent 0); }
.rimrun__ring { position: absolute; inset: 8px; border-radius: 26px; padding: 3px; display: block; background: var(--rb); background-size: 200% 100%; animation: rb-run 3.2s linear infinite;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask-composite: exclude; }
.rimrun[data-on] { animation: rim-sweep var(--dur, 1.6s) var(--ease-o) forwards; }
@keyframes rim-sweep { from { --sweep: 0deg; } to { --sweep: 360deg; } }
.rimrun[data-out] { opacity: 0; }
/* #748 (Esteban): Stufen der Meilensteine. t1 (3, 7): Papier, ein Regenbogen-Ring, Flamme 96 px. t2 (14, 30): dazu der
   Rand-Lauf. t3 (60, 100): Flamme 132 px, zwei Ringe, Titel groesser, Rand-Lauf doppelt (game.js). */
.mile__ring { position: absolute; left: 50%; top: 50%; width: 120px; height: 120px; margin: -60px 0 0 -60px; border-radius: 50%; background: var(--ring); -webkit-mask: radial-gradient(circle, transparent 58%, #000 60%, #000 66%, transparent 68%); mask: radial-gradient(circle, transparent 58%, #000 60%, #000 66%, transparent 68%); animation: mile-ring 1.1s cubic-bezier(.2, .7, .2, 1) .2s both; }
.mile__card { position: relative; display: flex; flex-direction: column; align-items: center; gap: 6px; text-align: center; padding: var(--s6); }
.mile__card .flame { flex-direction: column; gap: 4px; animation: mile-pop .7s cubic-bezier(.2, .8, .2, 1) both; }
.mile__card .flame__svg { width: 96px; height: 96px; flex-basis: 96px; }
.mile--t3 .mile__card .flame__svg { width: 132px; height: 132px; flex-basis: 132px; }
.mile--t3 .mile__card .flame { animation-duration: 1.1s; }
.mile--t3 .mile__ring { width: 160px; height: 160px; margin: -80px 0 0 -80px; animation-duration: 1.8s; }
.mile__ring--2 { animation-delay: .6s !important; animation-duration: 2.1s !important; }
.mile--t3 .mile__t { font-size: clamp(2.6rem, 9vw, 3.8rem); }
.mile__card .flame__n { display: none; }
.mile__k { margin: var(--s3) 0 0; font-size: var(--t-sm); font-weight: 700; color: var(--ink-3); letter-spacing: .02em; text-transform: uppercase; animation: mile-in .4s var(--ease-o) .35s both; }
.mile__t { margin: 4px 0 0; font-size: clamp(2.2rem, 7vw, 3.2rem); font-weight: 700; letter-spacing: -0.045em; line-height: 1; color: var(--ink); animation: mile-in .4s var(--ease-o) .45s both; }
.mile__s { margin: 4px 0 0; font-size: var(--t-lg); color: var(--ink-2); animation: mile-in .4s var(--ease-o) .6s both; }
.mile__link { margin: var(--s2) 0 0; font-weight: 700; }
.mile--info { cursor: default; }
.mile__tap { margin: var(--s5) 0 0; font-size: var(--t-xs); color: var(--ink-3); animation: mile-in .4s var(--ease-o) 1.1s both; }
@keyframes mile-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes mile-out { to { opacity: 0; } }
@keyframes mile-pop { 0% { transform: scale(.6); opacity: 0; } 100% { transform: none; opacity: 1; } }
@keyframes mile-ring { 0% { transform: scale(.4); opacity: 0; } 15% { opacity: .9; } 100% { transform: scale(6); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .mile, .mile__ring, .mile__card .flame, .mile__t, .mile__s, .mile__tap { animation: none; } .mile__ring { display: none; } }

/* ---- Serienschutz-Angebot (#744 R21, Esteban): Karte auf der Serien-Seite, wenn genau ein Tag fehlt ---- */
.shield { position: fixed; inset: 0; z-index: 70; display: grid; place-items: center; padding: var(--s5); background: color-mix(in oklab, var(--paper) 80%, transparent); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); animation: mile-in .35s var(--ease-o) both; }
.shield__card { width: 380px; max-width: 100%; padding: var(--s6) var(--s5) var(--s5); background: var(--paper); border-radius: var(--r-lg); box-shadow: var(--shadow-2); text-align: center; display: flex; flex-direction: column; align-items: center; gap: var(--s3); }
.shield__card .flame__svg { width: 56px; height: 56px; flex-basis: 56px; }
.shield__q { margin: 0; font-size: clamp(1.5rem, 5vw, 1.9rem); font-weight: 700; letter-spacing: -0.035em; line-height: 1.05; color: var(--ink); }
.shield__t { margin: 0; font-size: var(--t-md); color: var(--ink-2); line-height: 1.4; text-wrap: pretty; }
.shield__ok { display: inline-flex; align-items: center; justify-content: center; min-height: 52px; padding: 0 26px; border: 0; border-radius: var(--r-full); background: var(--ink); color: var(--paper); font: inherit; font-weight: 600; cursor: pointer; }
.shield__no { background: none; border: 0; color: var(--ink-3); font: inherit; font-size: var(--t-sm); cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }

/* #753: die Navigations-Regeln (Pille, Blatt, #750-Zusaetze) stehen NUR in _shared/nav.css; nav.js baut das Markup. */

/* ---- Duotone-Piktogramme der Spiele (#753, Esteban): gefuellte Illustration in zwei Toenen der Spielfarbe. Farbe = currentColor
   des Traegers; Ausschnitte in Papier; Striche (Flussband, Preis-Kerbe, Kurve) ebenfalls in currentColor. Legacy-Regeln wie
   `.gr svg { fill:none; stroke:currentColor }` sitzen auf dem <svg>, die Kinder hier setzen Fuellung/Strich selbst. */
svg.pk-duo { fill: none; stroke: none; }
svg.pk-duo .A { fill: currentColor; stroke: none; }
svg.pk-duo .S { fill: currentColor; stroke: none; opacity: .32; }
svg.pk-duo .P { fill: var(--paper); stroke: none; }
svg.pk-duo .La { fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
svg.pk-duo .Ls { fill: none; stroke: currentColor; stroke-width: 6; stroke-linecap: round; stroke-linejoin: round; opacity: .32; }

/* #757 (Esteban): das Mix-Zeichen = fuenf Punkte der heutigen Spiele. Animation «1-2-3-4-5 erscheinen, das Rad dreht kurz und
   laeuft langsam aus»: beim Zeigen (Fuss/Serie/Pille/CTA) und einmal beim ersten Besuch (Pille, data-wink); beim Verlassen dreht
   das Rad denselben Weg zurueck (Transition statt Keyframe). Regeln hier, damit site.css, nav.css und streak.html sie teilen. */
.gr__mixpk svg, .nav__mixpk svg { transform-origin: 50% 50%; transform: rotate(0deg); transition: transform 1.3s cubic-bezier(.15, .75, .25, 1); }   /* Drehung hin (Zeigen) und zurueck (Verlassen) */
.gr__mixpk circle, .nav__mixpk circle { transform-box: fill-box; transform-origin: center; }
@keyframes mixpop { from { transform: scale(0); opacity: 0; } to { transform: scale(1); opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .gr__mixpk svg, .gr__mixpk circle, .nav__mixpk svg, .nav__mixpk circle { animation: none !important; } }

/* ---- Rechner: die Schrift NUR IM BLATT eine Stufe hoch (#768, Runde 2) ------
   Runde 1 hob die ganze Leiter, auch auf der SPIELflaeche. Esteban: «bei Where
   musstest du eigentlich das nicht aendern, nur beim Reveal Screen» - die Karte
   und der Satz rutschten dadurch nach unten (Regression). Die Spielflaeche
   bleibt also exakt wie vorher; groesser wird nur, was IM Blatt steht.
   Steht ganz unten, sonst verliert die Regel bei gleicher Spezifitaet (#761). */
@media (min-width: 900px) and (min-height: 700px) {
  .sheet .sheet__verdict, .sheet .said, .sheet .sheet__line, .sheet .rv__truth,
  .sheet .truthline, .sheet .belong, .sheet .sg-said, .sheet .crowdline,
  .sheet .beat, .sheet .rv__dir, .sheet .factor__dir {
    font-size: var(--t-lg);
  }
  .sheet__scroll > p, .sheet > p { max-width: 62ch; }
  .sheet .srow__what, .sheet .srow__f, .sheet .srow { font-size: var(--t-md); }
  .sheet .sheet__src { font-size: var(--t-sm); }
}


/* ---- #768: DIE Tipp-Reihe, einmal fuer alle Spiele ------------------------
   (Esteban: «bei How many ist der Tipp oben statt unten · bei How sweet fehlt
   die richtige Anordnung, rechts tippen, links den Tipp einloesen · bei Which
   way soll der Tipp eigentlich auch unten sein · das muss uniform sein».)
   Gemessen vorher: jedes Spiel haengte den Tipp woanders hin - How big und How
   wide unten in einer Zeile, How many oben in der Buehne, Which way mitten in
   der Buehne (y=273), How sweet beim Gegenstand. Jetzt gilt EINE Regel:
   links der Tipp, rechts das Zahlenfeld, eine Zeile, direkt ueber dem Knopf.
   Fehlt eines von beidem, bleibt das andere an seiner Seite stehen. */
.aidrow {
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s3); width: 100%;
  margin-top: var(--s3);
}
.aidrow:empty { display: none; }
.aidrow > * { margin: 0; }
/* Steht nur EINES da, gehoert es trotzdem auf seine Seite, nicht in die Mitte. */
.aidrow > .hintbtn:only-child { margin-right: auto; }
.aidrow > .numfield:only-child { margin-left: auto; }
@media (min-width: 900px) and (min-height: 700px) {
  /* Am Rechner buendig mit dem Knopf darunter (der ist dort 460 px breit). */
  .aidrow { max-width: 460px; margin-inline: auto; }
}


/* #768 (Esteban-Entscheid): die Beschriftung «or type it / oder tippen» faellt
   ueberall weg. Sie erklaert nichts - ein Feld mit einer Zahl und einer Einheit
   IST ein Eingabefeld, und How wide? hatte es seit je ohne Wort. Am Handy kostet
   sie genau die Breite, die Tipp und Feld brauchen, um auf EINE Zeile zu passen.
   Der Text bleibt im DOM fuer Vorlese-Programme (aria-label am Feld). */
.numrow__lab { display: none; }


/* #768 (Esteban: «auf dem Desktop sind die beiden Links fast schon ineinander»
   und in Runde 2: «nur weil einer der beiden Links weiter rechts ist, ist einer
   ganz linksbuendig - das ist auch noch komisch»).
   Vorher: zwei Inline-Elemente ohne Trennung hintereinander; mit Einzug brach
   der zweite in eine neue Zeile und stand dann 16 px eingerueckt (gemessen:
   x=24 gegen x=40). Jetzt hat jede Quelle ihre EIGENE Zeile, beide buendig an
   derselben Kante wie alles andere im Blatt. */
.sheet__src { display: block; }
.sheet__src + .sheet__src { margin-left: 0; margin-top: var(--s1); }

/* #768: die Einordnungs-Zeile ist eine Aussage, kein Nachtrag - Fliesstext-
   Groesse und Abstand nach unten, nicht kleiner als der Rest. */
.beat, .dist__beat { font-size: var(--t-md); color: var(--ink-2); margin: 0 0 var(--s3); }
.beat:empty, .dist__beat:empty { display: none; }


/* ---- #768: die alten, jetzt leeren Tipp-/Feld-Wirte einklappen -----------
   (Esteban: «die anderen Spiele kann ich nicht mehr spielen, irgendetwas ist
   grundlegend falsch».) Seit Tipp und Zahlenfeld in der geteilten Reihe haengen,
   sind die frueheren Wirte in den Spielen LEER - aber sie standen weiter im
   Fluss und lagen ueber dem Festlegen-Knopf. Gemessen mit elementFromPoint auf
   der Knopf-Mitte: bei Which way? lag dort «row», bei When? und Who? «dock» -
   der Klick kam nie am Knopf an, das Spiel war unspielbar.
   Ein leerer Wirt nimmt jetzt weder Platz noch Klicks. */
.dock__row:empty, .dock__num:empty, .tools:empty,
.numhost:empty, .numrow:empty, .sg-numrow__a:empty, .sg-numrow__b:empty,
.dock .row:empty, .aid:empty { display: none !important; }

/* ---- #768: nach dem Aufdecken ist die Bedienung vorbei -------------------
   (Esteban: «wenn man jetzt aufdeckt, steht immer noch der Tipp pro Tag und das
   Eingabefeld - das sollte ja nicht mehr sein, weil unten der Reveal kommt, der
   eh schon alles zeigt».) Vorher raeumte jedes Spiel seine eigene Reihe selbst
   weg; die geteilte Reihe braucht die Regel einmal, hier. */
body.is-revealed .aidrow,
body.is-done .aidrow,
body.is-committed .aidrow,
.app[data-phase="reveal"] .aidrow,
.app[data-phase="done"] .aidrow { display: none; }


/* #768 (Esteban: «das Naeher-als-x-Prozent beginnt weiter links als die Zahl
   von so-und-so-mal-zu-gross»). Die Boxen liegen beide exakt auf derselben
   Kante (gemessen: x=24 und x=24) - der Versatz ist OPTISCH: eine Ziffer bei
   66 px Schriftgroesse hat eine Seitenluft, die ein 17-px-Satz nicht hat.
   Darum wird die grosse Zahl um diese Luft nach links geruckt, damit ihre
   TINTE auf der Kante steht und nicht ihre Box. Der Wert haengt an der
   Schriftgroesse, nicht an einer festen Pixelzahl. */
.factor, .mega, .rv__num { margin-left: -0.045em; }

/* #782 Rückkanal + Freunde-Ziele (Rest in duel.css, nachgeladen). Diese drei Stellen stehen in game.js/streak.js und
   müssen ohne duel.css tragen: der zweite Weg im Flammen-Blatt, die Zeile unter «Teilen», der Knopf im Flammen-Editor. */
.gate__friends { display: inline-flex; align-items: center; justify-content: center; gap: 8px; align-self: stretch; min-height: 48px; margin: 8px 0 0; padding: 0 18px; border: 0; border-radius: var(--r-full); background: var(--paper-2); color: var(--ink); font: inherit; font-size: var(--t-md); font-weight: 600; cursor: pointer; transition: background var(--d-fast) var(--ease), transform var(--d-fast) var(--ease); }
.gate__friends:hover, .gate__friends:focus-visible { background: var(--paper-3); outline: none; transform: translateY(-1px); }
.gate__friends:active { transform: scale(.98); }
/* #836 Freunde bringen (Esteban): an der Archiv-Wand dreht die Karte zum Einladen, ohne neue Karte; Inhalt der Wand tritt zurueck. */
.gate__card[data-inv] > :not(.gate__inv) { display: none; }
.gate__inv { display: none; flex-direction: column; align-items: stretch; width: 100%; }
.gate__card[data-inv] > .gate__inv { display: flex; }
button.gate__more { border: 0; font: inherit; font-size: var(--t-md); font-weight: 600; }
button.gate__more:disabled { opacity: .55; cursor: default; }
.gate--prompt .gate__text:empty { display: none; }   /* #836: Flammen-Fenster ohne Erklaersatz */
.gate__wait { margin: 12px 0 0; font-size: var(--t-sm); color: var(--ink-3); text-align: center; }
.gate--wall .gate__inv .gate__links { grid-template-columns: 1fr; }
.gate__days { color: inherit; text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; text-decoration-color: var(--line-strong); }
.gate__days:hover, .gate__days:focus-visible { color: var(--ink); text-decoration-color: var(--ink); outline: none; }
.gate--invite .gate__more { align-self: stretch; }
.gate--invite .gate__links { margin-top: 8px; }
.gate__friends span { white-space: nowrap; font-size: clamp(.92rem, 3.9vw, 1.02rem); }
.gate__friends svg { width: 19px; height: 19px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; flex: 0 0 auto; }
.sc__note { display: flex; align-items: center; justify-content: center; gap: 8px; margin: 0 4px 2px; font-size: var(--t-sm); line-height: 1.35; color: var(--ink-2); text-align: center; text-wrap: balance; }   /* #782 Esteban: mittig */
.sc__note svg { width: 18px; height: 18px; flex: 0 0 auto; fill: none; stroke: var(--ink-3); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.flame__friends { display: inline-flex; align-items: center; min-height: 32px; margin-left: 6px; padding: 0 14px; border: 0; border-radius: var(--r-full); background: var(--ink); color: var(--paper); font: inherit; font-size: var(--t-xs); font-weight: 600; cursor: pointer; vertical-align: middle; }
.flame__friends:hover, .flame__friends:focus-visible { outline: none; transform: translateY(-1px); }
.flame__prog { color: var(--ink-2); font-weight: 500; }
.sc__note { display: block; }   /* #782: mittig mit dem Symbol direkt vor dem Text (nicht am Rand) */
.sc__note svg { display: inline-block; vertical-align: -4px; margin-right: 6px; }
.sc__note span { display: inline; }

/* ---- #783 Anzeige-Einstellungen: Chip in der Tipp-Reihe + Blatt (Waehrung, Masse) ----------------------------------
   Esteban #783 R3: nicht in der Kopfzeile, sondern mitten im Bild, und nur wo es etwas umzustellen gibt. Der Chip hat
   die Gestalt des Tipp-Knopfs daneben (gleiche Hoehe, gleiche Pille), traegt aber den Stand («CHF · kg») statt eines
   Befehls. Beim Oeffnen gleiten die zwei Regler-Knoepfe gegeneinander: der eine Moment dieses Knopfs. */
.prefschip { appearance: none; cursor: pointer; border: 0; flex: 0 0 auto;
  display: inline-flex; align-items: center; gap: 7px;
  padding: 0 var(--s4) 0 14px; min-height: 44px; border-radius: var(--r-full);
  background: var(--paper-2); color: var(--ink-2);
  font: inherit; font-size: var(--t-sm); font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap;
  transition: color var(--d-fast, .15s) var(--ease), background var(--d-fast, .15s) var(--ease), transform .2s var(--ease-o); }
.prefschip svg { width: 18px; height: 18px; flex: 0 0 18px; overflow: visible; color: var(--ink-3); transition: color .2s var(--ease); }
.prefschip:hover, .prefschip[data-open] { color: var(--ink); }
.prefschip:hover svg, .prefschip[data-open] svg { color: var(--accent); }
.prefschip:active { transform: scale(.97); }
.prefschip:focus-visible { outline: 2px solid var(--accent-line); outline-offset: 2px; }
.prefsbtn__k { transform-box: fill-box; transform-origin: center; transition: transform .42s var(--ease-o); }
.prefschip[data-open] .prefsbtn__k--a { transform: translateX(-6px); }
.prefschip[data-open] .prefsbtn__k--b { transform: translateX(6px); }
/* In der Reihe: Tipp links, Zahlenfeld rechts, der Chip dazwischen. Steht er allein, gehoert er in die Mitte. */
.aidrow > .prefschip:only-child { margin-inline: auto; }
.aidrow > .hintbtn + .prefschip:last-child { margin-left: auto; }
@media (max-width: 380px) { .prefschip { padding: 0 12px 0 11px; gap: 6px; } }

.prefs { position: fixed; z-index: 70; width: min(20.5rem, calc(100vw - 24px)); padding: var(--s4) var(--s4) var(--s3);
  display: grid; gap: var(--s4);
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--r-md); box-shadow: var(--shadow-2);
  opacity: 0; transform: translateY(-6px) scale(.96); filter: blur(3px);
  transition: opacity .16s var(--ease), transform .16s var(--ease), filter .16s var(--ease); }
.prefs[hidden] { display: none; }
.prefs[data-open] { opacity: 1; transform: none; filter: none;
  transition: opacity .22s var(--ease-o), transform .32s var(--ease-o), filter .26s var(--ease-o); }
/* Spitze zum Knopf: zeigt, woher das Blatt kommt */
.prefs::before { content: ""; position: absolute; top: -6px; left: calc(var(--nib, 50%) - 6px); width: 12px; height: 12px;
  background: var(--paper); border-left: 1px solid var(--line); border-top: 1px solid var(--line); border-top-left-radius: 3px; transform: rotate(45deg); }
.prefs[data-side="oben"]::before { top: auto; bottom: -6px; border-left: 0; border-top: 0;
  border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); border-radius: 0 0 3px 0; }
.prefs__row { display: grid; gap: var(--s2); }
.prefs__row[hidden] { display: none; }
.prefs__h { margin: 0; font-size: var(--t-xs); font-weight: 600; color: var(--ink-3); }
.prefs__seg { position: relative; display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; padding: 3px;
  background: var(--paper-2); border-radius: var(--r-full); isolation: isolate; }
.prefs__mark { position: absolute; z-index: -1; top: 3px; bottom: 3px; left: 0; border-radius: var(--r-full);
  background: var(--paper); box-shadow: 0 1px 2px rgba(14,14,17,.08), 0 3px 10px rgba(14,14,17,.08);
  transition: transform .34s var(--ease-o), width .34s var(--ease-o), opacity .2s var(--ease); }
.prefs__opt { appearance: none; border: 0; background: transparent; cursor: pointer; font: inherit; color: var(--ink-2);
  min-height: 40px; padding: 4px 6px; border-radius: var(--r-full);
  display: grid; place-content: center; justify-items: center; gap: 0; transition: color .2s var(--ease); }
.prefs__opt:hover { color: var(--ink); }
.prefs__opt:focus-visible { outline: 2px solid var(--accent-line); outline-offset: -2px; }
.prefs__opt[aria-checked="true"] { color: var(--ink); }
.prefs__t { font-size: var(--t-sm); font-weight: 600; line-height: 1.15; letter-spacing: -.01em; font-variant-numeric: tabular-nums; }
.prefs__seg--many .prefs__t { font-size: var(--t-xs); letter-spacing: .01em; }
.prefs__s { font-size: 11px; font-weight: 500; line-height: 1.2; color: var(--ink-3); }
.prefs__opt[aria-checked="true"] .prefs__s { color: var(--accent); }
@media (min-width: 900px) { .prefs__opt { min-height: 36px; } }
/* Jede Menge blendet beim Wechsel neu ein */
.q-flip { animation: qflip .38s var(--ease-o); }
@keyframes qflip { from { opacity: 0; filter: blur(3px); transform: translateY(3px); } to { opacity: 1; filter: none; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .prefs, .prefs[data-open], .prefs__mark, .prefsbtn__k, .prefschip { transition: none; }
  .q-flip { animation: none; }
}
/* Dunkel: die Marke ist heller als die Schiene (im Hellen ist sie weiss auf grau) */
:root[data-theme="dark"] .prefs__mark { background: var(--paper-3); box-shadow: 0 1px 2px rgba(0,0,0,.4); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .prefs__mark { background: var(--paper-3); box-shadow: 0 1px 2px rgba(0,0,0,.4); } }
/* Oeffnet das Blatt nach oben (Chip steht tief im Bild), waechst es von unten */
.prefs[data-side="oben"]:not([data-open]) { transform: translateY(6px) scale(.96); }
/* Volle Reihe am Handy (Tipp + Chip + Zahlenfeld): der Chip wird zum runden Zeichen, damit nichts umbricht.
   Der Stand steht im Blatt und im aria-label. */
@media (max-width: 520px) {
  .aidrow:has(> .hintbtn):has(> .numfield) > .prefschip { width: 44px; padding: 0; justify-content: center; }
  .aidrow:has(> .hintbtn):has(> .numfield) > .prefschip .prefschip__t { display: none; }
  .aidrow:has(> .hintbtn):has(> .numfield) { gap: var(--s2); }
}
@media (max-width: 520px) {
  .aidrow:has(> .hintbtn):has(> .numfield) > .hintbtn { white-space: nowrap; flex: 0 0 auto; padding: 0 14px; }
  .aidrow:has(> .hintbtn):has(> .numfield) > .numfield { min-width: 0; flex: 0 1 auto; white-space: nowrap; }
}

/* #790 Namensfilter (Esteban: «die Nachricht soll visuell gut aussehen»): eine ruhige Zeile unter dem Feld, Warnfarbe, kleines
   gezeichnetes Zeichen; das Feld bekommt einen Rand in derselben Farbe. Kein Wackeln, kein Popup - man sieht sofort, was zu tun ist. */
.namebad { display: flex; align-items: flex-start; gap: 6px; margin: 8px 0 0; padding: 0; font-size: var(--t-xs); font-weight: 600; line-height: 1.35; color: var(--bad); text-align: left; animation: namebad-in .22s var(--ease-o, ease-out) both; }
.namebad svg { flex: 0 0 auto; width: 14px; height: 14px; margin-top: 1px; }
@keyframes namebad-in { from { opacity: 0; transform: translateY(-3px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .namebad { animation: none; } }
input.is-namebad, input.is-namebad:focus { box-shadow: inset 0 0 0 2px var(--bad) !important; outline: none; }

/* #790 Pille «Zurueck in den Raum»: schwebt unten mittig ueber jeder Seite ausserhalb des Raums (fest, nie im Weg der Navigation),
   Tinte auf Papier-Rand, ein pulsierender Punkt = «laeuft gerade». Faehrt von unten ein. × blendet sie fuer diesen Raum aus. */
.roomback { position: fixed; left: 50%; bottom: calc(16px + env(safe-area-inset-bottom, 0px)); z-index: 90; display: flex; align-items: center; gap: 2px;
  padding: 5px 5px 5px 6px; border-radius: 999px; background: var(--ink); color: var(--paper); box-shadow: 0 10px 30px -8px rgba(14,14,17,.45), 0 2px 6px rgba(14,14,17,.18);
  transform: translate(-50%, 140%); opacity: 0; transition: transform .38s var(--ease-o, ease-out), opacity .3s var(--ease-o, ease-out); max-width: calc(100vw - 32px); }
.roomback.is-in { transform: translate(-50%, 0); opacity: 1; }
.roomback__go { display: inline-flex; align-items: center; gap: 9px; padding: 8px 8px 8px 12px; border-radius: 999px; color: inherit; text-decoration: none; font-size: var(--t-sm); font-weight: 600; white-space: nowrap; }
.roomback__go b { font-weight: 800; letter-spacing: .06em; }
.roomback__go:hover, .roomback__go:focus-visible { background: color-mix(in oklab, var(--paper) 12%, transparent); outline: none; }
.roomback__dot { width: 8px; height: 8px; border-radius: 50%; background: oklch(72% 0.19 150); box-shadow: 0 0 0 0 oklch(72% 0.19 150 / .6); animation: roomback-puls 1.8s ease-out infinite; flex: 0 0 auto; }
@keyframes roomback-puls { 0% { box-shadow: 0 0 0 0 oklch(72% 0.19 150 / .55); } 70%, 100% { box-shadow: 0 0 0 8px oklch(72% 0.19 150 / 0); } }
.roomback__arr { font-style: normal; font-size: 18px; line-height: 1; opacity: .7; margin-left: -2px; }
.roomback__x { flex: 0 0 auto; width: 30px; height: 30px; border: 0; border-radius: 50%; background: transparent; color: inherit; opacity: .6; font: inherit; font-size: 18px; line-height: 1; cursor: pointer; }
.roomback__x:hover, .roomback__x:focus-visible { opacity: 1; background: color-mix(in oklab, var(--paper) 12%, transparent); outline: none; }
@media (prefers-reduced-motion: reduce) { .roomback { transition: none; } .roomback__dot { animation: none; } }

/* #831 Web Push (Esteban: «das Geraet waehlt»): sieht aus wie das Mail-Feld (#803, eine Zeile, Frage im Feld, kurzer Knopf), nur ohne
   Tippen; das Feld ist ein Text, der den Knopf ausloest. «Ausschalten» sieht aus wie der Einstellungs-Link. */
.remindme__ask { display: flex; align-items: center; color: var(--ink-3); cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; user-select: none; }
.remindme__off { background: none; border: 0; padding: 0; margin: 0 0 0 4px; font: inherit; font-weight: 500; color: var(--ink-3); text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
