/* ⚠️ KOPIE der App-weiten style.css, Stand 19.08.2026 (dortiges ?v=63).
   Beim Umzug auf partner.citisafari.de hierher kopiert, damit der
   Partner-Ordner eigenstaendig ist: eine eigene Subdomain kann nicht mehr
   per "../" in den App-Ordner greifen, und cross-origin geladene Schriften
   braeuchten zusaetzlich CORS-Header auf der App-Seite.

   FOLGE, bewusst in Kauf genommen: Brand-Aenderungen an der App-style.css
   kommen hier NICHT mehr automatisch an - sie muessen herkopiert werden.
   Im Gegenzug faellt partner/index.html aus der ?v=-Bump-Regel heraus
   (docs/DEPLOYMENT.md). Genutzt wird ohnehin nur eine Teilmenge:
   Brand-Variablen, .btn, .answer-input, .monitor-*, .feedback-box. */

:root {
  /* Brand-Palette (brand-kit/brand.md) */
  --color-green: #6bc93e;        /* Brand-Grün: Flächen, Deko, Marker */
  --color-green-deep: #35761d;   /* abgedunkelt für Buttons/Links (Kontrast >= 4.5:1) */
  --color-green-darker: #2a5e17;
  --color-coral: #ea6f63;
  --color-coral-deep: #b23a2c;   /* abgedunkelt für Fehlertexte */
  --color-cream: #ede4c8;
  --color-cream-light: #f7f2e3;
  --color-yellow: #f5d949;
  --color-periwinkle: #6572e4;

  --color-bg: var(--color-cream-light);
  --color-card: #ffffff;
  --color-text: #26221a;
  --color-muted: #52493a;        /* 20.07. abgedunkelt von #6b6250 - mehr Kontrast für grauen Fließtext */
  --color-border: #e3dabf;
  --color-success-bg: #e9f5e0;
  --color-error-bg: #fdece9;

  --font-head: "Rubik", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-body: "Nunito", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  --radius: 16px;
  --shadow: 0 2px 10px rgba(38, 34, 26, 0.12);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: 17px;
  -webkit-text-size-adjust: 100%;
}

