/* =====================================================================
   Peregra — die Website

   Die Farben sind **dieselben wie in der App** (lib/core/theme/app_theme.dart).
   Zwei Paletten für dasselbe Produkt wären der sichere Weg dahin, dass die
   Website nach einem halben Jahr anders aussieht als das, was man
   herunterlädt.

   Hell und Dunkel laufen über Bootstraps `data-bs-theme`. Wir setzen nur
   die eigenen Werte darunter neu — alles, was Bootstrap selbst färbt,
   folgt dann von allein.
   ===================================================================== */

:root {
  --pg-accent: #5b44d9;
  --pg-accent-2: #0b87b8;
  --pg-coral: #d63e6c;
  --pg-lime: #0e8f63;
  --pg-surface: #ffffff;
  --pg-surface-alt: #eff1f7;
  --pg-border: #e2e6f0;
  /* Die Kante der Karten ist bewusst blass. Für einen Knopf ist sie zu
     blass: Auf `--bs-body-bg` (#f6f7fb) bleibt von ihr fast nichts übrig,
     und der Knopf sah aus wie eine weiße Fläche ohne Rand. */
  --pg-border-strong: #ccd3e2;
  --pg-muted: #858da6;
  --pg-shadow: 0 1px 2px rgba(18, 22, 40, .06), 0 8px 24px rgba(18, 22, 40, .06);
  --pg-radius: 18px;

  /* **Das Blau der Knöpfe.** `.btn-primary` bringt es fest einkompiliert
     mit (#0d6efd); `--bs-primary` ändert daran nichts. Damit der Rest der
     Seite dieselbe Farbe trägt, steht sie hier — und nicht dreimal
     abgeschrieben.
     `--pg-blue-soft` ist dieselbe Farbe, aufgehellt: Auf dem dunklen Kopf
     erreicht #0d6efd für kleine Schrift keinen ausreichenden Kontrast
     (4,2:1 statt 4,5:1). Für Flächen und Linien reicht es, für Text
     nicht. */
  --pg-blue: #0d6efd;
  --pg-blue-soft: #5a9dff;

  --bs-body-bg: #f6f7fb;
  --bs-body-color: #121628;
  --bs-primary: var(--pg-accent);
  --bs-link-color-rgb: 91, 68, 217;
  --bs-border-radius: var(--pg-radius);
  --bs-font-sans-serif: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
}

[data-bs-theme="dark"] {
  --pg-accent: #9b85ff;
  --pg-accent-2: #4cdbff;
  --pg-coral: #ff7fa8;
  --pg-lime: #5fe0a6;
  --pg-surface: #161c2c;
  --pg-surface-alt: #1f2739;
  --pg-border: #2a3348;
  --pg-border-strong: #3b4761;
  --pg-muted: #7c859e;
  --pg-shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 12px 32px rgba(0, 0, 0, .35);

  --bs-body-bg: #0b0f1a;
  --bs-body-color: #f2f5fc;
  --bs-secondary-color: #b2bad0;
  --bs-link-color-rgb: 155, 133, 255;
  --bs-border-color: var(--pg-border);
}

/* --- Schriften -------------------------------------------------------
   Lokal, nicht von Google Fonts. Zwei Gründe, und der zweite wiegt
   schwerer: Ohne Netz fiele die Seite auf eine Systemschrift zurück, und
   ein Abruf bei Google überträgt die IP-Adresse jedes Besuchers an einen
   Dritten — das wäre ohne Einwilligung nicht zu haben, und genau die
   wollen wir uns sparen.
   `font-display: swap`, damit Text sofort steht statt unsichtbar zu
   bleiben, bis die Datei da ist.                                      */

@font-face {
  font-family: "Inter";
  src: url("/assets/fonts/Inter-Regular.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("/assets/fonts/Inter-SemiBold.woff2") format("woff2");
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Sora";
  src: url("/assets/fonts/Sora-SemiBold.woff2") format("woff2");
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Sora";
  src: url("/assets/fonts/Sora-Bold.woff2") format("woff2");
  font-weight: 700; font-style: normal; font-display: swap;
}

body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--bs-body-bg);
}

h1, h2, h3, .navbar-brand, .pg-section-title, .pg-page-title, .pg-hero-title {
  font-family: "Sora", var(--bs-font-sans-serif);
  font-weight: 600;
  letter-spacing: -.01em;
}

.skip-link {
  position: absolute; top: .5rem; left: .5rem; z-index: 2000;
  background: var(--pg-surface); padding: .5rem .9rem;
  border-radius: 10px; box-shadow: var(--pg-shadow);
}

/* --- Kopf ------------------------------------------------------------ */

.pg-header {
  background: color-mix(in srgb, var(--bs-body-bg) 82%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--pg-border);
}
.navbar-brand { font-weight: 600; font-size: 1.15rem; }
.brand-mark { flex: 0 0 auto; border-radius: 22%; }
.nav-link.active { color: var(--pg-accent) !important; font-weight: 600; }

/* --- Darstellung und Sprache -----------------------------------------

   Beide saßen vorher in `btn-outline-secondary` mit Bootstraps Caret —
   gemeldet als „die select boxen sehen billig aus". Sie waren es auch:
   die Vorgabe des Baukastens, ungefragt übernommen.

   Was sie jetzt eint, ist eine eigene Grundform — ein Feld auf
   `--pg-surface` mit feinem Rand, die Ecken so rund wie die Karten
   darunter. Was sie trennt, ist ihre Aufgabe: Die Darstellung hat drei
   Stellungen und zeigt sie alle, die Sprache hat sechs und klappt auf.  */

.pg-seg {
  display: flex;
  gap: 2px;
  padding: 3px;
  background: var(--pg-surface-alt);
  border: 1px solid var(--pg-border);
  border-radius: 999px;
}
/* **Gleich breit, nicht nach Textlänge.** `1 1 auto` gab dem längsten
   Wort das doppelte Feld — ein Umschalter, dessen Stellungen
   verschieden groß sind, sieht aus wie drei Knöpfe, die zufällig
   nebeneinander liegen. */
.pg-seg-item {
  flex: 1 1 0;
  min-width: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .4rem;
  padding: .35rem .5rem;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--pg-muted);
  font: inherit;
  font-size: .85rem;
  line-height: 1.2;
  cursor: pointer;
  transition: background-color .15s ease, color .15s ease;
}
.pg-seg-item:hover { color: var(--bs-body-color); }
/* Die Pille unter der aktiven Stellung. Sie trägt die ganze Auskunft —
   deshalb nicht nur eine andere Schriftfarbe, sondern eine Fläche. */
.pg-seg-item.active {
  background: var(--pg-surface);
  color: var(--pg-accent);
  box-shadow: 0 1px 2px rgba(18, 22, 40, .08);
}
[data-bs-theme="dark"] .pg-seg-item.active {
  box-shadow: 0 1px 2px rgba(0, 0, 0, .4);
}
.pg-seg-item:focus-visible {
  outline: 2px solid var(--pg-accent);
  outline-offset: 1px;
}

.pg-lang-btn {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  padding: .4rem .7rem;
  background: var(--pg-surface);
  border: 1px solid var(--pg-border);
  border-radius: 999px;
  color: var(--bs-body-color);
  font: inherit;
  font-size: .85rem;
  line-height: 1.2;
  cursor: pointer;
  transition: border-color .15s ease, color .15s ease;
}
.pg-lang-btn:hover,
.pg-lang-btn[aria-expanded="true"] {
  border-color: color-mix(in srgb, var(--pg-accent) 50%, var(--pg-border));
  color: var(--pg-accent);
}
.pg-lang-btn:focus-visible {
  outline: 2px solid var(--pg-accent);
  outline-offset: 1px;
}
.pg-lang-code { text-transform: uppercase; font-weight: 600; letter-spacing: .03em; }
/* Der Winkel dreht sich, wenn das Menü offen ist — dieselbe Bewegung wie
   bei den Gruppen in der App. */
.pg-chevron { transition: transform .18s ease; opacity: .7; }
.pg-lang-btn[aria-expanded="true"] .pg-chevron { transform: rotate(180deg); }

.pg-lang-menu {
  --bs-dropdown-padding-y: .35rem;
  --bs-dropdown-border-color: var(--pg-border);
  --bs-dropdown-bg: var(--pg-surface);
  --bs-dropdown-border-radius: 14px;
  --bs-dropdown-link-active-bg: transparent;
  --bs-dropdown-link-active-color: var(--pg-accent);
  box-shadow: var(--pg-shadow);
}
.pg-lang-menu .dropdown-item {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.5rem;
  border-radius: 9px;
  padding: .45rem .7rem;
  margin: 0 .35rem;
  width: auto;
}
.pg-lang-menu .dropdown-item:hover,
.pg-lang-menu .dropdown-item:focus {
  background: var(--pg-surface-alt);
}
.pg-lang-menu .dropdown-item.active { font-weight: 600; }
/* Das Kürzel ist die Wiedererkennung zum Knopf, nicht die Auskunft. */
.pg-lang-tag {
  text-transform: uppercase;
  font-size: .72rem;
  letter-spacing: .06em;
  color: var(--pg-muted);
}
.pg-lang-menu .dropdown-item.active .pg-lang-tag { color: var(--pg-accent); }

