/* ============================================================
   VeloCity — Bike-Sharing Würzburg

   HERKUNFT DER DESIGNSPRACHE
   Der Kopfbereich stammt vom Nutzer (Paket velocity-startsite) und
   ist unverändert übernommen. Alles Weitere auf dieser Seite wurde
   auf dessen Sprache gezogen: Palette, Schriften, Formen, Rhythmus.
   Die frühere Sprache (Fraunces als Auszeichnung, IBM Plex als Brot,
   Oxford-Navy #10275A) ist damit vollständig ersetzt.

   PALETTE
   Ein sehr tiefes Navy trägt die Fläche, ein einziges lautes Rot
   setzt die Akzente, ein kühles Papierweiß hält die Seite hell.
   Mint kommt nur dort vor, wo etwas gerade wirklich passiert:
   Live-Punkt, Kicker der Produktkarte, laufende Ausleihe.

   SCHRIFT
   Avenir Next für den Fließtext, Avenir Next Condensed für die
   grossen Zeilen, eine Systemmonospace für alle Etiketten.
   ACHTUNG: Avenir Next liegt auf macOS, nicht auf Windows. Dort
   greift Helvetica Neue, dann Arial — das Bild bleibt ruhig, wird
   aber breiter. Wer Verbindlichkeit über alle Rechner braucht,
   ersetzt den Stapel durch eine eingebundene Webschrift.

   FORM
   Schaltflächen sind Pillen (999px), Inhaltskarten haben eine harte
   Kante (2px). Linien sind Haarlinien in --mist. Grosse Zeilen
   laufen eng (letter-spacing bis -.065em), Etiketten weit (.16em).
   ============================================================ */

:root {
  /* Farbe — aus dem Entwurf des Nutzers */
  --navy:       #061841;
  --navy-2:     #0b255d;
  --red:        #f00038;
  --red-tief:   #c8002f;
  --paper:      #f3f5f8;
  --ink:        #111827;
  --mist:       #dbe2ec;
  --mint:       #58d6a1;
  --grau:       #5c677a;
  --grau-still: #68748a;

  /* Schrift */
  --body-schrift: "Avenir Next", Avenir, "Helvetica Neue", Helvetica, Arial, sans-serif;
  --schmal: "Avenir Next Condensed", "Arial Narrow", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* Fliessende Grade — aus dem Entwurf */
  --nav-font:     clamp(17px, 1.12vw, 19px);
  --meta-font:    clamp(14px, .88vw, 15px);
  --hero-font:    clamp(52px, 5.45vw, 96px);
  --control-font: clamp(15px, 1.05vw, 17px);
  --body-font:    clamp(15px, 1.05vw, 17px);
  --titel-font:   clamp(40px, 5vw, 78px);

  /* Fläche */
  /* Die Spur war 1240 breit. Auf einem breiten Schirm blieben davon
     links und rechts ueber vierhundert Punkte Rand - ein Fuenftel der
     Flaeche je Seite -, und alles wirkte in die Mitte gepresst. 1240 ist
     ein Mass fuer Fliesstext; diese Seite ist ein Plakat mit einem
     Produktbild. Der Fliesstext selbst bleibt schmal, dafuer sorgen
     seine eigenen Grenzen (68ch in den Fragen, 74ch im Rechtstext). */
  --spur: 1840px;
  /* EINE FLUCHT FUER DIE GANZE SEITE.
     Die Abschnitte stehen in einer 1240 breiten Spur, mittig; Kopfleiste
     und Buehne standen dagegen am Seitenrand. Ab 1240 Punkten Breite
     liefen sie auseinander - bei 1440 begann die Schlagzeile der Buehne
     bei 58, die Schlagzeile des naechsten Abschnitts bei 150. Zwei
     Fluchten fuer dieselbe Rolle; das liest man, auch wenn man es nicht
     benennen kann.

     Die Formel liefert genau die Flucht der Spur: unterhalb von 1240 den
     Seitenrand, darueber den Rand der Spur. Das Prozent bezieht sich auf
     das Element, in dem die Variable BENUTZT wird - bei padding auf
     dessen eigene Breite, bei left/right auf den umgebenden Block. In
     beiden Faellen ist das die volle Seitenbreite, und zwar OHNE den
     Rollbalken. Mit 100vw waere er mitgezaehlt, und die Flucht laege um
     sieben Punkte daneben. */
  --flucht: max(var(--rand), calc((100% - var(--spur)) / 2 + var(--rand)));
  /* DIE BUEHNE IST EINE ZWEISPALTIGE SEITE.
     Links die Zeile, rechts das Rad, dazwischen eine feste Gasse. Beide
     Spalten kennen einander: das Rad beginnt dort, wo die Textspalte
     endet, und endet an der Flucht der Spur. Vorher stand das Rad auf
     einem Prozentwert und die Zeile daneben - bei jeder Fensterbreite
     ein anderes Verhaeltnis, mal Luft, mal Ueberschneidung. */
  /* DIE TEXTSPALTE RECHNET IN SCHRIFTGRAD, NICHT IN PUNKTEN.
     Mit einem festen Deckel (500) wuchs die Schrift mit der
     Fensterbreite, die Spalte aber nicht - auf einem breiten Schirm
     standen die Schlagzeilen drei- und vierzeilig. Nachgemessen braucht
     die breiteste ("Noch entspannter | nach Hause cruisen.") 7,97 em
     fuer zwei Zeilen; 8,2 gibt etwas Luft. Weil beides am selben
     Schriftgrad haengt, bleibt der Umbruch bei jeder Breite gleich.

     Die Obergrenze ist die TATSAECHLICH freie Breite, nicht ein fester
     Anteil des Fensters: mit 48vw war die Spalte zwischen 520 und 900
     Punkten zu schmal, obwohl daneben nichts stand - dort wurden zwei
     der sechs Schlagzeilen wieder dreizeilig. */
  --textspalte: min(calc(var(--hero-font) * 8.2),
                    calc(100% - 2 * var(--flucht)));
  --gasse: clamp(32px, 3.4vw, 64px);
  --rand: clamp(22px, 4vw, 70px);
  --luft: clamp(70px, 8vw, 130px);

  /* Zustandsgrössen der Bühne, vom Skript gesetzt */
  --progress: 0;
  --ebike-exit: 0;
  --city-enter: 0;
  --choice-opacity: 0;
  --cta-opacity: 0;
  --bike-scale: 1.06;
  --bike-x: 3;
}

* { box-sizing: border-box; }
html { scroll-behavior: auto; }

/* Der Kopf ist fest und 92 px hoch. Ohne diese Reserve landet jedes
   Sprungziel darunter und die Ueberschrift des Abschnitts ist verdeckt. */
section[id], main[id] { scroll-margin-top: 108px; }
section[id] h1, section[id] h2 { scroll-margin-top: 118px; }
@media (max-width: 900px) { section[id] { scroll-margin-top: 88px; } }

/* Der Hintergrund darf nicht mitscrollen, solange der Dialog offen ist. */
body.dialog-offen { overflow: hidden; }

