/* ============================================================
   Gemeinsame Basis der Auto-Apps von ManniMindset
   Tanken, Tempo, Parken (und was noch kommt: iq, oel)

   EINE Quelle fuer alles, was in allen Apps gleich aussieht. Vorher lag jeder
   Baustein dreimal vor: gemessen 738 von 2.406 CSS-Zeilen, rund 30 Prozent.
   Jede Aenderung musste dreimal gemacht werden, und genau dabei ist Parken
   auseinandergelaufen (Banner 4 px hoeher, einfarbig statt Verlauf, ohne
   Schimmer, Aktualisieren-Knopf grau statt blau).

   Eingebunden VOR der App-eigenen Datei:
     <link rel="stylesheet" href="/app/basis.css">
     <link rel="stylesheet" href="styles.css?v=N">
   Umgekehrt gewinnt die Basis und die App verliert ihre Eigenheiten.

   App-eigen bleibt: das Zeilenraster (.app grid-template-rows) und alles
   Fachliche (Preiszellen, Eingabefelder, Preisampel).

   FARBEN: App-eigene Farben bekommen app-eigene Namen, die hier nicht
   vorkommen. Muss doch einmal ein Token von hier ueberschrieben werden, dann
   ZWINGEND paarweise, also auch im eigenen @media (prefers-color-scheme: dark).
   @media erhoeht die Spezifitaet nicht: wer nur den Hellwert ueberschreibt, hat
   den Dunkelmodus kaputtgemacht und merkt es erst nachts im Auto.

   Kein ?v= noetig: /app/.htaccess schaltet das Caching in diesem Ordner ab,
   genau wie in den App-Ordnern. Eine Aenderung hier ist beim naechsten Start
   in allen Apps da.

   ------------------------------------------------------------
   02.08.2026: UMGESTELLT AUF DAS MANNIMINDSET-DESIGN (mm_design)
   ------------------------------------------------------------
   Aus PIG-Blau auf weissgrau wird Amber auf warmem Grund, aus der Systemschrift
   wird Manrope. Die KLASSENNAMEN bleiben alle, wie sie sind: eine App merkt von
   der Umstellung nur, dass sie anders aussieht.

   DREI Dinge, die man wissen muss, sonst baut man sich Unlesbares:

   1. --blau HEISST WEITER SO und zeigt jetzt auf Amber. Das ist bewusst: in den
      zwanzig App-eigenen styles.css steht var(--blau) rund hundertmal, und ein
      Umbenennen haette alle zwanzig gleichzeitig angefasst. Wer neu baut, nimmt
      --akzent. Wer alt anfasst, darf --blau stehen lassen.

   2. AUF AMBER GEHOERT DUNKLER TEXT, NIEMALS WEISSER. Weiss auf #FFB61E kommt
      auf 1,9:1 und ist damit unlesbar; Schwarzbraun kommt auf ueber 11:1.
      Dafuer gibt es --auf-akzent. Jedes color:#fff auf einer blauen Flaeche von
      frueher ist beim Umstellen ein Fehler und muss --auf-akzent werden.

   3. AMBER DARF IM HELLEN MODUS KEIN TEXT SEIN. #FFB61E auf Papierweiss ist
      1,6:1. Fuer Schrift, Rahmen und Zeichen gibt es deshalb --akzent-text: im
      Dunkeln ist das Amber, im Hellen das dunkle Goldbraun #8A5A00 (5,9:1).
      Faustregel: FLAECHE = --akzent, SCHRIFT = --akzent-text.

   Der helle Modus bleibt erhalten und folgt weiter dem Geraet. Diese Apps
   werden an der Zapfsaeule, am Strassenrand und im Sommer draussen benutzt, und
   dunkler Grund ist bei Sonne schlechter lesbar. Er ist nur nicht mehr
   blaugrau, sondern warmes Papier aus derselben Palette. Soll es ueberall
   dunkel sein, egal was das Geraet sagt, ist das genau ein Handgriff: den Block
   @media (prefers-color-scheme: light) loeschen.
   ============================================================ */

/* Die Schriften holt die Basis SELBST. Sonst haette in allen zwanzig
   index.html eine Zeile ergaenzt werden muessen, und die eine App, die man
   dabei vergisst, sieht dann als einzige falsch aus. Ein @import auf eine
   Datei im selben Ordner kostet einen Wimpernschlag und liegt danach im
   Zwischenspeicher.
   @import muss VOR jeder Regel stehen, Kommentare darueber sind erlaubt. */
@import url('schriften.css');

:root {
  /* Hoehe des fest stehenden Werbestreifens am unteren Rand. */
  --werbehoehe: 88px;

  /* ---- Die Palette aus mm_design. Nur hier stehen Zahlenwerte. ---- */
  --mm-ink-900:  #0B0A07;   /* Seitengrund */
  --mm-ink-800:  #12100B;   /* Sektion, Panel */
  --mm-ink-700:  #1A1710;   /* Karte, Eingabefeld */
  --mm-ink-600:  #241D10;   /* Linie, Trenner */
  --mm-ink-500:  #3A3122;   /* Rand aktiv, Umriss */
  --mm-amber-500:#FFB61E;   /* Primaerakzent */
  --mm-amber-600:#E09A0C;   /* gedrueckt */
  --mm-amber-300:#FFD277;   /* Zeichen und Links auf dunkel */
  --mm-amber-ink:#8A5A00;   /* Amber-Ersatz, sobald Amber SCHRIFT sein soll */
  --mm-orange-500:#FF6B1A;  /* Zweitsignal, hoechstens einmal je Bildschirm */
  --mm-blue-500: #2E5BFF;   /* Auskunft, Kachelfarbe */
  --mm-cream-50: #FBF6EC;
  --mm-cream-200:#DED3BE;
  --mm-stone-300:#B3A68D;
  --mm-stone-400:#9B8E76;
  --mm-stone-600:#6A604F;
  --mm-success:  #3FC98A;
  --mm-danger:   #FF5A4D;
  --mm-paper-0:  #FFFFFF;
  --mm-paper-50: #FAF7F0;
  --mm-paper-200:#E6DFD2;
  --mm-paper-300:#D8CFBD;
  --mm-paper-500:#8A7E68;

  /* ---- DER ALTE STAND. Gilt fuer jede App, die noch nicht umgestellt ist.
     ----
     Die Umstellung laeuft in Wellen, und eine gemeinsame Datei wuerde sonst
     alle zwanzig Apps auf einmal umwerfen. In den App-eigenen Stilblaettern
     stehen 98 Stellen mit color:#fff, viele davon auf einer Flaeche in
     var(--blau). Auf Blau ist das richtig, auf Amber waere es 1,9:1 und damit
     unlesbar. Und weil jede App ihren eigenen Offline-Vorrat mitbringt, bliebe
     so ein Fehler wochenlang auf den Geraeten stehen.

     Umgeschaltet wird deshalb einzeln: Die App setzt data-mm an ihr
     html-Element, und erst dann gelten die Werte weiter unten. Eine Zeile je
     App, und sie faellt beim Umstellen ohnehin an. */
  --akzent:      #0091c8;
  --akzent-satt: #007099;
  --akzent-text: #0091c8;
  --auf-akzent:  #ffffff;
  --blau:        var(--akzent);   /* alter Name, siehe Kopf */
  --gruen:       #17864a;

  --bg:     #f4f5f7;
  --karte:  #ffffff;
  --text:   #10131a;
  --leise:  #5b6472;
  --linie:  #d9dde4;
  --gedimmt:#8a93a1;

  /* Warnfarbe fuer veraltete Staende. Bewusst eigener Name statt --rot: jede App
     darf ihn auf ihre Skala legen (Tanken auf --rot, Parken auf --p4), ohne dass
     die Basis etwas davon wissen muss. */
  --warn:     #c02626;
  --auf-warn: #ffffff;

  --schrift:      -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --schrift-zahl: ui-monospace, monospace;
  --mm-ease:      cubic-bezier(.2, .7, .2, 1);
}