body {
  height: 100vh;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* Koreanisch (10.08.2026). Zwei Dinge, die Latein-Layouts nicht brauchen:
   1. word-break: keep-all - ohne das bricht der Browser koreanische Zeilen an
      JEDER Silbe um, mitten im Wort. overflow-wrap bleibt als Notausgang für
      lange URLs/Codes, die sonst aus schmalen Karten herauslaufen würden.
   2. line-height etwas großzügiger: Hangul-Silben sind höher als Minuskeln,
      1.55 wirkt bei koreanischem Fließtext gedrängt.
   Rubik/Nunito liefern nur das Latin-Subset - Hangul rendert deshalb glyphweise
   in der System-Schrift (iOS: Apple SD Gothic Neo, Android: Noto Sans KR). Das
   ist bewusst so: ein Hangul-Webfont wären ~1-2 MB Extra-Download. */
:lang(ko) {
  word-break: keep-all;
  overflow-wrap: anywhere;
}

:lang(ko) p,
:lang(ko) li {
  line-height: 1.7;
}

h1, h2, h3 {
  font-family: var(--font-head);
  font-weight: 700;
  line-height: 1.25;
  margin: 0 0 0.4em;
}
p { line-height: 1.55; }

button {
  font-family: inherit;
  touch-action: manipulation;
}

/* ---------- Lucide-Icons (self-hosted Sprite, ISC-Lizenz, lucide.dev) ----------
   Das Sprite steht als <svg class="icon-sprite"> ganz oben in index.html bzw.
   admin/index.html; verwendet wird es per <svg class="ico"><use href="#i-NAME"/></svg>
   (in app.js über icon()/setIconText()). Stroke und Farbe erben von currentColor,
   das Icon passt sich damit jedem Kontext an.
   Regel (27.07.): Icons ersetzen die früheren Emojis in Menü, Overlays, Buttons
   und Foto-Aufgaben. BEWUSST als Emoji erhalten bleiben die Spielelemente -
   Rang (RANG_STUFEN), Streak-Flamme, Punkte-Sprout, Guide-Papagei, Meilenstein-
   Toasts und die Sprachflaggen auf dem Code-Screen. */
.icon-sprite,
.admin-icon-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.ico {
  display: inline-block;
  width: 1.1em;
  height: 1.1em;
  vertical-align: -0.15em;      /* auf der Textgrundlinie sitzen */
  margin-right: 0.4em;          /* Standard: Icon vor Text */
  flex: 0 0 auto;               /* in flex-Buttons (.btn) nicht schrumpfen */
  stroke: currentColor;
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.ico-only { margin-right: 0; }                    /* reine Icon-Buttons (☰, ✕, Würfel) */
.ico-end { margin-right: 0; margin-left: 0.3em; } /* Icon nach dem Text */

/* Header */
.app-header {
  flex-shrink: 0;
  /* Über dem Nächste-Station-Chip (500), unter den Overlays (2000):
     das Dev-Menü (Kind, z-index 1100) kann den Header-Kontext nicht
     verlassen und lag sonst unter dem Chip */
  z-index: 600;
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--color-bg);
  border-bottom: 2px solid var(--color-cream);
  padding: 10px 16px;
}

.app-logo {
  width: 44px;
  height: 44px;
  flex-shrink: 0;
}

.header-text {
  flex: 1;
  min-width: 0;
}

.app-header h1 {
  font-size: 1.1rem;
  margin: 0 0 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Zweizeiliger App-Header (nur index.html trägt "stacked" - monitor.html und
   partner/ nutzen .app-header weiterhin einzeilig): Zeile 1 Identität mit
   vollem Titel, Zeile 2 kompakte Stats-Chips */
.app-header.stacked {
  flex-direction: column;
  align-items: stretch;
  gap: 6px;
  padding: 6px 12px;
}

/* Hamburger im gestapelten Header: nackter grauer Glyph statt Button-Box
   (18.07. abends, spart Höhe in Zeile 1); monitor/partner behalten die Box.
   Dev-Modus-Signal wandert vom Hintergrund in die Glyph-Farbe. */
.app-header.stacked .app-menu-btn {
  width: 40px;
  height: 34px;
  border: none;
  background: transparent;
  color: var(--color-muted);
  font-size: 1.35rem;
}

.app-header.stacked .app-menu-btn.dev-active {
  background: transparent;
  border: none;
  color: var(--color-coral);
}

.header-row {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.app-header.stacked .app-logo {
  width: 34px;
  height: 34px;
  align-self: flex-start;
}

/* Voller Rallye-Titel: ganze Breite, Umbruch an Wortgrenzen statt Ellipsis;
   das 2-Zeilen-Clamp ist nur das Sicherheitsnetz für extrem lange Titel */
.app-header.stacked h1 {
  flex: 1;
  min-width: 0;
  margin: 0;
  font-size: 1rem;
  line-height: 1.25;
  white-space: normal;
  text-overflow: clip;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

.header-stats {
  gap: 8px;
}

/* Spot-Fortschritt: bewusst OHNE Chip-Optik (Rahmen/Hintergrund), da nicht
   antippbar - Chip-Look würde Antippbarkeit suggerieren. Schrumpft zuerst,
   damit Punkte- und Fever-Chip nie umbrechen */
.progress-chip {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  padding: 4px 2px;
  background: none;
  border: none;
}

.progress-bar {
  flex: 1;
  height: 13px;
  border-radius: 999px;
  background: var(--color-cream);
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  width: 0%;
  background: var(--color-green);
  border-radius: 999px;
  transition: width 0.3s ease;
}

.progress-text {
  font-size: 0.85rem;
  font-weight: 800;
  color: var(--color-muted);
  white-space: nowrap;
}

/* Punktestand-Chip im Header (öffnet das Punkte-Overlay) */
.score-chip {
  flex-shrink: 0;
  align-self: center;
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  padding: 4px 10px;
  background: var(--color-card);
  border: 1.5px solid var(--color-border);
  border-radius: 12px;
  cursor: pointer;
}

.score-chip[hidden] { display: none; }

.score-chip:active { background: var(--color-cream-light); }

.app-header.stacked .score-chip { min-height: 40px; }

/* Punkte steigen: Chip leuchtet kurz grün auf - Pendant zum orangen
   Streak-Aufleuchten (fade-in/-out, läuft mit dem Count-up). */
.score-chip.score-lightup { animation: score-lightup 1.1s ease; }

@keyframes score-lightup {
  0% { background: var(--color-card); }
  35% { background: #dcf1cb; }
  100% { background: var(--color-card); }
}

.score-emoji {
  font-size: 1.15rem;
  line-height: 1;
}

.score-lines {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  line-height: 1.15;
}

.score-points {
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 0.85rem;
  color: var(--color-green-deep);
  white-space: nowrap;
  /* Feste Breite gegen Layout-Sprung während des Count-ups: tabular-nums hält
     alle Ziffern gleich breit, min-width reserviert Platz für den breitesten
     Stand ("1600 / 1600"), sodass nur die Ziffern wechseln, nicht die Chip-Größe */
  font-variant-numeric: tabular-nums;
  display: inline-block;
  min-width: 6.1em;
}

.score-label {
  font-size: 0.6rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-muted);
}

/* Fever-Chip (Stats-Zeile): glüht mit steigender Serie heißer. Farbe ist nie
   alleiniger Informationsträger - Flamme + "Serie/Stufe"-Zahl stehen immer da */
.fever-chip {
  position: relative;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: 40px;
  padding: 4px 10px;
  background: var(--color-card);
  border: 1.5px solid var(--color-border);
  border-radius: 12px;
  cursor: pointer;
  transition: border-color 0.3s ease, box-shadow 0.3s ease;
}

.fever-chip[hidden] { display: none; }

.fever-chip:active { background: var(--color-cream-light); }

/* Kalte Flamme: solange keine Serie läuft (Combo 0, keine Glüh-Stufe-Klasse),
   ist die Flamme ausgegraut statt in voller Farbe zu stehen */
.fever-flame {
  font-size: 1.15rem;
  line-height: 1;
  filter: grayscale(1);
  opacity: 0.45;
  transition: filter 0.3s ease, opacity 0.3s ease;
}

.fever-chip.fever-warm .fever-flame,
.fever-chip.fever-hot .fever-flame,
.fever-chip.fever-blazing .fever-flame,
.fever-chip.fever-tick .fever-flame {
  filter: none;
  opacity: 1;
}

.fever-count {
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 0.85rem;
  color: var(--color-green-deep);
  white-space: nowrap;
}

/* Glüh-Stufen: Gelb (Serie 1-2) -> Orange (ab Stufe 3) -> Rot (ab 6).
   Textfarben abgedunkelt (Kontrast >= 4.5:1 auf Weiß) */
.fever-chip.fever-warm { border-color: var(--color-yellow); box-shadow: 0 0 6px rgba(245, 217, 73, 0.55); }
.fever-chip.fever-warm .fever-count { color: #8a6d00; }

.fever-chip.fever-hot { border-color: #f0921e; box-shadow: 0 0 9px rgba(240, 146, 30, 0.5); }
.fever-chip.fever-hot .fever-count { color: #a04f00; }

.fever-chip.fever-blazing { border-color: var(--color-coral); box-shadow: 0 0 12px rgba(234, 111, 99, 0.6); }
.fever-chip.fever-blazing .fever-count { color: var(--color-coral-deep); }

/* Bonus-Stufe erreicht: Chip pulst kurz, "+X" fliegt nach oben weg
   (Dauern 18.07. abends verlängert - waren kaum wahrnehmbar) */
.fever-chip.fever-pop { animation: fever-pop 1s ease; }

@keyframes fever-pop {
  0% { transform: scale(1); }
  35% { transform: scale(1.12); }
  100% { transform: scale(1); }
}

.fever-burst {
  position: absolute;
  left: 50%;
  top: -6px;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 0.95rem;
  color: var(--color-coral-deep);
  pointer-events: none;
  animation: fever-burst-up 2s ease-out forwards;
}

@keyframes fever-burst-up {
  0% { opacity: 0; transform: translate(-50%, 6px) scale(0.7); }
  15% { opacity: 1; transform: translate(-50%, -4px) scale(1.15); }
  100% { opacity: 0; transform: translate(-50%, -30px) scale(1); }
}

/* Normaler Streak-Treffer ohne Stufe: die Flamme zuckt kurz */
.fever-chip.fever-tick .fever-flame { animation: fever-tick 0.9s ease; }

@keyframes fever-tick {
  0% { transform: scale(1); }
  40% { transform: scale(1.3); }
  100% { transform: scale(1); }
}

/* Streak erhöht sich: der ganze Chip leuchtet kurz in hellem Orange auf
   (fade-in, kurz halten, fade-out) - zusätzliches Signal für das positive
   Ereignis. Läuft parallel zu fever-tick / fever-pop. */
.fever-chip.fever-lightup { animation: fever-lightup 1.1s ease; }

@keyframes fever-lightup {
  0% { background: var(--color-card); }
  35% { background: #ffe4bd; }
  100% { background: var(--color-card); }
}

/* Serienbruch: Flamme graut aus, kleiner Rauch-Puff steigt auf,
   danach versteckt updateFeverChip() den Chip */
.fever-chip.fever-out { border-color: var(--color-border); box-shadow: none; }

.fever-chip.fever-out .fever-flame {
  filter: grayscale(1);
  opacity: 0.45;
  transition: filter 0.4s ease, opacity 0.4s ease;
}

.fever-chip.fever-out::after {
  content: "💨";
  position: absolute;
  left: 4px;
  top: -4px;
  font-size: 0.9rem;
  pointer-events: none;
  animation: fever-smoke 1.6s ease-out forwards;
}

@keyframes fever-smoke {
  0% { opacity: 0; transform: translateY(6px) scale(0.7); }
  25% { opacity: 0.9; }
  100% { opacity: 0; transform: translateY(-16px) scale(1.2); }
}

/* Optionaler Hingucker bei hoher Serie: warmer Glow-Rand um die ganze Leiste */
.app-header.fever-glow {
  box-shadow: inset 0 0 0 2px rgba(240, 146, 30, 0.35), 0 2px 12px rgba(234, 111, 99, 0.3);
}

@media (prefers-reduced-motion: reduce) {
  .fever-chip.fever-pop,
  .fever-chip.fever-tick .fever-flame,
  .fever-chip.fever-lightup,
  .score-chip.score-lightup,
  .fever-chip.fever-out::after { animation: none; }
  .fever-burst { animation: fever-burst-static 2s ease forwards; }
}

/* Reduzierte Bewegung: "+X" nur ein-/ausblenden statt wegfliegen */
@keyframes fever-burst-static {
  0% { opacity: 0; transform: translate(-50%, -8px); }
  15% { opacity: 1; transform: translate(-50%, -8px); }
  85% { opacity: 1; transform: translate(-50%, -8px); }
  100% { opacity: 0; transform: translate(-50%, -8px); }
}

/* Streak-Overlay (Tap auf den Chip): große Serie + drei Kacheln + Regel */
.fever-sheet { text-align: center; }

.fever-big {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 2.6rem;
  margin: 6px 0 10px;
}

/* Drei Kacheln unter dem Score: höchster Streak (hervorgehoben, warme
   Glüh-Optik wie der heiße Chip), bisher verdient, nächster Bonus */
.fever-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  margin: 12px 0 4px;
}

.fever-stats .stat {
  background: var(--color-cream-light);
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius);
  padding: 10px 8px;
}

.fever-stats .stat-value {
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 1.1rem;
  line-height: 1.25;
  color: var(--color-green-deep);
}

/* "in X Stationen" ist Text statt Zahl - kleiner, damit nichts umbricht */
#fever-next-value { font-size: 0.9rem; }

/* Labels dürfen umbrechen (14.08.): mit white-space:nowrap liefen "Bisher
   verdient" und "Nächster Bonus" auf 375-px-Screens rechts aus der Kachel
   heraus (115 bzw. 119 px Text in einer 86 px breiten Box). Die Kacheln sind
   ein Grid - eine zweite Zeile zieht alle drei gleich hoch. */
.fever-stats .stat-label {
  font-size: 0.7rem;
  font-weight: 800;
  color: var(--color-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  line-height: 1.2;
  margin-top: 2px;
  overflow-wrap: break-word;
}

.fever-stats .stat.best {
  border-color: #f0921e;
  background: #fdf3e0;
  box-shadow: 0 0 9px rgba(240, 146, 30, 0.35);
}

.fever-stats .stat.best .stat-value { color: #a04f00; }

/* Selektor bewusst zweiteilig: das Sheet trägt .name-sheet, und dessen
   ".name-sheet p { margin: 0 0 18px }" hat mehr Spezifität als ein einzelnes
   .fever-explain - der frühere margin-top kam deshalb nie an (Abstand war 4 px
   statt der gesetzten 44). Seit 14.08. gewinnt diese Regel mit 68 px: der
   Erklärtext ist Regelwerk, keine Bildunterschrift der Kacheln. */
.fever-sheet .fever-explain {
  margin-top: 68px;
  color: var(--color-muted);
  font-size: 0.92rem;
}

/* Punktestand-Overlay */
.score-sheet {
  text-align: center;
  padding-top: 34px;
}

.score-team {
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 1.25rem;
  margin-bottom: 12px;
  overflow-wrap: break-word;
}

/* Zeile 1 unter dem Teamnamen: nur die Punkte, dezenter als der frühere
   .score-big-Fettdruck - der Rang (Zeile 2) trägt jetzt Emoji + Bezeichnung */
.score-points-line {
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 1.05rem;
  color: var(--color-muted);
  margin-bottom: 10px;
}

/* Zeile 2: eigener kleiner Rang-Chip (18.07. abends), Optik wie die
   bestehenden Pillen (.hs-badge/.fever-chip) statt eines neuen Stils */
/* Antippbar (18.07.->20.07.): oeffnet die Rang-Uebersicht. Button-Reset,
   dezenter Rahmen als Tap-Affordance, kleiner ">"-Chevron rechts */
.rang-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--color-cream-light);
  border: 1.5px solid var(--color-border);
  border-radius: 999px;
  padding: 6px 14px;
  margin-bottom: 18px;
  font-family: var(--font-head);
  font-size: 0.92rem;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.rang-chip::after {
  content: "›";
  font-weight: 700;
  color: var(--color-muted);
  margin-left: 2px;
}

.rang-chip:active { background: var(--color-cream); }

.rang-label {
  font-weight: 600;
  color: var(--color-muted);
}

.rang-emoji { font-size: 1.15rem; }

.rang-name {
  font-weight: 700;
  color: var(--color-green-deep);
}

/* Rang-Uebersicht (Tap auf den Rang-Chip): alle 7 Raenge als Liste,
   aktueller Rang hervorgehoben, je Rang der Anteil aller Teams */
.rang-sheet { text-align: center; }

.rang-intro {
  color: var(--color-muted);
  font-size: 0.9rem;
  margin: 4px 0 16px;
}

.rang-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  text-align: left;
}

.rang-row {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--color-cream-light);
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius);
  padding: 10px 14px;
}

.rang-row-emoji {
  font-size: 1.35rem;
  line-height: 1;
  flex-shrink: 0;
}

.rang-row-name {
  flex: 1;
  min-width: 0;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 0.98rem;
  color: var(--color-text);
}

.rang-row-pct {
  flex-shrink: 0;
  font-weight: 800;
  font-size: 0.9rem;
  color: var(--color-muted);
  font-variant-numeric: tabular-nums;
}

/* Aktueller Rang des Teams: warme Hervorhebung wie der heisse Fever-Chip */
.rang-row.current {
  border-color: var(--color-green);
  background: #eaf6ec;
  box-shadow: 0 0 8px rgba(76, 175, 108, 0.25);
}

.rang-row.current .rang-row-name,
.rang-row.current .rang-row-pct { color: var(--color-green-deep); }

.rang-row-badge {
  display: inline-block;
  vertical-align: middle;
  background: var(--color-green);
  color: #fff;
  font-family: var(--font-body);
  font-weight: 800;
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-radius: 999px;
  padding: 2px 7px;
  margin-left: 4px;
}

.rang-empty {
  color: var(--color-muted);
  font-size: 0.85rem;
  text-align: center;
  margin: 6px 0 0;
}

/* Statistik-Farben nur auf dem Team-Bildschirm: Gespielt blau, Falsch rot
   (Klassen vergibt renderScoreOverlay; der Finish-Screen bleibt grün) */
.stat.played .stat-value { color: var(--color-periwinkle); }
.stat.wrong .stat-value { color: var(--color-coral-deep); }

/* Highscore-Liste im Punkte-Overlay */
#score-highscore {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1.5px solid var(--color-border);
}

#score-highscore[hidden] { display: none; }

.hs-heading {
  font-size: 1.05rem;
  margin: 0 0 10px;
}

/* Spielmodus-Wahl (Story / Offene Rallye) */
.mode-buttons {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 6px;
}

.mode-btn {
  display: block;
  width: 100%;
  min-height: 52px;
  text-align: left;
  padding: 16px 18px;
  border-radius: 14px;
  border: 2px solid var(--color-border);
  background: #fff;
  cursor: pointer;
}

.mode-btn:active {
  background: var(--color-cream-light);
  border-color: var(--color-green-deep);
}

.mode-btn .mode-title {
  display: block;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 1.1rem;
  margin-bottom: 4px;
}

.mode-btn .mode-desc {
  display: block;
  font-size: 0.92rem;
  color: var(--color-muted);
  line-height: 1.45;
}

/* Untertitel im Name-Overlay (nur bei Gruppen-Zugängen sichtbar) */
.name-hint {
  font-size: 0.85rem;
  color: var(--color-muted);
  margin: -4px 0 2px;
}

.name-hint[hidden] { display: none; }

#name-intern-wrap[hidden] { display: none; }

/* Gruppen-Tabs (nur bei Zugängen mit gruppen_code, Firmen-Events) */
.hs-tabs {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
}

.hs-tab {
  flex: 1;
  min-height: 44px;
  padding: 8px 12px;
  border-radius: 999px;
  border: 1.5px solid var(--color-border);
  background: var(--color-card);
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 0.9rem;
  color: var(--color-muted);
  cursor: pointer;
}

.hs-tab.active {
  background: var(--color-green-deep);
  border-color: var(--color-green-deep);
  color: #fff;
}

.hs-status {
  color: var(--color-muted);
  font-size: 0.92rem;
}

.hs-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.hs-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border-radius: 10px;
  background: var(--color-cream-light);
  border: 1.5px solid transparent;
  font-size: 0.95rem;
  text-align: left;
}

.hs-row .hs-rank {
  flex-shrink: 0;
  width: 2.4em;
  font-family: var(--font-head);
  font-weight: 700;
  color: var(--color-muted);
}

.hs-row .hs-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 600;
}

/* Laufende Teams in der Bestenliste (Live-Highscore); blau = neutral-informativ
   (rot las sich wie ein Fehler), Palette wie die Safari-Wissen-Box */
.hs-row .hs-badge {
  flex-shrink: 0;
  font-size: 0.72rem;
  font-weight: 800;
  color: #333c8f;
  background: #eef0fc;
  border-radius: 999px;
  padding: 3px 8px;
  white-space: nowrap;
}

.hs-row .hs-points {
  flex-shrink: 0;
  font-family: var(--font-head);
  font-weight: 700;
  color: var(--color-green-deep);
}

/* Eigene Zeile: Brand-Grün-Fläche wie die Erfolgs-Feedback-Boxen */
.hs-row.own {
  background: var(--color-success-bg);
  border-color: #bfe0aa;
}

.hs-row.own .hs-rank { color: var(--color-green-darker); }

/* Eigene Platzierung ausserhalb der Top 20: abgesetzt unter der Liste */
.hs-own-outside {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1.5px dashed var(--color-border);
}

/* Nutzer-Menü (☰): offizielles Menü für alle (Sprachschalter, Shop-Link);
   der Dev-Abschnitt ganz unten erscheint nur auf localhost bzw. mit ?dev=1 */
.app-menu {
  position: relative;
  flex-shrink: 0;
  align-self: center;
}

.app-menu[hidden] { display: none; }

.app-menu-btn {
  width: 44px;
  height: 44px;
  border: 1.5px solid var(--color-border);
  border-radius: 10px;
  background: var(--color-card);
  color: var(--color-text);
  font-size: 1.15rem;
  line-height: 1;
  cursor: pointer;
}

/* Dev-Modus aktiv: Button deutlich markieren (nur in der Entwicklungsphase relevant) */
.app-menu-btn.dev-active {
  background: var(--color-coral);
  border-color: var(--color-coral);
  color: #fff;
}

.app-menu-list {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 1100;
  display: flex;
  flex-direction: column;
  min-width: 230px;
  background: var(--color-card);
  border: 1.5px solid var(--color-border);
  border-radius: 12px;
  box-shadow: var(--shadow);
  overflow: hidden;
}

.app-menu-list[hidden] { display: none; }

.menu-label {
  padding: 12px 16px 6px;
  font-size: 0.72rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-muted);
}