/* --- Das aufgeklappte Menü auf dem Telefon ---------------------------

   **Die Grundfassung ist die schmale.** Gemeldet am 16. September: *„auf
   mobile sieht das menu nicht gut aus und verschwindet teilweise aus dem
   viewport."* Drei Ursachen, und alle drei kamen daher, dass die Leiste
   für den breiten Schirm entworfen und dann zusammengeschoben wurde:

   * Der Knopf für die Darstellung zeigte nur noch seinen Pfeil — die
     Beschriftung war unter 1200 Punkten ausgeblendet, auch dort, wo das
     Menü aufgeklappt über die ganze Breite steht und Platz im Überfluss
     hat.
   * Die Klappmenüs waren rechtsbündig (`dropdown-menu-end`), ihre Knöpfe
     stehen im aufgeklappten Menü aber **links**. Das Menü klappte nach
     links auf und lag zur Hälfte außerhalb des Bildschirms.
   * Drei verschieden große Bedienelemente in einer Reihe, darüber zwei
     Verweise untereinander: kein Raster, das man lesen kann.

   Jetzt stehen sie untereinander und über die volle Breite, durch eine
   Linie von den Verweisen getrennt. Ab `lg` gilt wieder die Reihe — dort
   ist die Leiste eine Leiste.                                        */

.pg-nav-tools {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: .5rem;
  margin-top: .75rem;
  padding-top: .75rem;
  border-top: 1px solid var(--pg-border);
}
/* Im aufgeklappten Menü füllt alles seine Zeile — und **die Auswahl
   ebenso**: Ein schmales Menü legte sich sonst über den Wähler darunter
   und sah aus, als hinge es schief. */
.pg-nav-tools .dropdown { width: 100%; }
.pg-nav-tools .pg-lang-btn { width: 100%; justify-content: flex-start; }
.pg-nav-tools .pg-lang-btn .pg-chevron { margin-left: auto; }
.pg-nav-tools .dropdown-menu { width: 100%; }

@media (min-width: 992px) {
  .pg-nav-tools {
    flex-direction: row;
    align-items: center;
    gap: .5rem;
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
  }
  .pg-nav-tools .dropdown { width: auto; }
  .pg-nav-tools .pg-lang-btn { width: auto; }
  .pg-nav-tools .pg-lang-btn .pg-chevron { margin-left: 0; }
  .pg-nav-tools .dropdown-menu { width: auto; min-width: 11rem; }
  /* In der Leiste ist der Platz knapp: Dort tragen die Zeichen allein,
     und `title` samt `aria-label` sagen, was sie bedeuten. */
  .pg-seg-text { display: none; }
  .pg-seg-item { padding: .35rem .55rem; }
  /* Der Knopf für die App ist klein wie alles in der Leiste. */
  .pg-nav-tools .btn { --bs-btn-padding-y: .3rem; --bs-btn-padding-x: .9rem;
                       --bs-btn-font-size: .875rem; }
}

/* --- Titelbereich ----------------------------------------------------
   Der Kopf selbst steht weiter unten unter „Nachtraum". Hier bleibt nur,
   was auch anderswo gilt.

   **Nicht zweimal dasselbe setzen.** Der erste Entwurf hatte `.pg-hero`
   hier *und* dort — zwei Regeln mit gleicher Spezifität, von denen die
   spätere gewann. Das geht so lange gut, bis jemand die Reihenfolge der
   Datei ändert. */

.pg-kicker {
  text-transform: uppercase; letter-spacing: .12em;
  font-size: .78rem; font-weight: 600; color: var(--pg-blue);
  margin-bottom: .75rem;
}

.pg-section-title { font-size: clamp(1.5rem, 3vw, 2.1rem); }
.pg-page-title { font-size: clamp(1.7rem, 4vw, 2.6rem); line-height: 1.15; }

.pg-band { background: var(--pg-surface-alt); }

/* --- Karten ---------------------------------------------------------- */

.pg-card {
  background: var(--pg-surface);
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-radius);
  padding: 1.5rem;
  box-shadow: var(--pg-shadow);
}
.pg-card-icon {
  width: 42px; height: 42px; color: var(--pg-accent);
  background: color-mix(in srgb, var(--pg-accent) 12%, transparent);
  border-radius: 12px; display: grid; place-items: center;
}
.pg-card-icon svg { width: 22px; height: 22px; }

.pg-tile, .pg-place-card {
  display: block; height: 100%;
  background: var(--pg-surface);
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-radius);
  padding: 1.1rem;
  text-decoration: none; color: inherit;
  transition: transform .16s ease, border-color .16s ease, box-shadow .16s ease;
}
.pg-tile:hover, .pg-place-card:hover,
.pg-tile:focus-visible, .pg-place-card:focus-visible {
  transform: translateY(-2px);
  border-color: color-mix(in srgb, var(--pg-accent) 45%, var(--pg-border));
  box-shadow: var(--pg-shadow);
}
.pg-tile-name { display: block; font-weight: 600; margin-top: .4rem; }
.pg-tile-meta { display: block; font-size: .82rem; color: var(--pg-muted); }
.pg-flag { font-size: 1.6rem; line-height: 1; }
.pg-flag-lg { font-size: 1.5em; vertical-align: -.1em; margin-right: .3rem; }
.pg-place-emoji { font-size: 1.4rem; line-height: 1.2; }
.min-w-0 { min-width: 0; }

.pg-badge {
  background: color-mix(in srgb, var(--pg-accent) 14%, transparent);
  color: var(--pg-accent); font-weight: 500;
}
.pg-badge-soft {
  background: var(--pg-surface-alt); color: var(--pg-muted); font-weight: 500;
}

/* --- Ortsseite ------------------------------------------------------- */

.pg-crumbs .breadcrumb { --bs-breadcrumb-divider: "›"; }
/* --- Verweise ---------------------------------------------------------

   **Nicht die Bootstrap-Vorgabe.** Die färbt das Wort selbst violett und
   unterstreicht es voll — im Fließtext sticht jeder Verweis heraus wie
   ein Fehler, und auf dem Impressum standen fünf davon in einem Absatz.

   Hier trägt die **Unterstreichung** die Auskunft, nicht die Schriftfarbe:
   Das Wort bleibt in voller Lesefarbe, darunter liegt eine blasse Spur in
   der Akzentfarbe. Wer darauf zeigt, sieht sie kräftiger und dicker
   werden — dieselbe Bewegung, mit der sich oben die Route zeichnet.

   Zwei Dinge sind dabei Absicht:

   * **Nicht nur Farbe.** Die Linie ist auch ohne Farbwahrnehmung da; ein
     Verweis, den nur ein Farbton verrät, ist für Rotgrünblinde keiner.
   * **`text-decoration` und kein Hintergrundverlauf.** Die schickere
     Fassung malt die Linie als `background-size`-Animation — und
     zerfällt, sobald ein Verweis über zwei Zeilen läuft. Genau das
     passiert im Impressum mit langen Adressen.

   Die Spezifität ist bewusst niedrig (`a`, nicht `.pg-prose a`): Alles
   mit eigener Gestalt — Knöpfe, Navigation, Kacheln, Sprachwahl —
   überschreibt das ohne Zutun. */

a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--pg-accent) 38%, transparent);
  text-decoration-thickness: 1px;
  text-underline-offset: .22em;
  transition: color .15s ease, text-decoration-color .15s ease,
              text-decoration-thickness .15s ease;
}
a:hover, a:focus-visible {
  color: var(--pg-accent);
  text-decoration-color: var(--pg-accent);
  text-decoration-thickness: 2px;
}

.pg-prose { max-width: 68ch; }
.pg-prose p { line-height: 1.7; }
.pg-facts dt { color: var(--pg-muted); font-weight: 500; }

/* Der Hinweis auf die App. **Kein nachgemachter Text darunter, keine
   verwischte Attrappe** — wer so etwas sieht, fühlt sich vorgeführt, und
   eine Suchmaschine liest verborgenen Text als Täuschungsversuch. Hier
   steht, was es gibt, und wo man es findet. */
.pg-locked {
  background: var(--pg-surface-alt);
  border: 1px dashed var(--pg-border);
  border-radius: var(--pg-radius);
  padding: 1.6rem;
}
.pg-locked-count { font-weight: 600; color: var(--pg-accent); }


.pg-legal h2 { margin-top: 2.2rem; font-size: 1.3rem; }
.pg-legal h3 { margin-top: 1.4rem; font-size: 1.05rem; font-weight: 600; }
.pg-legal ul { line-height: 1.7; }
.pg-legal table { margin: 1rem 0; }

.pg-footer { background: var(--pg-surface-alt); border-top: 1px solid var(--pg-border); }
/* Luft unter der letzten Zeile — dort steht am Seitenende der Pfeil nach
   oben. Ohne sie läge er auf der OpenStreetMap-Nennung, und die muss
   lesbar bleiben (ODbL). Gerechnet: Abstand (25) + Knopf (48) + Luft (16)
   = 89 Punkte; der Container bringt 48 davon mit, hier stehen 44. **Wer
   `--pg-to-top-gap` ändert, rechnet hier nach.**

   **Am Container geht es nicht**: Bootstraps `py-5` steht dort mit
   `!important` und schlägt jede eigene Regel. Diese Zeile trägt keine
   solche Klasse. Links sieht es aus wie gewöhnlicher Fußzeilen-Abstand,
   niemandem fällt auf, wofür er da ist. */
.pg-footer-fine { padding-bottom: 2.75rem; }
.pg-footer a { color: inherit; text-decoration: none; }
.pg-footer a:hover { text-decoration: underline; }

/* Wer „weniger Bewegung" eingestellt hat, hat das so gemeint. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
  }
}

/* =====================================================================
   Der Kopf: Nachtraum, Karte, eine Route, die sich zeichnet

   **Er ist immer dunkel, in beiden Modi.** Die Weltkugel der App steht im
   schwarzen Weltraum; ein heller Kopf wäre ein anderes Produkt. Was darauf
   liegt, ist deshalb fest verdrahtet und folgt nicht dem Theme — dieselbe
   Regel wie in der App für Text auf Satellitenbildern.
   ===================================================================== */