@media (prefers-color-scheme: dark) {
  :root {
    --gruen:  #3ddc84;
    --bg:     #0b0d10;
    --karte:  #171b21;
    --text:   #f2f4f7;
    --leise:  #98a2b3;
    --linie:  #2a3038;
    --gedimmt:#6b7480;
    /* Im Dunkeln ein helles Lachsrot, darauf ist Weiss unlesbar (2,76:1),
       deshalb wandert die Schriftfarbe mit. */
    --warn:     #ff6b6b;
    --auf-warn: #10131a;
  }
}

/* ============================================================
   AB HIER DAS MANNIMINDSET-DESIGN, nur fuer Apps mit data-mm am html.
   Einschalten in der index.html:  <html lang="de" data-mm>
   ============================================================ */

:root[data-mm] {
  --akzent:      var(--mm-amber-500);   /* FLAECHEN */
  --akzent-satt: var(--mm-amber-600);   /* dieselbe Flaeche gedrueckt */
  --akzent-text: var(--mm-amber-500);   /* SCHRIFT, Rahmen, Zeichen */
  --auf-akzent:  var(--mm-ink-900);     /* was auf einer Akzentflaeche steht */
  --gruen:       var(--mm-success);

  --bg:     var(--mm-ink-900);
  --karte:  var(--mm-ink-700);
  --text:   var(--mm-cream-50);
  --leise:  var(--mm-stone-300);
  --linie:  var(--mm-ink-600);
  --gedimmt:var(--mm-stone-400);

  --warn:     var(--mm-danger);
  --auf-warn: var(--mm-ink-900);

  --schrift:      'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --schrift-zahl: 'IBM Plex Mono', ui-monospace, monospace;
}

/* Heller Modus. Warmes Papier statt kaltem Blaugrau, und Amber wird als
   SCHRIFT zu Goldbraun. Die Flaechen bleiben Amber, dort steht ohnehin dunkler
   Text (siehe --auf-akzent). */
@media (prefers-color-scheme: light) {
  :root[data-mm] {
    --akzent-text: var(--mm-amber-ink);

    --bg:     var(--mm-paper-50);
    --karte:  var(--mm-paper-0);
    --text:   #12100B;
    --leise:  #5C5344;
    --linie:  var(--mm-paper-200);
    --gedimmt:var(--mm-paper-500);

    /* Auf Papier ist das helle Lachsrot zu blass, hier ein satteres Rot mit
       weisser Schrift darauf. */
    --warn:     #C0362B;
    --auf-warn: #FFFFFF;
    /* Und Gruen dunkler, sonst leuchtet es auf Weiss ohne lesbar zu sein. */
    --gruen:    #1F8F5F;
  }
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;
  background: var(--bg);
  color: var(--text);
  /* Manrope kommt aus /app/schriften.css, das VOR dieser Datei eingebunden
     wird. Die Systemschriften bleiben als Rueckfall dahinter stehen: solange
     die eigene Schrift noch laedt (font-display: swap) oder wenn sie fehlt,
     ist der Text trotzdem lesbar. */
  font-family: var(--schrift);
  font-variant-numeric: tabular-nums;   /* Ziffern springen sonst beim Aktualisieren */
  -webkit-text-size-adjust: 100%;
}

/* Das Grundraster. Die ZEILEN setzt jede App selbst, sie hat unterschiedlich
   viele Kinder. Alles andere ist gleich. */
.app {
  display: grid;
  /* minmax(0, 1fr) statt einfach 1fr: sonst wird die Spalte so breit wie ihr
     breitester Inhalt und sprengt schmale Bildschirme. */
  grid-template-columns: minmax(0, 1fr);
  gap: 5px;
  /* HOEHE, teuer gelernt (Manni, 01.08.2026: "auf dem Handy hoert es
     ploetzlich auf, bitte den Platz komplett ausnutzen").
     -webkit-fill-available stand hier als Ruecksicht auf alte iOS-Fassungen,
     die dvh noch nicht kannten. Genau diese Zeile hat aber auf neueren
     iPhones gewonnen und eine ZU KLEINE Hoehe geliefert: unten blieb ein
     totes Feld stehen. Jetzt gilt dvh, wo es verstanden wird, und die alte
     Ruecksicht nur noch dort, wo es das wirklich braucht. */
  height: 100vh;
  /* Unten knapper als oben: die Bedienleiste sitzt dicht am Rand, damit die
     Liste eine Karte mehr fasst. */
  /* Unten das Mass des fest stehenden Werbestreifens, sonst laege er auf dem
     Inhalt. --werbehoehe steht in :root und wird auf kleinen Geraeten kleiner. */
  padding: calc(env(safe-area-inset-top) + 5px) 8px calc(env(safe-area-inset-bottom) + 6px + var(--werbehoehe, 88px));
}
/* Wo dvh verstanden wird, gilt dvh: das ist die einzige Angabe, die die
   ein- und ausfahrende Leiste des Handybrowsers richtig mitrechnet. */
@supports (height: 100dvh) {
  .app { height: 100dvh; }
}
@supports not (height: 100dvh) {
  .app { height: -webkit-fill-available; }
}


/* ---------- Band fuer den Pruefmodus ---------- */

.probe-band {
  position: fixed;
  top: 8px;
  left: 0;
  right: 0;
  z-index: 60;
  padding: 5px 8px;
  background: var(--mm-danger);
  color: var(--mm-ink-900);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: .4px;
  text-align: center;
}

/* ---------- Ladebalken ---------- */

/* Ganz oben und dick genug, um im Augenwinkel aufzufallen, ohne dass man den
   Blick von der Strasse nehmen muss. */
.fortschritt {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 8px;
  background: var(--linie);
  z-index: 50;
  opacity: 1;
  transition: opacity .25s ease;
}
.fortschritt.weg { opacity: 0; }

.balken {
  height: 100%;
  width: 0;
  background: var(--akzent);
  transition: width .3s ease;
}

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

   ZWEI Zeilen: oben welche App das hier ist, darunter der Weg zu den anderen.
   Vorher stand alles nebeneinander, und bei zwei Pillen blieben dem Namen 102
   von 173 noetigen Pixeln: aus "Parken by ManniMindset" wurde "Parken by ...".
   Die eigene Marke abzuschneiden ist das Gegenteil von dem, was sie soll. */

.kopf {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 5px;
  padding: 0 2px;
  min-width: 0;
}

/* Zeile 1: das ist diese App. */
.kopf-ich {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 36px;
  min-width: 0;
}
.kopf-zeichen { height: 38px; width: auto; flex: none; display: block; }
/* Name und Zweck untereinander. Beides zusammen bleibt niedriger als das
   Zeichen daneben, die Zeile wird dadurch keinen Pixel hoeher. */