/* Laufrichtung: reine Anzeige, kein Button - deshalb bewusst unauffaellig
   (25.07.). Nur sichtbar, wenn die Rallye Route B aktiv hat. Steht seit 14.08.
   als letzter Eintrag ueber der Rechts-Fusszeile, daher etwas mehr Luft nach
   unten als bei einem normalen .menu-label. */
.menu-route {
  text-transform: none;
  letter-spacing: 0;
  font-size: 0.8rem;
  color: var(--color-text);
  border-top: 1.5px solid var(--color-border);
  margin-top: 6px;
  padding-bottom: 12px;
}

/* Sprachwahl im ☰-Menü: seit 11.08. ein Dropdown statt einer Button-Leiste.
   Die Leiste war bei drei Sprachen auf ~70 px pro Button geschrumpft und wäre
   ab der vierten umgebrochen - das Select bleibt bei jeder Anzahl gleich groß.
   Die Menü-Liste ist nur ~228 px breit, deshalb hier schmaleres Padding. */
.menu-lang-row {
  padding: 0 16px 12px;
}

/* NUR monitor.html: der Monitor hat weiterhin zwei feste Sprach-Buttons
   (de/en, eigene Logik in der Datei) und teilt sich nur die Optik mit der
   App. Bis 11.08. hießen die Klassen .menu-lang-row/.menu-lang-btn und
   waren mit dem ☰-Menü geteilt - beim Umbau auf das Dropdown wäre der
   Monitor sonst ungestylt liegen geblieben. */
.monitor-lang-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(60px, 1fr));
  gap: 6px;
  padding: 0 12px 12px;
}

.monitor-lang-btn {
  min-height: 44px;
  padding: 0 4px;
  white-space: nowrap;
  border: 1.5px solid var(--color-border);
  border-radius: 10px;
  background: none;
  font-size: 0.85rem;
  font-weight: 800;
  color: var(--color-text);
  cursor: pointer;
}

.monitor-lang-btn.active {
  background: var(--color-green-deep);
  border-color: var(--color-green-deep);
  color: #fff;
}

.menu-link {
  display: block;
  min-height: 48px;
  padding: 13px 16px;
  border-top: 1.5px solid var(--color-border);
  font-size: 0.92rem;
  font-weight: 800;
  color: var(--color-text);
  text-decoration: none;
}

.menu-link:active { background: var(--color-cream-light); }

/* "Tutorial erneut starten" ist ein <button> in Link-Optik */
button.menu-link {
  width: 100%;
  border: none;
  border-top: 1.5px solid var(--color-border);
  background: none;
  text-align: left;
  font-family: inherit;
  cursor: pointer;
}

.menu-link[hidden] { display: none; }

/* Dev-Abschnitt (temporär): bewusst als "Baustelle" markiert, fliegt nach
   der Entwicklungsphase komplett raus (DEV-BLOCK in index.html/app.js) */
.menu-dev-section {
  border-top: 2px dashed var(--color-coral);
}

.menu-dev-section[hidden] { display: none; }

.menu-dev-label { color: var(--color-coral-deep); }

.menu-dev-section button {
  display: block;
  width: 100%;
  min-height: 48px;
  padding: 12px 16px;
  border: none;
  border-top: 1.5px solid var(--color-border);
  background: none;
  text-align: left;
  font-size: 0.92rem;
  font-weight: 800;
  color: var(--color-coral-deep);
  cursor: pointer;
}

.menu-dev-section button:first-of-type { border-top: none; }

.menu-dev-section button[hidden] { display: none; }

.menu-dev-section button:active { background: var(--color-cream-light); }

/* Rechtliches ganz unten im ☰-Menü: bewusst als kleine Fußzeile, nicht als
   .menu-link - Pflichtangaben sollen erreichbar sein, aber nicht mit den
   Spiel-Aktionen konkurrieren. Beide Einträge stehen nebeneinander. */
.menu-legal {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 14px;
  padding: 9px 16px;
  border-top: 1.5px solid var(--color-border);
  background: var(--color-cream-light);
}

/* <button> und <a> in identischer Optik - der Datenschutz öffnet ein Overlay,
   das Impressum führt auf die Website */
.menu-legal-link {
  padding: 4px 2px;
  border: none;
  background: none;
  font-family: inherit;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--color-muted);
  text-decoration: underline;
  cursor: pointer;
}

.menu-legal-link:active { color: var(--color-text); }

/* Das Datenschutz-Sheet selbst steht weiter unten, direkt hinter dem
   Hilfe-Overlay: .legal-sheet h2 muss NACH .hilfe-sheet h2 stehen
   (gleiche Spezifität - sonst gewinnt die zentrierte Hilfe-Regel). */

/* Status banner (GPS-Hinweise / Fehler) */
.status-banner {
  flex-shrink: 0;
  margin: 10px 16px 0;
  padding: 12px 14px;
  border-radius: var(--radius);
  font-size: 0.92rem;
  line-height: 1.4;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 10px;
  z-index: 5;
}

.status-banner[hidden] { display: none; }

.status-banner span {
  flex: 1 1 100%;
  min-width: 0;
}

.status-banner.info {
  background: #fdf6d8;
  color: #6b5a12;
  border: 1.5px solid #e8d98f;
}

.status-banner.error {
  background: var(--color-error-bg);
  color: var(--color-coral-deep);
  border: 1.5px solid #f2c1bd;
}

.status-banner button {
  flex-shrink: 0;
  background: rgba(0,0,0,0.07);
  border: none;
  border-radius: 10px;
  padding: 10px 14px;
  font-size: 0.88rem;
  font-weight: 800;
  color: inherit;
}

/* Ansichten (Karte / Liste) */
.view-container {
  flex: 1 1 auto;
  min-height: 0;
  position: relative;
}

.view {
  position: absolute;
  inset: 0;
}

.view[hidden] { display: none; }

.map-container {
  height: 100%;
  width: 100%;
  z-index: 0;
  background: var(--color-cream);
}

/* Nächste-Station-Chip über der Karte */
/* "Nächste Station"-Karte: oben mittig auf der Karte (die v=42-Reposition nach
   unten war ein Fehlgriff und ist rückgängig); bewusst dezentes Padding, damit
   sie nicht zu präsent wirkt. */
.next-chip {
  position: absolute;
  top: 12px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 500;
  max-width: calc(100% - 90px);
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--color-card);
  color: var(--color-text);
  border: none;
  border-radius: 999px;
  padding: 8px 14px;
  font-family: var(--font-head);
  font-weight: 500;
  font-size: 0.92rem;
  box-shadow: var(--shadow);
  white-space: nowrap;
  cursor: pointer;
}

.next-chip .chip-label {
  overflow: hidden;
  text-overflow: ellipsis;
}

.next-chip::before {
  content: "";
  flex-shrink: 0;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--color-coral);
}

.next-chip:active { background: var(--color-cream-light); }

.next-chip[hidden] { display: none; }