body {
  margin: 0;
  color: var(--ink);
  background: var(--paper);
  font-family: var(--body-schrift);
  font-size: var(--body-font);
  line-height: 1.55;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

button, a, input { font: inherit; }
button { cursor: pointer; }
img { max-width: 100%; }
:focus-visible { outline: 3px solid var(--red); outline-offset: 3px; }

.container { max-width: var(--spur); margin: 0 auto; padding: 0 var(--rand); }

.sprungmarke {
  position: absolute; left: 12px; top: -60px; z-index: 60;
  padding: 12px 18px;
  background: var(--navy); color: #fff;
  border-radius: 999px; font-weight: 700; text-decoration: none;
  transition: top .18s ease;
}
.sprungmarke:focus { top: 12px; }

.nur-vorlesen {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------------------------------------------------- Kopfzeile */

.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 30;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  min-height: 92px;
  padding: 0 var(--flucht);
  color: var(--navy);
  background: rgba(247, 249, 252, .985);
  border-bottom: 1px solid rgba(6, 24, 65, .12);
  box-shadow: 0 10px 34px rgba(6, 24, 65, .06);
}

.brand {
  color: var(--navy);
  text-decoration: none;
  font-size: clamp(30px, 2.2vw, 40px);
  font-weight: 800;
  letter-spacing: -.055em;
}
.brand span { color: var(--red); }
/* Das O ist das Rad — ein Ring statt eines Buchstabens. */
.brand i {
  display: inline-block;
  width: .44em; height: .44em;
  margin: 0 .08em;
  border: 2px solid currentColor;
  border-radius: 50%;
  vertical-align: .04em;
}

.site-nav { display: flex; gap: clamp(22px, 2.6vw, 48px); }
.site-nav a {
  color: inherit; text-decoration: none;
  font-size: var(--nav-font); font-weight: 700; letter-spacing: .02em;
  padding-bottom: 3px; border-bottom: 2px solid transparent;
}
.site-nav a:hover { color: var(--red); border-bottom-color: var(--red); }

.login {
  justify-self: end;
  color: #fff;
  background: var(--red);
  text-decoration: none;
  padding: 13px 20px;
  border: 1px solid var(--red);
  border-radius: 999px;
  font-size: var(--nav-font);
  font-weight: 700;
}
.login:hover { background: var(--red-tief); border-color: var(--red-tief); }

.kopf-aktionen {
  position: relative;
  justify-self: end;
  display: flex; align-items: center; gap: 10px;
}

/* Kontomenue. Es haengt an der Kopfzeile, nicht am Knopf, damit es auf
   schmalen Geraeten nicht ueber den Rand laeuft. */
.konto-menue {
  position: absolute; z-index: 40;
  top: calc(100% + 10px); right: 0;
  min-width: 236px;
  padding: 16px 18px 14px;
  background: #fff;
  border: 1px solid var(--mist);
  border-radius: 2px;
  box-shadow: 0 26px 60px rgba(6, 24, 65, .18);
}
.konto-menue[hidden] { display: none; }
.konto-wer {
  margin: 0 0 12px; padding-bottom: 12px;
  border-bottom: 1px solid var(--mist);
  font-size: 14px; line-height: 1.5; color: var(--grau);
}
.konto-wer strong { color: var(--navy); }
.konto-wer span { font-family: var(--mono); font-size: 12px; color: var(--grau-still); }
.konto-menue a, .konto-menue button {
  display: block; width: 100%;
  padding: 10px 0;
  text-align: left; text-decoration: none;
  color: var(--navy); background: none; border: 0;
  font-size: 15px; font-weight: 700;
}
.konto-menue a:hover, .konto-menue button:hover { color: var(--red); }
.konto-menue button {
  margin-top: 6px; padding-top: 12px;
  border-top: 1px solid var(--mist);
  color: var(--red);
}
/* Die Karte ist der Weg, den mobile Besucher wirklich suchen. Sie bleibt
   deshalb sichtbar, auch wenn der Rest ins Menue wandert. */
.kopf-karte {
  display: none;
  padding: 12px 16px;
  color: var(--navy); text-decoration: none;
  border: 1px solid rgba(6, 24, 65, .28);
  border-radius: 999px;
  font-size: var(--nav-font); font-weight: 700;
}
.kopf-karte:hover { border-color: var(--navy); background: rgba(6, 24, 65, .05); }

.menue-knopf {
  display: none;
  width: 46px; height: 46px;
  flex-direction: column; align-items: center; justify-content: center; gap: 5px;
  border: 1px solid rgba(6, 24, 65, .28);
  border-radius: 999px;
  background: transparent;
}
.menue-knopf span {
  display: block; width: 18px; height: 2px;
  background: var(--navy);
  transition: transform .2s ease, opacity .2s ease;
}
.menue-knopf.ist-offen span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.menue-knopf.ist-offen span:nth-child(2) { opacity: 0; }
.menue-knopf.ist-offen span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.menue {
  position: fixed; z-index: 29;
  top: 74px; left: 0; right: 0;
  display: flex; flex-direction: column;
  padding: 10px var(--rand) 22px;
  background: rgba(247, 249, 252, .985);
  border-bottom: 1px solid rgba(6, 24, 65, .12);
  box-shadow: 0 18px 40px rgba(6, 24, 65, .1);
}
.menue[hidden] { display: none; }
.menue a {
  padding: 15px 0;
  color: var(--navy); text-decoration: none;
  font-family: var(--schmal);
  font-size: 26px; font-weight: 800; letter-spacing: -.02em;
  border-bottom: 1px solid var(--mist);
}
.menue a:last-child { border-bottom: 0; }
.menue a:hover { color: var(--red); }

/* ------------------------------------------------ Bühne (Hero) */
/* Ab hier unverändert aus dem Entwurf des Nutzers übernommen. */

/* Die Laenge der Buehne war gestuft: 360vh, unter 900 px 210vh, unter
   520 px 185vh. Ein einziger Pixel Fensterbreite - 900 gegen 901 -
   verlaengerte die Seite damit um rund siebzig Prozent. Wer ein Fenster
   zieht, sieht die Seite springen.

   Jetzt eine stetige Funktion. 40vh traegt den Sockel, 250vw laesst sie
   mit der Breite wachsen, clamp haelt beide Enden:
     bis  473 px Breite → 180vh   (Telefon, kurze Strecke)
     ab  1024 px Breite → 360vh   (Schreibtisch, volle Inszenierung)
   dazwischen laeuft es durch, ohne Kante. */
/* Die Laenge der Buehne ist eine Rechnung, keine Geschmacksfrage: je
   Fahrt legt ein Rad eine volle Bildbreite zurueck, und das soll rund
   anderthalb Bildpunkte je Bildpunkt Scrollweg sein. Bei 360vh waren es
   sechs - eine Mausradraste warf das Rad ueber ein Drittel der Breite,
   und genau das wirkte ruckelig.

   Mobil laeuft die Buehne gar nicht mehr (siehe Umbruch unten): auf
   einem Telefon steht das Rad still und die Pille wechselt. */
.scroll-story {
  height: clamp(300vh, 40vh + 320vw, 470vh);
  min-height: 2200px;
  background: var(--paper);
}

.sticky-stage {
  position: sticky;
  top: 0;
  height: 100vh;
  min-height: 650px;
  overflow: hidden;
  isolation: isolate;
  background: var(--paper);
}

.photo-layer {
  position: absolute;
  /* Rechts endet die Ebene an der Flucht der Spur - hier loest sich das
     Prozent im Ausdruck gegen den umgebenden Block auf, also gegen die
     Buehne, und trifft damit genau die Spur. In background-position
     wuerde dasselbe Prozent gegen "Flaeche minus Bild" rechnen und weit
     danebenliegen; deshalb sitzt die Flucht an der EBENE. */
  inset: 0 var(--flucht) 0 0;
  z-index: -5;
  background-repeat: no-repeat;
  /* DAS RAD STEHT AUF DER FLUCHT DER SPUR.
     Sein Vorderrad endet dort, wo der Login-Knopf und die Live-Zahl
     enden - eine Linie fuer alles, was rechts steht. Moeglich ist das,
     weil die Bilder waagrecht randlos beschnitten sind: die Bildkante
     IST die Reifenkante (siehe tools/raeder_weissgrund.py).

     Die Zeile links darf dabei ueber das Hinterrad laufen. Bei einem
     Bild im Verhaeltnis zwei zu eins ist das keine Nachlaessigkeit,
     sondern die Bedingung dafuer, dass das Rad gross bleibt: ohne
     Ueberschneidung blieben ihm 570 Punkte Breite und 270 Hoehe, und es
     saehe aus wie eine Briefmarke. Lesbar bleibt die Zeile durch den
     hellen Saum an der Schrift, nicht durch einen Schleier ueber dem
     Bild - der hat zweimal das halbe Rad ausgewaschen. */
  /* Die Groesse haengt an der HOEHE, nicht an der Breite: die drei
     Bilder sind verschieden breit (das Lastenrad ist laenger), aber
     gleich hoch und im selben Massstab. Ueber die Hoehe bleibt das
     Groessenverhaeltnis erhalten. */
  background-size: auto 48%;
  background-position: right 68%;
  /* Die Schiene rechnet in Fensterbreiten: ein Rad, das nur um seine
     eigene Bildbreite faehrt, stuende beim Wechsel noch im Bild. */
  /* Der Ruhe-Versatz aus dem Scrollmodell (--bike-x) ist hier raus: er
     schob das Rad um drei Fensterprozent nach rechts und damit von der
     Flucht herunter. Was bleibt, ist die Schiene. */
  transform: translateX(calc(var(--x-rad, 0) * 104vw));
  will-change: opacity, transform;
}

/* DER SCHLEIER IST WEG (24.08.2026)
   Er hatte einen Zweck, solange hinter der Schlagzeile eine Betonwand
   stand: dunkles Marineblau auf mittlerem Grau traegt nicht. Er hatte
   aber auch einen Preis - sein staerkster Abfall lag mitten auf dem
   Hinterrad, und das las sich als zweites, graues Rad. Der Nutzer hat
   es zweimal gemeldet.

   Der helle Grund macht ihn ueberfluessig. Was bleibt, ist die Stelle,
   an der die Zeile ueber einen schwarzen Reifen laeuft; dort traegt ein
   feiner heller Saum an der Schrift (siehe .claim h1). Er kostet das
   Bild nichts, weil er nur an den Buchstaben klebt. */
.photo-shade {
  position: absolute;
  inset: 0;
  z-index: -3;
  /* Nur noch ein Hauch Tiefe nach unten, damit die Buehne nicht
     abrupt in den naechsten Abschnitt kippt. */
  background: linear-gradient(0deg, rgba(6,24,65,.06) 0%, transparent 18%);
  pointer-events: none;
}


/* DER GRUND
   Bis zum 24.08.2026 lag hier ein Foto: eine Betonwand, aus den
   Aufnahmen freigestellt und gekachelt. Sie hat drei Anlaeufe gekostet
   und am Ende doch nicht zu den Raedern gepasst - andere Ausleuchtung,
   andere Schatten.

   Die neuen Aufnahmen stehen vor weissem Grund. Damit braucht die
   Buehne kein Foto mehr: ein heller Verlauf traegt die Raeder, und der
   Schatten steht im Bild jedes Rades, wo er hingehoert. Das ist kein
   Notbehelf - es macht das Rot kraeftiger und die Schlagzeile lesbar,
   ohne dass ein Schleier darueber muss.

   Ausdruecklich ganz nach hinten: alle Radebenen teilen sich -5. */
.buehne-grund {
  position: absolute;
  inset: 0;
  z-index: -6;
  background:
    radial-gradient(120% 78% at 50% 12%, #ffffff 0%, rgba(255,255,255,0) 64%),
    linear-gradient(180deg, #fbfcfe 0%, #f4f7fb 54%, #e8edf5 100%);
}

/* Die drei Raeder haengen an EINER Schiene. Der Versatz ist der Abstand
   zum aktuellen Ort mal eine Bildbreite - daraus folgt von selbst, dass
   ein ankommendes Rad von rechts hereinfaehrt, ein gehendes nach links
   hinaus, und dass nie zwei an derselben Stelle stehen.

   104 statt 100 Prozent: ein Rest Luft, damit sich die Raeder auch bei
   gerundeten Zwischenwerten nicht beruehren.

   Vorher lief hier ein WebGL-Morph, der zwei Fotos ineinander rechnete.
   Auf halber Strecke standen zwei Rahmen und vier Laufraeder versetzt
   uebereinander - eine Doppelbelichtung, kein Uebergang. */
.photo-ebike {
  background-image: url("assets/rad-ebike-frei.webp?v=35080122");
  opacity: var(--o-ebike);
  --x-rad: var(--x-ebike);
}
.photo-city {
  background-image: url("assets/rad-city-frei.webp?v=e28fae0e");
  opacity: var(--o-city);
  --x-rad: var(--x-city);
}
.photo-cargo {
  background-image: url("assets/rad-cargo-frei.webp?v=a7c91eeb");
  opacity: var(--o-cargo);
  --x-rad: var(--x-cargo);
}


.top-meta {
  position: absolute;
  /* AN DIESELBE FLUCHT WIE DIE SCHLAGZEILE GEHAENGT.
     Ein fester Wert in Punkten stimmte nur bei einer Fensterhoehe: die
     Schlagzeile sitzt bei clamp(190px, 24vh, 320px), der Zaehler stand
     daneben bei 132 - auf einem hohen Bildschirm klaffte es, auf einem
     flachen ueberschnitt es sich.

     Jetzt beginnt der Zaehler an derselben Linie und wird um seine
     eigene Hoehe nach oben geschoben; die Zeile des Kickers bekommt er
     wieder dazu. Ergebnis: seine Beschriftung liegt auf der Zeile des
     Kickers, bei jeder Fensterhoehe. */
  top: clamp(190px, 24vh, 320px);
  transform: translateY(calc(-100% + 1.3 * var(--meta-font)));
  left: var(--flucht); right: var(--flucht);
  color: var(--navy);
  text-shadow: 0 1px 16px rgba(255, 255, 255, .9);
}

.meta-kurz { display: none; }

/* Vorher stand die Zahl in 14-px-Versalien neben einer zweiten Angabe -
   auf dem hellen Beton kaum zu lesen. Sie ist das einzige, was sich auf
   dieser Seite staendig aendert, und sieht das jetzt auch so aus. */
/* RECHTS, nicht links (24.08.2026, auf Wunsch des Nutzers).
   Links stehen Kicker und Schlagzeile untereinander; die Zahl daneben
   machte aus einer Spalte drei Anfaenge. Rechts hat sie freien Grund
   ueber dem Rad und stoert nichts.

   UNTEREINANDER, nicht nebeneinander. Nebeneinander bremste die Zahl
   die Beschriftung aus: beide teilten sich eine Zeile, und die Zahl
   konnte nicht wachsen, ohne die Zeile ueber das Rad zu schieben.
   Gestapelt und rechtsbuendig ist es ein Block - und die Zahl darf so
   gross werden, wie es ihr zusteht. Sie ist das einzige auf dieser
   Seite, das sich staendig aendert.

   Die rechte Flucht ist dieselbe wie die des Login-Knopfs. */
.live-zahl {
  display: flex; flex-direction: column;
  align-items: flex-end; justify-content: flex-start;
  gap: 2px;
  margin: 0;
  color: var(--navy);
  text-align: right;
}
.live-zahl b {
  position: relative;
  padding-left: .42em;
  font-family: var(--schmal);
  /* Nach oben gedeckelt, nicht aus Zurueckhaltung: auf einem breiten
     UND flachen Bildschirm (1920x700) waere der Block sonst bis auf
     vier Punkte an die Kopfleiste gestossen - er haengt ja an der
     Schlagzeile und waechst nach oben. 78 laesst ueberall Luft. */
  font-size: clamp(44px, 5.2vw, 78px);
  font-weight: 800;
  letter-spacing: -.03em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
/* Der Punkt waechst mit der Zahl - in em, nicht in Punkten. Vorher
   stand eine feste Groesse daneben, die bei grosser Zahl zum Staubkorn
   wurde. */
.live-zahl b::before {
  content: "";
  position: absolute; left: 0; top: .44em;
  width: .17em; height: .17em;
  border-radius: 50%;
  background: var(--mint);
  box-shadow: 0 0 0 .11em rgba(88, 214, 161, .16);
}
.live-zahl > span {
  font: 700 clamp(11px, .92vw, 15px)/1.3 var(--mono);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: rgba(6, 24, 65, .78);
  padding-right: .1em;
}

.claim {
  position: absolute;
  left: var(--flucht);
  top: clamp(190px, 24vh, 320px);
  /* Die Spalte war 690 breit, die laengste Zeile misst 476. Der
     Ueberhang war unsichtbar, kostete aber genau die Breite, die das
     Rad daneben braucht - und ohne sie lief die Zeile ins Hinterrad. */
  width: var(--textspalte);
  color: var(--navy);
  will-change: opacity, transform;
}
.claim h1 {
  margin: 0;
  font-family: var(--schmal);
  font-size: var(--hero-font);
  line-height: .99;
  letter-spacing: -.026em;
  font-weight: 800;
  max-width: 100%;
  text-wrap: balance;
  /* Ein feiner heller Saum, damit die Zeile auch dort steht, wo sie
     ueber einen schwarzen Reifen laeuft. Auf dem hellen Grund ist er
     unsichtbar - er klebt an den Buchstaben und nicht an der Flaeche.
     Das ist der Ersatz fuer den Schleier, der frueher das halbe Rad
     ausgewaschen hat. */
  text-shadow:
    0 0 3px rgba(247,249,252,.92),
    0 0 12px rgba(247,249,252,.72),
    0 0 28px rgba(247,249,252,.45);
}
.claim-line { display: block; }
.headline-primary { color: var(--navy); }
.headline-accent { margin-top: .34em; color: var(--red); }

/* Jede Schlagzeile haengt an ihrem eigenen Rad. Sie tritt von unten
   herein und nach oben ab - dieselbe Richtung wie die Buehne darunter. */
.claim-ebike { opacity: var(--z-ebike); transform: translateY(calc((1 - var(--z-ebike)) * 20px)); }
.claim-city  { opacity: var(--z-city);  transform: translateY(calc((1 - var(--z-city))  * 20px)); }
.claim-cargo { opacity: var(--z-cargo); transform: translateY(calc((1 - var(--z-cargo)) * 20px)); }
/* Das City-Bike stand in kleinerer Schrift, weil sein Satz der laengste
   ist und in der schmalen Spalte sonst vierzeilig wurde. Mit der
   mitwachsenden Spalte braucht es den Notbehelf nicht mehr - alle drei
   Schlagzeilen stehen jetzt im selben Grad. */

.sticky-stage.is-manual .claim {
  transition: opacity .52s cubic-bezier(.4, 0, .2, 1), transform .62s cubic-bezier(.4, 0, .2, 1);
}
.sticky-stage.is-manual .final-card {
  transition: opacity .36s ease, transform .45s cubic-bezier(.4, 0, .2, 1);
}

/* Rueckfall ohne inert-Unterstuetzung: was inert ist, nimmt keine Klicks.
   Mit !important, weil spaeter im Stil stehende Klassenregeln - etwa
   .final-card - sonst gewinnen: beide haben dieselbe Spezifitaet, und
   dann entscheidet die Reihenfolge. Wo der Browser inert kennt, ist die
   Regel ohnehin ohne Wirkung; wo nicht, ist sie die einzige Sperre. */
[inert], [inert] * { pointer-events: none !important; }

.choice-panel {
  position: absolute;
  left: var(--flucht);
  /* Rechts endet die Bank, bevor die Abschlusskarte beginnt. Vorher lief
     die Auswahlkarte vierunddreissig Punkte unter sie - zwei Auflagen,
     die einander ueberdecken, und keine davon absichtlich. */
  right: calc(var(--flucht) + min(410px, 32vw) + clamp(24px, 2.2vw, 44px));
  bottom: clamp(72px, 9vh, 120px);
  z-index: 4;
  display: grid;
  /* Die zweite Spalte waechst NICHT mit: auf breiten Schirmen zog sich
     die Auswahlkarte sonst auf neunhundert Punkte und stand fast leer
     da. Sie traegt drei kurze Zeilen; mehr als 420 braucht sie nie. */
  grid-template-columns: auto minmax(200px, 420px);
  justify-content: start;
  gap: 28px;
  align-items: end;
  opacity: var(--choice-opacity);
  transform: translateY(calc((1 - var(--choice-opacity)) * 30px));
  pointer-events: auto;
}

.product-tabs {
  display: inline-flex;
  padding: 5px;
  background: #071943;
  border: 1px solid rgba(255, 255, 255, .22);
  border-radius: 999px;
  box-shadow: 0 12px 34px rgba(6, 24, 65, .18);
}
.product-tab {
  min-height: 48px;
  padding: 0 18px;
  color: rgba(255, 255, 255, .7);
  background: transparent;
  border: 0;
  border-radius: 999px;
  font-weight: 750;
  font-size: var(--control-font);
}
.product-tab[aria-pressed="true"] { color: var(--navy); background: #fff; }

.product-copy {
  min-height: 98px;
  padding: 16px 20px 17px;
  border: 1px solid rgba(255, 255, 255, .18);
  border-radius: 14px;
  color: #fff;
  background: rgba(6, 24, 65, .96);
  box-shadow: 0 18px 46px rgba(6, 24, 65, .20);
}
.product-kicker {
  display: block;
  margin-bottom: 7px;
  color: var(--mint);
  font: 700 12px/1.2 var(--mono);
  letter-spacing: .16em;
  text-transform: uppercase;
}
.product-copy strong {
  display: block;
  font-size: clamp(22px, 2vw, 32px);
  line-height: 1.15;
  letter-spacing: -.03em;
}
.product-copy small {
  display: block;
  margin-top: 6px;
  color: rgba(255, 255, 255, .84);
  font-size: var(--body-font);
}

.final-card {
  position: absolute;
  right: var(--flucht);
  /* Dieselbe Unterkante wie Pille und Auswahlkarte. Vorher standen die
     drei Auflagen auf drei verschiedenen Linien - neun, elf und keine
     Punkte auseinander. Das sieht man nicht einzeln, aber zusammen. */
  bottom: clamp(72px, 9vh, 120px);
  z-index: 6;
  /* 410 waren zu knapp: "Bereit, wenn du es bist." brach in zwei
     Zeilen, und die Karte stand hoeher als noetig neben dem Rad. */
  width: min(470px, 34vw);
  padding: 26px 28px;
  color: var(--navy);
  background: rgba(255, 255, 255, .94);
  border-radius: 2px;
  box-shadow: 0 24px 70px rgba(0, 0, 0, .24);
  opacity: var(--cta-opacity);
  transform: translateY(calc((1 - var(--cta-opacity)) * 34px));
  /* pointer-events nimmt keine Zahl - die Zeile hier war wirkungslos.
     Die Sperre setzt jetzt hero.js ueber inert; das deckt Zeigergeraet
     und Tastatur zugleich ab. Diese Regel bleibt als Rueckfall, falls
     inert nicht unterstuetzt wird. */
  pointer-events: auto;
}
.final-card .label {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 28px;
  font: 700 12px/1.3 var(--mono);
  letter-spacing: .14em;
  text-transform: uppercase;
}
.final-card h2 {
  margin: 0 0 10px;
  font-family: var(--schmal);
  font-size: clamp(28px, 2.8vw, 46px);
  line-height: .98;
  letter-spacing: -.05em;
}
.final-card p { margin: 0 0 24px; color: #58657a; font-size: var(--body-font); line-height: 1.5; }

.primary-cta {
  display: flex; align-items: center; justify-content: space-between;
  width: 100%;
  padding: 17px 18px;
  color: #fff;
  background: var(--red);
  border: 0;
  text-decoration: none;
  font-weight: 800;
  font-size: var(--control-font);
}
.primary-cta:hover { background: var(--red-tief); }
.primary-cta span:last-child { font-size: 22px; }

/* Der Scrollhinweis.

   Drei Fassungen davor waren zu leise oder zu bieder: erst ein Satz,
   dann ein kleiner Winkel auf grauem Beton, dann derselbe Winkel auf
   einer weissen Scheibe - sichtbar, aber ohne Charakter.

   Jetzt ein Rad, das sich dreht, und ein Tropfen, der hindurchfaellt.
   Der Ring ist ein Laufrad in Navy mit einer roten Speiche; der Punkt
   faellt in der Hausfarbe hindurch und zieht die Richtung nach unten.
   Das Bild passt zum Gegenstand und ist in jeder Sprache lesbar. */
.scroll-hint {
  position: absolute;
  left: 50%; bottom: 24px;
  width: 64px; height: 64px;
  transform: translateX(-50%);
  opacity: var(--z-ebike);
  pointer-events: none;
}
/* Der Grund: eine weiche Aufhellung, damit der Hinweis auf jedem
   Bildinhalt steht - Beton, Asphalt oder Rad. */
.scroll-hint::before {
  content: "";
  position: absolute; inset: 0;
  border-radius: 50%;
  /* Der helle Grund hinter dem Hinweis war noetig, solange dahinter
     eine Betonwand stand. Vor hellem Grund ist Weiss auf Weiss
     dagegen gar nichts - der Hinweis war praktisch unsichtbar. Jetzt
     traegt ihn eine zarte Scheibe in der Hausfarbe. */
  background: rgba(6, 24, 65, .035);
}
/* Das Laufrad. */
.scroll-hint::after {
  content: "";
  position: absolute; inset: 11px;
  border-radius: 50%;
  border: 2px solid rgba(6, 24, 65, .26);
  border-top-color: var(--red);
  box-shadow: 0 6px 16px rgba(6, 24, 65, .10);
  animation: rollen 3.4s linear infinite;
}
/* Der Tropfen. */
.scroll-hint span {
  position: absolute;
  left: 50%; top: 18px;
  width: 8px; height: 8px;
  margin-left: -4px;
  border-radius: 50%;
  background: var(--red);
  animation: fallen 1.9s cubic-bezier(.45, 0, .35, 1) infinite;
}
@keyframes rollen {
  to { transform: rotate(360deg); }
}
@keyframes fallen {
  0%   { transform: translateY(0);    opacity: 0; }
  22%  { opacity: 1; }
  70%  { transform: translateY(26px); opacity: 1; }
  100% { transform: translateY(33px); opacity: 0; }
}
}
}
}

.progress-rail {
  position: absolute;
  right: 0; top: 0;
  width: 4px; height: 100%;
  background: rgba(255, 255, 255, .1);
}
.progress-rail::after {
  content: "";
  display: block;
  width: 100%;
  height: calc(var(--progress) * 100%);
  background: var(--red);
}

/* ---------------------------------------------------- Kennzahlen */
/* Raster aus dem Entwurf, Werte aus velocity.v_kennzahl. */

/* Die Kennzahlen folgen demselben Muster wie Ablauf, Tarife und FAQ:
   Abschnittskopf, Haarlinie, Inhalt. Vorher hatten sie ein eigenes
   Zweispalten-Layout mit min-height 72vh und space-between - zwischen
   Zahl und Etikett klaffte dadurch ein Loch von dreihundert Pixeln,
   und der Abschnitt fiel aus dem Rhythmus der Seite. */
/* Unten weniger Luft: der naechste Abschnitt hat denselben Grund, die
   doppelte Luft las sich als 230 Pixel Leere statt als Abschnittswechsel.
   Wo die Farbe wechselt (Tarife, Fusszeile) bleibt es bei der vollen. */
.facts { padding: var(--luft) 0 calc(var(--luft) * .35); background: var(--paper); }

.stat-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0;
}
.stat {
  display: flex; flex-direction: column; gap: 10px;
  padding-left: clamp(22px, 2.6vw, 40px);
  border-left: 1px solid var(--mist);
}
.stat:first-child { padding-left: 0; border-left: 0; }
.stat b {
  color: var(--navy);
  font-family: var(--schmal);
  font-size: clamp(44px, 5vw, 78px);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -.06em;
}
.stat span {
  color: var(--grau-still);
  font: 700 11px/1.3 var(--mono);
  letter-spacing: .14em;
  text-transform: uppercase;
}

/* --------------------------------------------- Gemeinsame Teile */

.eyebrow {
  display: block;
  margin: 0 0 28px;
  color: rgba(6, 24, 65, .72);
  font: 750 var(--meta-font)/1.3 var(--mono);
  letter-spacing: .18em;
  text-transform: uppercase;
}

/* Der Kopf jedes Abschnitts: Vorspann und Titel links, der
   Lesehinweis rechts auf gleicher Grundlinie. */
.section-header {
  display: grid;
  grid-template-columns: 1.6fr 1fr;
  grid-template-areas: "vorspann hinweis" "titel hinweis";
  gap: 0 clamp(28px, 4vw, 72px);
  margin-bottom: clamp(40px, 4.6vw, 66px);
  padding-bottom: clamp(18px, 2vw, 28px);
  border-bottom: 1px solid var(--mist);
}
.section-header .eyebrow { grid-area: vorspann; margin-bottom: 20px; }
.section-header h2 {
  grid-area: titel;
  margin: 0;
  color: var(--navy);
  font-family: var(--schmal);
  font-size: var(--titel-font);
  line-height: .94;
  letter-spacing: -.055em;
}
/* Ein Kopf ohne Lesehinweis braucht die zweite Spalte nicht - sonst
   stuende die Ueberschrift auf zwei Dritteln und rechts bliebe Leere. */
.section-header.ohne-hinweis {
  grid-template-columns: 1fr;
  grid-template-areas: 'vorspann' 'titel';
}
.section-header p {
  grid-area: hinweis;
  align-self: end;
  margin: 0;
  color: var(--grau);
  line-height: 1.6;
}

.howto-section, .faq-section { padding: var(--luft) 0; background: var(--paper); }
.map-wrapper { padding: var(--luft) 0; background: #fff; }

.btn-primary, .btn-outline, .btn-end-rental {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  border-radius: 999px;
  font-weight: 700;
  font-size: var(--control-font);
  padding: 14px 24px;
  text-decoration: none;
  border: 1px solid transparent;
  transition: background .18s ease, color .18s ease, border-color .18s ease;
}
.btn-primary { background: var(--red); border-color: var(--red); color: #fff; }
.btn-primary:hover { background: var(--red-tief); border-color: var(--red-tief); }
.btn-outline { background: transparent; border-color: rgba(6, 24, 65, .3); color: var(--navy); }
.btn-outline:hover { background: var(--navy); border-color: var(--navy); color: #fff; }
.full-width { width: 100%; }

/* ---------------------------------------------------- So geht's */

.howto-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: clamp(26px, 3.2vw, 56px);
}
.howto-card {
  display: flex; flex-direction: column;
  padding-left: clamp(22px, 2.6vw, 40px);
  border-left: 1px solid var(--mist);
}
.howto-card:first-child { padding-left: 0; border-left: 0; }
/* Die Reihenfolge ist hier echte Information — anders als bei den
   Abschnitten der Seite, die keine Abfolge sind. */
/* Die Ziffer ist der Schrittzaehler und traegt dieselbe Schrift wie
   die Kennzahlen - nur in Rot, weil hier eine Abfolge gemeint ist und
   kein Messwert. Ein Sinnbild daneben stand frueher hier; auf
   Kachelgroesse blieb davon ein Fleck, der nichts erklaerte. */
.step-number {
  margin-bottom: 16px;
  font-family: var(--schmal); font-weight: 800; line-height: 1;
  font-size: clamp(42px, 4.6vw, 70px);
  color: var(--red);
  letter-spacing: -.06em;
}
.step-number::before { content: '0'; }
.howto-card h3 {
  margin: 0 0 12px;
  color: var(--navy);
  font-family: var(--schmal);
  font-weight: 800;
  font-size: clamp(21px, 1.8vw, 27px);
  line-height: 1.08;
  letter-spacing: -.035em;
}
.howto-card p { margin: 0; color: var(--grau); }

/* ------------------------------------------------------- Tarife */
/* Das einzige dunkle Band zwischen Bühne und Fusszeile. */

.pricing { padding: var(--luft) 0; background: var(--navy); color: #fff; }
.pricing .section-header { border-bottom-color: rgba(255, 255, 255, .2); }
.pricing .section-header h2 { color: #fff; }
.pricing .section-header p { color: rgba(255, 255, 255, .68); }
.pricing .eyebrow { color: rgba(255, 255, 255, .62); }

.pricing-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(268px, 1fr));
  gap: clamp(18px, 2vw, 26px);
}
.price-card {
  display: flex; flex-direction: column; justify-content: space-between;
  position: relative;
  background: var(--navy-2);
  border: 1px solid rgba(255, 255, 255, .16);
  border-radius: 2px;
  padding: 30px 26px 26px;
}
.price-card.popular {
  border-color: var(--red);
  background: #10306f;
  box-shadow: 0 24px 60px -28px rgba(0, 0, 0, .85);
}
.badge-pop {
  position: absolute; top: 0; right: 0;
  background: var(--red); color: #fff;
  font: 700 11px/1 var(--mono);
  letter-spacing: .14em; text-transform: uppercase;
  padding: 7px 13px;
}
.price-card .header {
  font-family: var(--schmal);
  font-size: clamp(24px, 2vw, 32px);
  font-weight: 800;
  color: #fff;
  letter-spacing: -.04em;
  margin-bottom: 8px;
}
.price-card .price {
  font-family: var(--schmal);
  font-size: clamp(30px, 2.6vw, 44px);
  font-weight: 800;
  color: #fff;
  letter-spacing: -.05em;
  margin-bottom: 22px;
}
.price-card .price small {
  font-family: var(--mono); font-size: 12px; font-weight: 400;
  color: rgba(255, 255, 255, .55); letter-spacing: .06em;
}
.features-list { list-style: none; padding: 0; margin: 0 0 26px; }
.features-list li {
  display: flex; align-items: center; gap: 11px;
  padding: 11px 0;
  border-top: 1px solid rgba(255, 255, 255, .13);
  color: rgba(255, 255, 255, .9);
  font-size: var(--body-font);
}
.features-list li:first-child { border-top: 0; }
.features-list i { color: var(--mint); font-size: .8rem; }
.pricing .btn-outline { color: #fff; border-color: rgba(255, 255, 255, .38); }
.pricing .btn-outline:hover { background: #fff; color: var(--navy); border-color: #fff; }

/* Preisrechner — er stand frueher als schmaler Kasten links ueber den
   drei Tarifkarten und liess zwei Drittel der Breite leer. Jetzt nimmt
   er dieselbe Spur wie die Karten darunter und liegt quer: Auswahl,
   Eingabe, Ergebnis. Die Haarlinien zwischen den Spalten sind dieselbe
   Sprache wie bei den Kennzahlen und beim Ablauf.

   Er rechnet mit denselben Regeln wie die Datenbank und schluesselt die
   Posten so auf, wie velocity.entgeltposition sie speichert. */
.tarif-zaehler { margin-bottom: clamp(26px, 3vw, 40px); }
.rechner {
  display: grid;
  grid-template-columns: minmax(272px, 1.05fr) minmax(196px, .82fr) minmax(250px, 1.1fr);
  background: #fff;
  color: var(--navy);
  border: 1px solid var(--mist);
  border-left: 3px solid var(--red);
  border-radius: 0 2px 2px 0;
  box-shadow: 0 20px 44px -30px rgba(0, 0, 0, .8);
}
.rechner-spalte {
  display: flex; flex-direction: column;
  gap: 12px;
  padding: 20px clamp(18px, 2vw, 26px);
  border-left: 1px solid var(--mist);
}
.rechner-spalte:first-child { border-left: 0; }
.rechner-marke {
  font: 700 10.5px/1.3 var(--mono);
  letter-spacing: .16em; text-transform: uppercase; color: var(--grau-still);
}
.rechner-typen { display: flex; gap: 5px; flex-wrap: wrap; }
.rechner-typen button {
  padding: 7px 11px;
  font-size: 12px; font-weight: 700;
  color: var(--grau-still);
  background: transparent;
  border: 1px solid var(--mist);
  border-radius: 999px;
  white-space: nowrap;
}
.rechner-typen button:hover { border-color: var(--navy); color: var(--navy); }
.rechner-typen button[aria-pressed="true"] {
  background: var(--navy); border-color: var(--navy); color: #fff;
}

.rechner-feld { display: flex; align-items: baseline; gap: 9px; }
.rechner-feld input {
  width: 104px;
  padding: 9px 12px;
  font-family: var(--mono); font-size: 19px; font-weight: 700;
  color: var(--navy);
  border: 1px solid var(--mist); border-radius: 2px;
  font-variant-numeric: tabular-nums;
}
.rechner-feld input:focus { border-color: var(--navy); outline: none; }
.rechner-feld span { font-size: 14px; color: var(--grau); }
.rechner-spalte input[type="range"] {
  width: 100%; margin: 0; accent-color: var(--red);
}
.rechner-spalte input[type="range"]:focus-visible { outline: 2px solid var(--navy); outline-offset: 4px; }

/* Vier Griffe fuer die Zeiten, die man wirklich eingibt. Der Regler
   deckt jetzt den vollen Bereich bis 1440 ab; ohne diese Marken waere
   eine Tagesmiete ein Millimeterspiel. */
/* Vier Griffe in zwei Reihen. Nebeneinander passen sie in die Spalte
   nicht - drei plus einer sah nach Umbruch aus, zwei mal zwei nach
   Absicht. */
.rechner-marken {
  display: grid; grid-template-columns: 1fr 1fr; gap: 6px;
  margin-top: 14px;
}
.rechner-marken button {
  padding: 8px 10px;
  background: transparent; color: var(--grau);
  border: 1px solid var(--mist); border-radius: 999px;
  font: 700 12.5px/1 var(--body-schrift);
}
.rechner-marken button:hover { border-color: var(--navy); color: var(--navy); }
.rechner-marken button[aria-pressed="true"] {
  background: var(--navy); border-color: var(--navy); color: #fff;
}
.rechner-grenze {
  margin: 10px 0 0;
  font: 600 12.5px/1.4 var(--body-schrift);
  color: var(--grau-still);
}
.rechner-grenze.ist-korrigiert { color: var(--red-tief); font-weight: 700; }

/* Die Ergebnisspalte traegt den Betrag oben und die Posten darunter,
   damit die Summe auf einer Hoehe mit der Eingabe steht. */
.rechner-summe { justify-content: space-between; gap: 10px; }
.rechner-ergebnis { display: flex; align-items: baseline; gap: 8px; }
.rechner-betrag {
  font-family: var(--schmal); font-weight: 800;
  font-size: clamp(38px, 3.6vw, 52px); line-height: 1;
  letter-spacing: -.055em;
  font-variant-numeric: tabular-nums;
}
.rechner-waehrung {
  font-family: var(--mono); font-size: .95rem; font-weight: 600; color: var(--red);
}
.rechner-posten { list-style: none; margin: 0; padding: 0; }
.rechner-posten li {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 14px;
  padding: 6px 0;
  border-top: 1px solid var(--mist);
  font-family: var(--mono); font-size: 11.5px; color: var(--grau);
}
.rechner-posten li b { color: var(--navy); font-variant-numeric: tabular-nums; }
.rechner-posten li.ist-abzug, .rechner-posten li.ist-abzug b { color: var(--red); }

/* -------------------------------------------------------- Karte */

/* Die Karte nutzt jetzt die volle Fensterbreite. Vorher stand sie in
   der Spur und liess links und rechts Platz liegen, obwohl sie das
   Element ist, das Flaeche wirklich braucht. */
.map-container-shadow {
  position: relative;
  overflow: hidden;
  border-block: 1px solid var(--mist);
}
#map { height: clamp(520px, 74vh, 820px); width: 100%; }

/* ---- Marker ---- */
/* Eine Station traegt eine Scheibe mit der Zahl der freien Raeder.
   Der Durchmesser kommt aus dem Skript und waechst mit der Wurzel. */
/* Die Trefferflaeche folgt der sichtbaren Scheibe. Ohne das faengt die
   Ecke des einen Markers die Mitte des naechsten ab. */
.marker-rund { clip-path: circle(50%); }

.karten-station {
  display: flex; align-items: center; justify-content: center;
  background: var(--navy);
  color: #fff;
  border: 2px solid #fff;
  border-radius: 999px;
  box-shadow: 0 6px 18px rgba(6, 24, 65, .38);
  font-family: var(--mono); font-weight: 700;
  font-size: 13px; line-height: 1;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: transform .14s ease;
}
.leaflet-marker-icon:hover .karten-station { transform: scale(1.08); }

/* Frei abgestellte Raeder. Die drei Typen unterscheiden sich durch die
   Farbe des Rings, nicht durch ein zweites Sinnbild darauf - das war
   auf Kartengroesse nicht zu erkennen. */
/* Kleiner als die Stationsscheiben: eine Station ist die wichtigere
   Information, ein einzeln abgestelltes Rad die Ausnahme. */
.karten-rad {
  display: flex; align-items: center; justify-content: center;
  width: 24px; height: 24px;
  background: #fff;
  border: 2px solid var(--navy);
  border-radius: 999px;
  color: var(--navy);
  font-size: 11px;
  box-shadow: 0 3px 10px rgba(6, 24, 65, .28);
}
.karten-rad.ist-ebike { border-color: var(--mint); color: #0f7a52; }
.karten-rad.ist-cargo { border-color: var(--red);  color: var(--red); }

/* ---- Popover ---- */
.leaflet-popup-content-wrapper {
  border-radius: 3px;
  box-shadow: 0 22px 60px rgba(6, 24, 65, .3);
}
.leaflet-popup-content { margin: 0; font-family: var(--body-schrift); }
.pop { width: 100%; }
.pop-kopf {
  padding: 16px 18px 14px;
  border-bottom: 1px solid var(--mist);
}
.pop-marke {
  display: block; margin-bottom: 5px;
  font: 700 10px/1 var(--mono);
  letter-spacing: .16em; text-transform: uppercase; color: var(--grau-still);
}
.pop-kopf strong {
  display: block;
  font-family: var(--schmal); font-weight: 800;
  font-size: 24px; line-height: 1.05; letter-spacing: -.035em;
  color: var(--navy);
}
.pop-adresse {
  display: block; margin-top: 5px;
  font-size: 12.5px; line-height: 1.45; color: var(--grau);
}
.pop-frei {
  display: block; margin-top: 7px;
  font: 700 11px/1 var(--mono);
  letter-spacing: .12em; text-transform: uppercase; color: var(--navy);
}

/* Wie hoch liegt die Station, und wie weit ist es von dort noch
   hinauf? Stand frueher in einer eigenen Grafik unter der Karte. */
.pop-hoehe {
  padding: 11px 18px;
  border-bottom: 1px solid var(--mist);
  background: var(--paper);
}
.pop-hoehe-kopf {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  margin: 0;
}
.pop-hoehe-wert {
  font-family: var(--schmal); font-weight: 800; font-size: 20px;
  letter-spacing: -.03em; color: var(--navy);
}
/* "180 m" allein liess offen, was gemeint ist. Die Beifuegung sagt es. */
.pop-hoehe-was {
  font: 700 10.5px/1.4 var(--mono);
  letter-spacing: .1em; text-transform: uppercase; color: var(--grau-still);
}
.pop-hoehe-rest {
  margin: 5px 0 0;
  font: 700 10.5px/1.5 var(--mono);
  letter-spacing: .1em; text-transform: uppercase; color: var(--grau-still);
}
.pop-hoehe-marke { color: var(--navy); }

.pop-typ {
  display: grid;
  grid-template-columns: 74px 1fr auto;
  align-items: center;
  gap: 13px;
  padding: 12px 18px;
  border-bottom: 1px solid var(--mist);
}
/* Die Raeder sind freigestellt: contain statt cover, damit das ganze
   Rad zu sehen ist und nicht ein Ausschnitt davon. Weisser Grund, weil
   die Freisteller auf Weiss stehen - so faellt keine Kante auf. */
.pop-bild {
  width: 74px; height: 48px;
  overflow: hidden; border-radius: 2px;
  background: #fff;
  display: flex; align-items: center; justify-content: center;
}
.pop-bild img { width: 100%; height: 100%; object-fit: contain; display: block; }
.pop-kein-bild { color: var(--grau-still); font-size: 17px; }
.pop-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pop-text strong {
  font-size: 15px; font-weight: 700; color: var(--navy); letter-spacing: -.01em;
}
.pop-zahl {
  font: 700 11px/1.2 var(--mono);
  letter-spacing: .1em; text-transform: uppercase; color: var(--red);
}
.pop-preis, .pop-akku { font-size: 12px; color: var(--grau); }
.pop-akku { font-weight: 700; }
.pop-leihen {
  padding: 10px 16px;
  background: var(--red); color: #fff;
  border: 0; border-radius: 999px;
  font-weight: 700; font-size: 13.5px;
  white-space: nowrap;
}
.pop-leihen:hover { background: var(--red-tief); }
.pop-leer { margin: 0; padding: 16px 18px; color: var(--grau); font-size: 13px; }
.pop-fuss {
  margin: 0; padding: 12px 18px 14px;
  font-size: 11.5px; line-height: 1.5; color: var(--grau-still);
  background: var(--paper);
}

.map-controls {
  position: absolute; top: 18px; left: 18px; z-index: 500;
  padding: 14px 16px;
  background: rgba(255, 255, 255, .96);
  border: 1px solid var(--mist);
  border-radius: 2px;
  box-shadow: 0 14px 34px rgba(6, 24, 65, .14);
}
.control-title {
  margin-bottom: 9px;
  font: 700 10.5px/1 var(--mono);
  letter-spacing: .16em; text-transform: uppercase; color: var(--grau-still);
}
.filter-option {
  display: flex; align-items: center; gap: 9px;
  padding: 3px 0; font-size: 14px; cursor: pointer; color: var(--navy);
}
.filter-option input { accent-color: var(--red); }
/* Zurueck aufs Geschaeftsgebiet. Es gab hier frueher eine Schaltflaeche
   "Meinen Standort anzeigen", die nur ein alert() ausloeste - eine
   Attrappe. Diese hier tut etwas, das man wirklich braucht. */
.karte-knoepfe {
  position: absolute; right: 18px; top: 18px; z-index: 500;
  display: flex; gap: 8px;
}
.karte-zurueck {
  position: relative;
  padding: 11px 17px;
  background: #fff; color: var(--navy);
  border: 1px solid var(--mist); border-radius: 999px;
  font-weight: 700; font-size: 13.5px;
  box-shadow: 0 14px 34px rgba(6, 24, 65, .16);
}
.karte-zurueck:hover { background: var(--navy); border-color: var(--navy); color: #fff; }

/* Die Filter aendern die Karte sichtbar. Diese Zeile sagt es auch denen,
   die sie nicht sehen - und den anderen schadet sie nicht. */
.karte-stand {
  margin: 18px auto 0;
  font: 600 13.5px/1.5 var(--body-schrift);
  color: var(--grau-still);
}

/* Kein Typ gewaehlt: die Karte ist leer und sagt, wie es weitergeht. */
.karte-leer {
  position: absolute; inset: 0; z-index: 600;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 12px; padding: 30px; text-align: center;
  background: rgba(243, 245, 248, .93);
  backdrop-filter: blur(2px);
}
.karte-leer[hidden] { display: none; }
.karte-leer strong {
  font-family: var(--schmal); font-size: clamp(26px, 3vw, 38px);
  font-weight: 800; letter-spacing: -.03em; color: var(--navy);
}
.karte-leer p { margin: 0; max-width: 42ch; color: var(--grau); }
.karte-leer button {
  margin-top: 6px; padding: 13px 22px;
  background: var(--navy); color: #fff;
  border: 1px solid var(--navy); border-radius: 999px; font-weight: 700;
}
.karte-leer button:hover { background: var(--red); border-color: var(--red); }

.karte-ort { margin-top: 4px; color: var(--grau); }

/* Solange ein Infofenster offen ist, treten die Bedienelemente ab -
   sonst verdecken sie auf schmalen Geraeten dessen Kopf. */
.map-container-shadow.hat-infofenster .map-controls,
.map-container-shadow.hat-infofenster .karte-knoepfe,
.map-container-shadow.hat-infofenster .karte-hinweis { opacity: 0; pointer-events: none; }
.map-controls, .karte-knoepfe { transition: opacity .18s ease; }

/* ------------------------------------------------- Stationsliste */
/* Der verlaessliche Weg zur richtigen Station. Auf der Karte liegen die
   Scheiben im Zentrum uebereinander; hier steht jede fuer sich. */
.stationsliste { margin-top: 26px; }
.stationsliste h3 {
  margin: 0 0 14px;
  font: 700 11px/1 var(--mono);
  letter-spacing: .16em; text-transform: uppercase; color: var(--grau-still);
}
.stationsliste ul {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 1px;
  background: var(--mist);
  border: 1px solid var(--mist);
}
.stationsliste li { background: #fff; }
.stationsliste button {
  display: grid; width: 100%;
  grid-template-columns: 46px 1fr auto;
  align-items: center; gap: 14px;
  padding: 13px 16px;
  background: none; border: 0; text-align: left;
}
.stationsliste button:hover { background: var(--paper); }
.sl-zahl {
  display: grid; place-items: center;
  width: 40px; height: 40px;
  border-radius: 50%;
  background: var(--navy); color: #fff;
  font-family: var(--mono); font-weight: 700; font-size: 15px;
  font-variant-numeric: tabular-nums;
}
.sl-zahl.ist-leer { background: var(--mist); color: var(--grau-still); }
.sl-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.sl-text strong { color: var(--navy); font-size: 15.5px; }
.sl-text small { color: var(--grau-still); font-size: 12.5px; }
.sl-frei {
  font: 700 10.5px/1 var(--mono);
  letter-spacing: .12em; text-transform: uppercase; color: var(--grau-still);
}

/* Solange das Mausrad gesperrt ist, sagt die Karte, wie man es freigibt.
   Nach dem ersten Klick verschwindet der Hinweis. */
.karte-hinweis {
  position: absolute; left: 50%; bottom: 20px; z-index: 500;
  transform: translateX(-50%);
  padding: 9px 16px;
  background: rgba(6, 24, 65, .88); color: #fff;
  border-radius: 999px;
  font: 700 11px/1 var(--mono);
  letter-spacing: .12em; text-transform: uppercase;
  pointer-events: none;
  transition: opacity .25s ease;
}
.karte-hinweis.ist-aus { opacity: 0; }
.map-legend {
  display: flex; flex-wrap: wrap; gap: 22px;
  margin-top: 20px;
  font-family: var(--mono); font-size: 11px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--grau-still);
}
.legend-item { display: flex; align-items: center; gap: 9px; }
/* Die Legende zeigt dieselben Symbole wie die Karte, nur kleiner. */
.legende-scheibe {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px;
  background: var(--navy); color: #fff;
  border: 2px solid #fff; border-radius: 999px;
  box-shadow: 0 3px 9px rgba(6, 24, 65, .3);
  font-family: var(--mono); font-weight: 700; font-size: 11px; letter-spacing: 0;
}
.legende-rad {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px;
  background: #fff; border: 2px solid var(--navy); border-radius: 999px;
  color: var(--navy); font-size: 11px;
}
.legende-rad.ist-ebike { border-color: var(--mint); color: #0f7a52; }
.legende-rad.ist-cargo { border-color: var(--red);  color: var(--red); }
.legende-hinweis { color: var(--grau-still); text-transform: none; letter-spacing: .02em; }
.leaflet-popup-content { font-family: var(--body-schrift); font-size: 14px; }
.leaflet-popup-content b { font-family: var(--schmal); font-size: 17px; letter-spacing: -.02em; }

/* ---------------------------------------------------------- FAQ */

/* Einspaltig. Zweispaltig hingen je zwei Fragen in derselben
   Rasterzeile: oeffnete man die eine, blieb neben der anderen eine
   tote Flaeche in Antworthoehe stehen. */
.faq-grid { display: block; }
.faq-grid details { border-bottom: 1px solid var(--mist); }
.faq-grid details:first-child { border-top: 1px solid var(--mist); }
/* Die Antwort laeuft nicht ueber die volle Breite - Fliesstext wird
   jenseits von etwa 75 Zeichen schlecht lesbar. */
.faq-content { max-width: 68ch; }
.faq-grid summary {
  cursor: pointer; list-style: none; position: relative;
  padding: 21px 36px 21px 0;
  font-family: var(--schmal);
  font-size: clamp(19px, 1.6vw, 25px);
  font-weight: 800;
  letter-spacing: -.03em;
  color: var(--navy);
}
.faq-grid summary::-webkit-details-marker { display: none; }
.faq-grid summary::after {
  content: '+'; position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  font-family: var(--mono); font-size: 1.4rem; color: var(--red); line-height: 1;
}
.faq-grid details[open] summary::after { content: '–'; }
.faq-content { padding: 0 36px 22px 0; color: var(--grau); }

/* ----------------------------------------------------- Fusszeile */

footer {
  padding: var(--luft) 0 40px;
  color: rgba(255, 255, 255, .72);
  background: var(--navy);
  border-top: 4px solid var(--red);
}
.footer-grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr;
  gap: clamp(32px, 4vw, 70px);
}
footer .logo { margin-bottom: 14px; }
/* Dieselbe Marke wie im Kopf, nur auf dunklem Grund: das Rot wird
   heller, sonst verschwindet es im Navy. */
.brand-fuss {
  display: inline-block;
  color: #fff;
  font-size: clamp(28px, 2.2vw, 38px);
}
.brand-fuss span { color: #ff5f80; }
/* Vorher 11 px bei 45 % Weiss - rund 4,3:1 und damit unter der Schwelle
   fuer normalen Text. Jetzt 13 px bei 72 %. */
.wortspiel {
  margin: 0 0 18px;
  font: 700 13px/1.3 var(--mono);
  letter-spacing: .2em; text-transform: uppercase;
  color: rgba(255, 255, 255, .72);
}
.fuss-text { color: rgba(255, 255, 255, .72); line-height: 1.6; }
footer h4 {
  margin: 0 0 16px;
  color: #fff;
  font: 700 11px/1 var(--mono);
  letter-spacing: .16em; text-transform: uppercase;
}
footer ul { list-style: none; padding: 0; margin: 0; }
footer li { margin-bottom: 9px; }
footer a { color: rgba(255, 255, 255, .72); text-decoration: none; }
footer a:hover { color: #fff; text-decoration: underline; }
.impressum-sub {
  margin-top: clamp(40px, 5vw, 70px);
  padding-top: 22px;
  border-top: 1px solid rgba(255, 255, 255, .14);
  font-size: 14px;
  color: rgba(255, 255, 255, .5);
}

/* --------------------------------------- Anmeldung und Ausleihe */

.modal-overlay {
  display: none;
  position: fixed; inset: 0; z-index: 1000;
  align-items: center; justify-content: center;
  padding: 24px;
  background: rgba(6, 24, 65, .55);
  backdrop-filter: blur(3px);
}
.modal-overlay.active { display: flex; }
.modal-content {
  position: relative;
  width: min(460px, 100%);
  padding: 34px 32px 32px;
  background: #fff;
  border-radius: 2px;
  box-shadow: 0 40px 90px rgba(0, 0, 0, .35);
}
.close-modal {
  position: absolute; top: 14px; right: 16px;
  border: 0; background: none;
  font-size: 28px; line-height: 1; color: var(--grau-still);
}
.auth-tabs { display: flex; gap: 6px; margin-bottom: 22px; }
.auth-tab {
  flex: 1;
  padding: 11px 0;
  text-align: center;
  border: 1px solid transparent;
  border-radius: 999px;
  font-weight: 700; font-size: 15px;
  color: var(--grau-still);
  background: var(--paper);
  cursor: pointer;
}
.auth-tab.active { background: var(--navy); color: #fff; }
.auth-form { display: none; }
.auth-form.active { display: block; }
.auth-form[hidden] { display: none; }

/* Das Ergebnis einer Anmeldung oder Registrierung. Es bleibt stehen -
   ein Toast war nach drei Sekunden weg, und genau deshalb sah eine
   erfolgreiche Registrierung wie ein Fehlschlag aus. */
.auth-status {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px;
  margin-bottom: 20px;
  padding: 14px 16px;
  border-left: 4px solid var(--grau-still);
  background: var(--paper);
  font-size: 14.5px; line-height: 1.5;
}
.auth-status[hidden] { display: none; }
.auth-status.ist-erfolg  { border-left-color: #0f9d63; background: rgba(15, 157, 99, .09); }
.auth-status.ist-fehler  { border-left-color: var(--red); background: rgba(240, 0, 56, .07); }
.auth-status.ist-hinweis { border-left-color: #c98a00; background: rgba(201, 138, 0, .09); }

.feld-mit-knopf { position: relative; display: flex; }
.feld-mit-knopf input { padding-right: 92px; }
.passwort-zeigen {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  padding: 7px 11px;
  background: var(--paper); color: var(--grau-still);
  border: 1px solid var(--mist); border-radius: 999px;
  font: 700 12px/1 var(--body-schrift);
}
.passwort-zeigen:hover { color: var(--navy); border-color: var(--navy); }

.auth-fuss {
  margin: 16px 0 0;
  font-size: 13.5px; color: var(--grau-still); text-align: center;
}
.auth-fuss a { color: var(--navy); }
.auth-link {
  padding: 0; border: 0; background: none;
  color: var(--navy); font-size: inherit; font-weight: 700;
  text-decoration: underline; text-underline-offset: 3px;
}
.auth-link:hover { color: var(--red); }
.modal-content button:disabled, .modal-content input:disabled { opacity: .55; cursor: progress; }
.form-title {
  margin: 0 0 22px;
  font-family: var(--schmal); font-size: 30px; font-weight: 800;
  letter-spacing: -.04em; color: var(--navy);
}
.form-group { margin-bottom: 16px; }
.form-group label {
  display: block; margin-bottom: 6px;
  font: 700 10.5px/1 var(--mono);
  letter-spacing: .14em; text-transform: uppercase; color: var(--grau-still);
}
.form-group input {
  width: 100%;
  padding: 13px 14px;
  border: 1px solid var(--mist);
  border-radius: 2px;
  background: #fff;
  color: var(--ink);
}
.form-group input:focus { border-color: var(--navy); outline: none; }

/* --------------------------------------------------- Kurzmeldungen */
/* Die Meldungen erscheinen oben rechts - dort steht auch der Login. Bei
   390 px ueberlappten sie ihn um 112 Punkte. Wer nach dem Abmelden
   sofort wieder auf "Login" tippte, traf drei Sekunden lang den Toast
   und hielt den Knopf fuer defekt. Genau so wurde es gemeldet:
   "zustandsabhaengig", mal ging es, mal nicht.

   Die Meldungen ruecken deshalb unter die Kopfzeile. !important ist
   noetig, weil Toastify die Lage inline setzt. */
.toastify { top: 108px !important; }
@media (max-width: 900px) { .toastify { top: 88px !important; } }
.toastify.toastify-bottom { top: auto !important; }

/* ------------------------------------------------------ Rueckgabe */

.modal-content.rueckgabe { width: min(520px, 100%); }
.rueckgabe-rad {
  margin: -14px 0 22px;
  font: 700 12.5px/1.4 var(--mono);
  letter-spacing: .1em; text-transform: uppercase; color: var(--grau-still);
}
.rueckgabe-wahl { display: grid; gap: 10px; margin-bottom: 22px; }
.rueckgabe-wahl label {
  display: grid; grid-template-columns: auto 1fr; gap: 13px; align-items: start;
  padding: 15px 17px;
  border: 1px solid var(--mist); border-radius: 2px;
  cursor: pointer;
}
.rueckgabe-wahl label:hover { border-color: var(--navy); }
.rueckgabe-wahl input { margin-top: 3px; accent-color: var(--red); }
.rueckgabe-wahl input:checked + span strong { color: var(--red); }
.rueckgabe-wahl label:has(input:checked) { border-color: var(--navy); background: var(--paper); }
.rueckgabe-wahl span { display: flex; flex-direction: column; gap: 3px; }
.rueckgabe-wahl strong { color: var(--navy); font-size: 15.5px; }
.rueckgabe-wahl small { color: var(--grau); font-size: 13.5px; line-height: 1.45; }

.rueckgabe-block { margin-bottom: 20px; }
.rueckgabe-block[hidden] { display: none; }
.rueckgabe-marke {
  display: block; margin-bottom: 7px;
  font: 700 10.5px/1 var(--mono);
  letter-spacing: .14em; text-transform: uppercase; color: var(--grau-still);
}
.rueckgabe-block select {
  width: 100%; padding: 13px 14px;
  border: 1px solid var(--mist); border-radius: 2px; background: #fff; color: var(--ink);
}
.rueckgabe-block select:focus { border-color: var(--navy); outline: none; }
.rueckgabe-ort {
  margin: 0 0 12px;
  font-family: var(--mono); font-size: 13px; color: var(--grau);
}
.rueckgabe-status {
  margin-bottom: 18px; padding: 13px 15px;
  border-left: 4px solid var(--grau-still); background: var(--paper);
  font-size: 14.5px; line-height: 1.5;
}
.rueckgabe-status[hidden] { display: none; }
.rueckgabe-status.ist-erfolg  { border-left-color: #0f9d63; background: rgba(15, 157, 99, .09); }
.rueckgabe-status.ist-fehler  { border-left-color: var(--red); background: rgba(240, 0, 56, .07); }
.rueckgabe-status.ist-hinweis { border-left-color: #c98a00; background: rgba(201, 138, 0, .09); }

/* Der Beleg. Er bleibt stehen, bis er geschlossen wird. */
.beleg { margin: 0 0 18px; }
.beleg div {
  display: flex; justify-content: space-between; gap: 18px;
  padding: 11px 0; border-bottom: 1px solid var(--mist);
}
.beleg dt { margin: 0; color: var(--grau-still); font-size: 14px; }
.beleg dd { margin: 0; color: var(--navy); font-weight: 700; text-align: right; }
.beleg div:last-child dd { font-size: 19px; }
.beleg-posten { list-style: none; margin: 0 0 24px; padding: 0; }
.beleg-posten li {
  display: flex; justify-content: space-between; gap: 18px;
  padding: 7px 0;
  font-size: 13.5px; color: var(--grau);
}
.beleg-posten b { color: var(--navy); font-variant-numeric: tabular-nums; }

.rental-preis {
  font-family: var(--mono); font-weight: 700;
  font-variant-numeric: tabular-nums; color: var(--mint);
}

.rental-banner {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 900;
  padding: 14px 0;
  background: var(--navy);
  color: #fff;
  border-top: 3px solid var(--mint);
}
.rental-banner-content {
  display: flex; align-items: center; justify-content: space-between;
  gap: 18px; flex-wrap: wrap;
}
.rental-info { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; font-size: 15px; }
.rental-timer { font-family: var(--mono); font-weight: 700; font-variant-numeric: tabular-nums; }
.btn-end-rental { background: #fff; color: var(--navy); border-color: #fff; }
.btn-end-rental:hover { background: var(--mint); border-color: var(--mint); color: var(--navy); }

/* ----------------------------------------------- Rechtstexte */
/* Vorher standen im Fuss vier Verweise auf href="#". Bei Registrierung,
   Standortdaten und Zahlung ist das kein Schoenheitsfehler. */

.seite-recht { background: #fff; }
.recht { padding: calc(92px + var(--luft)) 0 var(--luft); }
.recht-warnung {
  margin-bottom: clamp(40px, 5vw, 64px);
  padding: 20px 24px;
  border-left: 4px solid var(--red);
  background: rgba(240, 0, 56, .06);
  font-size: 15.5px; line-height: 1.6;
}
.recht-warnung strong { display: block; margin-bottom: 4px; color: var(--navy); }

.recht h1 {
  margin: 0;
  font-family: var(--schmal);
  font-size: var(--titel-font); font-weight: 800;
  letter-spacing: -.035em; line-height: .98; color: var(--navy);
}
.recht-inhalt {
  display: flex; flex-wrap: wrap; gap: 10px;
  margin: 34px 0 clamp(46px, 6vw, 78px);
  padding-bottom: 30px;
  border-bottom: 1px solid var(--mist);
}
.recht-inhalt a {
  padding: 9px 16px;
  color: var(--navy); text-decoration: none;
  border: 1px solid var(--mist); border-radius: 999px;
  font-weight: 700; font-size: 14.5px;
}
.recht-inhalt a:hover { border-color: var(--navy); background: var(--paper); }

.recht-block { max-width: 74ch; margin-bottom: clamp(50px, 6vw, 84px); }
.recht-block h2 {
  margin: 0 0 20px;
  font-family: var(--schmal);
  font-size: clamp(30px, 3.2vw, 46px); font-weight: 800;
  letter-spacing: -.03em; color: var(--navy);
}
.recht-block h3 {
  margin: 30px 0 8px;
  font: 700 11px/1 var(--mono);
  letter-spacing: .16em; text-transform: uppercase; color: var(--grau-still);
}
.recht-block p { margin: 0 0 14px; line-height: 1.65; }
.recht-liste { margin: 0; padding-left: 20px; }
.recht-liste li { margin-bottom: 12px; line-height: 1.6; }
.recht-hinweis { color: var(--grau-still); font-size: 14.5px; }
.recht-zurueck { margin-top: 20px; }
.recht-zurueck a { color: var(--navy); font-weight: 700; }

/* ------------------------------------------------------- Umbruch */

@media (max-width: 1100px) {
  .section-header {
    grid-template-columns: 1fr;
    grid-template-areas: "vorspann" "titel" "hinweis";
    gap: 14px 0;
  }
  .section-header p { align-self: start; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 1023px) {
  /* Bis hierher verschwand die Navigation ersatzlos. Jetzt tritt das
     Menue an ihre Stelle und die Karte bleibt als eigene Schaltflaeche
     stehen - sie ist der Weg, den mobile Besucher wirklich suchen. */
  .site-nav { display: none; }
  .kopf-karte { display: inline-block; }
  .menue-knopf { display: flex; }
}

@media (max-width: 620px) {
  /* Auf sehr schmalen Geraeten traegt der Kopf nur noch Marke, Login
     und Menue; die Karte steht dann im Menue. */
  .kopf-karte { display: none; }
}

/* Nur auf schmalen Geraeten. Auf dem Desktop traegt die Kopfzeile den
   Weg zur Karte und die Buehne braucht keinen zweiten Knopf. */
.hero-cta { display: none; }

/* ------------------------------------------------------------------
   MOBIL: die Buehne steht still

   Auf einem Telefon ist ein Fahrrad in ganzer Laenge ohnehin kaum zu
   erkennen - und eine Scroll-Inszenierung, die dreimal ein Rad
   durchschiebt, kostet dort nur Weg. Die Buehne wird deshalb zu einem
   Bild: ein Rad, eine Zeile, ein Aufruf. Gewechselt wird ueber die
   Pille, die dort ohnehin sichtbar ist.

   Technisch: die Schiene laeuft weiter (hero.js rechnet unveraendert),
   nur der Scrollfortschritt erreicht sie nicht mehr, weil die Buehne
   nicht mehr laenger ist als der Bildschirm.
   ------------------------------------------------------------------ */
@media (max-width: 900px) {
  .scroll-story { height: 100svh; min-height: 620px; }
  .sticky-stage { position: relative; height: 100svh; min-height: 620px; }
  .progress-rail { display: none; }

  /* Das Rad steht GANZ im Bild, nicht angeschnitten. Auf dem Desktop
     fuellt es den Rahmen (cover); auf einem hochkant stehenden Telefon
     bliebe davon ein zufaelliger Ausschnitt - Lenker und Kiste, kein
     Fahrrad. Hier also contain in einem eigenen Band.

     Die Zahlen kommen aus dem Bild: die Wand traegt ihre Bodenlinie bei
     88,7 Prozent der Bildhoehe, und unter dem Rad liegen im Bild noch
     11,3 Prozent Luft. Das Band sitzt so, dass beides zusammenfaellt -
     das Rad steht auf dem Boden der Wand, nicht daneben. */
  /* Auf dem Telefon steht die Schlagzeile UEBER dem Rad, nicht daneben.
     Ein Schleier von links stuetzt dort nichts - er bleicht nur das
     Hinterrad aus. Er laeuft deshalb von oben nach unten: hell, wo die
     Zeile steht, klar, wo das Rad steht. */
  .photo-shade {
    background:
      linear-gradient(180deg, rgba(247,249,252,.92) 0%, rgba(247,249,252,.88) 40%,
                              rgba(247,249,252,.50) 52%, transparent 58%),
      linear-gradient(0deg, rgba(6,24,65,.10) 0%, transparent 22%);
  }
  .photo-ebike, .photo-city, .photo-cargo {
    /* Das Band steht ZWISCHEN Schlagzeile und Aufruf, nicht darunter.
       Vorher lag es tiefer; der rote Knopf und die Pille schnitten dem
       Rad das Hinterrad ab, und in der Mitte klaffte leere Wand.

       115 Prozent statt "contain": die Vorlage ist breiter als das Rad,
       das darin steht - bei contain blieb links und rechts Leerraum, und
       auf dem Telefon war das Rad dadurch nur 300 Punkte breit. Bei 115
       Prozent misst es 345, das Lastenrad als breitestes 376 und bleibt
       damit innerhalb der 390. Mehr geht nicht, ohne es anzuschneiden.

       Der untere Rand ist so gewaehlt, dass die Reifen bei 680 Punkten
       aufsetzen - knapp ueber dem Aufruf. Die Wand steht auf dem Telefon
       ohnehin in einem anderen Massstab; das Rad steht deshalb nicht auf
       ihrer Bodenkante, sondern davor auf derselben Flaeche. Das liest
       sich als Tiefe, nicht als Fehler. */
    /* Auch hier ueber die HOEHE, nicht die Breite: die drei Bilder sind
       verschieden breit, und ein Prozentwert auf die Breite haette alle
       drei gleich breit gemacht - beim Wechsel waere das Lastenrad
       geschrumpft. 46vw ist die groesste Hoehe, bei der das breiteste
       der drei (das Lastenrad, Verhaeltnis 2,03) noch in die Seite
       passt. */
    inset: auto 0 20% 0;
    height: 30%;
    background-size: auto 46vw;
    background-position: center bottom;
    transform: none;
  }
  /* Die Auswahl steht sofort; ihren Fokuszustand regelt hero.js. Die
     Abschlusskarte entfaellt - ihren Platz nimmt der Aufruf in der
     Buehne ein. */
  .choice-panel { opacity: 1; transform: none; }
  .final-card { display: none; }
  .hero-cta {
    position: absolute;
    left: var(--rand);
    /* Ans untere Ende, dicht ueber die Pille. Zwischen Schlagzeile und
       Rad war kein Platz mehr, sobald eine Zeile fuenf statt vier
       Zeilen brauchte - der Aufruf schnitt sie dann an. */
    top: auto;
    bottom: 104px;
    z-index: 4;
    display: inline-flex; align-items: center; gap: 12px;
    padding: 15px 24px;
    background: var(--red); color: #fff;
    border-radius: 999px; text-decoration: none;
    font-weight: 800; font-size: 16px; letter-spacing: -.01em;
    box-shadow: 0 16px 40px rgba(240, 0, 56, .32);
  }
  .hero-cta:hover { background: var(--red-tief); }
  .hero-cta.ist-weg { opacity: 0; pointer-events: none; transform: translateY(10px); }
  .hero-cta { transition: opacity .3s ease, transform .3s ease; }
  .site-header { grid-template-columns: 1fr auto; min-height: 74px; }
  .site-nav { display: none; }
  /* Auf dem Telefon steht der Zaehler oben links fuer sich; die
     Kopplung an die Schlagzeile gilt dort nicht. */
  .top-meta { top: 100px; transform: none; }
  /* Die Laenge regelt jetzt die clamp-Formel weiter oben - hier keine
     zweite Stufe mehr, sonst kehrt der Sprung zurueck. */
  .claim { top: 27vh; bottom: auto; width: calc(100% - 48px); }
  .claim h1 { font-size: var(--hero-font); max-width: 100%; }
  /* Das City-Bike stand in kleinerer Schrift, weil sein Satz der laengste
   ist und in der schmalen Spalte sonst vierzeilig wurde. Mit der
   mitwachsenden Spalte braucht es den Notbehelf nicht mehr - alle drei
   Schlagzeilen stehen jetzt im selben Grad. */
  .choice-panel { grid-template-columns: 1fr; gap: 15px; bottom: 64px; right: 24px; }
  .product-copy { display: none; }
  .final-card { top: 128px; right: 20px; bottom: auto; width: min(360px, calc(100% - 40px)); }
  .scroll-hint { display: none; }
  /* Vier Zahlen nebeneinander werden hier zu eng: zwei mal zwei.
     Die Haarlinie sitzt dann nur noch zwischen den Spalten. */
  .stat-grid { grid-template-columns: 1fr 1fr; row-gap: clamp(28px, 4vw, 44px); }
  .stat:nth-child(odd) { padding-left: 0; border-left: 0; }
  .howto-card { padding-left: 0; border-left: 0; }
  .footer-grid { grid-template-columns: 1fr; gap: 28px; }
  #map { height: clamp(420px, 66vh, 600px); }
  .pop-typ { grid-template-columns: 62px 1fr auto; gap: 10px; padding: 11px 14px; }
  .pop-bild { width: 62px; height: 40px; }
}

@media (max-width: 620px) {
  /* Die Scheiben werden im Skript kleiner gezeichnet, nicht hier
     skaliert - eine CSS-Skalierung verkleinert das Bild, laesst die
     Trefferflaeche aber unveraendert und macht das Problem groesser. */
  .stationsliste button { grid-template-columns: 40px 1fr; gap: 12px; }
  .sl-frei { display: none; }
}

@media (max-width: 520px) {
  /* Die laengste Schlagzeile - die des Loaders - braucht fuenf Zeilen.
     Bei 52 px blieb dem Rad darunter kaum Platz; 45 px lesen sich auf
     einem Telefon genauso gut und geben eine ganze Zeile Raum zurueck. */
  /* Auf dem Telefon ist die Spalte durch die Fensterbreite gedeckelt,
     nicht durch den Schriftgrad - also muss hier der Schriftgrad
     folgen, sonst werden zwei der sechs Schlagzeilen dreizeilig.
     8,8 statt 8,2 als Teiler, weil 100vw den Rollbalken mitzaehlt und
     die Spalte in Wirklichkeit etwas schmaler ist. */
  :root { --hero-font: min(45px, calc((100vw - 2 * var(--rand)) / 8.8)); }

  /* "221 RÄDER FREI" brach hier in drei Zeilen um. Zwei bewusst
     gesetzte sind besser als drei zufaellige. */
  /* Auf dem Telefon steht alles in einer Spalte - dort bleibt die
     Zahl links, sonst haette die Seite zwei Fluchten. */
  .live-zahl { flex-direction: column; align-items: flex-start;
               justify-content: flex-start; gap: 2px; }
  .live-zahl b { padding-left: 22px; font-size: 42px; }
  .live-zahl b::before { top: .36em; }
  .live-zahl > span { font-size: 12.5px; letter-spacing: .12em; }
  /* Die Metazeile brach hier unruhig um. */
  .meta-lang { display: none; }
  .meta-kurz { display: inline; }
  .karte-knoepfe { right: 12px; top: 12px; flex-direction: column; }
  .recht-block h2 { font-size: 30px; }
  .claim { top: 25vh; }
  .claim-city { top: 29vh; }
  .choice-panel { bottom: 34px; }
  .product-tab { padding: 0 14px; }
  .stat-grid { grid-template-columns: 1fr; row-gap: 26px; }
  .stat { padding-left: 0; border-left: 0; padding-top: 20px; border-top: 1px solid var(--mist); }
  .stat:first-child { padding-top: 0; border-top: 0; }
  .rechner { grid-template-columns: 1fr; }
  .rechner-spalte { border-left: 0; border-top: 1px solid var(--mist); }
  .rechner-spalte:first-child { border-top: 0; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .scroll-story { height: 100vh; min-height: 720px; }
  .photo-city, .photo-cargo, .claim-city, .claim-cargo, .final-card { display: none; }
  .photo-ebike { opacity: 1; transform: none; }
  .scroll-hint span, .scroll-hint::after { animation: none; }
  .scroll-hint span { opacity: 1; transform: translateY(17px); }
  .claim-ebike { opacity: 1; transform: none; }
  .choice-panel { opacity: 1; transform: none; }
  .choice-panel { opacity: 1; transform: none; }
  .progress-rail, .scroll-hint { display: none; }
  * { transition: none !important; animation: none !important; }
}