.kopf-text { display: flex; flex-direction: column; justify-content: center; min-width: 0; }
.kopf-name {
  font-size: 15px;
  font-weight: 800;
  letter-spacing: .2px;
  color: var(--leise);
  white-space: nowrap;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* SCHRIFT, also --akzent-text und nicht --akzent: im hellen Modus waere Amber
   auf Papierweiss 1,6:1 und damit unlesbar. */
.kopf-name b { color: var(--akzent-text); margin-left: 5px; font-size: 13px; }
/* Die Fassungsnummer. Sie MUSS sichtbar sein, sonst laesst sich nie sagen,
   ob eine Aenderung auf dem Geraet angekommen ist (genau das hat bei der
   Fehlersuche in der Vorleser-App tagelang gefehlt). Sie darf aber nichts
   vom Namen wegnehmen: eigene Farbe, kleiner Satz, keine eigene Zeile. */
.kopf-fassung {
  margin-left: 6px;
  padding: 1px 5px;
  border-radius: 6px;
  background: var(--karte);
  color: var(--gedimmt);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .3px;
  vertical-align: 1px;
}
/* Wofuer ist diese App gut? Ein Satz, der beim ersten Mal erklaert und danach
   nicht stoert, weil er leise gesetzt ist. */
.kopf-was {
  margin-top: 1px;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--gedimmt);
  white-space: nowrap;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Zeile 2: EIN Weg zu allen anderen Apps, nicht je eine Pille.
   Frueher stand hier je ein Sprung in jede andere App. Mit drei Apps ging das
   noch, mit fuenf nicht mehr, und bei jeder neuen App haette jede andere
   angefasst werden muessen. Jetzt fuehrt ein Knopf auf die Uebersicht /apps.
   Ein Tipp mehr zum Ziel, dafuer sieht man beim Wechseln die Werbeflaeche, die
   diese Apps kostenlos haelt (Manni, 30.07.2026). */
.app-wechsel {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 34px;
  padding: 2px 10px;
  border-radius: 999px;
  background: var(--karte);
  border: 2px solid var(--akzent-text);
  color: var(--akzent-text);
  font-size: 14px;
  font-weight: 800;
  text-decoration: none;
  white-space: nowrap;
}
.aw-zeichen { flex: none; display: flex; align-items: center; gap: 4px; }
.aw-zeichen img { height: 22px; width: auto; display: block; }
.aw-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.aw-pfeil { flex: none; font-size: 20px; font-weight: 700; line-height: 1; }

/* Sehr schmale Geraete: das Wort "wechseln" reicht, die Zeichen tragen den Rest. */
@media (max-width: 340px) {
  .app-wechsel { font-size: 13px; gap: 6px; }
  .aw-zeichen img { height: 20px; }
}

/* ---------- Formensprache ----------
   Eine App im Auto braucht eine klare Trennung: Was bedient wird, sieht anders
   aus als was informiert.

   Umschalter   = zusammenhaengende Leiste mit gleitendem Markierer
   Kippschalter = Schalter rechts, Beschriftung links
   Karte        = flach, ohne Rahmen, mit rundem Anfasser
   Aktion       = vollflaechig gefuellt
*/

/* Druckrueckmeldung fuer ALLES, was auf einen Tipp reagiert. Wichtigste einzelne
   Massnahme: die Hand bekommt sofort Antwort, lange bevor Daten da sind.

   touch-action: manipulation schaltet den Doppeltipp-Zoom ab. Ohne das zoomt das
   Handy, sobald man einen Plus-Knopf schnell zweimal antippt, und genau das
   passiert beim Einstellen einer Geschwindigkeit staendig. Das viewport-Attribut
   maximum-scale=1 hilft nicht: iOS Safari ignoriert es seit iOS 10 bewusst.
   Das Zoomen mit zwei Fingern bleibt erlaubt, nur der Doppeltipp faellt weg. */
.segment, .kippzeile, .karte, .knopf, .werbe-banner, .app-wechsel,
.d-los, .d-stopp, .ziel-eintrag, .gruss-weiter, .knopf-voll,
.zbtn, .chip, .fbtn {
  transition: transform .08s ease, filter .08s ease, background-color .15s ease;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
}
.segment:active, .kippzeile:active, .karte:active, .knopf:active,
.werbe-banner:active, .app-wechsel:active, .d-los:active, .d-stopp:active,
.ziel-eintrag:active, .zbtn:active, .chip:active, .fbtn:active {
  transform: scale(.97);
  filter: brightness(1.18);
}

/* ---------- Umschalter ---------- */

.umschalter {
  position: relative;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  padding: 5px;
  border-radius: 16px;
  background: var(--karte);
  border: 2px solid var(--linie);
  /* Innenschatten macht die Leiste als Rinne lesbar, in der etwas gleitet */
  box-shadow: inset 0 2px 5px rgba(0, 0, 0, .18);
}

/* Der gleitende Markierer. Breite aus der Segmentzahl, verschoben per transform,
   deshalb ohne Nachmessen im Programm. */
.markierer {
  position: absolute;
  top: 5px;
  bottom: 5px;
  left: 5px;
  width: calc((100% - 10px) / 3);
  border-radius: 12px;
  background: var(--akzent);
  box-shadow: 0 2px 8px rgba(255, 182, 30, .40);
  transition: transform .25s cubic-bezier(.4, 0, .2, 1);
  pointer-events: none;
}
.markierer.zwei { width: calc((100% - 10px) / 2); }
.markierer.drei { width: calc((100% - 10px) / 3); }
.markierer.vier { width: calc((100% - 10px) / 4); }
.markierer.fuenf { width: calc((100% - 10px) / 5); }

.segment {
  position: relative;
  z-index: 1;
  min-height: 50px;
  border: 0;
  background: transparent;
  color: var(--leise);
  font-size: 22px;
  font-weight: 700;
  font-family: inherit;
  letter-spacing: .3px;
  cursor: pointer;
  white-space: nowrap;
}
/* Das gewaehlte Segment sitzt auf dem Amber-Markierer, deshalb DUNKLE Schrift.
   Weiss stand hier frueher und war auf Blau richtig; auf Amber waere es 1,9:1. */
.segment[aria-pressed="true"] { color: var(--auf-akzent); font-weight: 800; }

/* Die haeufigste Wahl bekommt die groesste Flaeche, die seltenere weniger. */
.umschalter.gross .segment { min-height: 52px; font-size: 22px; }
.umschalter:not(.gross) .segment { min-height: 42px; font-size: 18px; }

/* Zusatzzeile unter einem Umschalter, passt in kein Segment */
.sort-zusatz {
  min-height: 17px;
  padding: 0 6px;
  font-size: 13px;
  font-weight: 600;
  color: var(--leise);
  text-align: center;
}

/* ---------- Kippschalter ---------- */

.kippzeile {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 48px;
  padding: 0 14px;
  border: 2px solid var(--linie);
  border-radius: 14px;
  background: var(--karte);
  color: var(--text);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}
.kz-text { display: flex; flex-direction: column; min-width: 0; }
.kz-titel { font-size: 17px; font-weight: 700; white-space: nowrap; }
.kz-unter { font-size: 13px; color: var(--leise); white-space: nowrap; }

/* Die Kippe selbst: das einzige Bedienelement, das jeder sofort erkennt. */
.kippe {
  position: relative;
  flex: none;
  width: 60px;
  height: 34px;
  border-radius: 999px;
  background: var(--gedimmt);
  transition: background-color .2s ease;
}
.kippe-knopf {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--mm-cream-50);
  box-shadow: 0 2px 5px rgba(0, 0, 0, .35);
  transition: transform .2s cubic-bezier(.4, 0, .2, 1);
}
.kippzeile[aria-checked="true"] .kippe { background: var(--akzent); }
.kippzeile[aria-checked="true"] .kippe-knopf { transform: translateX(26px); }

/* ---------- Liste und Karten ---------- */

/* Nur diese Liste scrollt, die Seite selbst nie. So bleiben Bedienleiste und
   Kopfzeile immer an ihrem Platz. */
.listenraum { position: relative; min-height: 0; }
.liste {
  display: grid;
  grid-auto-rows: max-content;
  gap: 5px;
  overflow-y: auto;
  min-height: 0;
  padding-right: 2px;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}

/* Eine Karte je Treffer: Information, kein Knopf. Deshalb kein kraeftiger
   Rahmen, sondern eine flache Flaeche. */