/* Marker: Stationen (Map-Pin im Logo-Stil) */
.station-marker {
  position: relative;
  width: 40px;
  height: 40px;
  border-radius: 50% 50% 50% 0;
  transform: rotate(-45deg);
  border: 3px solid #fff;
  box-shadow: 0 2px 6px rgba(0,0,0,0.35);
  display: flex;
  align-items: center;
  justify-content: center;
}

.station-marker span {
  transform: rotate(45deg);
  font-family: var(--font-head);
  font-size: 1rem;
  font-weight: 700;
  color: #fff;
  line-height: 1;
}

.station-marker.locked {
  background: #b3a98f;
}

/* Spielbar (im Radius): leicht grün pulsierend - Signal "jetzt antippen" */
.station-marker.in-range {
  background: var(--color-green);
  animation: pin-pulse 1.6s ease-out infinite;
}

.station-marker.completed {
  background: var(--color-green-deep);
}

/* Nicht gelöst: rot mit Kreuz statt grünem Haken */
.station-marker.failed {
  background: var(--color-coral-deep);
}

/* "Start"-Badge über dem Start-Pin (Geschwister des rotierten Pins,
   dadurch ohne Gegenrotation gerade) */
.station-start-label {
  position: absolute;
  top: -24px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--color-green-deep);
  color: #fff;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 0.68rem;
  border-radius: 999px;
  padding: 2px 9px;
  box-shadow: var(--shadow);
  white-space: nowrap;
}

@keyframes pin-pulse {
  0%   { box-shadow: 0 2px 6px rgba(0,0,0,0.35), 0 0 0 0 rgba(107,201,62,0.45); }
  70%  { box-shadow: 0 2px 6px rgba(0,0,0,0.35), 0 0 0 14px rgba(107,201,62,0); }
  100% { box-shadow: 0 2px 6px rgba(0,0,0,0.35), 0 0 0 0 rgba(107,201,62,0); }
}

/* Marker: Nutzerstandort */
.user-location-marker {
  position: relative;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--color-periwinkle);
  border: 3px solid #fff;
  box-shadow: 0 0 0 3px rgba(101,114,228,0.35), 0 1px 4px rgba(0,0,0,0.35);
  /* Blickrichtung: der Punkt ist rund, sichtbar rotiert nur der Kegel */
  transform: rotate(var(--user-heading, 0deg));
}

/* Richtungskegel, erscheint erst wenn der Kompass aktiv ist */
.user-location-marker.has-heading::after {
  content: "";
  position: absolute;
  left: 50%;
  top: -11px;
  transform: translateX(-50%);
  width: 0;
  height: 0;
  border-left: 7px solid transparent;
  border-right: 7px solid transparent;
  border-bottom: 10px solid var(--color-periwinkle);
  filter: drop-shadow(0 1px 2px rgba(0,0,0,0.3));
}

.leaflet-container {
  font-family: inherit;
}

/* Karten-Controls (Zoom + Standort) unten rechts, im App-Stil statt Leaflet-Default */
.map-container .leaflet-bar {
  border: 1.5px solid var(--color-border);
  border-radius: 14px;
  box-shadow: var(--shadow);
  overflow: hidden;
}

/* Gewinnt gegen Leaflets ".leaflet-touch .leaflet-bar a"-Defaults, weil
   style.css nach leaflet.css geladen wird (gleiche Spezifität, spätere Regel) */
.map-container .leaflet-bar a {
  width: 48px;
  height: 48px;
  line-height: 46px;
  background: var(--color-card);
  color: var(--color-green-deep);
  font-family: var(--font-head);
  font-size: 1.35rem;
  font-weight: 700;
  border-bottom: 1.5px solid var(--color-border);
}

.map-container .leaflet-bar a:last-child {
  border-bottom: none;
}

.map-container .leaflet-bar a:active {
  background: var(--color-cream-light);
}

.map-container .leaflet-bar a.leaflet-disabled {
  color: var(--color-muted);
  background: var(--color-cream-light);
}

/* Volle Selektor-Kette nötig: Leaflets ".leaflet-bar a" (display:block +
   line-height) gewinnt sonst und schiebt das Icon nach oben */
.map-container .leaflet-bar a.locate-btn {
  display: flex;
  align-items: center;
  justify-content: center;
}

.locate-btn svg {
  display: block;
  width: 24px;
  height: 24px;
  fill: currentColor;
}

/* Kompass läuft: Button gefüllt als Statusanzeige */
.locate-btn.compass-active {
  background: var(--color-green-deep) !important;
  color: #fff !important;
}

.map-container .leaflet-bottom.leaflet-right {
  margin-bottom: 6px;
}

/* Listenansicht */
.station-list {
  height: 100%;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  list-style: none;
  margin: 0;
  padding: 14px 16px calc(14px + var(--safe-bottom));
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.station-item {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  text-align: left;
  background: var(--color-card);
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius);
  padding: 14px 16px;
  min-height: 72px;
  cursor: pointer;
}

.station-item:active { background: var(--color-cream-light); }

.station-item .item-badge {
  flex-shrink: 0;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 1.05rem;
  color: #fff;
}

.station-item.locked .item-badge { background: #b3a98f; }
.station-item.in-range .item-badge { background: var(--color-green); }
.station-item.completed .item-badge { background: var(--color-green-deep); }
.station-item.failed .item-badge { background: var(--color-coral-deep); }

.station-item .item-text {
  flex: 1;
  min-width: 0;
}

.station-item .item-name {
  font-family: var(--font-head);
  font-weight: 500;
  font-size: 1rem;
  margin-bottom: 2px;
}

.station-item .item-bereich {
  font-size: 0.85rem;
  color: var(--color-muted);
}

.station-item .item-status {
  flex-shrink: 0;
  font-size: 0.85rem;
  font-weight: 800;
  color: var(--color-muted);
  white-space: nowrap;
}

.station-item.in-range .item-status { color: var(--color-green-deep); }
.station-item.completed .item-status { color: var(--color-green-deep); }
.station-item.failed .item-status { color: var(--color-coral-deep); }

/* Tab-Bar: flach gehalten, damit die Karte darüber möglichst viel Platz bekommt */
.tab-bar {
  flex-shrink: 0;
  z-index: 10;
  display: flex;
  gap: 8px;
  background: var(--color-card);
  border-top: 2px solid var(--color-cream);
  padding: 4px 12px calc(4px + var(--safe-bottom));
}

.tab-btn {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 36px;
  border: none;
  border-radius: 10px;
  background: none;
  font-family: var(--font-head);
  font-weight: 500;
  font-size: 0.9rem;
  color: var(--color-muted);
  cursor: pointer;
}

.tab-btn svg {
  width: 17px;
  height: 17px;
  fill: currentColor;
}

.tab-btn.active {
  background: var(--color-cream-light);
  color: var(--color-green-deep);
  font-weight: 700;
}

/* Overlay / bottom sheet */
.overlay {
  position: fixed;
  inset: 0;
  background: rgba(38, 30, 20, 0.5);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  z-index: 2000;
}

.overlay[hidden] { display: none; }

/* Kickoff-Countdown (Phase 2): leerer, ruhiger Vollbild-Screen mit einer
   grossen Zahl (3 - 2 - 1). Rein visuell - kein Sound, keine Vibration. */
.countdown-overlay {
  align-items: center;
  background: rgba(38, 30, 20, 0.92);
}

.countdown-number {
  font-family: var(--font-head);
  font-weight: 700;
  font-size: clamp(6rem, 40vw, 12rem);
  line-height: 1;
  color: var(--color-cream-light);
  animation: countdown-pop 1s ease-out;
}

@keyframes countdown-pop {
  0% { transform: scale(0.6); opacity: 0; }
  30% { transform: scale(1.05); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}

/* Lobby-Botschaft in der Start-Vorschau (Phase 1) */
.preview-start-note {
  font-weight: 700;
  color: var(--color-green-deep);
}

.sheet {
  position: relative;
  background: var(--color-card);
  width: 100%;
  max-width: 640px;
  max-height: 88vh;
  overflow-y: auto;
  border-radius: 24px 24px 0 0;
  padding: 22px 20px calc(24px + var(--safe-bottom));
  animation: slide-up 0.25s ease;
  -webkit-overflow-scrolling: touch;
}

@keyframes slide-up {
  from { transform: translateY(30px); opacity: 0.4; }
  to { transform: translateY(0); opacity: 1; }
}

/* Solange die Bild-Lightbox offen ist (app.js setzt die Klasse) */
.sheet.scroll-lock {
  overflow-y: hidden;
}

/* Scroll-Indikator im Frage-Overlay: dezenter Schatten vom unteren Rand
   nach oben, solange im Sheet noch Inhalt unterhalb liegt. Rein visuell -
   pointer-events: none, damit kein Tap darunter blockiert wird */
.sheet-scroll-shade {
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 100%;
  max-width: 640px; /* deckungsgleich mit dem Sheet */
  height: 36px;
  pointer-events: none;
  background: linear-gradient(to top, rgba(38, 34, 26, 0.22), rgba(38, 34, 26, 0));
  opacity: 0;
  transition: opacity 0.25s ease;
}

.sheet-scroll-shade.visible {
  opacity: 1;
}

/* Einheitlich auf allen Sheets (Frage, Vorschau, Punkte) - bewusst groß */
.sheet-dismiss {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 54px;
  height: 54px;
  border-radius: 50%;
  border: 1.5px solid var(--color-border);
  background: var(--color-cream-light);
  color: var(--color-text);
  font-size: 1.45rem;
  line-height: 1;
  cursor: pointer;
}

.q-bereich {
  font-family: var(--font-head);
  font-size: 0.8rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-coral-deep);
  margin-bottom: 4px;
  padding-right: 44px;
}

.q-name {
  font-family: var(--font-head);
  font-size: 1.35rem;
  font-weight: 700;
  margin-bottom: 10px;
  padding-right: 44px;
}

.q-frage {
  font-size: 1.05rem;
  line-height: 1.55;
  margin-bottom: 16px;
}

/* Optionales Stations-Bild unter dem Titel: der Slot reserviert seine Höhe
   fest (kein Layout-Sprung beim Nachladen), das Bild ist darin vollständig
   sichtbar und vertikal zentriert; die 32vh halten die Antwortoptionen bei
   durchschnittlichem Text ohne Scrollen erreichbar */
.q-bild-slot {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 32vh;
  margin-bottom: 16px;
}

.q-bild {
  max-width: 100%;
  max-height: 100%;
  border-radius: 14px; /* wie .option-btn */
  cursor: zoom-in;
  opacity: 0;
  transition: opacity 0.25s ease;
}

.q-bild.loaded {
  opacity: 1;
}

/* Bild-Lightbox: über Frage-Overlay (2000) und Coach-Marks (2500),
   unter Toast/Konfetti (3000) */
.lightbox-overlay {
  position: fixed;
  inset: 0;
  z-index: 2800;
  background: rgba(26, 22, 14, 0.92);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  overscroll-behavior: contain;
}

.lightbox-overlay[hidden] { display: none; }

.lightbox-img {
  max-width: 100%;
  max-height: 100%;
  border-radius: 14px;
}

/* Einheitliches Schließen-✕ (.sheet-dismiss), nur die Position ans
   Vollbild angepasst: unter der iOS-Notch bleiben */
.lightbox-overlay .sheet-dismiss {
  top: calc(10px + env(safe-area-inset-top, 0px));
}

.hint-toggle {
  background: none;
  border: none;
  color: var(--color-green-deep);
  font-weight: 800;
  font-size: 0.95rem;
  padding: 8px 0;
  margin-bottom: 8px;
  cursor: pointer;
}

/* Bestätigungs-Zustand (erster Tap): warnfarben, damit der bevorstehende
   Punktabzug klar ist, bevor der zweite Tap ihn auslöst */
.hint-toggle.hint-armed {
  color: var(--color-coral-deep);
}

.hint-box {
  background: #fdf6d8;
  border: 1.5px solid #e8d98f;
  color: #6b5a12;
  border-radius: 12px;
  padding: 12px 14px;
  font-size: 0.95rem;
  line-height: 1.5;
  margin-bottom: 14px;
}

.options-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 10px;
}