/* **Der Kopf ist immer dunkel** — unabhängig davon, was jemand oben
   gewählt hat. Deshalb schaltet er die eigenen Farbmarken auf die
   **Dunkelwerte der App** um; alles darin erbt sie dann von selbst.

   Ohne das griff hier der Hellmodus-Satz: Der Kicker stand in `#5b44d9`
   auf fast schwarzem Grund, und daneben lagen drei selbst erfundene
   Lilatöne (`#b9a6ff`, `#36436b`, `#33406a`), die es in der App nirgends
   gibt. Gemeldet wurde es so: *„diesen Lila-Ton gibt es nirgendwo in der
   App, oder?"* — zu Recht. */
.pg-hero {
  --pg-accent: #9b85ff;
  --pg-accent-2: #4cdbff;
  --pg-surface: #161c2c;
  --pg-surface-alt: #1f2739;
  --pg-border: #2a3348;
  --pg-border-strong: #3b4761;
  --pg-muted: #7c859e;

  position: relative;
  isolation: isolate;
  background: #0b0f1a;
  color: #f2f5fc;
  padding: clamp(5rem, 14vw, 9rem) 0 clamp(6rem, 12vw, 8rem);
  overflow: hidden;
}

.pg-hero-sky { position: absolute; inset: 0; z-index: -1; }
/* Der Rahmen um die Karte. Über 48em deckt er den ganzen Kopf und fällt
   nicht auf; auf dem Telefon ist er das Band und **beschneidet**. */
.pg-hero-map { position: absolute; inset: 0; overflow: hidden; }
.pg-sky-svg { width: 100%; height: 100%; display: block; }

/* Der Schleier macht die Schrift lesbar, ohne die Karte zuzudecken.
   Von links, nicht von oben: Der Text steht links, die Route rechts. */
