:root {
  --bg: #12151a; --fg: #f2f4f7; --muted: #98a2b3;
  --accent: #ffb020; --danger: #e5484d; --ok: #30a46c;
  --tap: 56px;
  /* Rollenfarbe. Bis zum Spielstart neutral, danach von app.js ueber
     body.role-* gesetzt. Siehe #status unten fuer die Begruendung. */
  --role: #232830; --roleFg: var(--fg);
}
/* Das Spiel besteht daraus, ob man gerade Gejagter oder Jaeger ist, und das
   kippt jede Sekunde. Vorher stand die Rolle als Text in der Statuszeile -
   gleiches Gewicht wie Muenzstand und Ringtimer, und nach dem Wegtippen des
   Rollentausch-Overlays sagte nichts mehr auf einen Blick, woran man ist.
   Jetzt traegt die gesamte Kopfzeile die Rollenfarbe: im Laufen aus dem
   Augenwinkel erkennbar, ohne lesen zu muessen.
   Gelb fuer den Gejagten (dieselbe Farbe wie sein Fangcode-Balken direkt
   darunter - er ist das Ziel, er leuchtet), Blau fuer die Jaeger (dieselbe
   Farbe, in der map.js den Spaeherblick zeichnet). */
body.role-hunted { --role: #ffb020; --roleFg: #1a1200; }
body.role-hunter { --role: #2f6fd0; --roleFg: #ffffff; }
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; height: 100%; overscroll-behavior: none; }
body {
  background: var(--bg); color: var(--fg); font: 16px/1.4 system-ui, sans-serif;
  display: flex; flex-direction: column; height: 100dvh;
}
button { font: inherit; min-height: var(--tap); border: 0; border-radius: 10px;
  background: #232830; color: var(--fg); padding: 0 16px; }
button.primary { background: var(--accent); color: #1a1200; font-weight: 700; }
input { font: inherit; min-height: var(--tap); width: 100%; padding: 0 14px;
  border-radius: 10px; border: 2px solid #333a45; background: #1a1e25; color: var(--fg); }

.screen { padding: 24px; display: flex; flex-direction: column; gap: 12px; justify-content: center; height: 100%; }
.error { color: var(--danger); min-height: 1.4em; }

#game { display: flex; flex-direction: column; height: 100%; }
#status { display: flex; gap: 12px; align-items: baseline; padding: 8px 14px;
  background: var(--role); color: var(--roleFg); font-weight: 700; }
/* Die Rolle ist das Erste und Groesste in der Zeile. Die uebrigen Angaben
   bleiben klein daneben - sie werden gelesen, wenn man ohnehin hinsieht,
   waehrend die Rolle auch dann ankommt, wenn man es nicht tut. */
#status #roleLabel { font-size: 21px; letter-spacing: 2px; margin-right: auto; }
#status #coins, #status #ringTimer { font-size: 15px; opacity: .85; }
/* Der Verbindungshinweis muss auch auf gelbem und blauem Grund alarmieren -
   dafuer reicht die Textfarbe nicht, er bekommt einen eigenen Chip. */
#status .offline { background: var(--danger); color: #fff; font-size: 14px;
  padding: 2px 8px; border-radius: 999px; }

/* Problem 1 aus der Task-16-Aufgabenstellung: ein GPS- oder Sendefehler darf
   nicht nur intern verbucht werden, sondern muss auf dem gesperrten,
   in der Sonne gehaltenen Handybildschirm sofort auffallen - deshalb ein
   voller Balken statt eines kleinen Icons, und dieselbe --danger-Farbe wie
   #status .offline. */
.warnBar { margin: 0; padding: 10px 14px; background: var(--danger); color: #fff;
  font-weight: 700; text-align: center; }
/* #statusStrip (Task 18): 'outside' nutzt die geerbte --danger-Farbe direkt
   (dieselbe Dringlichkeit wie #deviceWarn); 'rally' braucht eine eigene
   Akzentfarbe, weil ein nicht erreichter Sammelpunkt kein Alarm ist, sondern
   eine laufende Anweisung. */
.warnBar.rally { background: var(--accent); color: #1a1200; }

#catchCodeBar button { width: 100%; font-size: 40px; letter-spacing: 10px;
  font-weight: 800; background: var(--accent); color: #1a1200; border-radius: 0; min-height: 72px; }
#hunterBar button { width: 100%; border-radius: 0; min-height: 64px; font-size: 22px; }

.tab { flex: 1; overflow-y: auto; }
/* Grauer Hintergrund statt Weiss/kaputtem-Bild-Symbol: wenn Kacheln nicht
   laden (schwaches Netz), bleibt die Flaeche einfach neutral grau, waehrend
   Ring/Zielzone/Blips unabhaengig davon in ihrer eigenen Ebene weiterzeichnen
   (siehe map.js, errorTileUrl). */
#map { height: 100%; background: #232830; }
/* Namensnennung bleibt an (ODbL-Lizenzpflicht + OSM-Kachelrichtlinie), aber
   klein und unaufdringlich statt raumgreifend - siehe map.js fuer die
   Begruendung, warum sie nicht abgeschaltet wird. */
.leaflet-control-attribution { font-size: 10px; line-height: 1.3; padding: 1px 6px; }
/* Leaflets eigene Zoomknoepfe sind auch im Touch-Modus nur 30x30 px. Der
   Knopf wurde gerade deshalb wieder eingeschaltet, damit sich die Karte mit
   einem Daumen bedienen laesst - dann muss er auch die Groesse haben, die
   dieses Projekt sonst ueberall fuer Tap-Ziele verwendet. Zwei Finger zum
   Zoomen bleiben als Rueckfallweg, sind beim Laufen aber keine Option.
   44px statt der vollen 56px: die Karte ist die Flaeche, auf der man am
   wenigsten Platz verschenken will, und 44px ist die uebliche Untergrenze. */
.leaflet-touch .leaflet-control-zoom-in,
.leaflet-touch .leaflet-control-zoom-out,
.leaflet-control-zoom-in,
.leaflet-control-zoom-out {
  width: 44px; height: 44px; line-height: 42px; font-size: 24px;
}
#tabs { display: flex; }
#tabs button { flex: 1; border-radius: 0; font-weight: 700; letter-spacing: 1px; }
/* Auch der aktive Reiter traegt die Rollenfarbe, damit Kopf- und Fusszeile
   dieselbe Sprache sprechen. Gelb bleibt dadurch frei fuer genau eine
   Bedeutung: "hier drueckst du" (FANGEN, Losgehen, Kaufen) - auf blauem Grund
   sticht das umso mehr heraus. */
#tabs button.active { background: var(--role); color: var(--roleFg); }

#overlay { position: fixed; inset: 0; background: #12151a; z-index: 999;
  display: flex; flex-direction: column; gap: 20px; align-items: center;
  justify-content: center; text-align: center; padding: 28px; }
#overlay.danger { background: var(--danger); color: #fff; }
#overlay h2 { font-size: 30px; margin: 0; }
#overlay .huge { font-size: 22vw; letter-spacing: 6px; font-weight: 800; }

.card { background: #1a1e25; border-radius: 12px; padding: 14px; margin: 12px; }
.card h3 { margin: 0 0 6px; }
.card .meta { color: var(--muted); font-size: 14px; }
.card.solved { opacity: .55; }
.card.locked { opacity: .5; }