.option-btn {
  display: block;
  width: 100%;
  text-align: left;
  padding: 14px 16px;
  min-height: 52px;
  border-radius: 14px;
  border: 2px solid var(--color-border);
  background: #fff;
  font-size: 1rem;
  font-weight: 600;
  color: var(--color-text);
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.option-btn:active {
  background: var(--color-cream-light);
}

.option-btn.correct {
  border-color: var(--color-green-deep);
  background: var(--color-success-bg);
}

.option-btn.incorrect {
  border-color: var(--color-coral);
  background: var(--color-error-bg);
}

.option-btn:disabled {
  cursor: default;
}

.answer-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 10px;
}

.answer-input {
  width: 100%;
  padding: 14px 16px;
  min-height: 52px;
  border-radius: 14px;
  border: 2px solid var(--color-border);
  font-size: 1rem;
  font-family: inherit;
  font-weight: 600;
  background: #fff;
  color: var(--color-text);
}

.answer-input:focus {
  outline: none;
  border-color: var(--color-green-deep);
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 14px 20px;
  min-height: 52px;
  border-radius: 14px;
  border: none;
  font-family: var(--font-head);
  font-size: 1.05rem;
  font-weight: 700;
  cursor: pointer;
}

/* hidden+display-Falle (ARCHITEKTUR.md): inline-flex überschreibt sonst das
   hidden-Attribut (z.B. Share-Button beim vorzeitig beendeten Spiel) */
.btn[hidden] { display: none; }

.btn-primary {
  background: var(--color-green-deep);
  color: #fff;
}

.btn-primary:active {
  background: var(--color-green-darker);
}

.btn-secondary {
  background: var(--color-cream);
  color: var(--color-text);
}

.btn-block { width: 100%; }

.feedback-box {
  border-radius: 14px;
  padding: 14px 16px;
  font-size: 0.95rem;
  margin: 10px 0 14px;
  line-height: 1.5;
}

.feedback-box.wrong {
  background: var(--color-error-bg);
  color: var(--color-coral-deep);
  border: 1.5px solid #f2c1bd;
}

.feedback-box.correct {
  background: var(--color-success-bg);
  color: var(--color-green-darker);
  border: 1.5px solid #bfe0aa;
}

/* Neutral (grau): Auflösung nach falscher Antwort - weder Jubel noch Alarm */
.feedback-box.neutral {
  background: #f1eee6;
  color: var(--color-text);
  border: 1.5px solid var(--color-border);
}

.feedback-box .feedback-title {
  font-family: var(--font-head);
  font-weight: 700;
  margin-bottom: 4px;
}

/* Stations-Vorschau */
.preview-distance {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: var(--color-cream-light);
  border: 1.5px solid var(--color-border);
  border-radius: 999px;
  padding: 8px 16px;
  font-weight: 800;
  font-size: 0.95rem;
  margin-bottom: 14px;
}

.preview-note {
  color: var(--color-muted);
  font-size: 0.95rem;
  margin: 0 0 16px;
}

/* ---------- Standort-Freigabe (Pre-Permission) & Genauigkeits-Anleitung ---------- */

/* Pre-Permission-Screen: nutzt das zentrierte name-sheet-Muster.
   Das große Symbol oben ist seit 27.07. ein Lucide-Icon in einer runden,
   grün getönten Fläche (.sheet-hero-icon, weiter unten) statt eines Emojis. */
.geo-intro-sheet p {
  color: var(--color-muted);
  margin: 0 0 20px;
}

/* Übernahme-Dialog beim Gerätewechsel (Spielstand-Sync); Kopf-Symbol siehe
   .sheet-hero-icon */
.resume-sheet p {
  color: var(--color-muted);
  margin: 0 0 20px;
}

/* "Zuletzt gesichert vor 3 Min." - dezenter als der Fließtext darüber */
.resume-sheet .resume-stand {
  font-size: 0.9rem;
  margin: -8px 0 16px;
}

.resume-sheet .resume-stand:empty { display: none; }

/* Der Foto-Hinweis darf nicht untergehen: er ist der einzige echte Verlust
   beim Gerätewechsel (Fotos verlassen das Gerät per Produktentscheidung nie). */
.resume-sheet .resume-foto {
  background: #fdf6d8;
  color: #6b5a12;
  border: 1.5px solid #e8d98f;
  border-radius: var(--radius);
  padding: 10px 12px;
  font-size: 0.9rem;
}

/* Übernahme bei lebendem Altgerät: die Folge muss deutlicher stehen als der
   Foto-Hinweis darüber - hier wird ein anderes Team abgemeldet. */
.resume-sheet .resume-warnung {
  background: var(--color-error-bg);
  color: var(--color-coral-deep);
  border: 1.5px solid #f2c1bd;
  border-radius: var(--radius);
  padding: 10px 12px;
  font-size: 0.9rem;
  margin: 0 0 14px;
}

/* Der Übernehmen-Knopf trägt bewusst NICHT das Brand-Grün der normalen
   Weiter-Aktion (Zwei-Schritt-Bestätigung wie beim Hinweis-Abzug). */
.resume-sheet .btn-primary.resume-uebernehmen {
  background: var(--color-coral-deep);
}

.resume-sheet .btn-primary.resume-uebernehmen.resume-armed {
  background: #8f2f26;
}

/* Rückweg als dezenter Link, gleiches Muster wie „Überspringen“ */
.resume-abbrechen {
  display: block;
  width: 100%;
  margin-top: 12px;
  background: none;
  border: none;
  color: var(--color-muted);
  font-size: 0.92rem;
  text-decoration: underline;
  cursor: pointer;
}

.resume-abbrechen[hidden] { display: none; }

/* Genauigkeits-Anleitung */
.geo-accuracy-sheet h2 {
  margin: 0 0 10px;
  padding-right: 44px; /* Platz fürs ✕ */
}

.geo-accuracy-intro {
  color: var(--color-muted);
  font-size: 0.95rem;
  margin: 0 0 18px;
}

.geo-accuracy-warnung {
  color: var(--color-coral-deep);
  font-weight: 700;
  font-size: 0.95rem;
  margin: 0 0 10px;
}

.geo-accuracy-block {
  background: var(--color-cream-light);
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius);
  padding: 14px 16px;
  margin: 0 0 16px;
}

.geo-accuracy-geraet {
  margin: 0 0 12px;
  font-size: 1.02rem;
}

.geo-accuracy-steps {
  margin: 0;
  padding-left: 1.3em;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.geo-accuracy-steps li {
  font-size: 0.95rem;
  line-height: 1.4;
}

.geo-accuracy-hint {
  color: var(--color-muted);
  font-size: 0.9rem;
  margin: 0 0 16px;
}

/* Spielername-Abfrage */
.name-sheet {
  text-align: center;
  padding-top: 34px;
}

.name-sheet p {
  color: var(--color-muted);
  margin: 0 0 18px;
}

.name-sheet .answer-input {
  text-align: center;
}

/* Team-Namen-Generator: [Adjektiv ▾][Nomen ▾] 🎲 */
.name-generator {
  display: flex;
  align-items: stretch;
  gap: 8px;
}

.name-select {
  flex: 1;
  min-width: 0;
  min-height: 52px;
  padding: 12px 10px;
  border-radius: 14px;
  border: 2px solid var(--color-border);
  background: #fff;
  font-family: inherit;
  font-size: 0.98rem;
  font-weight: 600;
  color: var(--color-text);
}

.name-select:focus {
  outline: none;
  border-color: var(--color-green-deep);
}

.name-random {
  flex-shrink: 0;
  width: 52px;
  min-height: 52px;
  border-radius: 14px;
  border: 2px solid var(--color-border);
  background: var(--color-cream-light);
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
}

.name-random:active {
  background: var(--color-cream);
  transform: rotate(20deg);
}

/* Zugangscode-Eingabe (nutzt die Name-Sheet-Optik) */
.code-sheet .answer-input {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-family: var(--font-head);
}

.code-sheet .answer-input::placeholder {
  letter-spacing: normal;
  text-transform: none;
  font-family: var(--font-body);
}

.code-sheet .feedback-box {
  text-align: left;
}

.code-sheet button[hidden] { display: none; }

/* FAQ-Akkordeon unter dem "Rallye starten"-Button: Frage fett, Antwort
   übernimmt automatisch die .name-sheet p-Optik (gleich wie codeUntertitel) */
.code-faq {
  margin-top: 14px;
  margin-bottom: 10px;
  padding-top: 12px;
  border-top: 1.5px solid var(--color-border);
}

.code-faq summary {
  font-weight: 800;
  font-size: 0.95rem;
  cursor: pointer;
}

.code-faq p {
  margin-top: 10px;
}

.code-shop-note {
  margin-top: 14px;
  font-size: 0.9rem;
  color: var(--color-muted);
}

.code-shop-note a {
  color: var(--color-green-deep);
  font-weight: 600;
}

/* Sprachwahl unten auf dem Code-Screen: Überschrift + Dropdown, gleiche
   Bausteine wie im ☰-Menü. Die Überschrift kopiert bewusst die .menu-label-
   Optik (klein, versal, gedeckt), damit beide Einstiege gleich aussehen. */
.code-lang-label {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 20px;
  margin-bottom: 8px;
  font-size: 0.72rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-muted);
}

.code-lang-label .ico { width: 14px; height: 14px; margin-right: 0; }

.code-lang-row {
  margin-top: 0;
}