.karte {
  border-radius: 14px;
  background: var(--karte);
  border: 1px solid transparent;
  border-left: 4px solid transparent;
  overflow: hidden;
  cursor: pointer;
}
.karte.auf { border-color: var(--akzent-text); border-left-color: var(--akzent-text); }

.hero-meldung {
  align-self: center;
  font-size: 26px;
  line-height: 1.35;
  text-align: center;
  color: var(--leise);
  padding: 10px;
}
.hero-meldung strong { color: var(--text); }

/* ---------- Knoepfe ---------- */

/* Voll ausgefuellt in Amber, wie das aktive Segment oben.
   Doppelte Klasse, weil die Grundregel .knopf darunter steht und den Hintergrund
   sonst wieder ueberschreibt. */
.knopf.knopf-breit {
  width: 100%;
  background: var(--akzent);
  border-color: var(--akzent);
  color: var(--auf-akzent);
  font-size: 24px;
  font-weight: 800;
}
.knopf.knopf-breit:disabled { opacity: .55; }

.knopf {
  min-height: 54px;
  border: 2px solid var(--linie);
  border-radius: 14px;
  background: var(--karte);
  color: var(--text);
  font-size: 21px;
  font-weight: 700;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 0 6px;
  overflow: hidden;
  /* Ohne das bricht ein laengerer Text wie "Aktualisieren" mitten im Knopf um. */
  white-space: nowrap;
}
.knopf span { white-space: nowrap; }
.knopf:disabled { opacity: .5; }
.knopf.hinweis { background: var(--akzent); border-color: var(--akzent); color: var(--auf-akzent); }
.knopf-icon { font-size: 28px; }
.knopf-voll { width: 100%; background: var(--akzent); border-color: var(--akzent); color: var(--auf-akzent); }
/* Gedrueckt wird die Flaeche satter statt heller: brightness(1.18) auf Amber
   laesst sie ins Weissliche kippen und die dunkle Schrift darauf flimmern. */
.knopf.knopf-breit:active, .knopf.hinweis:active, .knopf-voll:active,
.d-los:active { background: var(--akzent-satt); filter: none; }

/* Zweizeilige Beschriftung: oben die Handlung, darunter der Datenstand. Er
   beantwortet genau die Frage, die man sich vor dem Tippen stellt: muss ich
   ueberhaupt neu laden? */
.knopf-text {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  line-height: 1.1;
  min-width: 0;
}
/* Eigenes Feld auf dem Knopf, nicht bloss hellere Schrift. Frueher eine dunkle
   Auflage mit weisser Schrift, weil Weiss auf PIG-Blau nur 3,57:1 erreichte.
   Auf Amber ist es genau andersherum: die Flaeche ist hell, also bleibt die
   Schrift dunkel und die Auflage wird nur leicht abgesetzt. */
.btn-stand {
  margin-top: 1px;
  padding: 1px 8px;
  border-radius: 999px;
  background: rgba(11, 10, 7, .14);
  color: var(--auf-akzent);
  font-size: 13px;
  font-weight: 700;
}
/* Ehrlich bleiben: ein alter Stand wird als alter Stand gekennzeichnet. */
.btn-stand.warn { background: var(--warn); color: var(--auf-warn); }
/* Leer heisst: noch nie geladen. Dann soll die Zeile keinen Platz kosten. */
.btn-stand:empty { display: none; }

/* Der eine Knopf zum Losfahren, in der aufgeklappten Karte. Steht hier in der
   Basis, weil er in Tanken und Parken dasselbe tut und deshalb auch gleich
   aussehen muss (Manni, 30.07.2026): vorher war er hier 54 px hoch mit dem
   Maps-Zeichen, dort 46 px mit einem Pfeil aus der Schriftart.
   Das rot-weisse Zeichen sagt ohne Lesen, wohin der Tipp fuehrt. */
.d-los {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  margin: 8px 12px 12px;
  min-height: 54px;
  border-radius: 12px;
  background: var(--akzent);
  color: var(--auf-akzent);
  font-size: 19px;
  font-weight: 800;
  text-decoration: none;
}
.d-los-pin { flex: none; }

/* ---------- Werbebanner ---------- */

.werbe-banner {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 38px;
  border-radius: 14px;
  text-decoration: none;
  /* Dunkle Schrift, die Flaeche ist jetzt hell. */
  color: var(--auf-akzent);
  font-size: 19px;
  font-weight: 800;
  letter-spacing: .6px;
  background: linear-gradient(100deg, var(--mm-amber-500) 0%, var(--mm-amber-300) 45%, var(--mm-orange-500) 100%);
  box-shadow: 0 3px 14px rgba(255, 182, 30, .30);
}
/* Laufender Lichtstreifen, gleiche Handschrift wie die Werbeflaeche auf der
   Empfehlungsseite. Bewusst nur hier: in einer Auto-App darf sich sonst nichts
   von selbst bewegen, das lenkt ab. Dieses eine Feld ist Werbung und darf. */
.werbe-banner::before {
  content: '';
  position: absolute;
  top: -60%;
  left: -60%;
  width: 45%;
  height: 220%;
  background: linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(255,255,255,.45) 50%, rgba(255,255,255,0) 100%);
  transform: rotate(18deg);
  animation: wbGlanz 3.6s ease-in-out infinite;
  pointer-events: none;
}
@keyframes wbGlanz {
  0%   { left: -60%; }
  55%  { left: 130%; }
  100% { left: 130%; }
}
.werbe-banner > * { position: relative; z-index: 1; }
.wb-funke { font-size: 18px; }
.wb-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.wb-pfeil { font-size: 25px; font-weight: 700; }

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

.fuss {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 10px;
  padding: 0 4px;
  margin-top: 2px;
  font-size: 13px;
  color: var(--leise);
}
.fuss .quelle { text-align: center; }
.fuss .quelle a { color: var(--leise); text-decoration: underline; }

/* ---------- Begruessung ---------- */

/* z-index MUSS sein: ohne ihn ist die Huelle zwar das letzte Element im
   Dokument, verliert aber gegen jedes positionierte Element mit z-index 1.
   Genau das war der Fall, Bedienknoepfe schienen durch die Verdunkelung
   (.segment und die Bannerinhalte tragen z-index 1). 100 liegt sicher ueber
   Ladebalken (50) und Pruefband (60). */