.pg-hero-veil {
  position: absolute; inset: 0;
  /* Links deckend, damit die Schrift trägt; rechts fast offen, weil dort
     die Route liegt. Der zweite Verlauf legt einen violetten Schimmer
     oben links — dieselbe Farbe, mit der die App ihre Kugel umgibt. */
  /* **Von oben, nicht von links — das ist die Grundfassung.** Auf einem
     Telefon steht der Text über der Karte, nicht daneben; ein Schleier
     von links deckte dort die falsche Hälfte. Erst ab 48em, wo Text und
     Route wirklich nebeneinander liegen, kommt er von der Seite. */
  background:
    linear-gradient(to bottom, #0b0f1a 22%, rgba(11,15,26,.72) 46%, rgba(11,15,26,.15) 72%),
    radial-gradient(120% 70% at 50% 0%, rgba(91,68,217,.28), transparent 62%),
    linear-gradient(to top, rgba(11,15,26,.8), transparent 26%);
}

/* **Mit Foto links deckt der Schleier nicht mehr, er dämpft.** Vorher war
   die linke Hälfte fast schwarz, damit die Schrift auf der Karte trägt —
   jetzt läge das genau auf dem Bild. Er bleibt dunkel genug für weiße
   Schrift auf Abendhimmel und wird zur Route hin durchsichtig. */
@media (min-width: 48em) {
  .pg-hero-veil {
    background:
      linear-gradient(100deg, rgba(11,15,26,.5) 0%, rgba(11,15,26,.62) 34%, rgba(11,15,26,.5) 48%, rgba(11,15,26,.06) 64%, rgba(11,15,26,.3) 100%),
      radial-gradient(120% 90% at 18% 0%, rgba(91,68,217,.22), transparent 62%),
      linear-gradient(to top, rgba(11,15,26,.75), transparent 28%);
  }
}

/* --- Das Foto --------------------------------------------------------
   **Auf dem Telefon oben, daneben links.** Es läuft in den Nachtraum aus,
   statt mit einer Kante zu enden: Auf dem Telefon nach unten zur Karte,
   daneben nach rechts. Eine harte Kante zwischen Foto und Karte sähe aus
   wie zwei Seiten, die jemand nebeneinandergelegt hat.

   `mask-image` statt eines Verlaufs darüber — ein Verlauf müsste die
   Hintergrundfarbe kennen, die Maske lässt einfach durchscheinen, was
   darunter liegt.

   **Die Maske sitzt auf `picture`, nicht auf `figure`.** Eine Maske
   eröffnet einen eigenen Stapelkontext; auf der `figure` lag die
   Kennzeichnung dadurch unter dem Schleier, egal welcher `z-index`. */
/* **Auf dem Telefon ein Band über dem Text, nicht dahinter.** Hinter dem
   Text lagen dort Foto, Karte und Nadeln übereinander — drei Ebenen auf
   390 Punkten Breite. Das Band ist so hoch wie `--pg-photo-h`, und der
   Kopf rückt seinen Text um genau so viel nach unten. */
.pg-hero { --pg-photo-h: min(62vw, 22rem); --pg-map-h: min(54vw, 17rem); }
@media (max-width: 47.99em) {
  /* **Die Karte bekommt ihr eigenes Band, wie das Foto.**
     
     Das Foto lag hier einmal hinter dem Text und wurde deshalb nach oben
     geholt — „drei Ebenen auf 390 Punkten Breite". Karte, Route und
     Nadeln blieben dabei zurück und lagen weiter *hinter* dem Absatz:
     Der Schleier deckt sie dort fast zu, die Route war ein Strich im
     Dunkeln, und die Nadeln standen als graue Tropfen zwischen den
     Zeilen. Gemeldet wurde es so: „auf mobile sind die Wegpunkte und die
     Route nicht erkennbar".
     
     Halb sichtbar ist hier die schlechteste Antwort: Wer die Nadeln nicht
     als Nadeln erkennt, sieht Schmutz auf dem Text. Jetzt sitzen sie
     unter Text und Knöpfen in einem eigenen Streifen — dort zeigt die
     Karte wieder, was sie zeigen soll.
     
     Das Skript rechnet dafür nichts nach: Die Nadeln hängen an
     Ankerpunkten *im* SVG und werden aus der echten Geometrie gesetzt.
     Das SVG wandert, die Nadeln wandern mit. */
  .pg-hero {
    padding-top: calc(var(--pg-photo-h) + 1rem);
    padding-bottom: calc(var(--pg-map-h) + 1.5rem);
  }
  /* **Maske und Beschnitt sitzen auf dem Rahmen, nicht auf dem SVG.**
     Beides rechnet im eigenen Koordinatensystem des Elements — und das
     skaliert `peregra.js` hier mit. Auf dem SVG wanderte die weiche Kante
     deshalb mit dem Zoom davon. */
  .pg-hero-map {
    inset: auto 0 0 0;
    height: var(--pg-map-h);
    --pg-map-mask: linear-gradient(to bottom, transparent, #000 26%);
    -webkit-mask-image: var(--pg-map-mask);
            mask-image: var(--pg-map-mask);
  }
  /* Der Schleier deckt den Text, **nicht das Band**: Dort hat er nichts
     lesbar zu machen, und was er dämpft, ist genau das, was man sehen
     soll. Unten läuft er weich aus, sonst stünde eine Kante quer im Bild. */
  .pg-hero-veil {
    bottom: var(--pg-map-h);
    background:
      linear-gradient(to bottom, transparent calc(var(--pg-photo-h) * .45), #0b0f1a calc(var(--pg-photo-h) + 1rem), #0b0f1a 72%, rgba(11,15,26,.55) 90%, transparent);
  }
}
.pg-hero-photo {
  position: absolute;
  inset: 0 0 auto 0;
  height: calc(var(--pg-photo-h) + 2rem);
  margin: 0;
}
.pg-hero-photo picture {
  display: block; height: 100%;
  --pg-photo-mask: linear-gradient(to bottom, #000 60%, transparent);
  -webkit-mask-image: var(--pg-photo-mask);
          mask-image: var(--pg-photo-mask);
}
.pg-hero-photo img {
  width: 100%; height: 100%;
  object-fit: cover;
  /* Das Paar steht links der Mitte, die Helme im oberen Viertel. Der Kopf
     ist breit und niedrig — mittig beschnitten fehlten die Köpfe. */
  object-position: 38% 18%;
  display: block;
}

/* Die Kennzeichnung. **Dezent wie ein Fotonachweis, aber nicht
   versteckt**: Art. 50 KI-VO verlangt einen klaren Hinweis beim ersten
   Ansehen, der im Impressum allein nicht wäre. Ohne Pille, dafür mit
   weichem Schatten — sonst verschwindet die Schrift auf dem hellen
   Abendhimmel. Und **über** dem Schleier, sonst dämpft er sie weg.

   **Das ist die Untergrenze.** Zweimal wurde sie zurückgenommen (erst
   ohne Pille, dann „KI-Bild" statt „KI-generiertes Bild", .5 statt .62).
   Blasser oder kleiner, und der Hinweis ist nur noch für den da, der
   ihn sucht — dann erfüllt er nicht mehr, wofür er steht. */
.pg-hero-photo-note {
  position: absolute; z-index: 1;
  /* Auf dem Telefon unten am Band, wo es schon dunkel wird — oben
     rechts ging er im hellen Himmel unter. */
  right: .75rem; top: calc(var(--pg-photo-h) - 1.1rem);
  font-size: .62rem; letter-spacing: .03em;
  color: rgba(242,245,252,.5);
  text-shadow: 0 0 4px rgba(11,15,26,.8), 0 1px 2px rgba(11,15,26,.6);
}

@media (min-width: 48em) {
  .pg-hero-photo {
    inset: 0 auto 0 0;
    width: 56%;
    height: 100%;
  }
  .pg-hero-photo picture {
    --pg-photo-mask: linear-gradient(to right, #000 62%, transparent);
  }
  .pg-hero-photo-note { top: auto; right: auto; left: .9rem; bottom: .7rem; }
}

.pg-stars circle { fill: #ffffff; opacity: .5; }

/* **Nicht skalierende Konturen.** Der Ausschnitt wird um den Faktor zehn
   vergrößert; eine Linienstärke in Nutzerkoordinaten würde daraus ein
   Band. `non-scaling-stroke` hält sie bei einem Bildpunkt, egal wie nah
   man herangeht. */
/* Ohne `non-scaling-stroke`: Der Umriss darf mit der Karte wachsen, das
   ist hier sogar richtig — und es spart dem Browser die Neuberechnung
   jeder Kontur bei jeder Fensteränderung. */
.pg-land { fill: var(--pg-surface-alt); stroke: var(--pg-border); stroke-width: .35; }

/* Die Route. `stroke-dasharray` und `-offset` werden vom Skript gesetzt,
   sobald die Länge bekannt ist — sie hängt vom Zuschnitt ab und lässt sich
   nicht im Blindflug beziffern. */
/* **Die Linie ist das Versprechen der App** — sie darf kräftig sein.
   Der erste Entwurf setzte sie auf drei Bildpunkte und ließ sie unter dem
   Schleier verschwinden; auf einem 2.600 Punkte breiten Monitor ist das
   ein Haar. `non-scaling-stroke` hält sie über alle Fenstergrößen gleich
   stark, sonst wäre sie auf dem Telefon ein Balken. */
.pg-route {
  fill: none;
  /* Blau wie die Knöpfe, nicht Lila und nicht Türkis. */
  stroke: var(--pg-blue);
  stroke-width: 5;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}

/* **Der Schein liegt auf einer zweiten Linie darunter, nicht auf einem
   Filter.** `drop-shadow` auf einem Pfad, der elffach vergrößert wird,
   zwang den Browser zu einem Weichzeichner über die ganze Fläche — die
   Seite fror ein. Eine breitere, blasse Kopie kostet nichts. */
.pg-route-glow {
  fill: none;
  stroke: rgba(13,110,253,.34);
  stroke-width: 14;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}
.pg-route.is-drawing {
  animation: pg-draw 2.6s cubic-bezier(.65,0,.35,1) forwards;
}
@keyframes pg-draw { to { stroke-dashoffset: 0; } }

/* Die Nadeln liegen als HTML über der Karte, gesetzt vom Skript auf
   Ankerpunkte **im** SVG. Damit stimmen sie bei jeder Fenstergröße —
   siehe `peregra.js`.

   Der Kasten deckt den ganzen Kopf; die Nadeln bekommen ihre Position in
   Pixeln. Kein `aspect-ratio` mehr: Genau das war die Annahme, die beim
   Verkleinern zerbrach. */
.pg-pins { position: absolute; inset: 0; pointer-events: none; }

.pg-anchor { fill: none; }

.pg-pin {
  position: absolute;
  transform: translate(-50%, -100%);
  opacity: 0;
  display: block;
}
/* Vor dem ersten Setzen stehen alle Nadeln links oben. Sichtbar wird der
   Kasten erst, wenn das Skript sie verteilt hat — sonst blitzt ein
   Häufchen in der Ecke auf. */
.pg-pins { visibility: hidden; }
.pins-placed .pg-pins { visibility: visible; }
.pg-pin svg { width: 21px; height: 31px; display: block; filter: drop-shadow(0 2px 5px rgba(0,0,0,.5)); }
.pg-pin-body { fill: #ffffff; }

/* Der Punkt in der Nadel — dasselbe Azur, mit dem die App ihre Messwerte
   zeichnet. Er sitzt im Kopf der Nadel, nicht darunter: eine Nadel ohne
   Auge sieht aus wie ein Tropfen. */
.pg-pin-dot { fill: var(--pg-blue); }

/* Der Hof pulsiert, nicht der Punkt selbst.
   
   **Eine zweite Form statt einer Animation auf der ersten** — ein
   wachsender Punkt würde die weiße Nadel innen aufblähen und wieder
   schrumpfen; ein Hof, der nach außen läuft und dabei verschwindet, liest
   sich als Signal. Genau das zeigt die App an einem laufenden Stopp.
   
   Sechs Sekunden Abstand, nicht eine: Ein Puls, der ständig schlägt, ist
   nach dem dritten Mal Flimmern. */
.pg-pin-halo {
  fill: none;
  stroke: var(--pg-blue);
  stroke-width: 1.6;
  opacity: 0;
  transform-origin: 8px 8px;
}
.pg-pin.is-landing .pg-pin-halo {
  animation: pg-pulse 6s cubic-bezier(.2,.6,.3,1) infinite;
  /* Versetzt wie die Nadeln selbst — sonst pulsen sechs Punkte im
     Gleichschritt, und das sieht nach Blinklicht aus statt nach Orten. */
  animation-delay: calc(1.6s + var(--i) * .9s);
}
@keyframes pg-pulse {
  0%   { opacity: .85; transform: scale(1); }
  14%  { opacity: 0;   transform: scale(2.6); }
  100% { opacity: 0;   transform: scale(2.6); }
}

/* Der Ortsname steht nur an der letzten Nadel — dem Ziel. Sechs
   Beschriftungen wären ein Kartenausschnitt, keine Bildmarke. */
.pg-pin-label { display: none; }
.pg-pin:last-child .pg-pin-label {
  display: block;
  position: absolute; left: 50%; top: calc(100% + 6px);
  transform: translateX(-50%);
  white-space: nowrap;
  font-size: .76rem; font-weight: 600; letter-spacing: .01em;
  color: #f2f5fc;
  background: rgba(11,15,26,.7);
  border: 1px solid rgba(242,245,252,.16);
  padding: .18rem .5rem; border-radius: 999px;
  backdrop-filter: blur(4px);
}

.pg-pin.is-landing {
  animation: pg-land-pin .5s cubic-bezier(.34,1.56,.64,1) forwards;
  animation-delay: calc(.35s + var(--i) * .42s);
}
@keyframes pg-land-pin {
  from { opacity: 0; transform: translate(-50%, calc(-100% - 12px)) scale(.6); }
  to   { opacity: 1; transform: translate(-50%, -100%) scale(1); }
}

.pg-hero-inner { position: relative; max-width: 1200px; }
/* **Blau wie die Route darunter** — hier die aufgehellte Fassung: Der
   Kopf ist in beiden Modi dunkel, und kleine Versalien in #0d6efd wären
   darauf zu dunkel. Dieselbe Farbe, nur heller. */
.pg-hero .pg-kicker { color: var(--pg-blue-soft); }
.pg-hero-title {
  /* Ein Hauch Schatten: Der Titel steht jetzt zum Teil auf dem hellen
     Abendhimmel des Fotos. */
  text-shadow: 0 1px 18px rgba(11,15,26,.45);
  font-size: clamp(2.3rem, 6vw, 4.2rem);
  line-height: 1.04;
  letter-spacing: -.025em;
  margin: 0 0 1.1rem;
  max-width: 16ch;
}
.pg-hero-lead {
  font-size: clamp(1.02rem, 1.5vw, 1.2rem);
  line-height: 1.65;
  color: #b2bad0;
  max-width: 54ch;
  margin-bottom: 2rem;
}
.pg-hero-actions { display: flex; flex-wrap: wrap; gap: .9rem; }
.pg-hero-note { color: #7c859e; font-size: .9rem; margin: 1.1rem 0 0; }

/* Die Grenzen liegen **auf** der Fläche, nicht an ihrem Rand — deshalb
   keine Lücken zwischen Nachbarländern. Blass genug, dass sie die Route
   nicht stören. */
.pg-borders { fill: none; stroke: var(--pg-border); stroke-width: .3; }

/* --- Knöpfe -----------------------------------------------------------

   **Warum hier überhaupt etwas steht.** Bootstraps Knöpfe sind flach, und
   ihr Radius kommt aus einem anderen Token als der der Karten:
   `--bs-border-radius-lg` statt `--bs-border-radius`. Weiter oben ist nur
   das zweite auf 18 px gesetzt — die großen Knöpfe im Kopf behielten
   dadurch Bootstraps 8 px und sahen neben allem anderen aus wie aus einem
   fremden Baukasten. Dazu ein Rand in Bootstraps Grau auf einem dunklen
   Foto, und der Hauptknopf eine Fläche ohne jede Tiefe.

   Deshalb eine eigene Schicht: ein Radius, der zu den Karten passt, eine
   Lichtkante am oberen Rand, ein Schatten in der Farbe des Knopfes statt
   in Grau, und beim Drücken sinkt er einen Bildpunkt ein.

   **Und nicht mehr als das.** Kein Wachsen beim Überfahren, kein
   Farbwechsel, kein Schimmern — dieselbe Regel wie für den Kopf: Die
   Bewegung ist ein Moment, nicht viele. Ein Knopf, der bei jedem
   Mauszeiger aufblüht, ist der nächste Hinweis darauf, dass eine Seite aus
   einem Generator kommt.

   Alle Werte gehen über Bootstraps `--bs-btn-*`. Die greifen auch dort,
   wo sonst `!important` steht, und die Zustände (Überfahren, Drücken,
   Tastaturfokus, deaktiviert) folgen von allein statt je Variante von Hand
   nachgezogen zu werden. */

.btn {
  --bs-btn-border-radius: 12px;
  --bs-btn-font-weight: 600;
  letter-spacing: -.005em;
  transition: background-color .16s ease, border-color .16s ease,
              box-shadow .16s ease, transform .1s ease, color .16s ease;
}
.btn-lg {
  --bs-btn-border-radius: 15px;
  --bs-btn-padding-x: 1.65rem;
  --bs-btn-padding-y: .72rem;
  --bs-btn-font-size: 1.03rem;
}
/* Eingesunken, nicht verschoben: Der Schatten unter dem Knopf wird beim
   Drücken flacher (siehe `--bs-btn-active-shadow` je Variante), und der
   Knopf selbst folgt ihm. */
.btn:not(.disabled):not(:disabled):active { transform: translateY(1px); }
@media (prefers-reduced-motion: reduce) {
  .btn { transition: none; }
  .btn:active { transform: none; }
}

/* Der Hauptknopf. Das Blau ist das der Seite (`--pg-blue`), nicht mehr
   Bootstraps einkompiliertes — dieselbe Farbe wie Route, Nadeln und
   Kicker. Der Verlauf ist ein Hauch Licht von oben (17 % Weiß auf 0), kein
   sichtbarer Farbwechsel; die Tiefe steckt im Schatten. */
.btn-primary {
  --bs-btn-bg: var(--pg-blue);
  --bs-btn-hover-bg: #2b81ff;
  --bs-btn-active-bg: #0a5ddb;
  --bs-btn-disabled-bg: var(--pg-blue);
  --bs-btn-border-color: transparent;
  --bs-btn-hover-border-color: transparent;
  --bs-btn-active-border-color: transparent;
  --bs-btn-disabled-border-color: transparent;
  --bs-btn-active-shadow: inset 0 1px 0 rgba(255,255,255,.14),
                          inset 0 2px 7px rgba(5,12,32,.3);
  --bs-btn-focus-box-shadow: var(--pg-btn-shade-blue), 0 0 0 .22rem rgba(90,157,255,.5);
  --pg-btn-shade-blue: inset 0 1px 0 rgba(255,255,255,.3),
                       0 1px 2px rgba(5,12,32,.28),
                       0 12px 24px -12px rgba(13,110,253,.85);
  background-image: linear-gradient(180deg, rgba(255,255,255,.17), rgba(255,255,255,0) 58%);
  box-shadow: var(--pg-btn-shade-blue);
}
.btn-primary:hover {
  box-shadow: inset 0 1px 0 rgba(255,255,255,.36),
              0 1px 2px rgba(5,12,32,.3),
              0 16px 30px -14px rgba(13,110,253,1);
}

/* Der zweite Knopf im Kopf. Glas statt Grau: Was dahinter liegt — Foto
   links, Karte rechts — scheint gedämpft durch, die Kante ist Licht und
   kein Bootstrap-Rand.

   **Getöntes Glas, nicht weißes.** Der erste Versuch war eine Fläche aus
   8 % Weiß, und darunter liegt das Reisfeld: Weiß über Grün, weichgezeichnet,
   ergibt Oliv — der Knopf sah aus wie verschmutzt und wäre auf jedem
   getauschten Foto wieder eine andere Farbe. Eine dunkle Tönung nimmt den
   Grund heraus, statt ihn anzumalen, und bleibt über Foto wie Karte
   dieselbe.

   `backdrop-filter` ist Zierde; wo er fehlt, bleibt die Tönung als Grund
   übrig. */
.btn-ghost {
  --bs-btn-color: #f2f5fc;
  --bs-btn-hover-color: #fff;
  --bs-btn-active-color: #fff;
  --bs-btn-bg: rgba(11,15,26,.34);
  --bs-btn-hover-bg: rgba(11,15,26,.46);
  --bs-btn-active-bg: rgba(11,15,26,.56);
  --bs-btn-border-color: rgba(242,245,252,.28);
  --bs-btn-hover-border-color: rgba(242,245,252,.55);
  --bs-btn-active-border-color: rgba(242,245,252,.55);
  --bs-btn-active-shadow: inset 0 2px 7px rgba(5,12,32,.45);
  --bs-btn-focus-box-shadow: var(--pg-btn-shade-glass), 0 0 0 .22rem rgba(242,245,252,.32);
  --pg-btn-shade-glass: inset 0 1px 0 rgba(255,255,255,.16),
                        0 10px 22px -14px rgba(0,0,0,.9);
  background-image: linear-gradient(180deg, rgba(255,255,255,.1), rgba(255,255,255,0) 62%);
  box-shadow: var(--pg-btn-shade-glass);
  backdrop-filter: blur(12px);
}

/* Weiß auf dem Foto am Seitenende. Der Schatten ist dort keine Zierde: Er
   trennt den Knopf vom Bild, das unter ihm hell werden kann. */
.btn-light {
  --bs-btn-bg: #fff;
  --bs-btn-color: #121628;
  --bs-btn-hover-bg: #fff;
  --bs-btn-hover-color: #0b0f1a;
  --bs-btn-active-bg: #eff1f7;
  --bs-btn-active-color: #0b0f1a;
  --bs-btn-disabled-bg: #fff;
  --bs-btn-disabled-color: #121628;
  --bs-btn-border-color: transparent;
  --bs-btn-hover-border-color: transparent;
  --bs-btn-active-border-color: transparent;
  --bs-btn-disabled-border-color: transparent;
  --bs-btn-active-shadow: inset 0 2px 7px rgba(5,12,32,.18);
  --bs-btn-focus-box-shadow: var(--pg-btn-shade-light), 0 0 0 .22rem rgba(255,255,255,.55);
  --pg-btn-shade-light: inset 0 1px 0 #fff,
                        0 1px 2px rgba(5,12,32,.3),
                        0 14px 28px -16px rgba(0,0,0,.95);
  box-shadow: var(--pg-btn-shade-light);
}

/* Der ruhige Knopf auf hellem Grund — „Alle Länder", „Zur Startseite".
   Er trägt den Rand der Karten daneben, nicht Bootstraps Grau, und eine
   Fläche: Ein reiner Umriss verschwindet auf `--pg-surface-alt`. */
.btn-outline-secondary {
  --bs-btn-color: var(--bs-body-color);
  --bs-btn-bg: var(--pg-surface);
  --bs-btn-border-color: var(--pg-border-strong);
  --bs-btn-hover-color: var(--bs-body-color);
  --bs-btn-hover-bg: var(--pg-surface-alt);
  --bs-btn-hover-border-color: var(--pg-muted);
  --bs-btn-active-color: var(--bs-body-color);
  --bs-btn-active-bg: var(--pg-surface-alt);
  --bs-btn-active-border-color: var(--pg-muted);
  --bs-btn-active-shadow: inset 0 2px 6px rgba(5,12,32,.12);
  --bs-btn-focus-box-shadow: 0 0 0 .22rem rgba(13,110,253,.28);
  box-shadow: 0 1px 2px rgba(18,22,40,.06);
}

/* Die Zahlen. Groß gesetzt, weil sie das Versprechen belegen — und ohne
   Kästen drumherum, damit sie nicht wie ein Dashboard aussehen.
   
   **Sie stehen unter der Weltkarte, nicht im Kopf.** Dort standen sie
   zuerst und beantworteten eine Frage, die auf der ersten Bildschirmhöhe
   noch niemand gestellt hat. Unter der Karte mit zweitausend Punkten sind
   sie die Bildunterschrift zu dem, was man gerade sieht. */
.pg-stats {
  display: flex; flex-wrap: wrap; gap: clamp(1.8rem, 5vw, 3.5rem);
  margin: 0;
}
.pg-stats dt {
  font-family: "Sora", var(--bs-font-sans-serif);
  font-size: clamp(1.8rem, 3.2vw, 2.6rem);
  font-weight: 700; line-height: 1; color: var(--bs-body-color);
}
.pg-stats dd {
  margin: .35rem 0 0; color: var(--pg-muted);
  font-size: .82rem; letter-spacing: .06em;
}

.pg-world-foot {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: 2rem;
  padding-top: 2rem; border-top: 1px solid var(--pg-border);
}

/* --- Die Weltkarte mit allen Orten ---------------------------------- */

.pg-world { padding: clamp(3.5rem, 8vw, 6rem) 0; background: var(--pg-surface-alt); }
.pg-world-head { max-width: 52ch; margin-bottom: 2rem; }
.pg-world-map { margin: 0 auto 2.5rem; max-width: 1100px; padding: 0 1rem; }
.pg-world-map svg { width: 100%; height: auto; }
.pg-world .pg-land { fill: var(--pg-border); stroke: none; }
.pg-world .pg-borders { stroke: var(--pg-surface-alt); stroke-width: .8; }
.pg-dots { fill: var(--pg-accent); opacity: .78; }

/* --- Übergänge zwischen den Abschnitten ------------------------------
   Eine geschwungene Kante statt eines harten Schnitts. Polarsteps setzt
   dafür eine Diagonale; eine Kurve passt besser zu einer App, in der alles
   Wege sind. Nur **einmal** verwendet, unter dem Kopf — an jeder Naht wäre
   es eine Masche. */

.pg-wave { display: block; width: 100%; height: clamp(38px, 5vw, 72px); margin-top: -1px; }
.pg-wave path { fill: var(--bs-body-bg); }

@media (prefers-reduced-motion: reduce) {
  .pg-route.is-drawing, .pg-pin.is-landing { animation: none; }
  .pg-pin.is-landing .pg-pin-halo { animation: none; opacity: 0; }
  .pg-route { stroke-dashoffset: 0 !important; }
  .pg-pin { opacity: 1; transform: translate(-50%, -100%); }
}

/* --- Die Funktionen ---------------------------------------------------
   **Kein Kartenraster.** Sechs gleich große Kästen mit gleichem Radius,
   gleichem Schatten und einem Symbol oben links sind das Kit, an dem man
   erzeugte Seiten erkennt. Hier trägt stattdessen eine feine Linie die
   Gliederung — dasselbe Mittel, mit dem die App ihre Zeilen ordnet. */

.pg-features-head { max-width: 46ch; margin-bottom: clamp(2rem, 4vw, 3rem); }

/* --- Die drei Etappen ------------------------------------------------

   Gebaut von schmal nach breit: Die Grundfassung ist **eine** Spalte,
   und das ist nicht der Notfall, sondern der Normalfall — eine Reise
   liest sich von oben nach unten. Erst ab 62em stehen die drei Etappen
   nebeneinander; dazwischen bleibt die Spalte auf Lesebreite begrenzt,
   damit die Zeilen nicht auf 900 Punkte auseinanderlaufen.

   Die Farbe je Etappe ist keine Willkür wie die alte `3n`-Rotation: Sie
   sagt, in welchem Abschnitt der Reise man ist. Das Blau der mittleren
   ist dasselbe, in dem die Route oben im Kopf leuchtet.               */

.pg-journey {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: clamp(2.2rem, 5vw, 3rem);
  max-width: 44rem;
}
.pg-stage { --stage: var(--pg-accent); }
.pg-stage:nth-child(2) { --stage: var(--pg-accent-2); }
.pg-stage:nth-child(3) { --stage: var(--pg-lime); }

/* Der Name der Etappe sitzt über dem Anfang der Spur, mit einem kurzen
   Strich davor: Von dort läuft die Linie los. Bewusst keine
   gesperrten Versalien — das Wort ist eine Überschrift, kein Etikett. */
.pg-stage-name {
  font-size: 1rem; font-weight: 600; letter-spacing: 0;
  color: var(--stage);
  margin: 0 0 1.4rem; padding-left: 3.25rem;
  position: relative; line-height: 1.4;
}
.pg-stage-name::before {
  content: ''; position: absolute;
  left: .75rem; top: .7em; width: 1.5rem; height: 2px;
  background: var(--stage); border-radius: 2px;
}

.pg-step { position: relative; padding-left: 3.25rem; }
.pg-step + .pg-step { margin-top: 2rem; }

/* Die Spur: von Marke zu Marke, nicht von Kante zu Kante — sie läuft
   **hinter** den Kreisen durch, und die decken sie ab. Der erste Anlauf
   ließ sie an der Kreisoberkante enden, und der Schein um den Kreis fraß
   den Rest: vier Punkte Spalt, und die Linie sah aus wie zerrissen.
   Am letzten Schritt gibt es sie nicht — sonst liefe sie ins Leere. */
.pg-step:not(:last-child)::before {
  content: ''; position: absolute;
  left: calc(1.25rem - 1px); top: 1.25rem; bottom: -3.25rem; width: 2px;
  background: linear-gradient(
    var(--stage),
    color-mix(in srgb, var(--stage) 18%, transparent)
  );
}

.pg-step-mark {
  position: absolute; left: 0; top: 0;
  width: 2.5rem; height: 2.5rem;
  display: grid; place-items: center;
  border-radius: 50%;
  color: var(--stage);
  background: var(--pg-surface);
  border: 1.5px solid color-mix(in srgb, var(--stage) 38%, transparent);
}
.pg-step-mark svg { width: 20px; height: 20px; }

.pg-step-title { font-size: 1.05rem; margin: .35rem 0 .5rem; }
.pg-step-body {
  font-size: .95rem; line-height: 1.6; margin: 0;
  color: var(--bs-secondary-color, var(--pg-muted));
  max-width: 36ch;
}

@media (min-width: 62em) {
  .pg-journey {
    max-width: none;
    grid-template-columns: repeat(3, 1fr);
    gap: clamp(2rem, 4vw, 3.5rem);
  }
}

/* --- Fotos unter dem Kopf --------------------------------------------

   **Der Hinweis „KI-Bild" steht an jedem Foto**, nicht nur oben — aus
   denselben Gründen wie im Kopf (siehe dort). Gleiche Schrift, gleiche
   Deckkraft: Er liegt immer auf dem Bild, deshalb feste Farben statt
   Theme. */

.pg-photo-note {
  position: absolute; z-index: 1;
  left: .75rem; bottom: .55rem;
  margin: 0;
  font-size: .62rem; letter-spacing: .03em;
  color: rgba(242,245,252,.5);
  text-shadow: 0 0 4px rgba(11,15,26,.8), 0 1px 2px rgba(11,15,26,.6);
}

/* Über jeder Etappe ein Foto — die Spur darunter beginnt erst am Namen. */
.pg-stage-photo {
  position: relative;
  margin: 0 0 1.6rem;
  border-radius: var(--pg-radius);
  overflow: hidden;
  aspect-ratio: 3 / 2;
  background: var(--pg-surface-alt);
}
.pg-stage-photo img {
  display: block; width: 100%; height: 100%;
  object-fit: cover;
}

/* --- Der Streifen ----------------------------------------------------

   **Eine Galerie, bis der Platz für alle fünf reicht.** Nebeneinander
   passen sie erst ab 75em (1200 Punkte) ohne zu schrumpfen; darunter
   waren sie briefmarkengroß — auf dem Tablet fünf Bildchen in einer
   Reihe, von denen keines mehr etwas zeigte. Bis dahin steht deshalb ein
   Streifen zum Wischen mit großen Bildern und Pfeilen an den Rändern.

   Die Bildbreite wächst mit dem Fenster: zwei Bilder auf dem Telefon,
   zweieinhalb auf dem Tablet. **Immer eines angeschnitten** — das ist
   der stumme Hinweis, dass es weitergeht; die Pfeile sagen es laut. */

.pg-moments { padding: 0 0 clamp(2.5rem, 6vw, 4rem); }
/* Der Rahmen um den Streifen — er trägt die Pfeile. */
.pg-moments-viewport { position: relative; }

.pg-moments-list {
  list-style: none; margin: 0 auto; padding: 0 1rem;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 62%;
  gap: .5rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: 1rem;
  scrollbar-width: none;
}
.pg-moments-list::-webkit-scrollbar { display: none; }
.pg-moment { scroll-snap-align: start; }

@media (min-width: 48em) {
  .pg-moments-list { grid-auto-columns: 40%; gap: .75rem; }
}

.pg-moment {
  aspect-ratio: 4 / 5;
  border-radius: 12px;
  overflow: hidden;
  background: var(--pg-surface-alt);
}
.pg-moment img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* Die Kennzeichnung liegt hier nicht auf dem Bild, sondern darunter —
   eine für alle fünf. Deshalb Theme-Farbe statt fester. */
.pg-moments-note {
  margin: .45rem auto 0; padding-inline: 1rem; text-align: right;
  font-size: .62rem; letter-spacing: .03em;
  color: var(--bs-secondary-color, var(--pg-muted));
}

/* Ab hier stehen alle fünf nebeneinander, ohne zu schrumpfen. */
@media (min-width: 75em) {
  .pg-moments-list {
    grid-auto-flow: row;
    grid-template-columns: repeat(5, 1fr);
    /* Mehr Luft als ein Fugenmaß: Fünf Bilder dicht an dicht lesen sich
       als ein zerschnittenes Bild, mit Abstand als fünf Aufnahmen. */
    gap: clamp(.75rem, 1.2vw, 1.25rem);
    overflow-x: visible;
    padding-inline: .75rem;
  }
  /* Auf sehr breiten Schirmen würden fünf Hochformate so hoch wie das
     Fenster — begrenzt, und mittig. */
  .pg-moments-list, .pg-moments-note { max-width: 1600px; }
  .pg-moments-note { padding-inline: .75rem; }
}

/* --- Die Pfeile am Streifen -------------------------------------------

   **Nur mit JavaScript und nur, solange gewischt wird.** Ohne Skript
   täten sie nichts, deshalb hängen sie an `html.js`; ab 75em gibt es
   nichts mehr zu wischen, dort sind sie weg.

   Sie sagen: Hier geht es weiter. Deshalb sitzen sie halb über dem Bild
   am Rand und verschwinden an den Enden — ein Pfeil, der ins Nichts
   zeigt, ist eine Falschaussage. */

.pg-moments-nav { display: none; }

html.js .pg-moments-nav {
  position: absolute; z-index: 2;
  top: 50%; transform: translateY(-50%);
  width: 2.5rem; height: 2.5rem;
  display: grid; place-items: center;
  padding: 0;
  border-radius: 50%;
  color: var(--bs-body-color);
  background: color-mix(in srgb, var(--pg-surface) 88%, transparent);
  border: 1px solid var(--pg-border);
  box-shadow: 0 2px 10px rgba(18, 22, 40, .18);
}
[data-bs-theme="dark"] .pg-moments-nav {
  background: color-mix(in srgb, var(--pg-surface-alt) 88%, transparent);
  box-shadow: 0 2px 10px rgba(0, 0, 0, .5);
}
.pg-moments-nav svg { width: 20px; height: 20px; }
.pg-moments-nav-prev { left: .4rem; }
.pg-moments-nav-next { right: .4rem; }
.pg-moments-nav[hidden] { display: none; }

@media (min-width: 75em) {
  html.js .pg-moments-nav { display: none; }
}

/* --- Der Aufruf am Ende ----------------------------------------------

   Foto links, Text rechts; auf dem Telefon untereinander, das Foto oben.
   **Das Foto behält sein Format (3:2).** Randlos über die ganze Breite
   wurde es auf breiten Schirmen zu einem Streifen beschnitten und über
   seine Auflösung hinaus vergrößert — siehe `appSection` in `pages.mjs`.

   Das Bild ist der größere Teil (6 zu 5): Es trägt die Stimmung, der
   Text nur zwei Sätze und zwei Knöpfe. */

.pg-cta { padding: clamp(3.5rem, 8vw, 6rem) 0; }
.pg-cta-grid {
  display: grid;
  /* `minmax(0, …)`, nicht die Vorgabe `auto`: Sonst wächst die Spalte
     auf die Breite des breitesten Inhalts — hier die Knöpfe mit
     `max-content` —, bevor irgendetwas umbrechen darf. */
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(1.75rem, 4vw, 3.5rem);
  align-items: center;
}
@media (min-width: 62em) {
  .pg-cta-grid { grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); }
}

.pg-cta-figure {
  position: relative;
  margin: 0;
  aspect-ratio: 3 / 2;
  border-radius: calc(var(--pg-radius) + 6px);
  overflow: hidden;
  background: var(--pg-surface-alt);
  box-shadow: var(--pg-shadow);
}
.pg-cta-figure img {
  display: block; width: 100%; height: 100%;
  object-fit: cover;
}
/* Die Kennzeichnung links unten, wie an allen Fotos — dort liegt die
   dunkle Decke, und rechts unten sitzt der Pfeil nach oben. */
.pg-cta-figure .pg-photo-note { left: 1rem; bottom: .8rem; }

.pg-cta-body {
  max-width: 38ch;
  margin: .75rem 0 0;
  font-size: 1.05rem; line-height: 1.6;
  color: var(--bs-secondary-color, var(--pg-muted));
}
/* **Die Knöpfe stehen untereinander, gleich breit** — wie zwei
   Store-Plaketten. Nebeneinander passten „Bei Google Play · Bald
   verfügbar" und „Im App Store · Bald verfügbar" nur auf sehr breiten
   Schirmen (gemessen: 605 Punkte Bedarf, 564 da); darunter brach der
   zweite um, und zwei ungleich lange Knöpfe übereinander sahen aus wie
   vergessen. `max-content` macht beide so breit wie den längeren. */
.pg-cta-actions {
  display: grid; gap: .75rem;
  grid-auto-rows: 1fr;   /* bricht einer um, wächst der andere mit */
  width: max-content; max-width: 100%;
  margin-top: 1.75rem;
}
/* „Bald verfügbar" soll lesbar bleiben, nicht auf Bootstraps 65 %
   verblassen — es ist eine Auskunft, kein abgeschalteter Knopf. */
.pg-cta .btn.disabled { opacity: .85; }
/* **Umbrechen dürfen, wenn es eng wird.** Bootstrap hält Knöpfe auf
   einer Zeile; „Download on the App Store · Coming soon“ ist bei 390 px
   aber 24 px breiter als der Schirm, und die ganze Seite ließ sich
   seitlich verschieben. Auf breiten Schirmen ändert sich nichts. */
.pg-cta-actions .btn { white-space: normal; text-wrap: balance; }

/* --- Zurück nach oben ------------------------------------------------

   **Ohne JavaScript steht er immer da, mit JavaScript erst weiter unten.**
   `html.js` setzt das Skript selbst (`peregra.js`); fehlt es, greift nur
   die erste Regel, und der Verweis bleibt sichtbar. Ein Pfeil, der ohne
   Skript nie erscheint, wäre für alle ohne Skript gar nicht da.

   **Präsent, aber nicht aufdringlich:** kräftiger Grund statt einer
   blassen Scheibe, der Pfeil in der Akzentfarbe, ein Ring darum, der den
   gelesenen Anteil zeigt. Keine Farbfläche und kein Schlagschatten, die
   ihn zur zweiten Hauptsache machen — er steht in der Ecke, nicht im Weg.

   **Er steht immer an derselben Stelle**, gleich weit von rechts wie von
   unten. Vorher wich er am Seitenende nach oben aus, um die Fußzeile
   nicht zu überdecken — das war ein sichtbarer Sprung und rückte ihn aus
   der Ecke. Stattdessen lässt die Fußzeile unten so viel Luft, dass er
   dort über nichts liegt (siehe `.pg-footer .container`).

   Unter dem Kopf (`sticky-top`, z-index 1020), damit er das Menü nicht
   überdeckt. `env(safe-area-inset-*)` hält ihn auf dem Telefon über der
   Leiste des Browsers. */

.pg-to-top {
  --pg-to-top-gap: 25px;             /* rechts wie unten, eine Zahl. */
  position: fixed; z-index: 1010;
  right: calc(var(--pg-to-top-gap) + env(safe-area-inset-right));
  bottom: calc(var(--pg-to-top-gap) + env(safe-area-inset-bottom));
  width: 3rem; height: 3rem;         /* Fingerbreit, nicht kleiner. */
  display: grid; place-items: center;
  border-radius: 50%;
  /* **Blau, nicht Lila.** Lila ist die Farbe der Hauptknöpfe („App
     holen", „Alle Länder"); ein gleichfarbiger Kreis in der Ecke sah aus
     wie ein zweiter Aufruf. Das Blau ist dasselbe, in dem die Route im
     Kopf leuchtet — und das der mittleren Etappe.

     **Im Dunkeln ist es das aufgehellte.** `--pg-blue` (#0d6efd) auf
     `--pg-surface-alt` (#1f2739) sind 3,3:1 — knapp über dem Mindestwert
     für Grafik und deutlich darunter für alles, was man lesen soll. Pfeil
     und Fortschrittsring wirkten dadurch wie abgeschaltet.
     `--pg-blue-soft` steht auf demselben Grund bei 5,5:1.

     Farbe und Grund stehen als eigene Variablen, weil drei Stellen sie
     brauchen — Pfeil, Ring und der Zustand beim Überfahren. Vorher
     mischte der Überfahr-Zustand in `--pg-surface`, also in den
     *helleren* Grund des hellen Modus: Im Dunkeln wurde der Kreis unter
     dem Zeiger dunkler statt heller. */
  --pg-to-top-ink: var(--pg-blue);
  --pg-to-top-bg: var(--pg-surface);
  color: var(--pg-to-top-ink);
  background: var(--pg-to-top-bg);
  border: 1px solid var(--pg-border);
  box-shadow: 0 2px 6px rgba(18, 22, 40, .10), 0 10px 28px rgba(18, 22, 40, .14);
  text-decoration: none;
}
[data-bs-theme="dark"] .pg-to-top {
  /* Im Dunkeln trägt der Schatten nicht — dort hebt der hellere Grund. */
  --pg-to-top-ink: var(--pg-blue-soft);
  --pg-to-top-bg: var(--pg-surface-alt);
  box-shadow: 0 2px 6px rgba(0, 0, 0, .5), 0 10px 28px rgba(0, 0, 0, .4);
}
.pg-to-top-arrow { width: 22px; height: 22px; }

/* Der Ring liegt genau auf dem Rand des Kreises. Gedreht, damit er oben
   beginnt; `pathLength="1"` heißt: Der Strich ist der Anteil selbst. */
.pg-to-top-ring {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  transform: rotate(-90deg);
  fill: none;
  stroke-width: 2.5;
}
.pg-to-top-track { stroke: color-mix(in srgb, var(--pg-to-top-ink) 22%, transparent); }
.pg-to-top-bar {
  stroke: var(--pg-to-top-ink);
  stroke-linecap: round;
  stroke-dasharray: 1;
  /* Ohne Skript kein Fortschritt — dann bleibt der Ring leer. */
  stroke-dashoffset: calc(1 - var(--p, 0));
}

.pg-to-top:hover, .pg-to-top:focus-visible {
  border-color: color-mix(in srgb, var(--pg-to-top-ink) 45%, transparent);
  background: color-mix(in srgb, var(--pg-to-top-ink) 10%, var(--pg-to-top-bg));
}

html.js .pg-to-top {
  opacity: 0; visibility: hidden;
  transform: translateY(.5rem);
  transition: opacity .18s ease, transform .18s ease, visibility .18s;
}
html.js .pg-to-top.is-visible {
  opacity: 1; visibility: visible; transform: none;
}

/* Sanft nach oben, **nur wenn Bewegung erwünscht ist**. Das gilt auch
   für die Sprungmarken im Menü — dieselbe Bewegung, derselbe Grund. */
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

/* Die leere Marke am Seitenanfang. Sie nimmt beim Sprung den Fokus auf,
   damit auch die Tastatur oben weitermacht — aber ohne Rahmen: Man hat
   sie nicht angeklickt, sondern ist dorthin gesprungen. */
#seitenanfang:focus { outline: none; }

/* Der Honigtopf des Kontaktformulars.
   Nicht `display:none` und nicht `hidden`: Beides überspringen viele Bots,
   weil sie es prüfen. Aus dem Bild geschoben fällt es ihnen nicht auf —
   und Screenreader überspringen es wegen `aria-hidden` am Elternteil. */
.pg-honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Eingabefelder des Kontaktformulars.
   Bootstraps Vorgabe ist ein sehr heller Rahmen — auf dem hellen
   Seitengrund (`--bs-body-bg`) ist das Feld dann kaum zu sehen; gemeldet
   am 5. Oktober mit drei Pfeilen auf einem Bildschirmfoto. Es bekommt
   deshalb den **kräftigeren** der beiden vorhandenen Rahmentöne, denselben,
   den auch die hellen Knöpfe tragen — kein neuer Zwischenton, nur der, der
   schon da ist. Die Fläche bleibt `--pg-surface`: ein Feld ist heller als
   seine Umgebung, sonst sieht es aus wie abgeschaltet. */
.form-control {
  background: var(--pg-surface);
  border-color: var(--pg-border-strong);
}
.form-control::placeholder { color: var(--pg-muted); opacity: 1; }

/* Beim Tippen führt die Akzentfarbe — dieselbe Spur wie bei den anderen
   Bedienelementen (`.pg-seg-item:focus-visible`). Bootstraps eigener
   Schein bliebe blau und passte nicht zum Violett der Seite. */
.form-control:focus {
  background: var(--pg-surface);
  border-color: var(--pg-accent);
  outline: 2px solid var(--pg-accent);
  outline-offset: 1px;
  box-shadow: none;
}

/* ───────────────────────────────────────────────────────────────────────
   Cookie-Banner (siehe src/assets/js/consent.js und src/lib/consent.mjs)

   Keine eigenen Zwischentöne, nur `--pg-*` — damit er im Hell- und im
   Dunkelmodus ohne zweite Fassung sitzt.

   **Bewusst ein Blatt von unten, kein bildschirmfüllender Vorhang.** Der
   erste Blick gehört der Seite, nicht der Frage; auf dem Telefon wäre ein
   Vollbild-Layer vor dem ersten Scrollen der sicherste Weg, jemanden
   wieder loszuwerden.
   ─────────────────────────────────────────────────────────────────────── */
.cc-root {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 1080;                 /* über der Navigationsleiste von Bootstrap */
  display: flex;
  justify-content: center;
  padding: .75rem;
  pointer-events: none;          /* nur das Blatt selbst fängt Klicks */
}

.cc-box {
  pointer-events: auto;
  width: 100%;
  max-width: 34rem;
  background: var(--pg-surface);
  color: var(--bs-body-color);
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-radius);
  box-shadow: var(--pg-shadow);
  padding: 1.1rem 1.2rem;
  font-size: .9rem;
  line-height: 1.5;
}

.cc-title { margin: 0 0 .5rem; font-size: 1.02rem; font-weight: 700; }
.cc-text  { margin: 0 0 .9rem; color: var(--pg-muted); }

.cc-cat { border-top: 1px solid var(--pg-border); padding: .7rem 0 .2rem; }
.cc-cat-head {
  display: flex; align-items: center; gap: .55rem;
  cursor: pointer; font-weight: 600;
}
.cc-cat-head input {
  width: 1.05rem; height: 1.05rem; flex: none;
  accent-color: var(--pg-accent);
}
.cc-cat-head input:disabled { cursor: not-allowed; opacity: .65; }
.cc-cat-title { font-size: .92rem; }
.cc-cat-desc {
  margin: .25rem 0 0 1.6rem; font-size: .82rem; color: var(--pg-muted);
}

.cc-actions { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: 1rem; }

.cc-btn {
  flex: 1 1 auto;
  min-width: 8.5rem;
  min-height: 2.75rem;           /* Trefferfläche für den Daumen */
  padding: .6rem 1rem;
  border: 1px solid transparent;
  border-radius: 999px;          /* wie die Knöpfe der Seite */
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s, border-color .15s;
}

/* **Annehmen und Ablehnen sind gleich groß und gleich auffällig.** Wer das
   Nein kleiner macht, hat am Ende eine Einwilligung, die nichts wert ist. */
.cc-btn-primary { background: var(--pg-accent); color: #fff; }
.cc-btn-primary:hover { filter: brightness(1.08); }
.cc-btn-ghost {
  background: transparent;
  color: var(--pg-accent);
  border-color: var(--pg-accent);
}
.cc-btn-ghost:hover { background: var(--pg-surface-alt); }
.cc-btn-secondary {
  background: var(--pg-surface-alt);
  color: var(--bs-body-color);
  border-color: var(--pg-border-strong);
}
.cc-btn-secondary:hover { border-color: var(--pg-accent); }
.cc-btn-link {
  flex: 0 0 100%;
  min-width: 0;
  min-height: 2.25rem;
  background: none;
  border: none;
  color: var(--pg-muted);
  text-decoration: underline;
  font-weight: 500;
}
.cc-btn-link:hover { color: var(--pg-accent); }
.cc-btn:focus-visible { outline: 2px solid var(--pg-accent); outline-offset: 2px; }

.cc-links { margin: .8rem 0 0; font-size: .78rem; color: var(--pg-muted); }
.cc-links a { color: inherit; text-decoration: underline; }
.cc-links a:hover { color: var(--pg-accent); }

@media (min-width: 480px) {
  .cc-root { padding: 1rem; }
  .cc-box { padding: 1.3rem 1.5rem; }
}

/* Ab Tablet eine Karte unten rechts statt einer Leiste über die ganze
   Breite — auf dem Telefon bliebe die Karte nur gequetscht. */
@media (min-width: 768px) {
  .cc-root { justify-content: flex-end; padding: 1.25rem; }
  .cc-box { max-width: 25rem; }
  .cc-actions .cc-btn { min-width: 7rem; }
}

/* **Der Pfeil nach oben wird nicht hier versteckt, sondern in
   `consent.js`.** Beide sitzen unten rechts, das Blatt liegt darüber —
   gemeldet an einem Bildschirmfoto. Über die Kaskade ging es nicht: Der
   Pfeil hängt an `html.js .pg-to-top.is-visible`, und selbst mit gleicher
   Spezifität blieb seine Deckkraft stehen (`pointer-events` griff,
   `opacity` nicht). Ein Element, das **sicher** verschwinden muss, ist im
   Stilattribut besser aufgehoben als in einem Wettlauf um Selektoren. */

@media (prefers-reduced-motion: no-preference) {
  .cc-box { animation: cc-auf .22s ease-out; }
  @keyframes cc-auf {
    from { transform: translateY(.75rem); opacity: 0; }
    to   { transform: translateY(0);      opacity: 1; }
  }
}

/* Der Verweis „Cookies" in der Fußzeile ist ein Knopf, kein Link: Er führt
   nirgendwohin, er öffnet ein Blatt. Ein `<a href="#">` wäre ein
   Versprechen auf eine Adresse, die es nicht gibt — und für die Tastatur
   ist der Knopf ohnehin das richtige Element. Aussehen wie die Nachbarn. */
.pg-link-btn {
  padding: 0;
  background: none;
  border: 0;
  color: inherit;
  font: inherit;
  text-decoration: underline;
  cursor: pointer;
}
.pg-link-btn:hover { color: var(--pg-accent); }

/* ---------------------------------------------------------------------------
   So sieht es aus — die App im Handyrahmen
   Schmal: Text über dem Telefon. Ab 48em nebeneinander.
   Der Rahmen ist CSS, nicht Teil des Videos: so passt er in beiden Modi.
   --------------------------------------------------------------------------- */
.pg-showcase-grid {
  display: grid;
  gap: 2rem;
  justify-items: center;
}
.pg-showcase-text { max-width: 32rem; width: 100%; }
.pg-chapters {
  list-style: none;
  padding: 0;
  margin: 1.75rem 0 0;
  display: grid;
  gap: clamp(.35rem, 1.2vh, .9rem);
}
.pg-chapter {
  display: grid;
  gap: .2rem;
  width: 100%;
  padding: clamp(.85rem, 2vh, 1.25rem) 1.1rem clamp(.85rem, 2vh, 1.25rem) 1.25rem;
  border: 0;
  border-left: 3px solid var(--pg-border);
  border-radius: 0 12px 12px 0;
  background: transparent;
  color: inherit;
  text-align: left;
  cursor: pointer;
  transition: background-color .2s, border-color .2s;
}
.pg-chapter:hover { background: var(--pg-surface-alt); }
.pg-chapter.is-active {
  border-left-color: var(--pg-accent);
  background: var(--pg-surface);
  box-shadow: var(--pg-shadow);
}
.pg-chapter-title {
  font-family: "Sora", var(--bs-font-sans-serif);
  font-weight: 700;
  font-size: 1.08rem;
}
.pg-chapter.is-active .pg-chapter-title { color: var(--pg-accent); }
.pg-chapter-body { color: var(--bs-secondary-color, var(--pg-muted)); font-size: .95rem; }
.pg-showcase-more {
  margin: 1.25rem 0 0 calc(1.25rem + 3px);
  color: var(--bs-secondary-color, var(--pg-muted));
  font-size: .95rem;
}
.pg-showcase-more strong { color: var(--bs-body-color); }
.pg-showcase-more a { white-space: nowrap; font-weight: 600; }
.pg-chapter:focus-visible { outline: 3px solid var(--pg-accent); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { .pg-chapter { transition: none; } }
.pg-showcase-figure {
  margin: 0;
  display: grid;
  justify-items: center;
  gap: .6rem;
}
/* Eigener Hinweis, nicht `.pg-photo-note`: der liegt absolut auf einem
   Foto und landete hier ohne Bezugsrahmen am linken Seitenrand. */
.pg-showcase-note {
  font-size: .75rem;
  color: var(--pg-muted);
}
/* Groß, seit die Kapitel daneben die Höhe füllen (gewünscht am
   7. Oktober: „die große Version“), und mit dem **ganzen** Bildschirm der
   App samt Status- und Navigationsleiste — ein Zuschnitt auf 9:16 sah im
   Rahmen abgeschnitten aus. Begrenzt durch die Fensterhöhe, damit das
   Telefon auf einem Laptop ganz im Bild bleibt: Samt Rand ist es rund
   2,3-mal so hoch wie breit. */
.pg-phone {
  position: relative;
  width: min(86vw, 400px, calc((100vh - 6rem) / 2.3));
  min-width: 260px;
  padding: 10px;
  border-radius: 46px;
  background: #0b0f1a;
  box-shadow: var(--pg-shadow), 0 0 0 1px var(--pg-border-strong);
}
.pg-phone-screen {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 540 / 1212;
  border-radius: 36px;
  background: var(--pg-surface-alt);
  object-fit: cover;
}
.pg-phone-screen:fullscreen {
  border-radius: 0;
  object-fit: contain;
  background: #0b0f1a;
}
.pg-showcase-toggle {
  position: absolute;
  right: 22px;
  bottom: 22px;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  color: #fff;
  background: rgba(11, 15, 26, .62);
  cursor: pointer;
}
.pg-showcase-full { right: auto; left: 22px; }
.pg-showcase-toggle svg { width: 20px; height: 20px; }
.pg-showcase-toggle .pg-icon-pause,
.pg-showcase-toggle.is-playing .pg-icon-play { display: none; }
.pg-showcase-toggle.is-playing .pg-icon-pause { display: block; }
.pg-showcase-toggle:focus-visible {
  outline: 3px solid var(--pg-accent);
  outline-offset: 3px;
}
/* Nebeneinander, **und zusammen in der Mitte** — vorher stand der Text
   links und das Telefon ganz rechts, mit einer leeren halben Seite
   dazwischen. */
@media (min-width: 48em) {
  .pg-showcase-grid {
    grid-template-columns: minmax(0, 32rem) auto;
    justify-content: center;
    align-items: center;
    gap: clamp(2rem, 4vw, 4rem);
  }
}