/* Das Sprach-Dropdown selbst (beide Screens). Bewusst OHNE appearance:none:
   der System-Pfeil und der native Picker sind auf iOS/Android das, was die
   Gäste kennen - wie beim Teamnamen-Generator (.name-select). Flaggen sind
   Emoji, kein Asset; Windows-Desktops zeigen dort "DE"/"GB"-Kürzel, das
   Sprachlabel steht daneben (akzeptiert). */
.lang-select {
  width: 100%;
  /* iOS zentriert den Text im eingeklappten Select nicht wie Desktop-Browser:
     mit padding:0 klebte die Zeile optisch am unteren Rand und das Feld wirkte
     flach. Symmetrisches Padding + etwas mehr Höhe (14.08.) gibt beiden
     Seiten Luft; die 48 px bleiben komfortabel über der 44-px-Touchgröße. */
  min-height: 48px;
  padding: 11px 10px;
  line-height: 1.2;
  border: 1.5px solid var(--color-border);
  border-radius: 10px;
  background: #fff;
  font-family: inherit;
  font-size: 0.9rem;
  font-weight: 800;
  color: var(--color-text);
  cursor: pointer;
}

.lang-select:focus {
  outline: none;
  border-color: var(--color-green-deep);
}

/* Finish screen */
.finish-sheet {
  text-align: center;
  padding-top: 34px;
}

.finish-logo {
  width: 76px;
  height: 76px;
  margin-bottom: 10px;
}

.finish-sheet h2 { font-size: 1.6rem; }

.finish-sheet p {
  color: var(--color-muted);
  margin-bottom: 18px;
}

/* Grid statt einer Flex-Zeile (19.07.): mit Rang-, Fever- und Zeit-Box
   liefen die Kacheln seitlich über den Sheet-Rand - zwei Spalten, beliebig
   viele Reihen, eine einzelne letzte Box nimmt die volle Breite */
.finish-stats {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  margin-bottom: 22px;
}

.finish-stats .stat {
  background: var(--color-cream-light);
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius);
  padding: 12px 10px;
}

.finish-stats .stat:last-child:nth-child(odd) {
  grid-column: 1 / -1;
}

/* Team-Bildschirm: die drei Boxen (Gespielt/Richtig/Falsch) bleiben eine
   Reihe - das 2-Spalten-Grid gilt nur dem volleren Finish-Screen */
#score-own .finish-stats {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

#score-own .finish-stats .stat:last-child:nth-child(odd) {
  grid-column: auto;
}

/* Zwei Kacheln im Team-Bildschirm brechen bewusst aus dem Grün aus (14.08.):
   "MAX 🔥" trägt dasselbe Orange wie die Best-Kachel im Streak-Bildschirm,
   die Spielzeit bleibt neutral schwarz - sie ist keine Leistung, nur eine Uhr */
#score-own .finish-stats .stat.streak .stat-value { color: #a04f00; }
#score-own .finish-stats .stat.time .stat-value { color: var(--color-text); }

.finish-stats .stat-value {
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 1.3rem;
  color: var(--color-green-deep);
}

/* Punkte-Box "X / MAX": längerer Wert als die reinen Zahlen-Boxen */
.finish-stats .stat.points .stat-value { font-size: 1.1rem; }

/* Rang-Stat-Box: Bezeichnung ist Text statt Zahl */
.finish-stats .stat.rang .stat-value {
  font-size: 0.95rem;
  line-height: 1.25;
  overflow-wrap: break-word;
}

.finish-stats .stat-label {
  font-size: 0.8rem;
  font-weight: 800;
  color: var(--color-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-top: 2px;
}

.finish-sheet .btn-block + .btn-block { margin-top: 10px; }

/* Richtungspfeil im Nächste-Station-Chip: zeigt relativ zur Blickrichtung
   zur nächsten Station, erscheint erst mit aktivem Kompass */
.next-chip .chip-arrow {
  display: inline-flex;
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  color: var(--color-green-deep);
}

.next-chip .chip-arrow svg {
  width: 100%;
  height: 100%;
  fill: currentColor;
}

.next-chip .chip-arrow[hidden] { display: none; }

/* Safari-Wissen (fun_fakt): eigener Look neben Erklärung und Hinweis */
.funfact-box {
  background: #eef0fc;
  border: 1.5px solid #c8cdf4;
  color: #333c8f; /* abgedunkeltes Periwinkle, Kontrast >= 4.5:1 */
  border-radius: 14px;
  padding: 14px 16px;
  font-size: 0.95rem;
  margin: 10px 0 14px;
  line-height: 1.5;
}

/* .feedback-title ist sonst auf .feedback-box gescoped - hier explizit fett */
.funfact-box .feedback-title {
  font-family: var(--font-head);
  font-weight: 700;
  margin-bottom: 4px;
}

/* Foto-Station (typ "foto"): Vorschau des aufgenommenen Team-Fotos +
   fester Trust-Hinweis. Das Foto bleibt strikt lokal (IndexedDB). */
.foto-preview {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 14px;
}

.foto-preview[hidden] { display: none; } /* display:flex schlägt sonst hidden (bekannte Falle) */

.foto-preview img {
  max-width: 100%;
  max-height: 38vh;
  border-radius: 14px; /* wie .q-bild */
  border: 1.5px solid var(--color-border);
}

/* Trust-Hinweis: bewusst ruhig und dezent, kein Feedback-Grün/-Rot */
.foto-trust {
  background: var(--color-cream-light);
  border: 1.5px solid var(--color-border);
  border-radius: 12px;
  padding: 12px 14px;
  margin: 12px 0 14px;
}

.foto-trust-line {
  font-size: 0.92rem;
  line-height: 1.5;
  color: var(--color-text);
  margin: 0 0 4px;
}

.foto-trust-line b { font-weight: 800; }

.foto-trust-hint {
  font-size: 0.85rem;
  line-height: 1.45;
  color: var(--color-muted);
  margin: 8px 0 0;
  padding-top: 8px;
  border-top: 1px solid var(--color-border);
}

/* Team-Foto auf dem Endbildschirm (nur sichtbar, wenn lokal vorhanden) */
.finish-foto {
  display: block;
  width: min(100%, 240px);
  border-radius: 14px;
  border: 1.5px solid var(--color-border);
  margin: 0 auto 18px;
}

.finish-foto[hidden] { display: none; }

/* Meilenstein-Toast: kurzer Feier-Moment, liegt über der offenen Frage */
.milestone-toast {
  position: fixed;
  top: 84px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 3000;
  max-width: calc(100% - 24px);
  background: var(--color-green-deep);
  color: #fff;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 1.02rem;
  border-radius: 999px;
  padding: 12px 22px;
  box-shadow: var(--shadow);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  animation: toast-pop 0.3s ease;
}

.milestone-toast[hidden] { display: none; }

@keyframes toast-pop {
  from { transform: translate(-50%, -12px); opacity: 0; }
  to { transform: translate(-50%, 0); opacity: 1; }
}

/* Live-Rang in der Bestenliste (nur während des Laufs) */
.hs-live {
  background: var(--color-success-bg);
  border: 1.5px solid #bfe0aa;
  color: var(--color-green-darker);
  border-radius: 12px;
  padding: 10px 14px;
  font-size: 0.92rem;
  font-weight: 600;
  margin-bottom: 12px;
}

/* ---------- Guide-Intro/-Outro (Texte aus rallyes.intro_text/outro_text) ---------- */

/* Betreiber-Text aus der DB: Absätze (Leerzeilen) bleiben erhalten;
   linksbündig, weil die Texte länger sind als die zentrierten Intro-Karten */
.guide-sheet .guide-text {
  white-space: pre-line;
  text-align: left;
  margin-bottom: 22px;
}

/* ---------- Onboarding: Intro-Karten + Coach-Marks ---------- */

.intro-card[hidden] { display: none; }

/* Punkte-Indikator unter den Karten */
.intro-dots {
  display: flex;
  justify-content: center;
  gap: 8px;
  margin: 4px 0 16px;
}

.intro-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--color-border);
}

.intro-dot.active { background: var(--color-green-deep); }

/* Dezenter Überspringen-Link unter dem Weiter-Button */
.intro-skip {
  background: none;
  border: none;
  color: var(--color-muted);
  font-family: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  text-decoration: underline;
  min-height: 44px;
  margin-top: 6px;
  cursor: pointer;
}

/* Coach-Marks: Vollbild-Layer fängt alle Taps ab; die Abdunklung kommt aus
   dem Box-Shadow des Spot-Divs, das Ziel bleibt dadurch hell "ausgeschnitten".
   z-index über Header (600), Menü-Liste (1100) und Chips (500);
   der Meilenstein-Toast (3000) bliebe drüber. */
.coachmark-overlay {
  position: fixed;
  inset: 0;
  z-index: 2500;
}

.coachmark-overlay[hidden] { display: none; }

.coachmark-spot {
  position: absolute;
  border-radius: 14px;
  box-shadow: 0 0 0 9999px rgba(38, 30, 20, 0.6);
  transition: left 0.25s ease, top 0.25s ease, width 0.25s ease, height 0.25s ease;
}

.coachmark-bubble {
  position: absolute;
  background: var(--color-card);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 16px;
  width: min(320px, calc(100vw - 24px));
}

.coachmark-bubble p {
  margin: 0 0 12px;
  font-size: 1rem;
  line-height: 1.5;
}

/* ---------- "Problem melden" (Feedback nach gelöster Frage) ---------- */

/* Bewusst nur grauer Text, klar sekundär - "Weiter" bleibt der Primär-Button */
.feedback-report-link {
  display: block;
  width: 100%;
  margin-top: 2px;
  padding: 10px;
  border: none;
  background: none;
  font-family: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--color-muted);
  text-decoration: underline;
  cursor: pointer;
}

.feedback-textarea {
  width: 100%;
  min-height: 130px;
  margin-bottom: 14px;
  padding: 14px 16px;
  border-radius: 14px;
  border: 2px solid var(--color-border);
  font-size: 1rem;
  font-family: inherit;
  font-weight: 600;
  background: #fff;
  color: var(--color-text);
  resize: vertical;
}

.feedback-textarea:focus {
  outline: none;
  border-color: var(--color-green);
}

/* ---------- Gesamt-Review nach Spielende ---------- */

.review-sheet {
  text-align: center;
  padding-top: 30px;
}

.review-sheet h2 {
  font-size: 1.45rem;
  margin-bottom: 16px;
  /* Platz für das absolut positionierte ✕ (54px, top/right 10) - der
     zentrierte Titel läuft sonst darunter */
  padding: 0 52px;
}

#review-step2 { margin-top: 6px; }

/* Sterne-Skala */
.review-stars {
  display: flex;
  justify-content: center;
  gap: 6px;
  margin-bottom: 8px;
}