.huelle {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: rgba(11, 10, 7, .82);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.huelle.hidden { display: none; }
/* Allgemein nutzbar: alle Apps blenden etwas damit aus (Pruefband, Hinweiszeile,
   Begruessung). Stand vorher in jeder App einzeln. */
.hidden { display: none; }

.kasten {
  background: var(--karte);
  border: 1px solid var(--linie);
  border-radius: 18px;
  padding: 24px;
  max-width: 420px;
}
/* Das App-Logo im Gruss. Weisse Platte, weil die Wortmarke eine weisse Flaeche
   mitbringt und die Schrift dunkelblau ist: ohne Platte waere sie im
   Dunkelmodus nicht lesbar. */
.gruss-logo {
  background: #fff;
  border-radius: 12px;
  padding: 10px 12px;
  margin: 0 0 14px;
}
.gruss-logo img { width: 100%; height: auto; display: block; }
.kasten h2 { margin: 0 0 10px; font-size: 30px; }
.kasten p  { margin: 0 0 14px; font-size: 19px; line-height: 1.45; }
.kasten .spruch { font-size: 22px; font-weight: 700; line-height: 1.35; }
.kasten .klein { font-size: 16px; color: var(--leise); }

/* Zwei Knoepfe: weiterblaettern oder loslegen. */
.gruss-knoepfe { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.gruss-weiter { background: transparent; border-color: var(--linie); color: var(--leise); font-size: 17px; }

/* ---------- Das Blatt ----------

   Ein Fenster, das von unten hereinfaehrt und die Einzelheiten zu einem
   Listeneintrag traegt. Es loest das Aufklappen IN der Liste ab, und zwar aus
   einem gemessenen Grund (Manni, 30.07.2026):

   Auf einem iPhone SE ist das Listenfenster der Park-App 79 px hoch. Eine
   aufgeklappte Karte braucht 254 bis 326 px. Der Knopf "Route über Google Maps"
   sass damit rund 162 px unterhalb der Kartenoberkante, also weit ausserhalb des
   sichtbaren Bereichs. Man musste scrollen, um ihn zu erreichen, und eine
   Scroll-Wache schloss die Karte nach 28 px wieder. Der Knopf war unerreichbar.

   Der Kniff ist nicht das Fenster an sich, sondern seine DREITEILUNG: Kopf und
   Fuss stehen fest, nur der Rumpf scrollt. Damit ist der Handlungsknopf im Fuss
   unabhaengig von Bildschirmhoehe und Textmenge immer sichtbar. Das ist die
   eigentliche Reparatur; die Scroll-Wache faellt ersatzlos weg. */

/* KEINE BEWEGUNG DARF DIE ERREICHBARKEIT BESTIMMEN. Das ist hier keine
   Feinheit, sondern die tragende Regel, und sie hat drei Anlaeufe gekostet:

   Anlauf 1, `animation: blattRein .24s both`: mit `both` haelt die Animation die
   Startlage fest, bevor sie laeuft. Gemessen hing das Blatt 337 px unterhalb des
   Bildschirms.
   Anlauf 2, eine Klasse, die im naechsten Bild per requestAnimationFrame wieder
   abgenommen wird: laeuft kein Bildaufbau, kommt kein naechstes Bild, und die
   Klasse bleibt kleben. Gemessen: dieselben 337 px.
   Anlauf 3, dieselbe Animation ohne fill-mode: auch das half nicht. Eine
   laufende, aber eingefrorene Animation haelt ihren ersten Bildpunkt fest, ganz
   gleich was fill-mode sagt. Wieder 337 px.

   Die Lehre ist nicht "ein anderer Trick", sondern: eine Bewegung, deren
   Startlage 337 px vom Ziel entfernt ist, darf es gar nicht geben. Jetzt sind es
   16 px. Friert die Animation ein, sitzt das Blatt 16 px tiefer als gedacht und
   ist vollstaendig bedienbar. Auf einem gesunden Geraet sieht man denselben
   Ruck nach oben wie vorher, nur kuerzer.
   Das Verblassen des Hintergrunds darf ruhig einfrieren: ein unsichtbarer
   Hintergrund verdeckt nichts. */
.blatt-huelle {
  position: fixed;
  inset: 0;
  z-index: 110;                 /* ueber der Begruessung (100), sonst nichts */
  display: flex;
  align-items: flex-end;
  background: rgba(11, 10, 7, .60);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  animation: blattGrund .18s ease-out;   /* ohne fill-mode, mit Absicht */
}
.blatt-huelle.zu { opacity: 0; transition: opacity .18s ease; }

.blatt {
  display: flex;
  flex-direction: column;
  width: 100%;
  /* 78 % statt 100 %: darueber bleibt ein Streifen der Liste sichtbar, und man
     sieht auf einen Blick, dass man in einem Fenster steht und nicht auf einer
     neuen Seite. Ein Fenster, das den Bildschirm fuellt, fuehlt sich an wie ein
     Seitenwechsel, und dann sucht man die Zurueck-Taste. */
  max-height: 78dvh;
  padding-bottom: env(safe-area-inset-bottom);
  border-radius: 20px 20px 0 0;
  background: var(--bg);
  box-shadow: 0 -8px 30px rgba(0, 0, 0, .38);
  transform: none;                       /* die Ruhelage ist die richtige Lage */
  animation: blattRein .24s cubic-bezier(.22, 1, .36, 1);   /* ohne fill-mode */
}
.blatt-huelle.zu .blatt {
  transform: translateY(100%);
  transition: transform .2s ease-in;
}

/* Der Griff. Kein Bedienelement, sondern ein Versprechen: hier laesst sich
   ziehen. Ohne ihn probiert es niemand. */
.blatt-griff {
  flex: none;
  width: 42px;
  height: 5px;
  margin: 8px auto 2px;
  border-radius: 999px;
  background: var(--linie);
}

.blatt-kopf {
  flex: none;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 6px 14px 10px;
  border-bottom: 1px solid var(--linie);
}
.blatt-titel { flex: 1; min-width: 0; }
.blatt-titel h3 {
  margin: 0;
  font-size: 19px;
  font-weight: 800;
  line-height: 1.2;
  color: var(--text);
}
.blatt-unter {
  display: block;
  margin-top: 3px;
  font-size: 14px;
  font-weight: 600;
  color: var(--leise);
}
.blatt-zu {
  flex: none;
  width: 38px; height: 38px;
  display: flex; align-items: center; justify-content: center;
  border: 0;
  border-radius: 50%;
  background: var(--karte);
  color: var(--leise);
  font-family: inherit;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
}

/* Der einzige Teil, der scrollt. min-height:0 ist Pflicht, sonst waechst ein
   Flex-Kind ueber seinen Anteil hinaus und der Fuss wird nach unten geschoben. */
.blatt-rumpf {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;   /* haelt das Scrollen im Blatt, nicht dahinter */
  padding: 12px 14px;
  display: grid;
  gap: 8px;
}

/* Der Fuss traegt die Handlung und steht fest. Genau dafuer ist das Blatt
   gebaut. Der obere Schatten setzt ihn ab, wenn darueber noch Text weiterlaeuft. */
.blatt-fuss {
  flex: none;
  padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--linie);
  background: var(--bg);
  box-shadow: 0 -6px 14px rgba(0, 0, 0, .07);
}
/* Im Blatt braucht der Losfahren-Knopf keinen eigenen Rand mehr, der Fuss hat
   schon einen. */
.blatt-fuss .d-los { margin: 0; width: 100%; }

/* SECHZEHN Pixel, nicht hundert Prozent. Die Begruendung steht oben bei
   .blatt-huelle: was einfrieren kann, darf nicht weit weg starten. */
@keyframes blattRein  { from { transform: translateY(16px); } to { transform: none; } }
@keyframes blattGrund { from { opacity: 0; } to { opacity: 1; } }

/* Waehrend das Blatt am Finger haengt, darf kein Uebergang dazwischenfunken,
   sonst laeuft es der Bewegung hinterher. */
.blatt.zieht { transition: none; animation: none; }

/* ---------- Ziehen zum Aktualisieren ----------

   Gehoert zu MPApp.ziehen() in basis.js. Kam aus der Tank-App hierher, als die
   Aktualisieren-Knoepfe ausgebaut wurden (Manni, 31.07.2026). Das Markup baut
   die Basis selbst; das Elternelement der scrollenden Flaeche braucht
   position: relative (der uebliche .listenraum hat das). */
.zieh-anzeige {
  position: absolute;
  top: 0; left: 0; right: 0;
  display: flex; align-items: center; justify-content: center;
  height: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 2;
}
/* Vertraute Form: eine runde Scheibe mit Schatten, darin ein Spinner. Die erste
   Fassung war ein nackter Ring, der sich beim Ziehen mitdrehte, das wirkte unruhig
   und ungewohnt. Beim Ziehen wird die Scheibe nur groesser, gedreht wird erst,
   wenn wirklich geladen wird. */
.zieh-ring {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px; height: 38px;
  border-radius: 50%;
  background: var(--karte);
  box-shadow: 0 2px 10px rgba(0, 0, 0, .35);
  opacity: 0;
  transform: scale(.6);
  transition: opacity .12s ease, transform .12s ease;
}
.zieh-ring::after {
  content: "";
  width: 18px; height: 18px;
  border-radius: 50%;
  border: 2.5px solid var(--linie);
  border-top-color: var(--akzent-text);
}
.zieh-anzeige.bereit .zieh-ring { transform: scale(1); }
.zieh-anzeige.bereit .zieh-ring::after { border-color: var(--linie); border-top-color: var(--akzent-text); }
.zieh-anzeige.laeuft .zieh-ring { opacity: 1; transform: scale(1); }
.zieh-anzeige.laeuft .zieh-ring::after { animation: ziehDreht .7s linear infinite; }
@keyframes ziehDreht { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .zieh-anzeige.laeuft .zieh-ring::after { animation: none; }
}

/* ---------- Werbestreifen ----------

   Die drei verkauften Plaetze IN der App (Manni, 30.07.2026). Gestapelt
   braeuchten sie 335 px, das geht auf einem 568-px-Handy nicht. Stattdessen eine
   Flaeche, die zwischen den gebuchten Anzeigen wechselt.

   Die Staffelung steckt in ZEIT und GROESSE: Platz 1 steht 10 Sekunden und ist
   44 px hoch, Platz 2 steht 6 Sekunden bei 38 px, Platz 3 steht 4 Sekunden bei
   32 px. Das sind 50, 30 und 20 Prozent der Sendezeit, und damit fast genau das
   Preisverhaeltnis 59 zu 39 zu 25 (48, 32, 20 Prozent). Die Sendezeit entspricht
   dem Preis, und das laesst sich nachrechnen.

   ENTSCHEIDEND gegen Gezappel: die AEUSSERE Flaeche behaelt immer die groesste
   Hoehe. Nur die Anzeige darin ist unterschiedlich hoch und sitzt mittig. Wuerde
   die Zeile selbst mitwachsen, ruckelte die Liste darueber alle paar Sekunden um
   12 px, und das waere schlimmer als jede Werbung. */

/* ---------- Toast ----------

   Eine kurze Meldung am unteren Rand, mit dem Zeichen der App darin. Ersetzt
   das alert(), das in jeder App anders aussah und die Seite anhielt.
   Heisst mp-toast und nicht toast: SOS hat ein eigenes .toast in seiner
   styles.css, und zwei gleichnamige Regeln aus zwei Dateien ergeben ein
   Aussehen, das niemand mehr vorhersagen kann. */

.mp-toast {
  position: fixed;
  left: 50%;
  /* ueber dem fest stehenden Werbestreifen, nicht darauf. */
  bottom: calc(16px + env(safe-area-inset-bottom) + var(--werbehoehe, 88px));
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 10px;
  /* width max-content ist Pflicht, nicht Geschmack: ein fixiertes Element ohne
     Breitenangabe nimmt sich nur den Platz von seiner linken Kante bis zum
     Rand. Bei left 50 Prozent ist das die halbe Bildschirmbreite, gemessen
     180 px auf einem 360er Handy, und ein Satz von siebzig Zeichen stand
     vierzeilig darin. */
  width: max-content;
  max-width: min(92vw, 430px);
  padding: 10px 16px 10px 10px;
  border-radius: 999px;
  /* Fest dunkel, auch im hellen Modus: der Toast ist eine Meldung, die sich vom
     Untergrund abheben muss, egal worauf sie liegt. */
  background: var(--mm-ink-700);
  color: var(--mm-cream-50);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.3;
  border: 1px solid var(--mm-ink-500);
  box-shadow: 0 8px 26px rgba(0, 0, 0, .45);
  /* Ruhelage ist UNSICHTBAR und ein Stueck tiefer. Die Bewegung ist klein
     gehalten, damit ein eingefrorener Zwischenzustand nichts verdeckt: das ist
     dieselbe Lehre wie beim Blatt. */
  transform: translateX(-50%) translateY(12px);
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s ease, transform .2s ease;
}
.mp-toast.da { transform: translateX(-50%); opacity: 1; }
/* Fuer Erfolgsmeldungen, die man nicht uebersehen soll. Amber-Flaeche, also
   dunkle Schrift, sonst steht die gute Nachricht in Weiss auf Gelb. */
.mp-toast.stark {
  background: linear-gradient(120deg, var(--mm-amber-500), var(--mm-amber-600));
  border-color: var(--mm-amber-600);
  color: var(--auf-akzent);
}

.mp-toast-zeichen {
  flex: none;
  width: 34px;
  height: 34px;
  padding: 3px;
  border-radius: 50%;
  /* Weisse Scheibe, weil die Zeichen freigestellt sind und ihre dunkelblauen
     Flaechen sonst im dunklen Band verschwinden. */
  background: #fff;
}
.mp-toast-text { min-width: 0; }

@media (prefers-reduced-motion: reduce) {
  .mp-toast { transition: opacity .2s ease; transform: translateX(-50%); }
}

/* FEST AM UNTEREN BILDSCHIRMRAND seit 01.08.2026 (Manni: "bei diversen Apps
   ist der Werbebanner nach oben gerutscht, er soll einen fixen Platz am
   untersten Bildschirmrand erhalten"). Vorher war er die letzte Zeile des
   App-Rasters und wanderte mit, sobald der Inhalt darueber kuerzer war oder
   die Browserleiste des Handys ihre Hoehe aenderte.
   Weil er damit aus dem Raster faellt, bekommt .app unten genau seine Hoehe
   als Polster, und die Toast-Leiste rueckt um dieselbe Hoehe nach oben. */
.wp-streifen {
  position: fixed;
  left: 8px;
  right: 8px;
  bottom: calc(env(safe-area-inset-bottom) + 2px);
  z-index: 40;
  /* Stand hier als var(--grund), und diesen Namen gibt es in der Basis gar
     nicht: der Streifen war also die ganze Zeit durchsichtig und die Liste
     schimmerte hinter der Werbung durch. Beim Umstellen aufgefallen
     (02.08.2026). Richtig ist der Seitengrund. */
  background: var(--bg);
  border-radius: 14px;
  display: flex;
  align-items: center;
  /* VERDOPPELT (Manni, 31.07.2026: "das ist noch zu klein da unten"). 88 statt
     44 px. Das ist verkaufte Flaeche, und eine Werbeflaeche, die man uebersieht,
     ist keinen Preis wert. Bezahlt wird sie aus der Fusszeile, die dafuer ganz
     entfaellt. */
  min-height: 88px;
  padding-left: 22px;            /* Platz fuer die Kennzeichnung am Rand */
}
/* Laeuft gerade ein FREIER Platz, gibt es nichts zu kennzeichnen (Eigenwerbung,
   siehe basis.js), und die 22 px gehen an die Flaeche zurueck. */
.wp-streifen.ohne-marke { padding-left: 0; }

/* Pflichtkennzeichnung nach Paragraf 6 DDG (frueher TMG), und zwar nur an
   gebuchter Fremdwerbung: basis.js blendet sie bei freien Plaetzen aus.
   Solange eine gebuchte Anzeige laeuft, steht sie dauerhaft da und nicht nur
   beim Wechsel: eine Kennzeichnung, die mitwandert, ist keine. Senkrecht am
   Rand, damit sie keine Hoehe kostet. */
.wp-marke {
  position: absolute;
  left: 0; top: 50%;
  transform: translateY(-50%) rotate(180deg);
  writing-mode: vertical-rl;
  font-size: 8.5px;
  font-weight: 800;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--gedimmt);
  pointer-events: none;
}
/* Ausdruecklich, nicht nur ueber das Browser-Standardblatt: bei .kippzeile hat
   genau diese Annahme schon einmal nicht gehalten. */