.review-star {
  background: none;
  border: none;
  padding: 4px 6px;
  line-height: 1;
  font-size: 2.7rem;
  color: #d9cfae;               /* leerer Stern */
  cursor: pointer;
  transition: color 0.12s ease, transform 0.12s ease;
  -webkit-tap-highlight-color: transparent;
}

.review-star.filled { color: #f2b705; }  /* Gold, Kontrast auf Weiss */

.review-star.pop { animation: review-star-pop 0.32s ease-out; }

@keyframes review-star-pop {
  0% { transform: scale(1); }
  40% { transform: scale(1.35); }
  100% { transform: scale(1); }
}

/* Auswahl-Pills (Mehrfachauswahl) */
.review-pills-titel {
  font-family: var(--font-head);
  font-size: 1.05rem;
  font-weight: 700;
  margin: 18px 0 12px;
}

.review-pills {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin-bottom: 16px;
}

.review-pill {
  border: 2px solid var(--color-border);
  background: var(--color-cream-light);
  color: var(--color-text);
  border-radius: 999px;
  padding: 9px 15px;
  min-height: 40px;
  font-family: var(--font-body);
  font-size: 0.92rem;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
  -webkit-tap-highlight-color: transparent;
}

.review-pill.selected {
  background: var(--color-green);
  border-color: var(--color-green-deep);
  color: #fff;
}

/* Freitext: kompakter Default; bei Unzufriedenheit (review-neg) prominenter */
.review-freitext {
  min-height: 88px;
  text-align: left;
}

.review-neg .review-freitext {
  min-height: 120px;
  border-color: var(--color-coral);
}

/* Abschluss */
.review-danke-emoji { font-size: 3rem; line-height: 1; margin-bottom: 6px; }
#review-danke h2 { font-size: 1.5rem; margin-bottom: 10px; }
#review-danke-text {
  color: var(--color-muted);
  line-height: 1.55;
  margin-bottom: 18px;
}

.review-sheet .btn-block + .btn-block { margin-top: 10px; }

/* dezentes "Überspringen" */
.review-skip {
  display: block;
  margin: 16px auto 2px;
  background: none;
  border: none;
  color: var(--color-muted);
  font-family: var(--font-body);
  font-size: 0.9rem;
  text-decoration: underline;
  cursor: pointer;
}

/* hidden+display-Falle (wie .btn[hidden]): display:flex/block überschreibt
   sonst das hidden-Attribut, wenn der Danke-Schritt Sterne/Skip/Pills verbirgt */
.review-stars[hidden], .review-skip[hidden], .review-pills[hidden] { display: none; }

/* ---------- Hilfe/FAQ-Overlay (☰-Menü) ---------- */

.hilfe-sheet { padding-top: 34px; }

.hilfe-sheet h2 {
  margin-bottom: 14px;
  text-align: center;
}

.hilfe-status {
  text-align: center;
  color: var(--color-muted);
  font-weight: 600;
  padding: 12px 0;
}

/* Native <details>-Auf-/Zuklapper, eine Frage pro Eintrag */
.faq-item {
  border-top: 1.5px solid var(--color-border);
}

.faq-item:last-child { border-bottom: 1.5px solid var(--color-border); }

.faq-item summary {
  padding: 13px 4px;
  font-weight: 800;
  font-size: 0.95rem;
  cursor: pointer;
}

.faq-antwort {
  padding: 0 4px 14px;
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--color-muted);
  white-space: pre-line; /* Absätze aus der DB (Leerzeilen) erhalten */
}

/* ---------- Datenschutz-Overlay (☰-Menü, Fußzeile) ---------- */

/* Fließtext-Sheet: erbt Kopf/Scroll von .hilfe-sheet, setzt nur die
   Lesetypografie für den langen Rechtstext. Muss NACH den .hilfe-sheet-Regeln
   stehen - gleiche Spezifität, es entscheidet die Reihenfolge. */
.legal-sheet { text-align: left; }

/* "Datenschutzerklärung" ist zu lang für die zentrierte Hilfe-Optik -
   zentriert lief das Wort unter das ✕. Deshalb linksbündig mit Freiraum
   rechts für den Schließen-Button (54 px + Rand). */
.legal-sheet h2 {
  text-align: left;
  padding-right: 60px;
  font-size: 1.2rem;
}

.legal-sheet h3 {
  margin: 18px 0 6px;
  font-size: 0.95rem;
}

.legal-sheet p,
.legal-sheet li {
  font-size: 0.88rem;
  font-weight: 600;
  line-height: 1.5;
  color: var(--color-muted);
}

.legal-sheet p { margin-bottom: 10px; }

.legal-sheet ul {
  margin: 0 0 10px;
  padding-left: 20px;
}

.legal-sheet li { margin-bottom: 6px; }

.legal-sheet strong { color: var(--color-text); }

/* Dienstleister-Tabelle: im schmalen Sheet klein gesetzt, damit die drei
   Spalten ohne horizontales Scrollen auf ein Handy passen */
.legal-table {
  width: 100%;
  margin-bottom: 10px;
  border-collapse: collapse;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--color-muted);
}

.legal-table th,
.legal-table td {
  padding: 7px 6px;
  border-bottom: 1.5px solid var(--color-border);
  text-align: left;
  vertical-align: top;
}

.legal-table th { color: var(--color-text); }

.legal-stand {
  margin-top: 14px;
  font-size: 0.8rem;
}

/* ---------- Veranstalter-Monitor (monitor.html) ---------- */

/* Eigenständige Seite: darf scrollen (App-Body ist overflow:hidden) */
.monitor-body {
  display: block;
  height: auto;
  min-height: 100vh;
  overflow: auto;
}

/* Subtitle einzeilig halten: lange Rallye-/Gruppennamen werden abgeschnitten
   statt den Header wortweise umzubrechen (iPhone) */
.monitor-subtitle {
  font-size: 0.85rem;
  color: var(--color-muted);
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.monitor-tools {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
}

/* Live-Punkt: pulsierend solange der Auto-Refresh funktioniert,
   bei Verbindungsfehlern statisch coral mit "Offline" */
.monitor-live {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 0.82rem;
  color: var(--color-green-deep);
}

.monitor-live[hidden] { display: none; }

.live-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--color-green);
  animation: live-pulse 1.6s ease-out infinite;
}

@keyframes live-pulse {
  0% { box-shadow: 0 0 0 0 rgba(107, 201, 62, 0.45); }
  70% { box-shadow: 0 0 0 7px rgba(107, 201, 62, 0); }
  100% { box-shadow: 0 0 0 0 rgba(107, 201, 62, 0); }
}

.monitor-live.is-offline { color: var(--color-coral-deep); }

.monitor-live.is-offline .live-dot {
  background: var(--color-coral-deep);
  animation: none;
}

/* Sprachwahl steckt im ☰-Menü: Optik kommt komplett aus den
   .app-menu*-Regeln des Spiels (oben), hier nichts Eigenes nötig */

.monitor-main {
  max-width: 860px;
  margin: 0 auto;
  padding: 18px 16px 40px;
}

.monitor-gate {
  max-width: 420px;
  margin: 40px auto;
  text-align: center;
}

/* Status-Chips = Filter-Pills (Single-Select) */
.monitor-summary {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 14px;
}

.monitor-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 40px;
  background: var(--color-card);
  border: 1.5px solid var(--color-border);
  border-radius: 999px;
  padding: 7px 14px;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 0.92rem;
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}

.monitor-chip.laeuft { color: var(--color-periwinkle); }
.monitor-chip.fertig { color: var(--color-green-deep); }
.monitor-chip.inaktiv { color: var(--color-coral-deep); }
.monitor-chip.quit { color: var(--color-muted); }

.monitor-chip.is-active {
  background: var(--color-text);
  border-color: var(--color-text);
  color: #fff;
}

.monitor-chip:focus-visible {
  outline: 2px solid var(--color-green-deep);
  outline-offset: 2px;
}

.monitor-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.monitor-row {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--color-card);
  border: 1.5px solid var(--color-border);
  border-radius: 14px;
  padding: 12px 18px;
  /* Feste Mindesthöhe gegen Sprünge, wenn Zeit-/Stille-Zeilen dazukommen */
  min-height: 76px;
}

.monitor-row.st-quit { opacity: 0.55; }

.monitor-rank {
  flex-shrink: 0;
  width: 2.4em;
  height: 2.4em;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--color-cream);
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 0.98rem;
  color: var(--color-text);
}

.monitor-name {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.monitor-name-main {
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 1.15rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Zeile immer reservieren (auch ohne internen Namen): alle Kacheln
   bekommen so exakt dieselbe Höhe */
.monitor-name-public {
  min-height: 1.15em;
  font-size: 0.82rem;
  color: var(--color-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.monitor-progress {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 8px;
}

.monitor-bar {
  width: 110px;
  height: 10px;
  border-radius: 999px;
  background: var(--color-cream);
  overflow: hidden;
}

.monitor-bar-fill {
  display: block;
  height: 100%;
  width: 0%;
  background: var(--color-green);
  border-radius: 999px;
  transition: width 0.3s ease;
}

.monitor-bar-text {
  min-width: 3.6em;
  text-align: right;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 0.9rem;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* Status-Spalte mit fester Breite: auftauchende Zeit-/Stille-Texte
   dürfen die Nachbarspalten nicht verschieben */
.monitor-status {
  flex-shrink: 0;
  width: 12.5em;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  font-size: 0.88rem;
  font-weight: 800;
}

.monitor-row.st-laeuft .monitor-status { color: var(--color-periwinkle); }
.monitor-row.st-fertig .monitor-status { color: var(--color-green-deep); }
.monitor-row.st-inaktiv .monitor-status { color: var(--color-coral-deep); }
.monitor-row.st-quit .monitor-status { color: var(--color-muted); }

/* Zweite Zeile (Zeit + Stille-Hinweis) ist immer reserviert und bricht
   nie um: lieber abschneiden als ungleich hohe Kacheln */
.monitor-status-sub {
  display: flex;
  flex-wrap: nowrap;
  gap: 10px;
  min-height: 1.3em;
  max-width: 100%;
  overflow: hidden;
  white-space: nowrap;
}

.monitor-time {
  font-weight: 600;
  color: var(--color-muted);
}

.monitor-stale {
  font-weight: 800;
  color: var(--color-coral-deep);
}

.monitor-points {
  flex-shrink: 0;
  width: 2.8em;
  text-align: right;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 1.3rem;
  color: var(--color-green-deep);
  font-variant-numeric: tabular-nums;
}

.monitor-empty {
  margin: 8px 0 0;
  background: var(--color-card);
  border: 1.5px dashed var(--color-border);
  border-radius: 14px;
  padding: 22px;
  text-align: center;
  color: var(--color-muted);
}

.monitor-hint {
  margin-top: 16px;
  font-size: 0.85rem;
  color: var(--color-muted);
  text-align: center;
}

/* Platzhalter fürs erste Laden, gleiche Höhe wie echte Karten */
.monitor-skeleton {
  border-style: dashed;
  animation: monitor-pulse 1.2s ease-in-out infinite alternate;
}

@keyframes monitor-pulse {
  from { opacity: 0.35; }
  to { opacity: 0.8; }
}

@media (prefers-reduced-motion: reduce) {
  .monitor-skeleton { animation: none; opacity: 0.5; }
  .monitor-bar-fill { transition: none; }
  .live-dot { animation: none; }
}

#monitor-gate[hidden], #monitor-board[hidden] { display: none; }

/* Schmale Screens (Handy-Blick des Veranstalters): Balken auf volle Breite,
   Status-Zeile bricht unter den Namen um statt rechts rauszulaufen */
@media (max-width: 560px) {
  /* Kompaktere Pills: möglichst zwei pro Zeile statt drei Zeilen Filter */
  .monitor-chip {
    padding: 6px 11px;
    font-size: 0.85rem;
    min-height: 36px;
    gap: 5px;
  }
  .monitor-row {
    display: grid;
    grid-template-columns: auto 1fr auto;
    grid-template-areas:
      "rank name points"
      "prog prog prog"
      "status status status";
    column-gap: 12px;
    row-gap: 8px;
    align-items: center;
  }
  .monitor-rank { grid-area: rank; }
  .monitor-name { grid-area: name; }
  .monitor-points { grid-area: points; width: auto; }
  .monitor-progress { grid-area: prog; width: 100%; }
  .monitor-bar { flex: 1; width: auto; }
  .monitor-status {
    grid-area: status;
    width: auto;
    flex-direction: row;
    flex-wrap: nowrap;
    align-items: baseline;
    gap: 12px;
    overflow: hidden;
    white-space: nowrap;
  }
  .monitor-status-sub { min-height: 0; }
}

/* Beamer / große Screens: mehr Luft und größere Schrift */
@media (min-width: 1100px) {
  .monitor-main { max-width: 1000px; }
  .monitor-name-main { font-size: 1.3rem; }
  .monitor-points { font-size: 1.5rem; }
  .monitor-bar { width: 170px; }
  .monitor-status { width: 13em; font-size: 0.95rem; }
}

/* Konfetti */
.confetti-layer {
  position: fixed;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 3000;
}

.confetti-piece {
  position: absolute;
  top: -16px;
  width: 9px;
  height: 14px;
  border-radius: 2px;
  animation: confetti-fall linear forwards;
}

@keyframes confetti-fall {
  to {
    transform: translateY(105vh) rotate(720deg);
    opacity: 0.9;
  }
}

/* ---------- Weiter-Joker (07.08.) ----------
   Beide Einstiege bleiben optisch klar sekundär: der Textbutton in der
   Stations-Vorschau sieht nie wie der Hauptweg aus, der Button im Frage-Modal
   steht unter Antworten und Hinweis. */

/* Dezenter Textbutton ("Station nicht erreichbar?", "Zurück") - Optik des
   Problem-melden-Links, damit die Hierarchie im Sheet erhalten bleibt */
.joker-link {
  display: block;
  width: 100%;
  margin-top: 6px;
  padding: 10px;
  border: none;
  background: none;
  font-family: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--color-muted);
  text-decoration: underline;
  cursor: pointer;
}

.joker-link[hidden] { display: none; }

/* Zwischenschritt-Sheet: Titel + Restkontingent über den zwei Wegen */
.joker-sheet-titel {
  margin: 0 0 6px;
  font-size: 1.15rem;
}

.joker-rest {
  margin: 0 0 18px;
  color: var(--color-muted);
  font-size: 0.9rem;
}

/* Erklärzeile unter jedem der beiden Wege - nimmt der Entscheidung die
   Unsicherheit ("kostet keinen Skip" / "kostet einen Skip"). Mehr Abstand
   zum Button darüber und darunter (11.08., wirkte vorher zu gedrängt). */
.joker-weg-note {
  margin: 10px 0 20px;
  color: var(--color-muted);
  font-size: 0.85rem;
  line-height: 1.45;
}

/* Einstieg B im Frage-Modal: eigener Bereich ganz unten, durch eine feine
   Linie vom Antwortbereich abgesetzt */
.joker-area {
  margin-top: 20px;
  padding-top: 14px;
  border-top: 1.5px solid var(--color-border);
}

.joker-area[hidden] { display: none; }

.joker-btn {
  display: block;
  width: 100%;
  padding: 12px;
  border: 1.5px solid var(--color-border);
  border-radius: 12px;
  background: none;
  font-family: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--color-muted);
  cursor: pointer;
}

.joker-btn[hidden] { display: none; }

.joker-btn:active { background: var(--color-cream-light); }

/* Kontingent aufgebraucht: freundlicher Hinweis statt Button (beide Einstiege) */
.joker-leer {
  margin: 6px 0 0;
  color: var(--color-muted);
  font-size: 0.85rem;
  line-height: 1.45;
}

.joker-leer[hidden] { display: none; }

/* Freiwilligkeits-Zeile im "Problem melden"-Sheet nach einem Skip */
.feedback-freiwillig {
  margin: -6px 0 12px;
  color: var(--color-muted);
  font-size: 0.9rem;
}

.feedback-freiwillig[hidden] { display: none; }

/* Übersprungene Station: neutral grau mit Pfeil - bewusst weder das grüne ✓
   der gelösten noch der rote ✕-Pin der gescheiterten. Der Glyph "→" trägt die
   Information mit, Farbe ist nie alleiniger Träger. */
.station-marker.skipped {
  background: #8c8577;
}

.station-item.skipped .item-badge { background: #8c8577; }
.station-item.skipped .item-status { color: var(--color-muted); }

/* Stat-Boxen: übersprungene Stationen und genutzte Joker neutral, nicht rot -
   ein Joker ist kein Fehler */
.stat.skipped .stat-value,
.stat.joker .stat-value { color: var(--color-muted); }

/* ---------- Icon-Feinschliff je Kontext (27.07.) ----------
   Steht bewusst am Dateiende: die Basis-.ico ganz oben legt Größe/Stroke fest,
   hier gewinnen die kontextabhängigen Ausrichtungen gegen die display-Angaben
   der jeweiligen Komponenten weiter oben. */

/* ☰-Button und Würfel-Button: reines Icon, exakt zentriert */
.app-menu-btn,
.name-random {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* Menü: Icon-Spalte links, Text daneben - alle Einträge fluchten */
.menu-label,
.menu-link {
  display: flex;
  align-items: center;
  gap: 10px;
}
.menu-label .ico,
.menu-link .ico { margin-right: 0; }
/* Die Label-Zeilen sind klein gesetzt (0.72rem) - das Icon darf etwas größer
   als 1.1em bleiben, sonst verschwindet es neben dem Versal-Text */
.menu-label .ico { width: 14px; height: 14px; }
/* Muss nach den display:flex-Regeln stehen: #menu-route wird per hidden-Attribut
   aus- und eingeblendet, eine Author-display-Angabe schlaegt sonst hidden */
.menu-label[hidden],
.menu-link[hidden] { display: none; }

/* Schließen-Button auf allen Sheets */
.sheet-dismiss {
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Großes Kopf-Symbol in zentrierten Sheets (Standort-Freigabe, Übernahme-
   Dialog): Lucide-Icon in runder, dezent grüner Fläche - ruhiger und
   professioneller als das frühere 2,6rem-Emoji */
.sheet-hero-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 64px;
  height: 64px;
  margin: 4px auto 12px;
  border-radius: 50%;
  background: var(--color-success-bg);
  border: 1.5px solid #bfe0aa;
  color: var(--color-green-deep);
}
.sheet-hero-icon .ico { width: 30px; height: 30px; stroke-width: 1.8; }

/* Modus-Kacheln: Icon vor dem Titel */
.mode-btn .mode-title {
  display: flex;
  align-items: center;
  gap: 8px;
}
.mode-btn .mode-title .ico { margin-right: 0; }

/* Hinweis-Button, Feedback-Titel, Bestenlisten-Überschrift:
   Icon und Text auf einer Zeile, Umbrüche rücken sauber ein */
.hint-toggle,
.feedback-box .feedback-title,
.hs-heading,
.hs-live,
.geo-accuracy-warnung,
.preview-distance {
  display: flex;
  align-items: center;
  gap: 8px;
}
.hint-toggle .ico,
.feedback-box .feedback-title .ico,
.hs-heading .ico,
.hs-live .ico,
.geo-accuracy-warnung .ico,
.preview-distance .ico { margin-right: 0; }
/* .preview-distance ist als Pille gesetzt */
.preview-distance { display: inline-flex; }
/* Mehrzeilige Boxen: Icon oben halten statt vertikal mittig */
.hs-live,
.geo-accuracy-warnung { align-items: flex-start; }
.hs-live .ico,
.geo-accuracy-warnung .ico { margin-top: 0.15em; }

/* "läuft noch"-Pille in der Bestenliste */
.hs-row .hs-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.hs-row .hs-badge .ico { margin-right: 0; width: 12px; height: 12px; }

/* Stations-Liste: "Start"-Marker */
.station-item .item-status {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.station-item .item-status .ico { margin-right: 0; }

/* Foto-Aufgaben: die beiden Datenschutz-Zusagen. Blau als Signalfarbe für
   "privat/sicher" (Betreiber-Wunsch 27.07.: blaues Schloss statt 🔒-Emoji);
   bewusst nicht grün, damit die Zeilen nicht wie eine Richtig-Rückmeldung
   gelesen werden. Der Farbwert ist derselbe wie in der Safari-Wissen-Box. */
.foto-trust-line {
  display: flex;
  align-items: flex-start;
  gap: 9px;
}
.foto-trust-line .ico {
  margin-right: 0;
  margin-top: 0.12em;
  width: 1.25em;
  height: 1.25em;
  color: #333c8f;
}

/* Veranstalter-Monitor (27.07.): Filter-Pills und Status-Spalte tragen dieselben
   Lucide-Icons (footprints / pause / circle-check / circle-x). Farbe kommt weiter
   aus .monitor-chip.<status> bzw. .monitor-row.st-<status> - currentColor sorgt
   dafür, dass Icon und Text automatisch dieselbe Statusfarbe haben (inkl. der
   weißen Schrift des aktiven Filter-Chips). */
.monitor-chip .chip-icon {
  display: inline-flex;
  align-items: center;
}
.monitor-status-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.monitor-status-label .ico { margin-right: 0; }

@media (min-width: 480px) {
  .overlay { align-items: center; }
  .sheet { border-radius: 24px; margin: 20px; }
}