.wp-marke[hidden] { display: none; }

.wp-anzeige {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  width: 100%;
  border-radius: 12px;
  color: #fff;
  text-decoration: none;
  font-weight: 800;
  letter-spacing: .4px;
  animation: wpRein .3s ease-out both;
}
/* ALLE DREI GLEICH GROSS (Manni, 31.07.2026). Der erste Entwurf staffelte auch
   die Hoehe, 44 / 38 / 32 px. Mit dem, was wir jetzt wissen, ist das falsch:
   auf 320 px Breite sieht man den Unterschied kaum, und wer Platz 3 bucht, soll
   keine sichtbar schlechtere Flaeche bekommen. Der Unterschied liegt allein in
   der ZEIT, und die ist ehrlich messbar.
   Die Farbe unterscheidet weiter, aber nur als Wiedererkennung zu den drei
   Plaetzen auf /neugierig und im Buchungsformular. */
/* Die drei Plaetze behalten ihre drei unterschiedlichen Farben, denn daran
   erkennt ein Kunde auf /neugierig und im Buchungsformular wieder, was er
   gebucht hat. Sie kommen jetzt nur aus der eigenen Palette: Orange fuer
   Platz 1, Koenigsblau fuer Platz 2, Stein fuer Platz 3.
   ALLE DREI BLEIBEN DUNKEL GENUG FUER WEISSE SCHRIFT. Amber kommt hier
   ausdruecklich NICHT vor: der Akzent gehoert der Bedienung, nicht der
   Werbung. Sonst sieht eine gekaufte Anzeige aus wie ein Knopf der App. */
.wp-anzeige { min-height: 88px; font-size: 20px; }
.wp-anzeige.p1 {
  background: linear-gradient(120deg, #FF8A3D 0%, var(--mm-orange-500) 45%, #C4470A 100%);
  box-shadow: 0 4px 16px rgba(255, 107, 26, .32); }
.wp-anzeige.p2 {
  background: linear-gradient(120deg, #5C7FFF 0%, var(--mm-blue-500) 60%, #1B3ABF 100%);
  box-shadow: 0 4px 14px rgba(46, 91, 255, .28); }
.wp-anzeige.p3 {
  background: linear-gradient(120deg, #6A604F 0%, #4A4235 60%, #2E2A21 100%);
  box-shadow: 0 3px 10px rgba(0, 0, 0, .26); }

/* Der laufende Lichtstreifen, wie auf der Empfehlungsseite. Er ist hier NICHT
   Zierat, sondern Teil des Angebots (Manni, 31.07.2026: "der Kunde sieht auch
   direkt, was er bekäme, schön schimmern lassen"): ein freier Platz sieht damit
   aus wie eine gebuchte Anzeige, nur mit dem Preis darauf. Wer ihn bucht, weiss
   vorher genau, was er bekommt.
   Gestaffelt wie die Sendezeit: Platz 1 laeuft schnell und hell, Platz 3
   langsam und zart. */
.wp-anzeige::before {
  content: '';
  position: absolute; top: -60%; left: -60%;
  width: 45%; height: 220%;
  background: linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(255,255,255,.42) 50%, rgba(255,255,255,0) 100%);
  transform: rotate(18deg);
  animation: wpGlanz 3.4s ease-in-out infinite;
  pointer-events: none;
}
.wp-anzeige.p2::before { animation-duration: 5.2s; opacity: .72; }
.wp-anzeige.p3::before { animation-duration: 7s;   opacity: .55; }
@keyframes wpGlanz {
  0%   { left: -60%; }
  55%  { left: 130%; }
  100% { left: 130%; }
}
.wp-anzeige > * { position: relative; z-index: 1; }

/* Ein FREIER Platz sieht aus wie eine gebuchte Anzeige, denn genau das ist er
   im Angebot. Kein gestrichelter Rahmen, keine blasse Farbe: das waere die
   Vorfuehrung eines schlechteren Produkts als das verkaufte.
   Unterschieden wird nur durch das Wort auf der Flaeche und durch die
   gepunktete Umrandung des Platzhalters, wo spaeter das Kundenlogo steht. */
.wp-frei-platz {
  display: inline-block;
  padding: 0 7px;
  border: 2px dashed rgba(255, 255, 255, .75);
  border-radius: 7px;
  font-size: .8em;
  animation: wpPuls 1.9s ease-in-out infinite;
}
@keyframes wpPuls {
  0%, 100% { border-color: rgba(255, 255, 255, .35); }
  50%      { border-color: rgba(255, 255, 255, .95); }
}

.wp-logo { flex: none; height: 24px; width: auto; border-radius: 5px; }
.wp-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wp-pfeil { flex: none; font-size: 22px; font-weight: 700; line-height: 1; }

/* ---------- Der ablaufende Zaehler ----------
   Manni, 31.07.2026: "damit es keine Streitereien gibt, dass man sehen kann,
   wie die Zeit herunterlaeuft."

   Das ist kein Zierat, sondern der Beleg fuer die gebuchte Leistung. Wer Platz 1
   bucht, kann in jeder App nachsehen, dass dort fuenf Minuten stehen, statt es
   glauben zu muessen. Beides kostet KEINE Hoehe: die Zahl sitzt in der Ecke, der
   Balken auf der Unterkante. */
.wp-rest {
  position: absolute;
  top: 5px; right: 9px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .3px;
  color: rgba(255, 255, 255, .85);
  font-variant-numeric: tabular-nums;   /* damit die Zahl nicht zappelt */
  pointer-events: none;
}
/* ---------- Der Balken als MINUTENTAKTE ----------

   Manni, 31.07.2026: "man erkennt nicht so gut, dass die Laufleiste langsam
   ablaeuft."

   Er hat recht, und es ist keine Geschmacksfrage, sondern Wahrnehmung. Ein
   durchgehender Balken bewegt sich ueber fuenf Minuten um 0,33 Prozent je
   Sekunde. Das liegt unter der Schwelle, ab der ein Auge Bewegung ueberhaupt
   bemerkt; man sieht erst nach einer halben Minute, DASS sich etwas geaendert
   hat, aber nie, dass es sich BEWEGT.

   Drei Aenderungen, jede mit einem eigenen Zweck:

   1. UNTERTEILUNG IN SECHS ABSCHNITTE. Statt eines langen Balkens sechs kurze,
      bei jedem Platz gleich viele. Drei, zwei und eine Minute gehen alle glatt
      durch sechs, ein Abschnitt dauert also 30, 20 oder 10 Sekunden.
      Es leert sich immer nur EIN Kaestchen, und das bewegt sich sechsmal
      schneller als der ganze Balken: 3,3 Prozent je Sekunde bei Platz 1 statt
      0,33. Dazu erlischt alle 30, 20 oder 10 Sekunden ein Kaestchen ganz, und
      das ist ein Sprung. Ein Sprung wird immer bemerkt, eine stetige Bewegung
      unterhalb der Schwelle nie.
   2. LEUCHTENDE KANTE. Das Auge liest die POSITION einer Kante viel genauer als
      die LAENGE einer Flaeche. Die Vorderkante des laufenden Kaestchens bekommt
      deshalb einen hellen Schein.
   3. MEHR KONTRAST UND HOEHE. 6 statt 3 px, dunklere Rinne, und abgesetzt vom
      Rand statt auf der Kante, wo die Rundung ihn frueher halb verschluckte. */
.wp-balken {
  position: absolute;
  left: 12px; right: 12px; bottom: 5px;
  display: flex;
  gap: 3px;
  height: 6px;
  pointer-events: none;
}
.wp-takt {
  flex: 1;
  min-width: 0;
  border-radius: 3px;
  /* Deutlich dunkler als vorher: die leere Rinne muss als leer lesbar sein,
     sonst sieht der ganze Balken immer gleich voll aus. */
  background: rgba(0, 0, 0, .28);
  overflow: hidden;
}
.wp-takt i {
  display: block;
  height: 100%;
  width: 100%;
  border-radius: 3px;
  background: #fff;
  /* Eine Sekunde linear: der Wert springt im Sekundentakt, die Bewegung
     glaettet ihn. Faellt sie aus, springt er eben, und die Zahl stimmt weiter. */
  transition: width 1s linear;
}
/* Nur das laufende Kaestchen leuchtet an der Kante. Ein Schein auf allen
   waere Zierat, hier ist er die Auskunft "genau hier passiert gerade etwas". */
.wp-takt.aktiv i {
  box-shadow: 1px 0 7px 1px rgba(255, 255, 255, .95);
}

@keyframes wpRein { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

/* ---------- Bewegung ---------- */

/* Kurzes Aufblenden nach dem Umschalten. */
@keyframes reinrutschen {
  from { opacity: .25; transform: translateY(9px); }
  to   { opacity: 1;   transform: none; }
}
.schwung .karte { animation: reinrutschen .3s ease-out both; }
.schwung .karte:nth-child(2) { animation-delay: .04s; }
.schwung .karte:nth-child(3) { animation-delay: .08s; }

@keyframes aufklappen {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}

/* Wer Bewegung abgeschaltet hat, bekommt keine. Die Bedienung bleibt
   vollstaendig, nur ohne Gleiten, Blitzen und Pulsieren. */
@media (prefers-reduced-motion: reduce) {
  .schwung .karte,
  .karte.gefallen, .karte.gestiegen,
  .skelett, .zieh-anzeige.laeuft .zieh-ring { animation: none; }
  .werbe-banner::before { animation: none; opacity: 0; }
  .markierer, .kippe-knopf, .segment, .kippzeile, .karte, .knopf { transition: none; }
  /* Das Blatt faehrt nicht mehr herein, es ist einfach da. Und die Werbung
     wechselt nicht mehr: Bewegung im Blickfeld beim Fahren ist ohnehin heikel,
     wer sie abgeschaltet hat, meint es ernst.
     Die Ruhelage bleibt richtig, weil sie nicht an der Bewegung haengt. */
  .blatt, .blatt-huelle { transition: none; }
  .wp-anzeige, .wp-anzeige::before, .wp-frei-platz { animation: none; }
  .wp-frei-platz { border-color: rgba(255, 255, 255, .8); }
  /* Die Kaestchen springen dann im Sekundentakt statt zu gleiten, und die
     leuchtende Kante entfaellt. Zahl und Fuellstand bleiben: das ist Auskunft
     und keine Bewegung. */
  .wp-takt i { transition: none; }
  .wp-takt.aktiv i { box-shadow: none; }
}

/* ---------- Kleine Bildschirme ----------

   DREI Stufen statt einer (Manni, 30.07.2026: "das maximalste, was herausholbar
   ist"). Anlass war eine Messung an der Park-App auf einem iPhone SE, 320 x 568:

       feste Umgebung  488 px  (86 Prozent)
       Liste            79 px  (14 Prozent, also 1,2 Karten)

   Die alte einzige Stufe bei 700 px sparte ganze 12 px. Das ist nichts gegen
   488. Also: frueher greifen, tiefer greifen, und ueber clamp() dazwischen
   gleiten statt zu springen.

   Die eine Grenze, die NICHT verhandelbar ist: eine Trefferflaeche bleibt bei
   mindestens 36 px. Darunter tippt man am Steuer daneben, und dann ist die
   gewonnene Zeile teurer als die verlorene. */

/* Stufe "knapp": was frueher erst bei 700 px galt, greift jetzt ab 780 px.
   Damit sind auch die haeufigen 812er- und 844er-Geraete im Hochformat
   abgedeckt, sobald die Systemleisten ihren Teil genommen haben. */
@media (max-height: 780px) {
  .knopf { min-height: 52px; font-size: 20px; }
  .knopf.knopf-breit { font-size: 22px; }
  .werbe-banner { min-height: 36px; font-size: 18px; }
  .kopf-ich { min-height: 32px; }
  .kopf-zeichen { height: 32px; }
  .app-wechsel { min-height: 32px; }
}

/* Stufe "eng": ab hier zaehlt jede Zeile. Gekuerzt wird an Luft, Schrift und
   Doppelungen, nie am Inhalt. */
@media (max-height: 640px) {
  .app { gap: 4px; padding-top: calc(env(safe-area-inset-top) + 4px); }

  /* Die Kopfzeile wird EINZEILIG: Zeichen und Name links, der Weg zu den
     anderen Apps rechts als reine Zeichenreihe. Der Satz "Meine anderen
     kostenlosen Apps" faellt weg, die Zeichen sagen dasselbe kuerzer.
     Ersparnis 35 px, das ist eine halbe Karte. */
  .kopf { flex-direction: row; align-items: center; gap: 8px; }
  .kopf-ich { flex: 1; min-height: 34px; }
  .kopf-zeichen { height: 30px; }
  .kopf-name { font-size: 14px; }
  .kopf-name b { font-size: 12px; }
  .kopf-was { display: none; }        /* der Zweck steht auf /apps, hier stoert er */
  .app-wechsel { flex: none; min-height: 34px; padding: 2px 8px; gap: 5px; }
  .aw-text { display: none; }
  .aw-zeichen img { height: 21px; }

  /* Umschalter: 36 px ist die Untergrenze, nicht weniger. */
  .umschalter { padding: 4px; }
  .umschalter.gross .segment { min-height: 36px; font-size: 15px; }
  .umschalter:not(.gross) .segment { min-height: 36px; font-size: 14px; }
  .markierer { top: 4px; bottom: 4px; left: 4px; }

  .kippzeile { min-height: 40px; padding: 0 12px; }
  .kz-titel { font-size: 15px; }
  .kz-unter { font-size: 12px; }

  .knopf { min-height: 44px; font-size: 18px; }
  .knopf.knopf-breit { font-size: 19px; }
  .knopf-icon { font-size: 22px; }

  .sort-zusatz { min-height: 15px; font-size: 12px; }
  .fuss { font-size: 11px; }
  .fuss .quelle { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block; }

  /* Der Werbestreifen behaelt seine Hoehe: er ist verkaufte Flaeche, und was
     verkauft ist, wird nicht heimlich kleiner. Nur die Schrift geht mit. */
  .wp-streifen { min-height: 80px; }
  :root { --werbehoehe: 80px; }
  .wp-anzeige { min-height: 80px; font-size: 18px; }

  /* Das Blatt darf hier hoeher werden: bei 568 px sind 78 Prozent nur 443 px,
     und davon gehen Kopf und Fuss ab. */
  .blatt { max-height: 86dvh; }
  .blatt-kopf { padding: 4px 12px 8px; }
  .blatt-titel h3 { font-size: 17px; }
  .blatt-rumpf { padding: 10px 12px; }

  /* Und die Liste selbst enger (Manni, 31.07.2026: "die einzelnen Zeilen müssen
     viel enger sein, damit mehr Platz geschaffen wird"). Der Zwischenraum ist
     der billigste Gewinn: bei sechs Karten sind fuenf Fugen, jede gesparte
     Zeile ist bares Blickfeld. */
  .liste { gap: 3px; }
  .karte { border-radius: 11px; border-left-width: 3px; }
}

/* Sehr flache Geraete, etwa ein SE im Querformat oder ein geteilter Bildschirm.
   Hier faellt zusaetzlich die Fusszeile weg: die Quellennennung steht dann im
   Blatt unter "Quelle", die Pflicht ist damit erfuellt, ohne dauerhaft eine
   Zeile zu kosten. */
@media (max-height: 470px) {
  .fuss { display: none; }
  .kopf-name { font-size: 13px; }
  .umschalter.gross .segment, .umschalter:not(.gross) .segment { min-height: 36px; }
}
