/* Das Haus-System. Eine Datei, aus der alles andere folgt.
 *
 * WOHER DIE ZAHLEN KOMMEN
 *
 * Sie sind an mobbin.com gemessen, nicht geschaetzt: Die Seite ist mit Framer
 * gebaut und traegt ihre Stile inline, also lassen sich die Stufen auslesen.
 * Was uebernommen wurde, ist das SYSTEM - Schriftstufen, Abstandsraster,
 * Radien, wie leise die Trennlinien sind. Was NICHT uebernommen wurde: kein
 * Text, kein Bild, keine Farbe, an der man die Marke erkennt. Deren Blau
 * (#0065ff) waere genau das gewesen; Fastspeech bleibt einfarbig schwarz.
 *
 * DIE VIER ENTSCHEIDUNGEN, die den Unterschied machen:
 *
 * 1. TINTE IST NICHT SCHWARZ. #141414 statt #0a0a0a. Reines Schwarz auf Weiss
 *    ist ein Kontrast, den es in der Natur nicht gibt; er ermuedet beim Lesen
 *    und laesst Flaechen billig wirken. Zwei Prozent Grau nimmt die Haerte,
 *    ohne dass jemand sagen koennte, woran es liegt.
 *
 * 2. LINIEN SIND FAST NICHT DA. #4040400f ist Schwarz bei sechs Prozent.
 *    Bisher stand hier #e8e8e4 - eine Linie, die man SIEHT. Der Unterschied
 *    zwischen einer Seite, die aus Kaesten besteht, und einer, die aus
 *    Flaechen besteht, ist genau diese Deckkraft.
 *
 * 3. RADIEN SIND KLEINER GEWORDEN. 16 / 20 / 24 statt 22 / 44. Ein Radius von
 *    44px macht aus einem Abschnitt eine Pille; das sah 2021 neu aus und sieht
 *    jetzt nach 2021 aus. Rund bleibt nur, was wirklich rund sein soll: der
 *    Knopf, die Marke, der Schalter.
 *
 * 4. DIE ZEILENHOEHE IST ENG. 44px Schrift auf 44px Zeile. Grosse Schrift auf
 *    weiter Zeile zerfaellt in einzelne Zeilen; erst wenn sie eng steht, liest
 *    man einen Block. Umgekehrt beim Fliesstext: 16px auf 26px, weil dort
 *    jede Zeile einzeln gefunden werden muss.
 */

/* Die vier Schnitte, die die Seite wirklich benutzt. Ein fuenfter waere
   ein weiterer Abruf fuer einen Unterschied, den niemand benennen kann.
   font-display:swap: Lieber der Text in der Ersatzschrift als drei Sekunden
   nichts. */
@font-face{font-family:Figtree;src:url(/assets/fonts/Figtree-Regular.woff2) format("woff2");font-weight:400;font-display:swap}
@font-face{font-family:Figtree;src:url(/assets/fonts/Figtree-Medium.woff2) format("woff2");font-weight:500;font-display:swap}
@font-face{font-family:Figtree;src:url(/assets/fonts/Figtree-SemiBold.woff2) format("woff2");font-weight:600;font-display:swap}
@font-face{font-family:Figtree;src:url(/assets/fonts/Figtree-Bold.woff2) format("woff2");font-weight:700;font-display:swap}
/* Eine Ersatzschrift, die genauso viel Platz einnimmt wie Figtree.
 *
 * Bis die Schrift geladen ist, steht die Seite in der Systemschrift, und deren
 * Buchstaben sind anders breit. Auf next-steps brach der Satz unter der
 * Ueberschrift dadurch auf eine Zeile mehr, und als Figtree ankam, sprang
 * alles darunter um 27 Punkte nach oben: gemessen 0,112, also ueber der
 * Schwelle von 0,1, ab der Google eine Seite als springend zaehlt. Das
 * Vorladen im Kopf hat den Sprung verkleinert, nicht abgeschafft.
 *
 * Diese Schrift hier zeichnet nichts. Sie nimmt die Systemschrift und streckt
 * sie so, dass sie Figtrees Platz einnimmt. Gemessen, nicht geraten: derselbe
 * Satz ist in Figtree 3336 Punkte breit und in der Ersatzschrift 3305,6, macht
 * 100,92 Prozent. Die Ueber- und Unterlaenge stehen bei Figtree auf 95 und 25
 * Hundertsteln, geteilt durch dieselben 100,92 Prozent sind das 94,1 und
 * 24,8 - so ist auch die Zeile gleich hoch und nicht nur gleich breit.
 *
 * Genau treffen kann das nur dort, wo die Systemschrift dieselbe ist, an der
 * gemessen wurde. Auf einem Mac oder unter Windows heisst sie anders und faellt
 * etwas anders aus. Naeher als vorher ist sie aber ueberall. */
@font-face{font-family:"Figtree Ersatz";
  src:local("Arial"),local("Helvetica Neue"),local("Helvetica"),local("Liberation Sans");
  size-adjust:100.92%;ascent-override:94.1%;descent-override:24.8%;line-gap-override:0%}

/* ══ 1. Die Werte ═══════════════════════════════════════════════════════════
   Alles, was zweimal vorkommt, steht hier einmal. Wer eine Zahl direkt ins
   Regelwerk schreibt, hat sie an einer zweiten Stelle schon vergessen. */
:root {
  /* --- Flaechen und Tinte --- */
  --tinte: #141414;          /* Ueberschriften, Fliesstext        16.5:1 */
  --tinte-still: #5c5c5c;    /* Beitext, Beschreibungen            6.7:1 */
  --tinte-leise: #6e6e6e;    /* Beschriftungen, Einheiten          5.1:1 */
  /* WARUM NICHT #adadad, wie bei Mobbin gemessen:
     Weil es dort als TEXTFARBE steht und in dieser Rolle durchfaellt. Auf
     Weiss sind das 2,24:1; die Schwelle fuer Fliesstext liegt bei 4,5:1. Ich
     hatte den Wert mit dem Rest der Skala uebernommen und ihn damit an rund
     zehn Stellen benutzt: Abschnittsbeschriftungen, Preiseinheiten, der
     Tabellenkopf, die Fusszeile, das "—" fuer "nicht enthalten".

     Gefunden hat es keine Meinung, sondern eine Messung ueber alle elf Seiten.
     Eine Vorlage getreu zu uebernehmen heisst nicht, auch ihre Maengel
     mitzunehmen - und wer 13px in Hellgrau setzt, schreibt fuer Leute mit
     guten Augen und einem guten Bildschirm.

     Die Abstufung bleibt erhalten (16,5 / 6,7 / 5,1), nur liegt sie jetzt
     ganz oberhalb der Schwelle, auch auf den beiden getoenten Flaechen
     --papier-still und --papier-tief. */
  --papier: #ffffff;
  --papier-still: #fafafa;   /* Abschnitte, die sich absetzen sollen */
  --papier-tief: #f4f4f4;    /* Felder, Schalterrinnen */
  --dunkel: #141414;         /* Knoepfe, dunkle Karten */
  --dunkel-hoch: #262626;    /* Erhoehtes AUF dunkel */
  /* Der Ring, der einmal aus einer Kachel der Wortwolke herauslaeuft. Er
     steht als eigener Wert, weil er im dunklen Blatt hell sein muss und
     rgba() mit einer Zahl das nicht von selbst tut. */
  --chip-ring: rgba(20, 20, 20, .42);

  /* --- Linien: drei Staerken, alle fast unsichtbar --- */
  --linie: #4040400f;        /*  6 % - die Regel */
  --linie-klar: #40404014;   /*  8 % - wenn zwei Flaechen sich beruehren */
  --linie-stark: #4040401a;  /* 10 % - Umrandung eines Knopfes */

  /* --- Schrift ---
     Figtree, und zwar aus dem eigenen Haus: Sie liegt unter /assets/fonts und
     wird nicht von fremden Rechnern geholt. Das ist hier keine Vorliebe,
     sondern Datenschutz - eine Schriftart von einem fremden Dienst schickt
     die Adresse jedes Besuchers dorthin, und genau dafuer gibt es in
     Deutschland Urteile.

     Die STUFEN sind bei Mobbin gemessen, die SCHRIFT ist unsere. Wer beides
     uebernimmt, hat die Seite eines anderen. */
  /* "Figtree Ersatz" steht gleich hinter Figtree: die Systemschrift, auf
     Figtrees Platz gestreckt. Siehe die Begruendung oben am @font-face. */
  --schrift: Figtree, "Figtree Ersatz", -apple-system, BlinkMacSystemFont,
             "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  /* --- Die Stufen. Sechs, mehr nicht. ---
     Eine siebte Stufe ist immer eine Stufe, die jemand gebraucht hat, weil
     zwei bestehende nicht passten - und danach passt gar nichts mehr. */
  --gr-riesig: clamp(2.75rem, 6vw, 4.5rem);   /* Aufmacher */
  --gr-gross:  clamp(2rem, 3.6vw, 2.75rem);   /* Abschnittstitel  44/44 */
  --gr-mittel: clamp(1.375rem, 2vw, 1.5rem);  /* Kartentitel      24 */
  --gr-lies:   1.25rem;                        /* Vorspann         20/30 */
  --gr-text:   1rem;                           /* Fliesstext       16/26 */
  --gr-klein:  0.8125rem;                      /* Beschriftung     13 */

  /* --- Das Abstandsraster: alles ein Vielfaches von 4 --- */
  --a1: 4px;   --a2: 8px;   --a3: 12px;  --a4: 16px;
  --a5: 20px;  --a6: 24px;  --a8: 32px;  --a10: 40px;
  --a12: 48px; --a16: 64px; --a20: 80px;
  /* Der Abstand zwischen zwei Abschnitten. Waechst mit dem Fenster, aber
     nicht ins Uferlose - ab 1500px sieht mehr Luft nicht grosszuegiger aus,
     sondern nach fehlendem Inhalt. */
  --a-abschnitt: clamp(72px, 8vw, 120px);

  /* --- Radien --- */
  --r-klein: 10px;   /* Feld, Marke, kleines Zeichen */
  --r-karte: 16px;   /* die Regel */
  --r-gross: 20px;   /* Karte, die eine Karte enthaelt */
  --r-flaeche: 24px; /* ganze Abschnitte */
  --r-rund: 999px;   /* Knopf, Schalter, Pille */

  /* --- Breiten ---
     1440 statt 1300: Auf einem 16-Zoll-Bildschirm stand die Seite bisher als
     Saeule in der Mitte mit Rand daneben. Der Lesetext bleibt trotzdem bei
     760px - eine Zeile ueber 90 Zeichen findet man am Anfang nicht wieder. */
  --breit: 1440px;
  --schmal: 760px;
  --rand: clamp(20px, 4vw, 40px);

  /* --- Zwei Werte, die die Bausteine selbst setzen ---
     Sie stehen hier mit einer Vorgabe, nicht weil sie hier gebraucht wuerden,
     sondern damit ein Baustein, der sie zu setzen vergisst, zusammenbricht
     statt falsch auszusehen: Ein Balken ohne --anteil ist dann null lang und
     nicht ungueltig, und eine Markierung ohne --wahl-grund ist grau und nicht
     unsichtbar. */
  --anteil: 0%;              /* Laenge eines Balkens, gesetzt am Element */
  --marke: var(--tinte);     /* Markenfarbe eines Zeichens im Logo-Lauf */
  --zeichen: none;
  /* Die Nummer einer Karte im Faecher. Sie wird je Karte im Blatt gesetzt;
     hier steht sie mit einer Vorgabe, damit eine Karte, die sie zu setzen
     vergisst, in der Mitte des Stapels liegt statt die ganze Rechnung
     ungueltig zu machen. Ein ungueltiges calc() faellt still aus - die Karte
     stuende dann ohne Versatz, ohne Drehung, ohne alles. */
  --i: 3;           /* die Datei, die dort als Maske dient */
  --wahl-grund: #1414141f;   /* der markierte Satz im Befehlsmodus */

  /* --- Bewegung: EIN Bogen, drei Zeiten --- */
  --bogen: cubic-bezier(.2, .7, .2, 1);
  --zeit-kurz: .18s;   /* Farbe, Deckkraft - soll man nicht bemerken */
  --zeit: .32s;        /* Verschiebung, Groesse */
  --zeit-lang: .75s;   /* Einblendung beim Scrollen */
}

/* ══ 2. Zuruecksetzen ═══════════════════════════════════════════════════════
   Nur, was wirklich stoert. Ein Vollreset macht die Fehlersuche schwerer,
   weil man danach nicht mehr weiss, was der Browser und was das Blatt tut. */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
/* AUF DEM TELEFON WIRD GESCHOBEN UND GETIPPT, SONST NICHTS.
 *
 * Auf Ansage: kein Aufziehen mit zwei Fingern, kein Doppeltipp-Zoom, kein
 * Gummiband am oberen und unteren Ende. Die Seite soll sich anfuehlen wie
 * eine App und nicht wie ein Blatt Papier, das man verschieben kann.
 *
 * pan-x pan-y heisst genau das: Schieben ja, Zwei-Finger-Zoom nein,
 * Doppeltipp-Zoom nein. "manipulation" waere zu wenig, das laesst das
 * Aufziehen zu; "none" waere zu viel, dann liesse sich auch nicht mehr
 * scrollen.
 *
 * overscroll-behavior nimmt das Gummiband: Am Ende der Seite federt nichts
 * mehr nach, und ein Wisch nach unten laedt die Seite nicht neu.
 *
 * text-size-adjust haelt die Schrift fest. Ohne das vergroessert iOS beim
 * Drehen ins Querformat einzelne Absaetze von sich aus, und dann steht die
 * Seite in zwei verschiedenen Schriftgroessen da.
 *
 * WAS DAS KOSTET, und es steht hier, damit es niemand uebersieht: Wer
 * schlecht sieht, kann die Seite nicht mehr aufziehen. WCAG 1.4.4 verlangt,
 * dass Text sich auf 200 Prozent bringen laesst. Genau deshalb war diese
 * Sperre schon einmal draussen. Sie ist auf ausdrueckliche Ansage zurueck,
 * und sie gilt bewusst NICHT fuer die Schriftgroesse des Systems: Wer im
 * Telefon grosse Schrift eingestellt hat, bekommt sie hier weiterhin, denn
 * alle Groessen der Seite rechnen in rem. */
html {
  touch-action: pan-x pan-y;
  overscroll-behavior: none;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
/* overscroll-behavior steht NUR am <html> und nicht auch am <body>.
 *
 * Gemeldet: "mit dem Mausrad geht Scrollen irgendwie nicht." Die Rollleiste
 * ging, die Tastatur ging, das Rad tat nichts. Das ist kein Skript, das ist
 * diese Zeile.
 *
 * Eine Seite weiter unten steht "html, body { overflow-x: hidden }" gegen das
 * seitliche Schieben auf dem Telefon. Und hier liegt die Falle: Wer
 * overflow-x auf hidden setzt, bekommt overflow-y NICHT auf visible zurueck -
 * die Regel schreibt vor, dass daraus auto wird. Damit ist der <body> selbst
 * ein Rollbehaelter. Er hat nichts zu rollen, und overscroll-behavior: none
 * verbietet ihm, den Schub an das <html> darunter weiterzureichen. Das Rad
 * dreht also in einen Behaelter, der schon am Anschlag steht, und nichts
 * passiert. Die Rollleiste bedient das <html> direkt und geht deshalb weiter.
 *
 * Am <html> ist die Angabe richtig und reicht auch: Die Regel sagt, dass
 * overscroll-behavior vom Wurzelelement auf den Sichtbereich uebergeht. Das
 * Gummiband und das Neuladen beim Herunterwischen bleiben also weg, genau wie
 * gewollt. Am <body> hat sie nie etwas dazu beigetragen, sondern nur das Rad
 * verschluckt. */
body {
  touch-action: pan-x pan-y;
  margin: 0;
  background: var(--papier);
  color: var(--tinte);
  font-family: var(--schrift);
  font-size: var(--gr-text);
  line-height: 1.625;          /* 16 auf 26 */
  letter-spacing: 0;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: "cv05" 1, "cv11" 1;  /* offenes a, gerades l */
}
img, svg, video { display: block; max-width: 100%; height: auto; }
button, input, select, textarea { font: inherit; color: inherit; }
a { color: inherit; text-decoration: none; }

/* ══ 3. Schrift ═════════════════════════════════════════════════════════════
   Die Regel, die alles zusammenhaelt: JE GROESSER, DESTO ENGER. Grosse
   Schrift mit normaler Laufweite faellt auseinander; kleine Schrift mit enger
   Laufweite wird unleserlich. Deshalb -0.045em oben und +0.02em unten. */
h1, h2, h3, h4 { margin: 0; font-weight: 700; }

.t-riesig {
  font-size: var(--gr-riesig);
  line-height: 1.0;
  letter-spacing: -.045em;
}

/* Die Zeile des Aufmachers. Sie stand zuletzt einfarbig und in derselben
   Stufe wie jede andere grosse Ueberschrift der Seite - der Aufmacher sah
   damit aus wie ein Abschnitt, nicht wie der Anfang.

   ZWEI TOENE, und zwar aus einem Grund und nicht als Zierde: "The keyboard"
   ist das Bekannte, "you talk to" ist die Behauptung. Der Ton trennt die
   Voraussetzung von der Aussage, und das Auge liest die Pointe zuerst. Genau
   so stand es hier schon einmal; ich hatte es gegen eine einfarbige Zeile
   getauscht mit der Begruendung, bei vier Woertern sei das ein Effekt ohne
   Aussage. Das war falsch - die vier Woerter sind nicht vier gleiche Woerter.

   GROESSER: eigene Stufe statt --gr-riesig, und die Zeile sitzt enger (0.92
   statt 1.0). Grosse Schrift auf weiter Zeile faellt in Streifen auseinander;
   erst eng gesetzt wird aus zwei Zeilen ein Block. */
.t-riesig.auf-zeile {
  font-size: clamp(3.25rem, 7.6vw, 6rem);
  line-height: .92;
  letter-spacing: -.05em;
  max-width: 15ch;
  margin-inline: auto;
}
.t-riesig.auf-zeile .leise { color: var(--tinte-leise); }

/* MEHR LUFT IM AUFMACHER. Gemeldet: "mach bisschen mehr Abstand zwischen die
   Spaces damit es nicht immer zu eng wird" - und beim Nachmessen stimmt es.
   Zwischen Zeile und Vorspann standen 20 Punkte, zwischen Vorspann und
   Knoepfen 28. Bei einer 96-Punkt-Ueberschrift ist das eng: Der Abstand muss
   mit der Schrift mitwachsen, sonst kleben die Teile aneinander, sobald die
   Zeile groesser wird.

   Die Werte wachsen deshalb mit dem Fenster statt festzustehen. */
.hero-banner.dl-auf .t-lies,
.auf-vorspann {
  max-width: 46ch; margin: clamp(var(--a6), 3vw, var(--a10)) auto 0;
  color: var(--tinte-still);
  /* text-wrap: balance verteilt die Zeilen gleichmaessig, statt jede bis zum
     Rand zu fuellen und den Rest in die letzte zu kippen. Ohne das stand hier
     auf der dritten Zeile das Wort "in." allein - ein Schusterjunge, und bei
     einem Vorspann direkt unter einer 96-Punkt-Zeile faellt er auf.
     Browser, die es nicht kennen, brechen wie bisher. */
  text-wrap: balance;
}
.auf-knoepfe {
  justify-content: center;
  margin-top: clamp(var(--a8), 3.4vw, var(--a12));
  gap: var(--a3);
}
/* Die Zeile ueber das, was noch kommt. Sie steht deutlich abgesetzt: Sie
   gehoert nicht zu den Knoepfen, sondern ist eine Auskunft daneben. */
.auf-bald {
  margin: clamp(var(--a5), 2.2vw, var(--a8)) 0 0;
  text-align: center;
  font-size: 13.5px; color: var(--tinte-leise);
}

/* Der Pfeil am Nebenknopf. Er zeigt nicht nur nach rechts, er RUECKT beim
   Zeigen nach rechts - ein Pfeil, der sich nicht bewegt, ist ein Zeichen;
   einer, der sich bewegt, ist eine Richtung. Vier Punkte reichen dafuer; mehr
   sieht nach Spielerei aus. */
.knopf.pfeil-rechts { gap: var(--a2); }
.knopf .pf {
  width: 18px; height: 18px; flex: none;
  transition: transform var(--zeit-kurz) var(--bogen);
}
@media (hover: hover) {
  .knopf.pfeil-rechts:hover .pf { transform: translateX(4px); }
}
@media (prefers-reduced-motion: reduce) { .knopf .pf { transition: none; } }
.t-gross {
  font-size: var(--gr-gross);
  line-height: 1.05;
  letter-spacing: -.035em;
}
.t-mittel {
  font-size: var(--gr-mittel);
  line-height: 1.25;
  letter-spacing: -.02em;
}
.t-lies {
  font-size: var(--gr-lies);
  line-height: 1.5;
  letter-spacing: -.01em;
  color: var(--tinte-still);
}

/* DER ABSTAND ZWISCHEN UEBERSCHRIFT UND VORSPANN GEHOERT INS SYSTEM.
 *
 * Er stand bisher als Inline-Stil an einzelnen Stellen ("margin:16px auto 0")
 * oder gar nicht. Auf fuenf Seiten stand er gar nicht, und dort sassen null
 * Punkte zwischen Zeile und Vorspann: Simple pricing., Everything you might
 * be wondering, Official showcases and tutorials, What's new, Thank you.
 * Am Schreibtisch liest sich das noch als eng, auf dem Telefon kleben sie.
 *
 * Ein Abstand, den jede Stelle einzeln mitbringen muss, wird irgendwann
 * vergessen. Er wachst mit dem Fenster, wie der im Aufmacher: Bei einer
 * grossen Zeile braucht es mehr Luft als bei einer kleinen.
 *
 * Inline-Stile schlagen diese Regel, die vorhandenen Stellen bleiben also
 * unveraendert. Neu ist nur, wo bisher nichts stand. */
h1 + .t-lies,
h2 + .t-lies,
.t-riesig + .t-still,
.t-gross + .t-still,
.t-riesig + .steps,
.t-gross + .steps { margin-top: clamp(var(--a4), 2.4vw, var(--a6)); }
.t-still { color: var(--tinte-still); }
.t-leise { color: var(--tinte-leise); }

/* Die Beschriftung ueber einem Abschnitt. Gross geschrieben und weit
   gelaufen - das ist der einzige Ort, an dem weite Laufweite richtig ist,
   weil Versalien ohne sie zusammenkleben. */
.marke {
  font-size: var(--gr-klein);
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--tinte-leise);
  margin: 0 0 var(--a3);
}

p { margin: 0 0 var(--a4); }
p:last-child { margin-bottom: 0; }

/* ══ 4. Grundrisse ══════════════════════════════════════════════════════════ */
.bahn { width: 100%; max-width: var(--breit); margin-inline: auto; padding-inline: var(--rand); }
.bahn-schmal { width: 100%; max-width: var(--schmal); margin-inline: auto; padding-inline: var(--rand); }
.feld { padding-block: var(--a-abschnitt); }
.feld-still { background: var(--papier-still); }
/* Ein Abschnitt, der etwas enger steht. Der Faecher traegt seine Hoehe
   schon selbst, mit dem vollen Abschnittsabstand darueber und darunter
   wirkte er verloren. */
.feld-eng { padding-block: calc(var(--a-abschnitt) * 0.68); }

/* Ein Raster, das sich selbst umbricht. Die Zahl in minmax() ist die
   Entscheidung: Unter 260px wird aus einer Karte ein Zettel. */
.raster { display: grid; gap: var(--a5); }
.raster-2 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.raster-3 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.raster-4 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }

/* Zwei Spalten, Text und Bild. Nicht auto-fit: Hier ist die Reihenfolge
   gemeint und nicht die Breite. */
.paar {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(var(--a10), 6vw, var(--a20));
  align-items: center;
}
.paar-eng { grid-template-columns: 1fr 1.15fr; }
@media (max-width: 900px) {
  .paar, .paar-eng { grid-template-columns: 1fr; gap: var(--a10); }
}

.stapel { display: flex; flex-direction: column; }
.stapel > * + * { margin-top: var(--a4); }
.reihe { display: flex; align-items: center; gap: var(--a3); flex-wrap: wrap; }
.mitte { text-align: center; }
.mitte .t-lies, .mitte p { margin-inline: auto; }

/* ══ 5. Knoepfe ═════════════════════════════════════════════════════════════
   Zwei Sorten, mehr braucht keine Seite: Der eine, den man druecken soll, und
   der andere. Eine dritte Sorte ist immer eine Entscheidung, die jemand nicht
   treffen wollte. */
.knopf {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--a2);
  height: 44px;
  padding-inline: var(--a5);
  border: 0;
  border-radius: var(--r-rund);
  background: var(--dunkel);
  color: #fff;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -.01em;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--zeit-kurz) var(--bogen),
              transform var(--zeit-kurz) var(--bogen),
              opacity var(--zeit-kurz) var(--bogen);
}

/* Ein Knopf mit "hidden" ist versteckt, Punkt.
   display:inline-flex weiter oben schlaegt die Regel des Browsers fuer
   [hidden] - ein Knopf, der weg sein soll, stand dann da und fing Klicks ab.
   Hier steht die Gegenregel einmal fuer alle Knoepfe statt einmal je Fall;
   test/versteckt-heisst-versteckt.test.js sucht genau diese Form. */
.knopf[hidden] { display: none; }
.knopf:hover { background: var(--dunkel-hoch); }
/* Ein Knopf, der beim Druecken NICHT nachgibt, fuehlt sich an wie ein Bild.
   Ein Pixel reicht; zwei sind ein Wackeln. */
.knopf:active { transform: translateY(1px); }
.knopf:focus-visible { outline: 2px solid var(--tinte); outline-offset: 3px; }

.knopf.stumm {
  background: transparent;
  color: var(--tinte);
  box-shadow: inset 0 0 0 1px var(--linie-stark);
}
.knopf.stumm:hover { background: var(--papier-tief); }
.knopf.gross { height: 52px; padding-inline: var(--a6); font-size: 16px; }
.knopf.breit { width: 100%; }

/* ══ 6. Karten ══════════════════════════════════════════════════════════════
   Eine Karte ist eine Flaeche mit einer Kante, nicht ein Kasten mit einem
   Schatten. Schatten kommt nur dazu, wenn etwas WIRKLICH davorliegt - beim
   Ueberfahren, in einem Menue. Sonst schwebt die ganze Seite. */
.karte {
  background: var(--papier);
  border-radius: var(--r-karte);
  box-shadow: inset 0 0 0 1px var(--linie);
  padding: var(--a6);
}
.karte.tief { background: var(--papier-still); box-shadow: none; }
.karte.dunkel { background: var(--dunkel); color: #fff; box-shadow: none; }
.karte.dunkel .t-still, .karte.dunkel .marke { color: #8a8a8a; }
.karte.gross { border-radius: var(--r-gross); padding: var(--a8); }

/* Beim Ueberfahren hebt sich, was anklickbar IST. Was nur dasteht, hebt sich
   nicht - sonst verspricht die Seite Klicks, die es nicht gibt. */
.karte.klickbar {
  transition: box-shadow var(--zeit) var(--bogen), transform var(--zeit) var(--bogen);
}
@media (hover: hover) {
  .karte.klickbar:hover {
    transform: translateY(-2px);
    box-shadow: inset 0 0 0 1px var(--linie-klar), 0 8px 28px rgba(20, 20, 20, .07);
  }
}

/* ══ 7. Pille ═══════════════════════════════════════════════════════════════ */
.pille {
  display: inline-flex;
  align-items: center;
  gap: var(--a1);
  height: 26px;
  padding-inline: var(--a3);
  border-radius: var(--r-rund);
  background: var(--papier-tief);
  color: var(--tinte-still);
  font-size: var(--gr-klein);
  font-weight: 600;
  letter-spacing: 0;
}
.pille.dunkel { background: var(--dunkel); color: #fff; }

/* ══ 8. Tabelle ═════════════════════════════════════════════════════════════
 *
 * Eine Vergleichstabelle ist die Stelle, an der die meisten Seiten schlechter
 * werden statt besser: Man legt ein Gitter aus Linien an, und der Kunde sucht
 * darin nach dem Unterschied zwischen zwei Spalten.
 *
 * Deshalb hier: KEINE senkrechten Linien. Der Blick laeuft ohnehin waagerecht,
 * Zeile fuer Zeile - die senkrechte Linie hindert ihn nur. Die Spalte, um die
 * es geht, wird nicht durch einen Rahmen hervorgehoben, sondern dadurch, dass
 * sie eine Flaeche hat und die anderen keine.
 *
 * Und der Kopf bleibt oben stehen. Eine Vergleichstabelle, bei der man nach
 * der vierten Zeile nicht mehr weiss, welche Spalte welcher Tarif ist, ist
 * eine Liste von Haken.
 */
.tab-huelle {
  overflow-x: auto;
  border-radius: var(--r-gross);
  box-shadow: inset 0 0 0 1px var(--linie);
  -webkit-overflow-scrolling: touch;
}
.tab { width: 100%; min-width: 640px; border-collapse: collapse; text-align: left; }
.tab th, .tab td {
  padding: var(--a4) var(--a5);
  border-bottom: 1px solid var(--linie);
  vertical-align: middle;
}
.tab tr:last-child th, .tab tr:last-child td { border-bottom: 0; }
.tab thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--papier);
  border-bottom: 1px solid var(--linie-klar);
  font-size: var(--gr-klein);
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--tinte-leise);
  white-space: nowrap;
}
/* Die erste Spalte nennt die Sache, die anderen beantworten sie. Nur die
   erste steht in Tinte. */
.tab tbody th { font-weight: 500; color: var(--tinte); width: 40%; }
.tab td { color: var(--tinte-still); font-variant-numeric: tabular-nums; }
/* Die hervorgehobene Spalte: eine Flaeche, kein Rahmen. */
.tab .spalte-hoch { background: var(--papier-still); color: var(--tinte); font-weight: 600; }
.tab thead .spalte-hoch { background: var(--papier-still); color: var(--tinte); }
.tab tbody tr { transition: background var(--zeit-kurz) var(--bogen); }
@media (hover: hover) { .tab tbody tr:hover { background: #40404008; } }

/* Ja und Nein als Zeichen, nicht als Wort: In einer Tabelle mit dreissig
   Zeilen liest niemand dreissigmal "ja". */
.ja, .nein { display: inline-block; width: 18px; text-align: center; }
.ja { color: var(--tinte); }
.nein { color: var(--tinte-leise); }

/* ══ 9. Trennung ════════════════════════════════════════════════════════════ */
.strich { height: 1px; background: var(--linie-klar); border: 0; margin: 0; }

/* ══ 10. Nur fuer Vorleseprogramme ══════════════════════════════════════════
   Nicht display:none - das nimmt es dem Vorleser auch weg. */
.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;
}


/* ══ 12. Die dunkle Fassung ═════════════════════════════════════════════════
 *
 * Nur die Werte werden getauscht, keine einzige Regel. Das ist der ganze Sinn
 * der Werte oben: Wer eine Farbe direkt in eine Komponente schreibt, muss
 * jede Komponente zweimal bauen und vergisst beim naechsten Mal eine.
 *
 * Weiss ist die Vorgabe des Hauses. Dunkel gibt es, weil man danach fragt -
 * nicht, weil es die eigentliche Fassung waere.
 *
 * #0f0f0f statt #000: Reines Schwarz laesst auf einem OLED-Schirm jede Kante
 * flimmern, weil daneben buchstaeblich nichts leuchtet. Und die Linien werden
 * heller statt dunkler - auf dunklem Grund trennt Licht, nicht Schatten. */
:root[data-theme="dark"] {
  --tinte: #f2f2f2;
  /* Die beiden leisen Farben steigen mit den Flaechen mit. Sie waren gegen
     die SEITE gerechnet (#0f0f0f), und dort stimmten sie auch. Auf der
     angehobenen Flaeche #242424 fiel --tinte-leise aber auf genau 4,50:1,
     also auf die Schwelle selbst - "Windows" im Systemschalter und die
     Feldnamen im Mailfenster standen damit auf der Kante.

     Gerechnet wird gegen die HELLSTE Flaeche, auf der Text liegt, und das
     ist seit den erhoehten Karten --papier-hoch (#303030): dort 6,0:1 und
     4,8:1, auf der Seite 7,7:1 und 6,8:1. Bei #949494 waren es auf dieser
     Flaeche 4,35 - wieder knapp darunter. */
  --tinte-still: #a6a6a6;
  --tinte-leise: #9c9c9c;
  /* ERHOEHT. Im hellen Blatt liegt eine hervorgehobene Flaeche WEISS auf
     Grau: der gewaehlte Knopf in einer Schiene, die Karte im Kasten, der
     Chip auf der Karte. Sie fuellen sich mit --papier, und genau das geht
     im Dunkeln schief: Dort ist --papier die Farbe der SEITE, also das
     Dunkelste, was es gibt. Aus "liegt oben" wurde damit "liegt unten",
     und auf dem Bild sah es aus wie ein Loch.
     Diese Farbe ist die Gegenrichtung: heller als alles darunter. */
  --papier-hoch: #303030;
  --papier: #0f0f0f;
  /* DIE STUFEN WAREN ZU DICHT BEIEINANDER. Gemeldet: "man sieht nichts, es
     ist zu dunkel", mit einem Bild vom Aufmacher auf dem Telefon. Gemessen
     stand die Sprachkarte bei 1,07:1 zur Seite, der Systemschalter bei 1,15
     und das Tempo-Bild bei 1,00 - es trug denselben Grund wie die Seite. Auf
     einem OLED-Schirm bei halber Helligkeit ist das nichts.

     Die Flaechen steigen deshalb, aber nur maessig: Auf einem Grund von
     #0f0f0f braeuchte eine Flaeche #5b5b5b fuer die 3:1, die WCAG 1.4.11
     fuer eine Umrandung verlangt - das waere kein dunkles Thema mehr. Die
     Arbeit machen die LINIEN, und die steigen kraeftig. So machen es dunkle
     Oberflaechen ueberall: ruhige Flaeche, deutliche Kante. */
  --papier-still: #1a1a1a;
  --papier-tief: #242424;
  --dunkel: #f2f2f2;         /* Der Knopf dreht sich um: hell auf dunkel. */
  --dunkel-hoch: #ffffff;
  --chip-ring: rgba(255, 255, 255, .42);
  /* 7, 11 und 15 Prozent standen hier. Eine Linie mit 7 Prozent Weiss auf
     #0f0f0f ergibt #222222 und damit 1,19:1 - eine Kante, die niemand sieht.
     Jetzt 19, 27 und 36 Prozent: 1,7:1, 2,3:1 und 3,1:1. Die staerkste traegt
     damit die 3:1 aus WCAG 1.4.11, und sie ist die, die um Karten und
     Fenster liegt. */
  --linie: #ffffff30;
  --linie-klar: #ffffff45;
  --linie-stark: #ffffff5c;
}
:root[data-theme="dark"] .knopf { color: #0f0f0f; }
:root[data-theme="dark"] .knopf.stumm { color: var(--tinte); }
:root[data-theme="dark"] .karte.dunkel { background: var(--papier-tief); color: var(--tinte); }
@media (hover: hover) {
  :root[data-theme="dark"] .karte.klickbar:hover { box-shadow: inset 0 0 0 1px var(--linie-klar); }
  :root[data-theme="dark"] .tab tbody tr:hover { background: #ffffff08; }
}

/* ══ 13. Die Kopfzeile ══════════════════════════════════════════════════════
 *
 * Sie schwebt nicht mehr als Pille in der Mitte, sondern sitzt als Leiste
 * ueber der Seite. Die Pille war ein Element, das die Seite ANSAGT; eine
 * Leiste ist eines, das sie BEDIENT. Auf einer Seite mit sieben Abschnitten
 * ist das Zweite richtig.
 *
 * Der Hintergrund ist nicht deckend, sondern milchig: Was darunter
 * durchscrollt, bleibt zu ahnen. Das sagt "die Seite geht weiter" ohne ein
 * einziges zusaetzliches Element.
 */
/* Die Kopfzeile ist wieder eine schwebende Pille - auf Ansage des Inhabers.
 *
 * Ich hatte sie zur vollbreiten Leiste gemacht, mit dem Argument: Eine Pille
 * sagt die Seite an, eine Leiste bedient sie. Das Argument stimmt weiter und
 * ist trotzdem nicht die Entscheidung: Die Pille ist das Erkennungszeichen
 * dieser Seite, und wer sie taeglich sieht, hat ein Urteil darueber, das
 * meines schlaegt.
 *
 * Sie bekommt aber die Werte des neuen Systems - Radius, Linie, Schatten und
 * Schrift kommen von hier, nicht mehr aus dem alten Blatt. */
.nav {
  position: sticky;
  top: 12px;
  width: fit-content;
  max-width: calc(100% - 28px);
  margin: 12px auto 0;
  border-radius: var(--r-rund);
  background: color-mix(in srgb, var(--papier) 82%, transparent);
  box-shadow: 0 1px 2px rgba(20,20,20,.05),
              0 8px 24px -8px rgba(20,20,20,.10),
              inset 0 0 0 1px var(--linie);
  z-index: 50;
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  transition: box-shadow var(--zeit) var(--bogen);
}
/* Beim Scrollen wirft die Pille etwas weiter - sie liegt dann wirklich auf
   etwas. Ueber unberuehrtem Weiss waere derselbe Schatten eine Behauptung. */
.nav.gescrollt {
  box-shadow: 0 1px 2px rgba(20,20,20,.06),
              0 14px 34px -10px rgba(20,20,20,.16),
              inset 0 0 0 1px var(--linie-klar);
}
/* Aeltere Browser koennen kein color-mix - dort deckend statt durchsichtig,
   was schlechter aussieht, aber nie unleserlich ist. */
@supports not (background: color-mix(in srgb, #fff 50%, transparent)) {
  .nav { background: var(--papier); }
}
.nav-in {
  display: flex;
  align-items: center;
  /* Mehr Luft zwischen Marke und Knopf, auf Ansage: Das Logo weiter nach
     links, der Download-Knopf weiter nach rechts. Die Leiste ist eine
     schwebende Pille und so breit wie ihr Inhalt - breiter wird sie also
     nicht ueber eine Breite, sondern ueber den Abstand zwischen ihren drei
     Teilen und ueber die Polsterung links.
     Links 22 und rechts 8, weil rechts ein Knopf mit eigener Flaeche sitzt:
     Gleiche Zahlen auf beiden Seiten saehen rechts nach doppeltem Rand aus. */
  gap: clamp(var(--a5), 4vw, var(--a12));
  height: 58px;
  padding: 0 10px 0 28px;
}
.nav-logo { display: flex; align-items: center; flex: 0 0 auto; }
.nav-logo img { height: 22px; width: auto; }
/* Das Logo liegt als weisse Datei vor; auf hellem Grund wird es umgedreht.
   Eine zweite Datei waere eine zweite Stelle, an der man sie vergisst. */
:root:not([data-theme="dark"]) .nav-logo img { filter: invert(1); }

.nav-links { display: flex; align-items: center; gap: var(--a2); }
.nav-links a {
  padding: var(--a2) var(--a3);
  border-radius: var(--r-klein);
  font-size: 15px;
  font-weight: 500;
  color: var(--tinte-still);
  transition: color var(--zeit-kurz) var(--bogen), background var(--zeit-kurz) var(--bogen);
}
.nav-links a:hover { color: var(--tinte); background: var(--papier-tief); }
/* Die Seite, auf der man steht, behaelt ihre Flaeche.
   Hier stand vorher nur dunklere und fettere Schrift, mit der Begruendung, ein
   Link auf die eigene Seite solle nicht anklickbar wirken. Auf Ansage bleibt
   jetzt die Pille stehen: Sie beantwortet die Frage "wo bin ich gerade" auf
   einen Blick, und das wiegt schwerer. Beim Zeigen aendert sich trotzdem
   nichts, sie ist schon da.
   Der Strich, der hier frueher darunter lag, ist in premium.css entfernt; die
   Begruendung steht dort. */
.nav-links a[aria-current="page"],
.nav-links a.active {
  color: var(--tinte);
  font-weight: 600;
  background: var(--papier-tief);
}
.nav-links a[aria-current="page"]:hover,
.nav-links a.active:hover { background: var(--papier-tief); }

/* Im Handy-Menue DIESELBE Pille wie oben, nicht etwas Eigenes.
 *
 * Hier stand erst ein Strich am linken Rand der Zeile. Der war meine Idee und
 * nicht die Ansage; zurueckgemeldet kam "mach das wie auf PC, nicht so ein
 * Strich". Also dieselbe Flaeche, dieselbe Farbe, derselbe Gedanke: Was
 * markiert ist, liegt auf einer eigenen Flaeche.
 *
 * Sie ist hier so breit wie die Zeile, und das ist kein Zufall, sondern
 * dasselbe: Oben ist die Pille so breit wie ihr Eintrag, und ein Eintrag ist
 * dort so breit wie sein Wort. Im Menue stehen die Eintraege untereinander
 * und sind so breit wie das Menue. Dieselbe Regel, andere Zeilenbreite.
 *
 * Der Trennstrich unter der markierten Zeile wird unsichtbar: Er laege sonst
 * quer auf der Unterkante der Flaeche und saehe aus wie ein Schnitt. */
.mobile-menu a[aria-current="page"] {
  color: var(--tinte);
  font-weight: 700;
  background: var(--papier-tief);
  border-radius: var(--r-klein);
  border-bottom-color: transparent;
}

.nav-cta { display: flex; align-items: center; gap: var(--a2); flex: 0 0 auto; }
.nav-cta .btn, .nav-cta .knopf { height: 38px; padding-inline: var(--a4); font-size: 14px; }

/* Der Klappknopf: zwei Striche, die sich zum Kreuz drehen. Ein drittes
   Streichlein in der Mitte muesste beim Drehen verschwinden, und genau das
   sieht in jeder zweiten Umsetzung nach einem Fehler aus. */
.burger {
  display: none;
  position: relative;
  width: 38px; height: 38px;
  border: 0; border-radius: var(--r-klein);
  background: transparent; cursor: pointer;
}
.burger span {
  position: absolute; left: 10px;
  width: 18px; height: 1.5px;
  background: var(--tinte); border-radius: 2px;
  transition: transform var(--zeit) var(--bogen), top var(--zeit) var(--bogen);
}
.burger span:nth-child(1) { top: 16px; }
.burger span:nth-child(2) { top: 21px; }
.burger[aria-expanded="true"] span:nth-child(1) { top: 18.5px; transform: rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2) { top: 18.5px; transform: rotate(-45deg); }

.mobile-menu {
  display: flex; flex-direction: column; gap: var(--a1);
  padding: var(--a3) var(--rand) var(--a5);
  border-top: 1px solid var(--linie);
  background: var(--papier);
}
/* DIESE ZEILE IST NICHT OPTIONAL, UND SIE HAT GEFEHLT.
   Ohne sie stand das Menue auf JEDER Seite und auf JEDEM Telefon offen - von
   dem Tag an, an dem es gebaut wurde.

   "display: flex" oben ist eine Klassenregel und schlaegt damit die Regel des
   Browsers fuer [hidden], die display:none setzt. Im Blatt steht das Menue
   richtig mit hidden da, und main.js schaltet auch richtig .hidden um: Es war
   nie die Logik, sondern eine Regel, die staerker war als der Zustand.

   Was man gesehen hat: Unter der Kopfzeile standen Home, Pricing, FAQ und
   Download untereinander, davor der Aufmacher nach unten geschoben und die
   Sprachwahl mitten darin. Der Hamburger-Knopf daneben klappte auf und zu,
   ohne dass sich etwas ruehrte.

   Es ist derselbe Fehler wie bei .fa-buehne[hidden], zwei Abschnitte weiter
   unten - und dass er hier ein zweites Mal steckte, ist der Grund fuer
   test/versteckt-heisst-versteckt.test.js: Der Test sucht ihn jetzt ueberall,
   statt dass ich mich an zwei Stellen erinnere. */
.mobile-menu[hidden] { display: none; }
.mobile-menu a {
  padding: var(--a3) var(--a2);
  border-radius: var(--r-klein);
  font-size: 17px; font-weight: 500;
}
.mobile-menu a:active { background: var(--papier-tief); }
/* Beide Farben mit Ausweichwert.
   Gemeldet wurde ein Knopf, der als schwarzer Balken OHNE Beschriftung
   dastand. Hier nachgestellt bei 390, 412 und 430 Punkten: nicht zu sehen,
   die Schrift steht da. Was ein solches Bild aber erzeugen KANN: Loest einer
   der beiden Namen nicht auf, faellt die ganze Zeile weg, und die Schrift
   erbt dann die dunkle Farbe des Menues - dunkel auf dunkel. Mit Ausweichwert
   kann das nicht mehr passieren, egal woran es lag.
   Die Werte sind die des hellen Satzes; im dunklen Thema drehen sich beide
   Namen um, und dann gelten sie und nicht der Ausweich. */
.mobile-menu .m-signin {
  margin-top: var(--a3);
  text-align: center;
  background: var(--dunkel, #141414);
  color: var(--papier, #ffffff);
  border-radius: var(--r-rund);
  padding-block: var(--a3);
  font-weight: 600;
}

/* DIE OFFENE LEISTE IST KEINE PILLE MEHR.
 *
 * Zu ist sie eine: 999 Punkte Radius auf 60 Punkten Hoehe. Offen steckt das
 * Menue IN ihr, sie wird rund 450 Punkte hoch, und derselbe Radius zieht dann
 * einen riesigen Bogen quer hinter dem Logo durch. Auf dem Telefon sah es
 * aus, als sei die Leiste kaputt.
 *
 * overflow:hidden dazu, weil die weisse Flaeche des Menues eckig ist und ohne
 * das an den unteren Ecken aus der Rundung herausschaut.
 *
 * Die Klasse setzt main.js. Mit :has() waere es eine Zeile weniger, aber wo
 * :has() fehlt, stuende der Bogen wieder da. */
.nav.menue-offen {
  border-radius: var(--r-flaeche);
  overflow: hidden;
}

@media (max-width: 900px) {
  .nav-links { display: none; }
  .burger { display: block; }

  /* DER AUFBAU DES TELEFONS.
     Am Schreibtisch ist die Leiste eine Pille, die sich auf ihren Inhalt
     zusammenzieht: Wortmarke links, viel Luft, Knoepfe rechts. Auf dem Telefon
     geht das nicht - da ist die Luft das Erste, was fehlt.

     Hier stand einmal ein Raster aus drei Spalten mit mittiger Wortmarke, und
     es ging nicht auf: Damit die Marke wirklich MITTIG steht, muessen die
     beiden aeusseren Spalten gleich breit sein. Rechts standen damals
     Download, Flagge, Zeichen und Hamburger, zusammen rund 200 Punkte; links
     muesste dann ebenfalls Platz fuer 200 sein, und 200 + Marke + 200 sind
     mehr als die 366, die auf einem 390 Punkte breiten Bildschirm bleiben.

     Der Download-Knopf ist seither aus der Leiste heraus, er steht nur noch
     im Menue. Damit geht die Mitte auf, und sie ist auf Ansage zurueck:
     Helligkeit links, Wortmarke in der Mitte. Nachgemessen bei 320, 360, 390
     und 430 Punkten: links 92 (Helligkeit und Flagge), Marke 65, rechts 44
     (Hamburger). Das sind 249 von 290 auf dem schmalsten Geraet.

     Die aeusseren Spalten sind 1fr und damit gleich breit, egal was darin
     steht. Die Marke steht deshalb in der Mitte der LEISTE und nicht in der
     Mitte dessen, was uebrig bleibt - der Unterschied faellt genau dann auf,
     wenn eine Sprache die Flagge breiter macht. */
  .nav-in {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: var(--a2);
    height: 54px; padding: 0 12px;
    position: relative;
  }
  .seiten-schalter { grid-column: 1; justify-self: start; }
  .nav-logo { grid-column: 2; justify-self: center; }
  .nav-cta { grid-column: 3; justify-self: end; }
  /* Und damit auch die Flagge einfach in der Reihe steht. Sie lag absolut in
     der linken Ecke, weil das Raster ihr dort eine leere Spalte liess; ohne
     Raster gibt es die Spalte nicht mehr, und absolut gelegt wuerde sie auf
     der Wortmarke landen. Genau das war zu sehen: Die Marke las sich
     "[Flagge]ST". */
  .nav-cta .lang-knopf { position: static; transform: none; }
  .nav-cta { gap: 2px; }
  /* DER DOWNLOAD-KNOPF GEHOERT HIER NICHT IN DIE LEISTE, sondern ins Menue.
     Auf Ansage, und die Rechnung dahinter ist einfach: Auf 390 Punkten teilen
     sich Wortmarke, Download, Aussehen, Sprache und Hamburger eine Zeile. Der
     Knopf ist der Breiteste davon und draengt die uebrigen an den Rand -
     und im Menue steht er ohnehin schon, gross und ueber die ganze Breite.
     Zweimal dasselbe Ziel, einmal gedraengt und einmal in Ruhe.

     Die Regel steht HIER und nicht in styles-light.css, wo sie schon einmal
     stand und nichts tat: Dort setzt sie display:none an .nav-anmelden,
     system.css setzt danach display:flex an .knopf. Gleiche Spezifitaet,
     spaeter im Blatt - der Knopf blieb stehen. Es ist derselbe Fehler wie bei
     der Kopfzeile selbst, und beide Male sah es so aus, als sei die Regel
     einfach vergessen worden. */
  .nav-cta .nav-anmelden { display: none; }

  /* Die Leiste ist hier so breit wie der Bildschirm und keine Pille mehr,
     die sich auf ihren Inhalt zusammenzieht. */
  .nav { width: auto; }
}
@media (min-width: 901px) { .mobile-menu { display: none !important; } }

/* ══ 14. Schalter fuer Aussehen und Sprache ═════════════════════════════════
   Beide sitzen oben rechts und sind bewusst leiser als der Download-Knopf:
   Sie sind Einstellungen und nicht das, wofuer jemand gekommen ist. */
/* Der Schalter steht wieder als eigene kleine Pille oben rechts.
 *
 * Ich hatte ihn in die Leiste geholt, weil er dort ueber dem Download-Knopf
 * lag - das stimmte, solange die Kopfzeile vollbreit war. Jetzt ist sie
 * wieder eine mittige Pille, also ist die rechte Ecke frei, und in der Pille
 * wuerde er sie um gut hundert Punkte verbreitern. Sie ist aber so schmal wie
 * ihr Inhalt, und genau das macht sie aus. */
.seiten-schalter {
  position: sticky;
  top: 18px;
  z-index: 60;
  float: right;
  display: flex;
  align-items: center;
  gap: var(--a1);
  width: fit-content;
  margin: 18px 14px -58px auto;
  padding: 5px 6px;
  border-radius: var(--r-rund);
  background: color-mix(in srgb, var(--papier) 82%, transparent);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  box-shadow: 0 1px 2px rgba(20,20,20,.05),
              0 8px 24px -8px rgba(20,20,20,.10),
              inset 0 0 0 1px var(--linie);
}
/* UNTER 900 PUNKTEN HAENGT DER SCHALTER IN DER LEISTE, und dann muss alles
   weg, was ihn als freischwebende Pille ausmacht.

   main.js haengt ihn dort um - das stand schon da und war richtig. Was
   fehlte, war diese Regel: Er behielt float, sticky und den negativen
   Rand von minus 54 Punkten und sass damit halb unter der Kopfzeile, halb
   daneben. Auf dem Telefon war die Sprachwahl eine Flagge, die an der
   rechten unteren Ecke der Leiste klebte und in den Aufmacher hineinragte.

   Es ist die Kehrseite desselben Umbaus: Wer ein Element per JS woanders
   hinhaengt, muss auch sagen, wie es sich DORT verhaelt. */
@media (max-width: 900px) {
  .seiten-schalter {
    /* static, und zwar mit Absicht. Der Sprachknopf darin liegt absolut und
       gehoert in die LINKE Spalte der Leiste (styles-light.css: left:12px an
       .nav-cta .lang-knopf). Sein Bezug ist der naechste positionierte
       Vorfahr - also muss die Schale unpositioniert bleiben, damit das
       .nav-in darueber der Bezug ist.

       Mit sticky, wie es hier stand, war der Bezug die Schale selbst: Die
       Flagge sass dann 12 Punkte rechts von ihr, also mitten auf dem
       Download-Knopf. Mit relative dasselbe. Es sieht nach einer Kleinigkeit
       aus und ist der Unterschied zwischen "Flagge links in der Ecke" und
       "Flagge auf dem Logo". */
    position: static; float: none;
    margin: 0; padding: 0;
    background: none; box-shadow: none;
    backdrop-filter: none; -webkit-backdrop-filter: none;
  }
}

/* Ein Knopf, der nur ein Zeichen traegt, ist rund. Ein abgerundetes Quadrat
   liest sich als Kachel und verlangt damit nach Nachbarn - hier steht er
   allein neben der Sprachwahl. */
.theme-toggle {
  width: 38px; height: 38px;
  display: grid; place-items: center;
  border: 0; border-radius: 50%;
  background: transparent; cursor: pointer;
  color: var(--tinte-still);
  transition: color var(--zeit-kurz) var(--bogen), background var(--zeit-kurz) var(--bogen);
}
.theme-toggle:hover { color: var(--tinte); background: var(--papier-tief); }
/* NUR die Huelle wird hier neu gesetzt. WELCHES Symbol zu sehen ist,
   entscheidet weiter das Haus-Blatt, und zwar so: Im Hellen steht der Mond -
   das Symbol zeigt die WIRKUNG ("mach dunkel"), nicht den Zustand. Genau das
   sagt auch die Beschriftung am Knopf ("Switch to dark mode").

   Ich hatte das hier zuerst andersherum gebaut, weil die andere Lesart fuer
   sich genommen auch stimmt. Das Ergebnis waren zwei Regeln, die einander
   aufhoben: Die eine blendete die Sonne aus, die andere den Mond, und im Knopf
   stand ein leerer grauer Kreis. Zwei richtige Konventionen im selben Knopf
   sind eine falsche. */
/* .tt-bahn ist nur noch der Platz, auf dem die beiden Zeichen uebereinander
   liegen - KEINE eigene Flaeche.
   
   Der Fehler, den das behebt: Das Haus-Blatt setzt
   ".theme-toggle:hover .tt-bahn { background: ... }" (Spezifitaet 0,2,0) und
   gewinnt damit gegen ein blosses ".tt-bahn" (0,1,0). Beim Ueberfahren
   erschien deshalb ein hartkantiges helles Quadrat hinter dem Symbol, mitten
   in einem runden Knopf - es sah aus, als waere etwas kaputt geladen.

   Die Rueckmeldung beim Ueberfahren gehoert an den KNOPF, nicht an eine
   Flaeche darin. Deshalb hier ausdruecklich mit derselben Spezifitaet
   zurueckgenommen. */
/* Mit :where() haette das keine Chance gegen die Hausregel; mit dem
   doppelten Klassennamen liegt die Spezifitaet bei (0,3,0) und damit ueber
   jeder .theme-toggle:hover .tt-bahn (0,2,0) - egal, in welchem der beiden
   Haus-Blaetter sie steht. Kein !important: Das faehrt jede spaetere Regel
   mit um, auch eine, die recht haette. */
.tt-bahn.tt-bahn,
.theme-toggle:hover .tt-bahn.tt-bahn,
.theme-toggle:active .tt-bahn.tt-bahn {
  display: grid; place-items: center;
  width: 18px; height: 18px;
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  transform: none;
}
.theme-toggle .ic { width: 17px; height: 17px; }
/* IN DER DUNKLEN FASSUNG WAR DER SCHALTER KAPUTT, auf jeder Seite: ein
   graues Quadrat mit einem fast schwarzen Symbol darin. Gemessen, nicht
   gesehen - die Sonne stand auf rgb(10,10,10) vor rgb(15,15,15).
   Zwei Regeln aus premium.css, beide aus der Zeit der ZWEI Blaetter:
     html[data-theme="dark"] .tt-bahn { background: rgba(255,255,255,.10) }
     html[data-theme="dark"] .theme-toggle .tt-sun { color: var(--ink) }
   Damals wurde bei Dunkel ein anderes Blatt geladen, und --ink war dort hell.
   Heute wird nur noch das Merkmal am :root umgelegt, styles-light.css bleibt
   liegen - also bleibt --ink schwarz, und die Regel malt Schwarz auf Schwarz.
   Die Flaeche gehoert ohnehin an den Knopf und nicht an eine Huelle darin. */
:root[data-theme="dark"] .tt-bahn.tt-bahn { background: none; }
:root[data-theme="dark"] .theme-toggle .ic { color: currentColor; }
.tt-knopf { display: none; }

.lang-knopf {
  display: inline-flex; align-items: center; gap: var(--a2);
  height: 38px; padding-inline: var(--a3);
  border: 0; border-radius: var(--r-klein);
  background: transparent; cursor: pointer;
  font-size: 14px; font-weight: 500; color: var(--tinte-still);
  transition: color var(--zeit-kurz) var(--bogen), background var(--zeit-kurz) var(--bogen);
}
.lang-knopf:hover { color: var(--tinte); background: var(--papier-tief); }
/* IM DUNKLEN STEHEN BEIDE HELL, nicht grau.
   Sie trugen var(--tinte-still), und das ist im hellen Thema ein ruhiges Grau
   auf Weiss - richtig fuer eine Einstellung, die nicht rufen soll. Im dunklen
   Thema wird daraus ein mittleres Grau auf fast Schwarz, und das ist nicht
   mehr ruhig, sondern schwer zu lesen: Das Sonnenzeichen und das Wort neben
   der Flagge verschwanden fast im Grund.
   Ein Zeichen darf leise sein. Unlesbar darf es nicht sein. */
:root[data-theme="dark"] .lang-knopf,
:root[data-theme="dark"] .theme-toggle { color: var(--tinte); }
.lang-knopf img, .lang-knopf svg.flagge { width: 18px; height: 13px; border-radius: 2px; }
.lang-pfeil { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2; }
@media (max-width: 520px) { .lang-knopf .lang-name { display: none; } }

/* Die Sprachwahl liegt ueber der Seite, nicht daneben: Bei zwanzig Sprachen
   ist eine Klappliste am Rand entweder zu kurz oder haengt aus dem Bild. */
#lang-dlg { position: fixed; inset: 0; z-index: 100; display: grid; place-items: center; }
#lang-dlg::before { content: ""; position: absolute; inset: 0; background: rgba(10,10,10,.4); backdrop-filter: blur(3px); }
.lang-kasten {
  position: relative;
  width: min(520px, calc(100vw - 32px));
  max-height: min(640px, calc(100vh - 64px));
  overflow: auto;
  padding: var(--a8);
  border-radius: var(--r-flaeche);
  background: var(--papier);
  box-shadow: 0 24px 64px rgba(10,10,10,.22);
}
.lang-kasten h3 { font-size: var(--gr-mittel); letter-spacing: -.02em; margin-bottom: var(--a2); }
.lang-kasten > p { color: var(--tinte-still); margin-bottom: var(--a5); }
.lang-zu {
  position: absolute; top: var(--a5); right: var(--a5);
  width: 32px; height: 32px; display: grid; place-items: center;
  border: 0; border-radius: var(--r-klein); background: var(--papier-tief);
  color: var(--tinte-still); cursor: pointer;
}
.lang-zu:hover { color: var(--tinte); }
.lang-zu svg { width: 15px; height: 15px; }
.lang-liste { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: var(--a1); }
.lang-w {
  display: flex; align-items: center; gap: var(--a3);
  padding: var(--a3);
  border: 0; border-radius: var(--r-klein);
  background: transparent; cursor: pointer; text-align: left;
  font-size: 15px; color: var(--tinte);
  transition: background var(--zeit-kurz) var(--bogen);
}
.lang-w:hover { background: var(--papier-tief); }
.lang-w.an { background: var(--papier-tief); font-weight: 600; }
.lang-w img, .lang-w svg.flagge { width: 20px; height: 15px; border-radius: 2px; flex: 0 0 auto; }
.lang-zusatz { color: var(--tinte-leise); font-style: normal; font-size: var(--gr-klein); }

/* DER SPRACHKASTEN IM DUNKELN: schwarz bleibt schwarz, aber eine Spur heller.
 *
 * Auf Ansage, mit einem Bild: "lass schwarz, aber vielleicht leicht heller,
 * und die Details mit mehr Grau."
 *
 * Der Kasten fuellte sich mit --papier, und das ist im Dunkeln die Farbe der
 * SEITE - er stand also in genau demselben Schwarz wie alles hinter ihm, und
 * nur der Weichzeichner im Hintergrund verriet, dass da ein Kasten ist. Jetzt
 * liegt er eine Stufe hoeher und traegt eine Kante.
 *
 * Die Details, in der Reihenfolge, in der man sie sieht:
 *
 *   die gewaehlte Zeile   lag bei 1,23:1 ueber dem Kasten, jetzt auf der
 *                         Stufe fuer Erhoehtes
 *   der Schliessknopf     genauso, dazu hellere Schrift darin
 *   eine Trennlinie       unter dem Vorspann, damit Kopf und Liste zwei
 *                         Sachen sind und nicht ein Block
 *   der Hintergrund       dunkler, damit der Kasten sich abhebt statt in ihm
 *                         zu verschwinden
 */
:root[data-theme="dark"] #lang-dlg::before { background: rgba(0, 0, 0, .66); }
:root[data-theme="dark"] .lang-kasten {
  background: var(--papier-still);
  box-shadow: inset 0 0 0 1px var(--linie), 0 24px 64px rgba(0, 0, 0, .55);
}
:root[data-theme="dark"] .lang-kasten > p {
  padding-bottom: var(--a5);
  margin-bottom: var(--a5);
  border-bottom: 1px solid var(--linie);
}
:root[data-theme="dark"] .lang-w:hover,
:root[data-theme="dark"] .lang-w.an { background: var(--papier-hoch); }
:root[data-theme="dark"] .lang-zu {
  background: var(--papier-hoch);
  color: var(--tinte);
  box-shadow: inset 0 0 0 1px var(--linie);
}

/* ══ 15. Die Fusszeile ══════════════════════════════════════════════════════
   Hier stehen die Rechtstexte, und deshalb ist sie keine Restflaeche: § 5 DDG
   verlangt "leicht erkennbar, unmittelbar erreichbar, staendig verfuegbar".
   Sie stehen deswegen als eigene Spalte und nicht als Kleingedrucktes. */
/* DIE ALTE FUSSZEILE, auf Ansage wiederhergestellt. Was sie ausgemacht hat und
   was ich ihr genommen hatte:

   1. DAS PUNKTRASTER. Der Fuss ist die einzige Flaeche der Seite mit einer
      eigenen Textur. Ohne sie laeuft die Seite unten einfach aus; mit ihr hat
      sie einen Boden. Es ist dasselbe Raster wie im Haus-Blatt, nur leiser.
   2. DIE VERWEISE IN VERSALIEN. Eine Fusszeile wird nicht gelesen, sie wird
      abgesucht. Gesperrte Versalien haben eine gleichmaessigere Aussenlinie
      als Gemischtschreibung und lassen sich schneller abfahren - deshalb
      stehen sie dort und nur dort.
   3. DAS KLEINGEDRUCKTE UNTER DER MARKE statt unten quer. Damit hat der Fuss
      oben vier Spalten und unten eine Zeile, und in dieser Zeile steht dann
      genau eine Sache: womit man bezahlen kann. */
.fuss {
  border-top: 1px solid var(--linie);
  padding-block: var(--a16) var(--a10);
  background-image: radial-gradient(circle at 1px 1px,
    color-mix(in srgb, var(--tinte) 7%, transparent) 1px, transparent 0);
  background-size: 22px 22px;
}
.fuss-raster {
  display: grid;
  grid-template-columns: 1.6fr repeat(3, 1fr);
  gap: var(--a10) var(--a5);
}
@media (max-width: 860px) { .fuss-raster { grid-template-columns: 1fr 1fr; } }
@media (max-width: 480px) { .fuss-raster { grid-template-columns: 1fr; } }
.fuss .fuss-titel {
  font-size: var(--gr-klein); font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--tinte); margin-bottom: var(--a5);
}
.fuss-spalte a {
  display: block; padding-block: 7px;
  color: var(--tinte-still); font-size: 13px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
}
.fuss-spalte a:hover { color: var(--tinte); }
.fuss-marke img { height: 20px; width: auto;}
.fuss-recht { margin-top: var(--a5); max-width: 24ch;
  font-size: 14.5px; line-height: 1.55; color: var(--tinte-still); }
:root:not([data-theme="dark"]) .fuss-marke img { filter: invert(1); }
/* IN DER DUNKLEN FASSUNG WAR DAS LOGO UNSICHTBAR, im Kopf wie im Fuss.
   Gefunden durch Messen und nicht durch Hinsehen: Die Datei ist weiss
   (Helligkeit 255 von 255, nachgerechnet), auf dem dunklen Grund kam sie bei 9
   heraus - schwarz auf schwarz.
   Die Ursache steht im Haus-Blatt: "img[src*=fast-logo-white] { invert(1) }",
   ohne jede Bedingung. Die Regeln hier daneben drehen es nur im HELLEN um; im
   Dunklen bleibt die alte stehen und dreht ein weisses Logo auf Schwarz.
   Eine Regel, die an einem DATEINAMEN haengt, weiss nichts vom Thema - deshalb
   wird sie hier nicht ergaenzt, sondern fuer die dunkle Fassung abgeschaltet. */
:root[data-theme="dark"] .nav-logo img,
:root[data-theme="dark"] .fuss-marke img { filter: none; }
/* Unten steht nur noch EINE Sache, also steht sie rechts: Die Zeile ist
   Beiwerk, und Beiwerk in der Mitte sieht aus wie ein zweiter Versuch, wichtig
   zu sein. */
.fuss-unten {
  display: flex; justify-content: flex-end; align-items: center;
  gap: var(--a4); flex-wrap: wrap;
  margin-top: var(--a12); padding-top: var(--a6);
  border-top: 1px solid var(--linie);
  color: var(--tinte-leise); font-size: var(--gr-klein);
}
.fuss-unten .zahlreihe b {
  font-size: 11px; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--tinte-leise);
}

/* ══ 16. Die Bausteine der Startseite ═══════════════════════════════════════
 *
 * Diese Teile gab es schon; sie werden hier auf die neuen Werte gezogen. Was
 * sich dabei durchgehend aendert, sind zwei Dinge:
 *
 * DIE SCHATTEN werden leiser. Vorher stand an den Karten
 * "0 34px 80px rgba(0,0,0,.18)" - achtzig Pixel Weichzeichnung bei
 * achtzehn Prozent. Das ist der Schatten eines Gegenstands, der einen halben
 * Meter ueber dem Tisch schwebt. Auf einer Seite, auf der alles so schwebt,
 * schwebt nichts mehr; der Schatten sagt dann nichts mehr ueber Naehe aus.
 *
 * DIE RADIEN werden kleiner. 26px an einer Karte, 44px an einem Abschnitt -
 * ab einer gewissen Groesse ist ein Radius keine abgerundete Ecke mehr,
 * sondern eine Form, und dann konkurriert er mit dem Inhalt.
 */

/* --- Der Abstand zwischen den Themenzeilen ---
   Sie standen 240 Pixel auseinander. Zweihundertvierzig Pixel Leere zwischen
   zwei Zeilen, die zusammengehoeren, liest man nicht als Ruhe, sondern als
   Abbruch: Man glaubt, der Abschnitt sei zu Ende, und scrollt weiter. */
.zeilen { margin-top: var(--a-abschnitt); }
.zeilen > * + * { margin-top: var(--a-abschnitt); }
.featrow {
  display: grid;
  grid-template-columns: 1fr 1.1fr;
  gap: clamp(var(--a10), 6vw, 96px);
  align-items: center;
  margin: 0;
}
.featrow.flip { grid-template-columns: 1.1fr 1fr; }
.featrow.flip .frcopy { order: 2; }
.featrow.flip .frcard { order: 1; }
@media (max-width: 900px) {
  .featrow, .featrow.flip { grid-template-columns: 1fr; gap: var(--a8); }
  .featrow.flip .frcopy { order: 1; }
  .featrow.flip .frcard { order: 2; }
}

/* --- Die dunklen Beispielkarten --- */
.fcard {
  background: var(--dunkel);
  color: #fff;
  border-radius: var(--r-gross);
  padding: var(--a6);
  box-shadow: 0 12px 32px rgba(20, 20, 20, .10);
}
:root[data-theme="dark"] .fcard { background: var(--papier-tief); color: var(--tinte); box-shadow: none; }
.fcard-head b { font-size: 16px; font-weight: 600; letter-spacing: -.01em; }
.fcard-head .plus { width: 28px; height: 28px; font-size: 16px; background: #ffffff14; }
.rows { gap: var(--a2); }
.rowp { border-radius: var(--r-klein); padding: var(--a3) var(--a4); font-size: 14px; font-weight: 500; }

/* --- Vorher/Nachher im Aufraeum-Abschnitt ---
 *
 * ZWEI KARTEN, NICHT EINE MIT EINEM STRICH DARIN.
 *
 * Gemeldet: "die haben zu wenig Spalt zwischen, die sind wie geklebt." Und so
 * war es gebaut: zwoelf Punkte Abstand, und der Pfeil dazwischen mit
 * margin:-15px auf beiden Seiten, also mit der Hoehe null. Er sass damit
 * genau auf der Naht und hielt die beiden Karten zusammen, statt zwischen
 * ihnen zu stehen. Was man sah, war ein Block mit einer hellen und einer
 * dunklen Haelfte.
 *
 * Die Aussage des Abschnitts ist aber ein SCHRITT: das hier wird zu dem da.
 * Ein Schritt braucht einen Zwischenraum, sonst ist es kein Schritt.
 *
 * Der Stapel ist jetzt ein Raster mit echtem Abstand, und der Pfeil ist eine
 * eigene Zeile darin statt eines Aufklebers auf der Naht. Zwischen den Karten
 * liegen damit zwanzig Punkte, der Pfeil, und noch einmal zwanzig. */
.ae-stack { display: grid; gap: var(--a5); justify-items: stretch; }
.ae-card {
  border-radius: var(--r-karte); padding: var(--a5) var(--a6);
  /* Beide Karten werfen einen Schatten, auch die dunkle. Ohne ihn liegt die
     helle AUF der Seite und die dunkle IN ihr - zwei verschiedene Tiefen fuer
     zwei Dinge, die nebeneinandergehoeren. */
  box-shadow: 0 1px 2px rgba(20,20,20,.04),
              0 12px 28px -14px rgba(20,20,20,.16);
}
.ae-card.you {
  background: var(--papier);
  box-shadow: inset 0 0 0 1px var(--linie-klar),
              0 1px 2px rgba(20,20,20,.04),
              0 12px 28px -14px rgba(20,20,20,.16);
}
.ae-card.writes {
  background: var(--dunkel); color: #fff; margin-top: 0;
  box-shadow: 0 1px 2px rgba(20,20,20,.10),
              0 14px 32px -14px rgba(20,20,20,.30);
}
:root[data-theme="dark"] .ae-card.writes { background: var(--papier-tief); color: var(--tinte); }
.ae-card .lab {
  font-size: var(--gr-klein); font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: var(--tinte-leise); margin-bottom: var(--a2);
}
/* Feste Farbe, weil die Karte im hellen Blatt SCHWARZ ist: --tinte-leise
   waere dort dunkelgrau auf Schwarz. Im dunklen Blatt ist die Karte aber
   #242424, und dann steht dasselbe Grau bei 4,50:1, also genau auf der
   Schwelle. Dort gilt deshalb der Wert aus dem Thema. */
.ae-card.writes .lab { color: #8a8a8a; }
:root[data-theme="dark"] .ae-card.writes .lab { color: var(--tinte-leise); }
.ae-card .txt { min-height: 66px; font-size: 15.5px; line-height: 1.6; }
/* Der Pfeil zwischen den beiden Karten sagt "daraus wird das" - er traegt
   also eine Aussage und ist kein Zierrat. Als blosses Zeichen sass er mit
   height:0 halb ueber der dunklen Karte und kam dort auf 3,88:1. Als Plaettchen
   bringt er seinen eigenen Grund mit und ist damit unabhaengig davon, was
   zufaellig darunter liegt. */
.ae-arrow {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  /* margin:0 und nicht -15px: Der Pfeil ist eine eigene Zeile im Raster und
     traegt seine Hoehe selbst. Mit dem negativen Rand hatte er keine, sass
     auf der Naht und klebte die beiden Karten aneinander. */
  margin: 0 auto;
  border-radius: 50%;
  background: var(--dunkel);
  color: var(--papier);
  font-size: 16px;
  line-height: 1;
  /* Kein Ring mehr: Er war dazu da, den Pfeil vom Grund abzusetzen, wenn er
     halb auf einer Karte lag. Jetzt liegt er auf nichts. */
  box-shadow: 0 2px 8px -2px rgba(20,20,20,.30);
}
:root[data-theme="dark"] .ae-arrow { background: var(--papier-tief); color: var(--tinte); }
/* Die zwei Merkzettel sassen an festen Pixelwerten IM Markup ("top:14px;
   right:22px"). Eine Gestaltungsentscheidung im style-Attribut findet beim
   naechsten Umbau niemand wieder - deshalb stehen sie jetzt hier. */
.fix-chip {
  position: absolute; top: var(--a4); right: var(--a5);
  padding: 5px var(--a3); border-radius: var(--r-rund);
  background: var(--papier); color: var(--tinte);
  box-shadow: 0 4px 14px rgba(20,20,20,.12);
  font-size: 12px; font-weight: 600; white-space: nowrap;
}
.fix-chip.zwei { top: auto; right: auto; bottom: -10px; left: var(--a8); }

/* --- Die Preiskarten --- */
.pr-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--a5);
  text-align: left;
}
.pr-card {
  position: relative;
  display: flex; flex-direction: column;
  padding: var(--a8) var(--a6) var(--a6);
  border-radius: var(--r-gross);
  background: var(--papier);
  box-shadow: inset 0 0 0 1px var(--linie);
}
/* Der eine Tarif, um den es geht, bekommt eine FLAECHE - keinen Rahmen und
   keine zweite Farbe. Ein farbiger Rahmen um eine von drei Karten liest sich
   wie eine Warnung, nicht wie eine Empfehlung. */
.pr-card.hot { background: var(--papier-still); box-shadow: inset 0 0 0 1px var(--linie-klar); }
.pr-badge {
  position: absolute; top: -11px; left: var(--a6);
  padding: 4px var(--a3); border-radius: var(--r-rund);
  background: var(--dunkel); color: var(--papier);
  font-size: 11.5px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
}
.pr-card .for { font-size: var(--gr-klein); font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: var(--tinte-leise); }
.pr-card h3 { font-size: var(--gr-mittel); letter-spacing: -.02em; margin: var(--a3) 0 var(--a2); }
.pr-card .price { font-size: 2.25rem; font-weight: 700; letter-spacing: -.04em;
  font-variant-numeric: tabular-nums; line-height: 1.1; }
.pr-card .price .per { font-size: 15px; font-weight: 500; color: var(--tinte-leise); letter-spacing: 0; }
.pr-card .price .jz { display: block; font-size: 13px; font-weight: 500; color: var(--tinte-leise); letter-spacing: 0; margin-top: 2px; }
.pr-card ul { list-style: none; margin: var(--a5) 0 var(--a6); padding: 0; flex: 1; }
.pr-card li { position: relative; padding-left: var(--a6); margin-bottom: var(--a3);
  font-size: 15px; color: var(--tinte-still); }
.pr-card li::before { content: "✓"; position: absolute; left: 0; color: var(--tinte); font-weight: 600; }

/* --- Der Schalter monatlich/jaehrlich ---
   Die Rinne ist die Flaeche, der laufende Knopf ist das, was sich bewegt. Ein
   Schalter, bei dem stattdessen die Beschriftung die Farbe wechselt, sagt
   nicht, dass es ZWEI Zustaende gibt - er sieht aus wie ein Fehler. */
.zeitwahl-pr {
  /* flex mit fit-content und automatischem Rand statt inline-flex: Ein
     inline-flex haengt daran, dass der Elternteil zentriert - und auf der
     Preisseite tut er das nicht, weshalb der Schalter dort links klebte.
     So zentriert er sich selbst, egal wo er steht. */
  position: relative; display: flex; width: fit-content; margin-inline: auto; gap: 0;
  padding: 4px; border-radius: var(--r-rund);
  background: var(--papier-tief);
}
.zeitwahl-pr button {
  position: relative; z-index: 1;
  height: 36px; padding-inline: var(--a5);
  border: 0; border-radius: var(--r-rund); background: transparent;
  color: var(--tinte-still); font-size: 14px; font-weight: 600; cursor: pointer;
  transition: color var(--zeit-kurz) var(--bogen);
}
.zeitwahl-pr button.an { color: var(--tinte); }
.zeitwahl-pr button:focus-visible { outline: 2px solid var(--tinte); outline-offset: 2px; }
.zeitwahl-pr button em { font-style: normal; color: var(--tinte-leise); }
.zeitwahl-pr button.an em { color: var(--tinte-still); }
/* Der laufende Anzeiger ist das ::before des Schalters - main.js misst den
   aktiven Knopf und setzt --an-x und --an-w. Diese Mechanik bleibt; nur die
   Farbe dreht sich um.

   Vorher: dunkler Anzeiger, weisse Beschriftung darauf. Jetzt: heller
   Anzeiger auf grauer Rinne, dunkle Beschriftung. Das ist nicht Geschmack,
   sondern folgt aus dem Rest der Seite - der einzige schwarze Knopf ist der,
   den man druecken SOLL. Ein zweiter schwarzer Knopf, der nur eine
   Einstellung umlegt, nimmt ihm genau das weg.

   Beim Umbau stand eine halbe Sekunde lang dunkle Schrift auf dunklem
   Anzeiger - unlesbar. Deshalb wird die Hinterlegung am Knopf hier
   ausdruecklich abgeraeumt und nicht nur ueberschrieben. */
.zeitwahl-pr::before {
  background: var(--papier);
  box-shadow: 0 1px 3px rgba(20, 20, 20, .10);
}
.zeitwahl-pr button.an,
.zeitwahl-pr.gleitet button.an { background: none; box-shadow: none; color: var(--tinte); }

/* --- Das Fenster im Aufmacher --- */
/* Der Abstand zum Fenster waechst mit. 72 Punkte waren die Obergrenze und
   damit bei einer 96-Punkt-Ueberschrift zu wenig: Der Aufmacher und die
   Vorfuehrung darunter lasen sich als ein Block statt als zwei Sachen. */
.hero-demo { margin-top: clamp(var(--a12), 7vw, 104px); }
.win {
  max-width: 900px; margin-inline: auto;
  border-radius: var(--r-flaeche); overflow: hidden;
  background: var(--dunkel); color: #fff; text-align: left;
  box-shadow: 0 24px 64px rgba(20, 20, 20, .13);
}
:root[data-theme="dark"] .win { background: var(--papier-tief); color: var(--tinte); box-shadow: none; }
.win-bar { display: flex; gap: 6px; padding: var(--a4) var(--a5); }
.win-bar i { width: 10px; height: 10px; border-radius: 50%; background: #ffffff1f; }
.win-body { padding: var(--a5) var(--a6) var(--a10); min-height: 132px; }
.typed { font-size: clamp(17px, 2vw, 21px); line-height: 1.5; letter-spacing: -.01em; }
.win-foot { padding: 0 var(--a6) var(--a6); }
.win-foot .pille { background: #ffffff14; color: #fff; }
:root[data-theme="dark"] .win-foot .pille { background: var(--papier); color: var(--tinte); }

/* --- Das Wettrennen Tastatur gegen Stimme --- */
.race { display: grid; grid-template-columns: 1fr 1fr; gap: var(--a5); text-align: left; }
@media (max-width: 760px) { .race { grid-template-columns: 1fr; } }
.lane { padding: var(--a6); border-radius: var(--r-gross); background: var(--papier-still); }
.lane.voice { background: var(--dunkel); color: #fff; }
:root[data-theme="dark"] .lane.voice { background: var(--papier-tief); color: var(--tinte); }
.lane .cap { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: var(--a4); }
.lane .who { font-weight: 600; }
.lane .wpm { font-size: var(--gr-klein); color: var(--tinte-leise); font-variant-numeric: tabular-nums; }
.lane.voice .wpm { color: #8a8a8a; }
.lane .out { min-height: 78px; font-size: 15px; line-height: 1.55; }
.lane .prog { height: 3px; border-radius: 2px; background: var(--linie-stark); overflow: hidden; }
.lane .prog i { display: block; height: 100%; width: 0; background: var(--tinte); border-radius: 2px; }
.lane.voice .prog { background: #ffffff1f; }
.lane.voice .prog i { background: #fff; }
.lane .stat { display: flex; align-items: center; gap: var(--a3); margin-top: var(--a3);
  font-size: var(--gr-klein); color: var(--tinte-leise); font-variant-numeric: tabular-nums; }

/* --- Das laufende Band mit den Stimmen --- */
.t-marquee { overflow: hidden; mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); }
.t-row { display: flex; gap: var(--a5); width: max-content; }

/* ══ 17. Textseiten ═════════════════════════════════════════════════════════
 *
 * Impressum, Datenschutz, AGB, Kuendigung, Ueber uns. Fuenf Seiten, die
 * niemand zum Vergnuegen liest - aber jemand liest sie, wenn er kurz vor
 * einer Zahlung wissen will, mit wem er es zu tun hat. Genau dann darf die
 * Seite nicht aussehen wie ein abgelegtes Pflichtdokument.
 *
 * Die Spalte ist 760px breit, und das ist keine runde Zahl aus Bequemlichkeit:
 * Bei 16px Schrift sind das rund 90 Zeichen je Zeile. Darueber findet das Auge
 * den Anfang der naechsten Zeile nicht mehr zuverlaessig wieder, und man liest
 * dieselbe Zeile zweimal.
 */
.legal-wrap {
  max-width: var(--schmal);
  margin-inline: auto;
  padding: var(--a16) var(--rand) var(--a20);
}
.legal-wrap h1 {
  font-size: clamp(2.25rem, 5vw, 3rem);
  line-height: 1.05;
  letter-spacing: -.04em;
  margin-bottom: var(--a5);
}
/* Der Abstand ueber einer Zwischenueberschrift ist gross, der darunter klein:
   Die Ueberschrift gehoert zu dem, was FOLGT. Stehen beide gleich weit, haengt
   sie zwischen zwei Abschnitten und man weiss nicht, zu welchem. */
.legal-wrap h2 {
  font-size: var(--gr-mittel);
  line-height: 1.3;
  letter-spacing: -.02em;
  margin: var(--a12) 0 var(--a3);
  padding-top: var(--a5);
  border-top: 1px solid var(--linie);
}
.legal-wrap h1 + p, .legal-wrap h1 + .t-lies { color: var(--tinte-still); font-size: var(--gr-lies); }
.legal-wrap h3 { font-size: 1.0625rem; margin: var(--a6) 0 var(--a2); }
.legal-wrap p, .legal-wrap li { color: var(--tinte-still); }
.legal-wrap a { text-decoration: underline; text-underline-offset: 2px; }
.legal-wrap a:hover { color: var(--tinte); }
.legal-wrap ul, .legal-wrap ol { padding-left: var(--a5); margin: 0 0 var(--a4); }
.legal-wrap li { margin-bottom: var(--a2); }
.legal-wrap table { width: 100%; border-collapse: collapse; margin: var(--a5) 0; font-size: 15px; }
.legal-wrap th, .legal-wrap td { padding: var(--a3) var(--a4); border-bottom: 1px solid var(--linie); text-align: left; }
.legal-wrap th { font-weight: 600; color: var(--tinte); }
.legal-wrap td { color: var(--tinte-still); }

/* Die schmale Fusszeile der Textseiten. Sie traegt dieselben drei Verweise wie
   die grosse - das ist die Form, die § 5 DDG meint. */
.legal-foot {
  display: flex; justify-content: space-between; gap: var(--a4); flex-wrap: wrap;
  margin-top: var(--a16); padding-top: var(--a5);
  border-top: 1px solid var(--linie);
  color: var(--tinte-leise); font-size: var(--gr-klein);
}
.legal-foot a { color: var(--tinte-still); text-decoration: none; }
.legal-foot a:hover { color: var(--tinte); text-decoration: underline; }

/* ══ 18. Zwei Stellen, die die Kontrastmessung gefunden hat ═════════════════ */

/* Die Zeile unter den Download-Karten stand in #8a8a8a und kam damit auf
   2,83:1. Sie traegt eine Aussage, die man vor dem Herunterladen lesen will
   ("One app, both systems"), also ist sie kein Zierrat. */
.note, .hero-banner .note, .final .note { color: var(--tinte-still); }

/* "Watch on YouTube": Weiss auf YouTube-Rot sind 4,00:1 - unter der Schwelle
   von 4,5 fuer Fliesstext, aber ueber der von 3,0 fuer GROSSE Schrift, und
   gross heisst ab 18,66px fett. Statt das Rot zu faelschen (dann ist es nicht
   mehr die Marke, auf die der Knopf zeigt) waechst die Schrift auf genau die
   Groesse, fuer die der Kontrast reicht. Das ist keine Umgehung der Regel,
   sondern die Regel: Grosse Schrift braucht weniger Kontrast, weil sie mehr
   Flaeche hat. */
.show-knoepfe .show-yt { font-size: 19px; font-weight: 700; }

/* ══ 18b. Die Bausteine des neuen Aufbaus ══════════════════════════════════
 *
 * Diese fuenf gab es vorher nicht, weil es die Abschnitte nicht gab. Sie
 * stehen in derselben Reihenfolge wie auf der Seite.
 */

/* --- Der Aufmacher ---
   Weniger Luft oben als beim alten: Der wichtigste Satz der Seite soll nicht
   erst nach einem Bildschirm Leere kommen. */
.feld-auf { padding: clamp(48px, 6vw, 88px) 0 var(--a-abschnitt); }
.feld-schmal { padding-block: var(--a12); }

/* --- 2 · Die Reihe der Programme ---
   Leise, einzeilig, ohne Kaesten. Sie soll man UEBERFLIEGEN und nicht lesen:
   Die Aussage ist "viele", nicht "diese hier". Deshalb auch keine Zeichen -
   acht bunte Logos nebeneinander ziehen mehr Aufmerksamkeit auf sich als der
   Satz darueber. */
.logo-band {
  display: flex; flex-wrap: wrap;
  justify-content: center; align-items: center;
  gap: var(--a4) clamp(var(--a5), 3vw, var(--a10));
}
.logo-band span {
  font-size: clamp(15px, 1.4vw, 17px);
  font-weight: 600;
  letter-spacing: -.01em;
  color: var(--tinte-leise);
  transition: color var(--zeit-kurz) var(--bogen);
}
@media (hover: hover) { .logo-band span:hover { color: var(--tinte); } }

/* --- 3 · Die Geschwindigkeit als Grafik ---
 *
 * Hier standen drei grosse Ziffern. Eine Ziffer ist Typografie, keine
 * Darstellung: "5×" muss man glauben. Zwei Balken im wahren Verhaeltnis kann
 * man nachmessen - und genau das ist der Unterschied.
 *
 * Die Laengen sind gerechnet, nicht gestaltet: 45 von 220 Woertern sind
 * 20,5 %. Steht die Zahl im Text einmal anders, sieht man es sofort am Bild.
 */
.tempo-bild {
  /* So breit wie die Sprachkarte darueber. 880 Punkte waren ein Rest aus der
     Zeit, als die Karte allein in einem schmalen Abschnitt stand: Seit die
     Sprachen direkt darueber die ganze Bahn nehmen, sass sie darunter wie
     eingerueckt, und zwei Karten mit verschiedenen Raendern lesen sich als
     zwei verschiedene Abschnitte. */
  margin: 56px auto 0;
  /* "Mach das Feld laenger": Das Polster war eng gerechnet, und die Karte sass
     damit wie ein Kasten um zwei Balken. Mehr Luft oben und unten macht aus
     ihr eine Flaeche, auf der etwas gezeigt wird - und die beiden Zahlen
     bekommen Platz, statt sich den Rand zu teilen. */
  padding: clamp(var(--a8), 5vw, var(--a16)) clamp(var(--a6), 4vw, var(--a12));
  border-radius: var(--r-flaeche);
  background: var(--papier);
  box-shadow: inset 0 0 0 1px var(--linie),
              0 1px 2px rgba(20,20,20,.04),
              0 20px 48px -24px rgba(20,20,20,.12);
}
.tempo-zeile + .tempo-zeile { margin-top: var(--a10); }
.tempo-kopf { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 10px; }
.tempo-was { font-size: 15px; font-weight: 600; color: var(--tinte-still); }
.tempo-wert { font-size: clamp(1.75rem, 3vw, 2.5rem); font-weight: 700;
  letter-spacing: -.04em; line-height: 1; font-variant-numeric: tabular-nums; }
.tempo-wert i { font-style: normal; font-size: 14px; font-weight: 500;
  letter-spacing: 0; color: var(--tinte-leise); margin-left: 6px; }

.tempo-bahn { height: 18px; border-radius: 999px; background: var(--papier-tief); overflow: hidden; }
/* Der Balken hat eine eigene Uhr.
 *
 * Vorher hing seine Breite an --p aus bewegung.js, und --p ist der Weg des
 * Elements durchs Bild. Wer schnell scrollt, sieht den Balken deshalb nicht
 * wachsen, sondern schon voll: Die Grafik war so schnell wie der Daumen und
 * damit gar keine Grafik mehr. Gemeldet genau so.
 *
 * Jetzt laeuft er in eigener Zeit, sobald der Block im Bild steht. Eine
 * Sekunde, mit einer Kurve, die schnell anfaengt und weich ausklingt; die
 * zweite Zeile setzt 350 ms spaeter ein, damit man den Vergleich als
 * Bewegung liest und nicht als zwei Striche, die gleichzeitig erscheinen.
 *
 * .laeuft setzt main.js, sobald die UNTERE Bahn wirklich im Bild steht. Nicht
 * .in: Die kommt grosszuegig, schon wenn die Karte 200 Punkte unter dem
 * Bildschirmrand haengt, und dann war das Fuellen vorbei, bevor es jemand
 * gesehen hat. Auf dem Telefon gemessen und gemeldet.
 *
 * alles-zeigen ist die Notbremse aus dem Kopf der Seite. Beide fuellen den
 * Balken ganz: Ein Balken, der leer bleibt, weil ein Skript klemmt, ist
 * kaputt und nicht zurueckhaltend. */
.tempo-bahn i {
  display: block; height: 100%; border-radius: 999px;
  width: 0;
  background: var(--tinte-leise);
  transition: width 1s cubic-bezier(.22, .8, .25, 1);
}
.tempo-bild.laeuft .tempo-bahn i,
html.alles-zeigen .tempo-bahn i { width: var(--anteil); }
.tempo-bild.laeuft .tempo-zeile.stimme .tempo-bahn i { transition-delay: .35s; }
/* Zurueckgenommen wird ohne Uebergang.
   Die Karte zaehlt bei jedem Vorbeiscrollen wieder (siehe main.js), und
   zurueckgestellt wird sie, sobald sie ganz aus dem Bild ist. Liefe der
   Balken dabei in einer Sekunde auf null, faende jemand, der schnell wieder
   heraufscrollt, einen halb geschrumpften Balken vor, der von dort aus
   weiterwaechst. Der Sprung passiert ausserhalb des Bildes und sieht darum
   niemand. */
.tempo-bild.zurueck .tempo-bahn i { transition: none; width: 0; }
@media (prefers-reduced-motion: reduce) {
  .tempo-bahn i { transition: none; width: var(--anteil); }
}
.tempo-zeile.stimme .tempo-bahn i { background: var(--dunkel); }
:root[data-theme="dark"] .tempo-zeile.stimme .tempo-bahn i { background: var(--tinte); }
/* Das Fazit stand als ein Absatz da: fette Zahl, Gedankenstrich, Erklaerung.
   Jetzt sind es zwei Zeilen - oben die Zahl, darunter der Satz. Das ist nicht
   nur Gestaltung: Der Gedankenstrich war genau der, der hier nicht mehr
   vorkommen soll, und ohne ihn braucht die Zahl ihre eigene Zeile. */
.tempo-fazit { margin: var(--a10) 0 0; padding-top: var(--a8);
  border-top: 1px solid var(--linie); color: var(--tinte-still); font-size: 16px; }
.tempo-fazit b {
  display: block; margin-bottom: 6px;
  color: var(--tinte); font-weight: 700;
  font-size: clamp(1.5rem, 2.6vw, 2rem); letter-spacing: -.035em; line-height: 1;
}
.tempo-fazit span { display: block; }

/* ---- Die Sprachkarte ----
 *
 * Hier standen zwei schmale Karten nebeneinander, "100+ Sprachen" und
 * "0 Fenster zum Wechseln". Die zweite ist auf Ansage raus, und sie war auch
 * die schwaechere: Sie sagte dasselbe wie der Aufmacher, nur als Ziffer, und
 * eine Null als Kennzahl liest sich wie ein Messfehler.
 *
 * Die Sprachen bekommen dafuer die ganze Breite und etwas, das eine Zahl nie
 * kann: Gesichter. Zehn runde Flaggen hintereinander, und am Ende steht, wie
 * viele noch kommen. "100+" ist eine Behauptung; zehn Flaggen und ein "+ 90
 * more" sind eine Aufzaehlung, die man abbrechen musste. */
.sprach-karte {
  /* DER RING UM DIE SCHEIBEN TRAEGT DIE FARBE DIESER KARTE.
     Er ist kein Rand, er ist der Abstand zwischen zwei Scheiben, nur innerhalb
     der Form statt daneben. Dafuer muss er genau so aussehen wie der Grund,
     auf dem er liegt. Er stand fest auf --papier; im dunklen Blatt ist die
     Karte aber --papier-still, und damit sass um jede Flagge ein Ring, der
     DUNKLER war als die Karte: ein schwarzer Hof, den niemand bestellt hat.
     Als Wert an der Karte geht er mit, wo immer die Karte hinkommt. */
  --scheibe: var(--papier);

  /* ZWEI SPALTEN, nicht eine. Vorher stand alles linksbuendig untereinander
     und die rechte Haelfte der Karte blieb leer - auf einem 1440er Bildschirm
     rund siebenhundert Punkte Nichts neben einem Absatz. Eine Karte, die nur
     zur Haelfte benutzt wird, sieht nicht ruhig aus, sondern unfertig.

     Links steht, was gelesen wird, rechts, was gesehen wird. Die Spalten sind
     bewusst UNGLEICH (5 zu 4): Gleich breite Spalten legen nahe, dass beide
     Seiten dasselbe Gewicht haben, und das stimmt hier nicht - der Satz
     traegt die Aussage, die Flaggen belegen sie. */
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 4fr);
  align-items: center;
  gap: var(--a10) var(--a16);
  margin-top: var(--a5);
  padding: var(--a12) var(--a10);
  border-radius: var(--r-flaeche);
  background: var(--papier);
  box-shadow: inset 0 0 0 1px var(--linie-klar);
}
.sprach-kopf b {
  display: block;
  /* Groesser als vorher: Die Zahl ist das Argument dieser Karte, und sie stand
     in derselben Stufe wie eine gewoehnliche Abschnittsueberschrift. */
  font-size: clamp(3rem, 5.5vw, 4.5rem); font-weight: 700;
  letter-spacing: -.04em; line-height: .92;
}
.sprach-kopf span {
  display: block; margin-top: var(--a2);
  font-size: 18px; font-weight: 600; color: var(--tinte);
}
.sprach-satz { margin: var(--a5) 0 0; max-width: 42ch;
  font-size: 16px; line-height: 1.62; color: var(--tinte-still); }

/* Die Flaggen als RASTER und nicht als Reihe. Als Reihe lagen sie in einer
   Zeile unter dem Text und liefen dort aus; als Raster in der zweiten Spalte
   bilden sie einen Block, der der Textspalte an Gewicht standhaelt.

   Vier Spalten mal drei Zeilen sind zwoelf Felder: zehn Flaggen, und das
   Schild mit der Restzahl nimmt die letzten beiden. Deshalb bleibt kein Feld
   leer, und deshalb hoert die Aufzaehlung nicht willkuerlich auf. */
/* Die Flaggen liegen uebereinander wie ein Stapel Karten, nicht nebeneinander
   wie Kacheln.

   Gemeldet mit einem Bild und einem Strich unter die ganze Reihe: Sie sollen
   aneinandergeklebt sein, so dass von jeder nur der letzte Rest verdeckt ist.
   Und er hat recht - nebeneinander sind zehn Kreise zehn Dinge, die man
   zaehlt; uebereinander sind sie EINE Gruppe. Es ist dieselbe Form, in der
   ueberall Beteiligte an einer Sache gezeigt werden, und sie wird deshalb
   sofort als "viele, und es geht noch weiter" gelesen.

   Der Ring ist der Punkt, ohne den es nicht funktioniert: Ohne ihn beruehren
   sich zwei Flaggenraender und werden zu einem Fleck. Der Ring hat die Farbe
   der Karte, nicht der Flagge - er ist der Abstand, nur eben innerhalb der
   Form statt daneben. */
.sprach-flaggen { display: flex; align-items: center; padding-left: 5px; }
/* DIE GROESSE KOMMT AUS DER BREITE DER REIHE, NICHT AUS EINER ZAHL.
 *
 * Hier standen feste Werte: 54 Punkte am Schreibtisch, auf dem Telefon
 * min(30px, 6.6vw). Beides ging daneben, und zwar in beide Richtungen:
 *
 * Am Schreibtisch war die Reihe ZU BREIT fuer ihre Spalte. Gemessen bei 900
 * Punkten Fensterbreite: Die Spalte ist 304 Punkte breit, elf Scheiben zu 54
 * brauchen 504. Korea war angeschnitten, Saudi-Arabien, die Tuerkei und die
 * "+90" standen ueberhaupt nicht mehr im Bild. Erst ab rund 1350 Punkten
 * passte es. Ein Fehler, den man am grossen Bildschirm nie sieht, weil man
 * dort meistens breiter als 1350 sitzt.
 *
 * Auf dem Telefon war sie ZU SCHMAL: 6,6vw sind bei 390 Punkten 26, und die
 * Reihe brauchte damit 232 von 270 vorhandenen. Gemeldet als "die Groesse
 * ist zu klein", und nachgemessen stimmt es.
 *
 * Jetzt rechnet die Scheibe aus der Breite, die sie wirklich hat. Elf
 * Scheiben, zehn Ueberschneidungen zu je einem Drittel, dazu zwei Punkte
 * Luft vor der "+90":
 *
 *     1 + 9 x (1 - 0,33) + 1 = 8,03 Scheibenbreiten, plus 2 Punkte
 *
 * Der Teiler steht mit 8,05 einen Hauch darueber, damit Rundung nie in den
 * Ueberlauf kippt. Prozente an einem Flex-Kind rechnen gegen die Breite der
 * Reihe, und die kennt jede Spalte, jede Karte und jedes Fenster - deshalb
 * passt es ueberall von selbst, ohne eine Zahl je Bildschirmgroesse.
 *
 * 64 Punkte als Deckel: Darueber wuerden elf Flaggen zu einer Girlande.
 *
 * height: auto mit aspect-ratio statt einer zweiten Prozentzahl: Eine
 * Prozenthoehe rechnet gegen die HOEHE des Elternteils, und die steht hier
 * nicht fest. */
.flagge { flex: none; }
.flagge {
  display: grid; place-items: center;
  width: min(64px, calc((100% - 4px) / 8.05));
  height: auto;
  aspect-ratio: 1;
  border-radius: 50%;
  margin-left: calc(min(64px, (100% - 4px) / 8.05) * -.33);
  position: relative;
  /* Die Stapelhoehe steht als Wert, nicht als fertige Eigenschaft: Die Welle
     weiter unten rechnet damit und hebt die angehobene Flagge um denselben
     Betrag ueber ALLE ruhenden, ohne die Reihenfolge untereinander zu
     verlieren. */
  z-index: var(--z, 1);
  background: var(--scheibe, var(--papier));
  box-shadow: 0 0 0 3px var(--scheibe, var(--papier));
  transition: transform var(--zeit) var(--bogen), box-shadow var(--zeit) var(--bogen);
}
/* DER RING LIEGT ALS EIGENE LAGE UEBER DER FLAGGE.

   Als inset-Schatten an .flagge tat er nichts Sichtbares: Der Schatten eines
   Elements liegt UNTER seinem Inhalt, und die Flagge fuellt den Kreis ganz
   aus. Zu sehen war der Ring deshalb nur an "+90", wo kein Bild darueber
   liegt - und genau das sah dann aus, als habe eine einzige Scheibe eine
   Umrandung bekommen und die anderen nicht.

   Gebraucht wird er, weil helle Flaggen am Rand in den weissen Grund
   auslaufen: Japan und Korea sahen ohne ihn angeschnitten aus. Deutlich, aber
   nicht schwarz - ein voller Strich um jede Flagge macht aus der Reihe ein
   Raster aus Kreisen, und man sieht die Umrandung statt der Flaggen. */
.flagge::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  pointer-events: none;
  box-shadow: inset 0 0 0 2px rgba(20,20,20,.45);
}
:root[data-theme="dark"] .flagge::after {
  box-shadow: inset 0 0 0 2px rgba(255,255,255,.40);
}

/* Die erste liegt ganz oben und die letzte ganz unten - so, wie ein Stapel
   liegt, den jemand von links nach rechts hingelegt hat. Ohne die Stufung
   deckt die LETZTE alle anderen zu, und dann sieht man vom "+90" den ganzen
   Kreis und von der britischen Flagge nichts. */
.flagge:nth-child(1)  { --z: 11; margin-left: 0; }
.flagge:nth-child(2)  { --z: 10; }
.flagge:nth-child(3)  { --z: 9; }
.flagge:nth-child(4)  { --z: 8; }
.flagge:nth-child(5)  { --z: 7; }
.flagge:nth-child(6)  { --z: 6; }
.flagge:nth-child(7)  { --z: 5; }
.flagge:nth-child(8)  { --z: 4; }
.flagge:nth-child(9)  { --z: 3; }
.flagge:nth-child(10) { --z: 2; }
.flagge .cfl { display: block; width: 100%; height: 100%; border-radius: 50%; }

/* Das "+90" ist die letzte Scheibe des Stapels und kein Schild daneben.

   Vorher stand dort ein graues Pillen-Schild mit "+ 90 more" - in derselben
   Reihe wie zehn Kreise, aber breiter, anders geformt und anders gefuellt.
   Das ist die Form, die ein Knopf hat, und es war keiner: Es liess sich nicht
   druecken und tat nichts. Eine Flaeche, die aussieht wie ein Knopf und keiner
   ist, ist der billigste Fehler, den eine Seite machen kann.

   Als dunkle Scheibe in derselben Groesse ist es das, was es wirklich ist:
   das Ende der Aufzaehlung. */
/* "+90" war eine schwarze Scheibe mit weisser Schrift und damit das
   Auffaelligste in der Reihe - ausgerechnet das Element, das nur sagt, dass
   es noch weitergeht. Es zog den Blick an sich und die Flaggen daneben
   wurden zu seinem Hintergrund.

   Jetzt ist es eine Scheibe wie alle anderen: heller Grund, dunkle Schrift,
   derselbe Ring. Es zaehlt weiter, ohne zu rufen. */
/* Die "+90" liegt als letzte GANZ UNTEN im Stapel, jede Nachbarin deckt sie
   zu - bei grossen Scheiben frisst das nur ihren Rand, bei kleinen das
   Pluszeichen. Auf dem Bild stand einmal ".90". Sie rueckt deshalb ein
   Stueck heraus und steht frei; die zwei Punkte sind in der Breite oben
   schon eingerechnet. */
.flagge.mehr {
  --z: 1;
  margin-left: 2px;
  background: var(--scheibe, var(--papier));
}
.flagge.mehr b {
  font-size: 15px; font-weight: 700; letter-spacing: -.02em;
  color: var(--tinte);
}
:root[data-theme="dark"] .flagge.mehr { background: var(--scheibe, var(--papier)); }

@media (hover: hover) {
  /* Beim Zeigen hebt sich die eine heraus, und zwar hinter ihrer linken
     Nachbarin, genau wie in der Welle. Ein z-index stand hier einmal; er
     schob den weissen Ring ueber die Nachbarin und schnitt ihr eine Sichel
     heraus. */
  .flagge:hover { transform: translateY(-5px) scale(1.08);
    box-shadow: 0 0 0 3px var(--scheibe, var(--papier)), inset 0 0 0 1px var(--linie-stark),
                0 10px 20px rgba(20,20,20,.16); }
  .flagge.mehr:hover { box-shadow: 0 0 0 3px var(--scheibe, var(--papier)), 0 10px 20px rgba(20,20,20,.2); }
}

/* DIE WELLE DURCH DIE FLAGGEN.
 *
 * Auf Ansage: Die Flaggen sollen nacheinander huepfen, in Abstaenden, und sich
 * danach wieder zurueckziehen. Derselbe Gedanke wie bei den Chips, nur dass
 * hier elf runde Scheiben uebereinanderliegen.
 *
 * Zwei Dinge, ohne die es nicht aussieht wie gemeint:
 *
 * 1. Der Schatten geht mit. Eine Scheibe, die sich hebt, wirft mehr Schatten;
 *    ohne das sieht es aus, als rutsche sie nach oben statt sich zu heben.
 *
 * 2. Der Weg zurueck dauert laenger als der Weg hinauf. Hinauf 0,18 s, zurueck
 *    0,54 s. Gleich lang gemessen wirkt jede Bewegung mechanisch.
 *
 * Und eines, das hier einmal stand und wieder weg musste: Die angehobene
 * Scheibe wurde nach vorn geholt, damit die linke Nachbarin ihr nicht die
 * Seite abschneidet. Dabei legte sie ihren drei Punkte breiten Ring UEBER
 * diese Nachbarin und biss ihr eine weisse Sichel aus der Flanke. Gemeldet
 * als "das weisse Umfeld kommt spaeter und sieht haesslich aus", und genau
 * das war es: Mit der Welle wanderte eine weisse Kerbe durch die Reihe.
 *
 * Ohne das Vorholen steigt jede Scheibe hinter ihrer linken Nachbarin auf und
 * bleibt vor ihrer rechten, also in derselben Ordnung, in der die Reihe
 * ruht. Abgeschnitten wird dabei nichts: Der Bogen, den die Nachbarin
 * verdeckt, ist genau der, den sie im Ruhen auch verdeckt. Nachgesehen am
 * angehaltenen Bild, bei jeder Scheibe. 
 *
 * DER TAKT: NICHT DER ABSTAND ENTSCHEIDET, SONDERN DIE UEBERLAPPUNG.
 *
 * Drei Werte sind hier durchprobiert worden, und alle drei waren aus
 * demselben Grund falsch.
 *
 *   0,11 s  Elf Flaggen in 1,21 s durch, danach fast zehn Sekunden Stille.
 *           Gemeldet als Flimmern.
 *   2,00 s  Auf dem Telefon sieht man die Reihe nur kurz im Vorbeiscrollen,
 *           und in dieser Zeit passierte ein einziger Sprung.
 *   1,00 s  Gemeldet als "nicht mit zwei Sekunden Pause dazwischen, das soll
 *           eine Welle sein".
 *
 * Der Fehler lag jedes Mal woanders, als an der Zahl gedreht wurde. Was eine
 * Welle zur Welle macht, ist nicht der Abstand zwischen den Scheiben, sondern
 * ob sich ihre Spruenge UEBERSCHNEIDEN. Bei einer Sekunde Abstand und einem
 * Sprung von 1,1 s war immer genau eine Scheibe in der Luft: elf Spruenge
 * nacheinander, eine Prozession. Eine Welle braucht einen Kamm, und ein Kamm
 * ist mehrere Scheiben breit.
 *
 * Jetzt 0,13 s Abstand bei einem Sprung von 0,65 s. Am angehaltenen Bild
 * nachgezaehlt, alle 40 ms ueber viereinhalb Sekunden: drei bis vier
 * Scheiben stehen gleichzeitig in der Luft, jede ein Stueck hoeher oder
 * tiefer als ihre Nachbarin. Das ist von aussen ein Kamm, der durch die
 * Reihe laeuft.
 *
 * Elf mal 0,13 s ergeben 1,43 s, bis der Kamm die letzte Scheibe erreicht,
 * plus ihren eigenen Sprung macht 1,95 s. Der Takt steht auf 1,9 s, der
 * naechste Kamm setzt also ein, waehrend der letzte noch ausklingt.
 * Gemessen bleiben 10 % der Zeit ohne jede Bewegung, gut ein Fuenftel einer
 * Sekunde - eben kein Halt, sondern der Atemzug zwischen zwei Wellen. Bei
 * einer Sekunde Abstand waren es 70 %. */
/* Die Zahlen sind Anteile von 1,9 Sekunden: 11 % sind 0,21 s Anstieg, nach
   34 % steht die Scheibe wieder. Der Hub geht mit der Groesse mit, sonst
   huepfte eine 64er Scheibe genauso weit wie eine 25er - bei der einen waere
   es ein Wippen, bei der anderen ein Satz. */
@keyframes flaggen-welle {
  0%    { transform: translateY(0) scale(1);
          box-shadow: 0 0 0 3px var(--scheibe, var(--papier)); }
  11%   { transform: translateY(-22%) scale(1.09);
          box-shadow: 0 0 0 3px var(--scheibe, var(--papier)), 0 12px 22px rgba(20, 20, 20, .20); }
  34%   { transform: translateY(0) scale(1);
          box-shadow: 0 0 0 3px var(--scheibe, var(--papier)); }
  100%  { transform: translateY(0) scale(1);
          box-shadow: 0 0 0 3px var(--scheibe, var(--papier)); }
}
.flagge { animation: flaggen-welle 1.9s var(--bogen) infinite; }
.flagge:nth-child(1)  { animation-delay: 0s; }
.flagge:nth-child(2)  { animation-delay: .13s; }
.flagge:nth-child(3)  { animation-delay: .26s; }
.flagge:nth-child(4)  { animation-delay: .39s; }
.flagge:nth-child(5)  { animation-delay: .52s; }
.flagge:nth-child(6)  { animation-delay: .65s; }
.flagge:nth-child(7)  { animation-delay: .78s; }
.flagge:nth-child(8)  { animation-delay: .91s; }
.flagge:nth-child(9)  { animation-delay: 1.04s; }
.flagge:nth-child(10) { animation-delay: 1.17s; }
.flagge:nth-child(11) { animation-delay: 1.3s; }
/* Wer die Maus in die Reihe haelt, legt die Welle ab, statt sie anzuhalten.
   Angehalten bliebe jede Flagge auf dem Bild stehen, das gerade dran war, also
   die halbe Reihe schief in der Luft. Und eine laufende Bildfolge schlaegt
   jedes transform aus einer Regel: Das Anheben beim Zeigen waere wirkungslos.

   Ohne Bildfolge sinken alle ueber ihren Uebergang zurueck, weich, und die
   eine unter dem Zeiger hebt sich. Geht die Maus wieder heraus, setzt die
   Welle von vorne ein. */
@media (hover: hover) {
  .sprach-flaggen:hover .flagge { animation: none; }
}
@media (prefers-reduced-motion: reduce) {
  .flagge { transition: none; animation: none; }
}
:root[data-theme="dark"] .sprach-karte {
  background: var(--papier-still);
  --scheibe: var(--papier-still);
}

/* DIE SPRACHKARTE AUF DEM TELEFON.
 *
 * Sie war zweispaltig, und es fehlte die Regel, die daraus eine Spalte macht.
 * Bei 390 Punkten blieben 114 fuer den Text und 91 fuer elf Flaggen: Der Satz
 * brach nach drei Woertern um, die Flaggen wurden zur Sprungfeder.
 *
 * Untereinander also, und die Scheiben kleiner. Nachgemessen statt geschaetzt:
 * Eine Karte hat auf einem 390er Schirm INNEN 270 Punkte, nicht 350, sie hat
 * ja selbst noch Rand. Elf Scheiben zu 30 Punkten mit 7 Punkten
 * Ueberschneidung brauchen 30 + 10 * (30 - 7) = 260 und passen hinein.
 *
 * Beim ersten Versuch standen hier 36, gerechnet gegen die falschen 350, und
 * die Reihe stand 59 Punkte ueber. Deshalb die Zahl im Kommentar: damit der
 * Naechste gegen die richtige Breite rechnet. */
@media (max-width: 820px) {
  .sprach-karte { grid-template-columns: minmax(0, 1fr); gap: var(--a6); }
  .sprach-flaggen { justify-content: flex-start; padding-left: 3px; }
  /* Breite und Ueberschneidung stehen oben und rechnen sich aus der Reihe;
     hier bleibt nur, was auf dem Telefon anders ist: ein duennerer Ring und
     eine duennere Kante, weil die Scheiben kleiner sind. */
  .flagge { box-shadow: 0 0 0 2px var(--scheibe, var(--papier)); }
  .flagge.mehr b { font-size: 12px; }
  .flagge::after { box-shadow: inset 0 0 0 1.5px rgba(20,20,20,.45); }
  :root[data-theme="dark"] .flagge::after { box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.40); }
}

/* --- 4 · Die Chips ---
   Zwoelf kleine Flaechen, die man in zwei Sekunden ueberfliegt. Eine Liste mit
   zwoelf Punkten haette dieselben Woerter und wuerde gelesen statt
   ueberflogen - und beim achten Punkt haette man aufgehoert. */
.chips { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--a2); }
/* Ruhe ist hell, der Sprung ist dunkel.
   Das war schon einmal umgekehrt: Auf Ansage leuchtete die huepfende Kachel
   weiss auf, und auf Ansage steht es jetzt wieder so wie davor, weil die
   weisse Reihe komisch aussah. Der Ring, den die weisse Kachel brauchte, um
   sich vom Blatt abzusetzen, faellt damit auch wieder weg.

   Was BLEIBT, ist der harte Wechsel weiter unten. Der gehoert nicht zur
   Farbfrage, er behebt einen eigenen Fehler. */
.chips span {
  padding: 9px var(--a4);
  border-radius: var(--r-rund);
  background: var(--papier-tief);
  color: var(--tinte-still);
  font-size: 14.5px; font-weight: 500;
  transition: background var(--zeit-kurz) var(--bogen), color var(--zeit-kurz) var(--bogen);
}
@media (hover: hover) { .chips span:hover { background: var(--dunkel); color: var(--papier); } }

/* DIE WELLE DURCH DIE WOLKE.
 *
 * Auf Ansage: Die Woerter sollen nacheinander hell werden und kurz springen,
 * als liefe eine Welle durch die Reihe, in Dauerschleife.
 *
 * Und sie sagt etwas. Die Wolke zaehlt auf, was Fastspeech im Vorbeigehen
 * aufraeumt, und genau so laeuft es auch: nicht alles auf einmal, sondern
 * eines nach dem anderen, waehrend man spricht. Eine Reihe, die still
 * dasteht, ist eine Liste; eine, durch die etwas hindurchlaeuft, ist ein
 * Vorgang.
 *
 * DER TAKT: DREI SEKUNDEN JE WORT, UND IMMER NUR EINES.
 *
 * Vorher sprang alle 0,42 Sekunden das naechste an, und mehrere leuchteten
 * gleichzeitig. Gemeldet als "das geht zu schnell", und beim Nachsehen
 * stimmt es: Zwoelf Woerter in fuenf Sekunden liest niemand mit, das flackert
 * nur. Jetzt steht jedes Wort DREI SEKUNDEN und uebergibt dann an das
 * naechste. Man hat Zeit, es zu lesen, bevor das naechste dran ist.
 *
 * Die Uebergabe ist nahtlos: Die Leuchtzeit ist genau so lang wie der
 * Versatz, also geht eines aus, waehrend das naechste angeht. Es ist nie
 * keines an und nie zwei. Zwoelf Woerter zu drei Sekunden ergeben 36
 * Sekunden; danach faengt es wieder vorne an.
 *
 * Der Versatz steht als nth-child hier und nicht als Zahl im Blatt oder als
 * Variable aus dem Skript. Beides waere kuerzer gewesen und beides ging nicht:
 * rhythmus.css setzt an jedes Kind einer data-staffel-Gruppe
 * "animation-delay: var(--stufe) !important", und ein !important schlaegt
 * jede Verzoegerung, die hier steht. Deshalb traegt die Wolke kein
 * data-staffel mehr, und die zwoelf Zeilen unten sind der Preis dafuer, dass
 * die Welle ohne Skript laeuft. */
/* DER AUGENBLICK, IN DEM EIN WORT DRAN IST.
 *
 * Hier standen sieben Punkte Sprung und ein Ring. Zurueckgemeldet: "das hat
 * eine richtig billige oder fast gar keine Animation" - und beim Nachsehen
 * stimmt das. Sieben Punkte an einer vierzig Punkte hohen Kachel sind ein
 * Zucken, und ein einzelner blasser Ring verschwindet auf einem hellen Blatt,
 * bevor das Auge ihn findet.
 *
 * Was jetzt in den ersten anderthalb Sekunden passiert, und warum jedes
 * Stueck davon da ist:
 *
 * 1. SIE HEBT AB. Zwoelf Punkte hoch und ein Stueck groesser, mit einem
 *    Schatten darunter. Nicht "sie wackelt", sondern "sie liegt jetzt oben".
 *
 * 2. SIE KOMMT MIT GEWICHT ZURUECK. Hoch in 0,25 s, zurueck ueber 0,8 s, und
 *    dazwischen ein kurzes Nachfedern. Gleich lang hin und zurueck wirkt
 *    mechanisch; das Nachfedern ist der Unterschied zwischen einem Bauteil
 *    und einem Gegenstand.
 *
 * 3. ZWEI RINGE LAUFEN HINAUS, nicht einer, und zeitversetzt. Der zweite
 *    faengt an, wenn der erste schon halb verlaufen ist. Ein Ring ist ein
 *    Rand, zwei sind eine Welle - und genau die war gemeint, als "ein
 *    besonderer Effekt" gewuenscht wurde.
 *
 * Alle drei liegen als Schatten AN der Kachel und nicht als eigene Lagen:
 * Eigene Lagen braeuchten zwoelf eigene Verzoegerungen, Schatten laufen in
 * derselben Bildfolge mit. Dass jedes Bild dieselbe ANZAHL Schatten traegt,
 * ist dabei Pflicht - sonst blendet der Browser sie gegen Nichts und die
 * Ringe springen.
 *
 * Die Zahlen sind Anteile von 36 Sekunden: 0,7 % sind 0,25 s. Nach 4,2 %,
 * also rund anderthalb Sekunden, ist alles vorbei und das Wort steht ruhig
 * da, bis es nach drei Sekunden abgibt. */
@keyframes chip-welle {
  0%    { transform: translateY(0) scale(1);
          box-shadow: 0 0 0 0 var(--chip-ring),
                      0 0 0 0 var(--chip-ring),
                      0 0 0 0 rgba(20, 20, 20, 0); }
  0.7%  { transform: translateY(-12px) scale(1.07);
          box-shadow: 0 0 0 7px var(--chip-ring),
                      0 0 0 0 var(--chip-ring),
                      0 14px 24px -6px rgba(20, 20, 20, .22); }
  1.9%  { transform: translateY(-3px) scale(1.02);
          box-shadow: 0 0 0 18px rgba(20, 20, 20, 0),
                      0 0 0 7px var(--chip-ring),
                      0 8px 16px -6px rgba(20, 20, 20, .14); }
  2.9%  { transform: translateY(0) scale(1);
          box-shadow: 0 0 0 24px rgba(20, 20, 20, 0),
                      0 0 0 16px rgba(20, 20, 20, 0),
                      0 3px 8px -4px rgba(20, 20, 20, .06); }
  4.2%  { transform: translateY(0) scale(1);
          box-shadow: 0 0 0 0 rgba(20, 20, 20, 0),
                      0 0 0 0 rgba(20, 20, 20, 0),
                      0 0 0 0 rgba(20, 20, 20, 0); }
  100%  { transform: translateY(0) scale(1);
          box-shadow: 0 0 0 0 rgba(20, 20, 20, 0),
                      0 0 0 0 rgba(20, 20, 20, 0),
                      0 0 0 0 rgba(20, 20, 20, 0); }
}

/* Die angehobene Kachel gehoert nach VORN.
 *
 * Ohne das laufen ihre Ringe unter die Nachbarinnen und werden von deren
 * Flaechen abgeschnitten: Die Welle endet dann mitten in der Luft. Die
 * Kacheln liegen im Gegensatz zu den Flaggen NICHT uebereinander, das
 * Vorholen aendert also nichts am Bild - es laesst die Ringe nur zu Ende
 * laufen.
 *
 * Gesprungen wird der Wert, nicht gezaehlt: Ein weich gezaehlter z-index
 * wandert durch alle Zwischenstufen und kreuzt dabei fremde Ebenen. */
@keyframes chip-vorn {
  0%   { z-index: 3; animation-timing-function: steps(1, end); }
  4.2% { z-index: 3; animation-timing-function: steps(1, end); }
  4.3% { z-index: 1; animation-timing-function: steps(1, end); }
  100% { z-index: 1; }
}
/* Der Farbwechsel springt, er blendet nicht.
 *
 * Weich ueberblendet wandern Flaeche UND Schrift gemeinsam durchs Grau, und
 * auf halbem Weg steht grauer Text auf grauem Grund. Auf dem Bild war das
 * eine Kachel, die man mitten in der Welle nicht mehr lesen konnte.
 *
 * steps(1, end) an jedem Bild haelt den Wert bis zum naechsten und springt
 * dann. Damit gibt es keinen Zwischenzustand, den man lesen muesste. Der
 * Sprung selbst bleibt weich, der laeuft in chip-welle. */
/* Die Kachel ist von der ersten Sekunde ihres Takts an hell und bleibt es
   drei Sekunden, also bis 8,333 % von 36. Genau dort faengt die naechste an.
   Vor ihrem Takt zeigt eine Kachel ihr normales Aussehen, weil hier kein
   fill-mode steht: Beim Laden leuchtet deshalb nur die erste. */
@keyframes chip-hell {
  0%      { background: var(--dunkel);      color: var(--papier);      animation-timing-function: steps(1, end); }
  8.333%  { background: var(--papier-tief); color: var(--tinte-still); animation-timing-function: steps(1, end); }
  100%    { background: var(--papier-tief); color: var(--tinte-still); }
}
.chips span {
  position: relative;
  z-index: 1;
  animation: chip-welle 36s var(--bogen) infinite,
             chip-hell  36s linear infinite,
             chip-vorn  36s linear infinite;
}
.chips span:nth-child(1)  { animation-delay:  0s; }
.chips span:nth-child(2)  { animation-delay:  3s; }
.chips span:nth-child(3)  { animation-delay:  6s; }
.chips span:nth-child(4)  { animation-delay:  9s; }
.chips span:nth-child(5)  { animation-delay: 12s; }
.chips span:nth-child(6)  { animation-delay: 15s; }
.chips span:nth-child(7)  { animation-delay: 18s; }
.chips span:nth-child(8)  { animation-delay: 21s; }
.chips span:nth-child(9)  { animation-delay: 24s; }
.chips span:nth-child(10) { animation-delay: 27s; }
.chips span:nth-child(11) { animation-delay: 30s; }
.chips span:nth-child(12) { animation-delay: 33s; }
/* Wer die Maus darauf haelt, haelt auch die Welle an: Sonst springt das Wort
   unter dem Zeiger weg, waehrend man es liest. */
@media (hover: hover) {
  .chips:hover span { animation-play-state: paused; }
}
/* Im dunklen Thema ist --dunkel hell und --papier dunkel; die Welle dreht
   sich damit von selbst mit, ohne zweite Regel. Nur der Ring braucht eine:
   Er soll gegen das BLATT stehen, nicht gegen die Kachel, und das Blatt
   wechselt die Seite. */
@media (prefers-reduced-motion: reduce) {
  .chips span { animation: none; }
}

/* --- 5 · Die Befehle: geloescht ---
   Hier standen .befehle / .befehl / .bf-sagt: vier graue Kaesten mit dem
   Wortlaut eines Befehls darin. Die Begruendung dafuer lautete, ein Knopf
   verspreche, dass etwas passiert, wenn man draufdrueckt, und das hier sei
   nur ein Beispiel. Genau das war der Fehler - es SOLL etwas passieren. Die
   Bausteine stehen jetzt in Abschnitt 24 (.schrift, .cmd), und dort ist der
   Befehl ein Knopf, der wirklich ausloest, was er verspricht. */

/* --- 6 · Das Dreier-Raster ---
   Alle drei gleich hoch, und die dunklen Beispielkarten unten buendig. Mit
   align-items:start war jede so hoch wie ihr Inhalt: Die Woerterbuch-Karte
   haelt Platz fuer sieben Zeilen frei, die Sprachen-Karte fuer vier - und
   damit standen drei Karten in drei Hoehen nebeneinander, was wie ein Fehler
   aussieht und nicht wie eine Reihe.

   Die feste Hoehe der Beispielkarte ist die Loesung und nicht das Problem:
   Was darin passiert, ist eine Schleife, die immer wieder von vorn beginnt.
   Sie braucht keinen Platz fuer ihren laengsten Zustand, sie braucht einen
   Rahmen. */
/* ── Was es sich merkt: drei volle Zeilen ────────────────────────────────────
 *
 * Auf Ansage aus drei Spalten geworden. Die Spalten waren selbst schon eine
 * Antwort auf drei hohe Bloecke untereinander, die zusammen fast zweitausend
 * Punkte hoch waren - und die Gefahr ist, mit den Zeilen genau dorthin
 * zurueckzufallen.
 *
 * Tut es nicht, weil die Zeile BREIT ist und nicht hoch: Text und Vorfuehrung
 * stehen nebeneinander, nicht uebereinander. Jede Zeile ist so hoch wie ihre
 * Vorfuehrung, also rund 300 Punkte, und die drei zusammen bleiben unter dem,
 * was die drei Bloecke damals allein gebraucht haben.
 *
 * Die Spalten sind UNGLEICH und wechseln die Seite. Gleich breite Spalten
 * legen nahe, dass beide Seiten dasselbe Gewicht haben; hier ist die
 * Vorfuehrung das Argument und der Text die Erklaerung dazu. Und drei gleich
 * gebaute Zeilen untereinander liest man als Tabelle - wechselnde Seiten geben
 * dem Auge bei jeder Zeile einen neuen Anfang. */
.lern-reihen { display: grid; gap: clamp(40px, 5vw, 72px); }
.lern-reihe {
  display: grid;
  grid-template-columns: minmax(0, 0.82fr) minmax(0, 1fr);
  gap: clamp(28px, 4vw, 64px);
  align-items: center;
}
.lern-reihe.kehr { grid-template-columns: minmax(0, 1fr) minmax(0, 0.82fr); }
/* Beim Spiegeln tauschen NUR die Spalten, nicht die Reihenfolge im Blatt:
   Vorgelesen wird weiter erst die Ueberschrift und dann die Vorfuehrung. */
.lern-reihe.kehr .lern-wort  { grid-column: 2; grid-row: 1; }
.lern-reihe.kehr .lern-buehne { grid-column: 1; grid-row: 1; }

.lern-nr {
  display: block; margin-bottom: var(--a3);
  font-size: 12px; font-weight: 600; letter-spacing: .16em;
  color: var(--tinte-leise); font-variant-numeric: tabular-nums;
}
.lern-wort > p { margin: var(--a3) 0 0; max-width: 46ch; }

/* Die Vorfuehrung. Dieselbe Hoehe wie vorher, damit die drei Zeilen einen
   gemeinsamen Takt haben - und derselbe weiche Auslauf unten, damit die
   abgeschnittene Liste "hier geht es weiter" heisst und nicht "hier ist etwas
   kaputt". */
.lern-buehne .fcard {
  height: 268px;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 44px), transparent 100%);
  mask-image: linear-gradient(to bottom, #000 calc(100% - 44px), transparent 100%);
}
/* Die Zeile hebt sich beim Zeigen an, die Vorfuehrung eine Spur mehr als der
   Text. Das ist der ganze Effekt: Sie reagiert, ohne zu springen. */
.lern-buehne .fcard {
  transition: transform var(--zeit) var(--bogen), box-shadow var(--zeit) var(--bogen);
}
@media (hover: hover) {
  .lern-reihe:hover .lern-buehne .fcard {
    transform: translateY(-6px);
    box-shadow: 0 1px 2px rgba(20,20,20,.06),
                0 22px 48px -20px rgba(20,20,20,.26);
  }
}
@media (prefers-reduced-motion: reduce) {
  .lern-buehne .fcard { transition: none; }
  .lern-reihe:hover .lern-buehne .fcard { transform: none; }
}

@media (max-width: 900px) {
  /* Auf dem Telefon steht der Text ueber der Vorfuehrung, und zwar in JEDER
     Zeile gleich: Das Spiegeln hat dort keinen Sinn - untereinander gibt es
     keine linke und keine rechte Seite, nur ein Vorher und ein Nachher. */
  .lern-reihe, .lern-reihe.kehr { grid-template-columns: minmax(0, 1fr); }
  .lern-reihe.kehr .lern-wort,
  .lern-reihe.kehr .lern-buehne { grid-column: 1; grid-row: auto; }
  .lern-buehne .fcard { height: 280px; }
}

/* --- 7 · Die Stimmen ---
   Ein Raster, kein Laufband. Ein Zitat, das wegfaehrt, waehrend man es liest,
   ist keine Empfehlung, sondern Zierrat - und ein Name, den man nicht lesen
   kann, ist kein Name. */
/* Wieder ein laufendes Band, auf Ansage des Inhabers - aber nicht das alte.
 *
 * Mein Einwand gegen das Band war: Ein Zitat, das wegfaehrt, waehrend man es
 * liest, ist keine Empfehlung, sondern Zierrat. Der Einwand galt dem ALTEN
 * Band, und er ist hier beantwortet statt weggewischt:
 *
 *   - Es haelt an, sobald der Zeiger darauf liegt. Wer lesen will, liest.
 *   - Es laeuft langsam genug, dass ein Zitat zwoelf Sekunden im Bild ist.
 *   - Die Raender laufen weich aus, statt die Karten abzuschneiden.
 *   - Die einzelne Karte hebt sich beim Zeigen heraus - sie ist dann das
 *     Ding, das man liest, und nicht mehr Teil einer Bewegung.
 *
 * Damit hat das Band, was das Raster besser konnte, und behaelt, was ein
 * Raster nie hat: Es zeigt in einem Blick, dass es VIELE sind. */
.stimmen { position: relative; overflow: hidden; }
.stimmen::before, .stimmen::after {
  content: ""; position: absolute; top: 0; bottom: 0; z-index: 2;
  width: clamp(40px, 10vw, 180px); pointer-events: none;
}
.stimmen::before { left: 0; background: linear-gradient(90deg, var(--lauf-grund), transparent); }
.stimmen::after { right: 0; background: linear-gradient(270deg, var(--lauf-grund), transparent); }
.stimmen-reihe {
  display: flex; gap: var(--a5); width: max-content;
  animation: laufen 64s linear infinite;
}
.stimmen-reihe .doppelt { display: contents; }
@media (hover: hover) { .stimmen:hover .stimmen-reihe { animation-play-state: paused; } }
@media (prefers-reduced-motion: reduce) {
  .stimmen-reihe { animation: none; flex-wrap: wrap; width: 100%; justify-content: center; }
  .stimmen::before, .stimmen::after { display: none; }
}
.stimmen .t-card {
  flex: none; width: min(380px, 78vw);
  display: flex; flex-direction: column;
  transition: transform var(--zeit) var(--bogen), box-shadow var(--zeit) var(--bogen);
  /* Linksbuendig. Zentrierter Fliesstext liest sich schlecht, weil jede Zeile
     an einer anderen Stelle anfaengt - bei drei Zeilen merkt man es, bei
     einem Zitat mit Namen darunter erst recht. */
  text-align: left;
  padding: var(--a6);
  border-radius: var(--r-gross);
  background: var(--papier);
  box-shadow: inset 0 0 0 1px var(--linie);
}
.stimmen .t-card q { display: block; font-size: 16.5px; line-height: 1.6; quotes: none; }
.stimmen .t-card q::before, .stimmen .t-card q::after { content: none; }
.stimmen .t-card .who { margin-top: var(--a5); font-size: 14px; color: var(--tinte-still); }
.stimmen .t-card .who b { color: var(--tinte); font-weight: 600; }
/* Der Buchstabe im Kreis steht fuer ein Foto, das es nicht gibt. Ein
   erfundenes Gesicht waere schlimmer als keins. */
@media (hover: hover) {
  .stimmen .t-card:hover { transform: translateY(-4px);
    box-shadow: inset 0 0 0 1px var(--linie-klar), 0 12px 30px rgba(20,20,20,.10); }
}
.stimmen .t-card .ava {
  width: 34px; height: 34px; margin-bottom: var(--a4);
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--papier-tief);
  font-size: 14px; font-weight: 700; color: var(--tinte-still);
}

/* --- 8 · Der Schluss ---
   Eine dunkle Flaeche, das einzige Mal auf der Seite. Sie ist der Grund, warum
   der Aufmacher hell sein darf: Wenn nur EIN Abschnitt dunkel ist, heisst
   dunkel "hier entlang". Sind es zwei, heisst es nichts mehr. */
.schluss {
  padding: clamp(var(--a12), 8vw, 96px) var(--a6);
  border-radius: var(--r-flaeche);
  /* #141414 als Zahl und NICHT als var(--dunkel). Im dunklen Thema wird
     --dunkel zu #f2f2f2 - die Knoepfe drehen sich dort um. Der Kasten hat das
     mitgemacht: weisser Kasten mit weisser Schrift, gemessen 1,04:1 bis
     1,12:1 an jeder einzelnen Stelle darin. Er soll in BEIDEN Themen schwarz
     sein, also darf er keinen Wert benutzen, der sich mit dem Thema dreht. */
  background: #141414;
  color: var(--papier);
  text-align: center;
}
:root[data-theme="dark"] .schluss { background: var(--papier-tief); color: var(--tinte); }
.schluss .t-lies { color: #9a9a9a; }
:root[data-theme="dark"] .schluss .t-lies { color: var(--tinte-still); }
/* Auf dunklem Grund dreht sich der Knopf um: hell mit dunkler Schrift. */
.schluss .knopf { background: var(--papier); color: var(--dunkel); }
.schluss .knopf:hover { background: #e8e8e8; }
.schluss .knopf.stumm { background: transparent; color: var(--papier); box-shadow: inset 0 0 0 1px #ffffff33; }
.schluss .knopf.stumm:hover { background: #ffffff14; }
:root[data-theme="dark"] .schluss .knopf { background: var(--dunkel); color: var(--papier); }
/* background MUSS hier noch einmal stehen. Ohne die Zeile gewinnt die Regel
   darueber auch fuer den stummen Knopf: :root[data-theme="dark"] .schluss
   .knopf ist spezifischer (0,4,0) als .schluss .knopf.stumm (0,3,0), obwohl
   letztere die genauere Aussage macht. Ergebnis war weisse Schrift auf weissem
   Grund - 1,00:1, also unsichtbar.

   Gefunden hat es die Kontrastmessung im dunklen Modus, nicht das Auge: Der
   Knopf war ja da, nur unlesbar, und im hellen Modus stimmte alles. */
:root[data-theme="dark"] .schluss .knopf.stumm {
  background: transparent;
  color: var(--tinte);
  box-shadow: inset 0 0 0 1px var(--linie-stark);
}

/* ══ 19. Kleine Fenster ════════════════════════════════════════════════════
 *
 * GANZ AM ENDE, und das ist keine Ordnungsfrage. Dieser Block stand als
 * Abschnitt 11 mitten in der Datei - vor den Bausteinen, die er ueberschreiben
 * soll. Bei gleicher Spezifitaet gewinnt die spaetere Regel, also gewann jedes
 * Mal der Baustein: Der Schalter blieb bei 36 Punkten, die Verweise in der
 * Fusszeile bei 34, obwohl hier 44 stand.
 *
 * Das ist der Fehler, den man beim Lesen der Datei NICHT sieht - beide Regeln
 * stehen da, beide sehen richtig aus. Gefunden hat ihn eine Messung im
 * Browser. */
@media (max-width: 720px) {
  :root { --a-abschnitt: 64px; }
  .knopf.breit-klein { width: 100%; }
  .reihe.stapelt-klein { flex-direction: column; align-items: stretch; }

  /* BERUEHRFLAECHEN. Auf dem Schreibtisch sind 38 Punkte reichlich - dort
     trifft eine Maus einen Punkt. Auf dem Telefon trifft ein Daumen eine
     Flaeche, und die kleinste, die noch zuverlaessig sitzt, ist 44 Punkte
     im Quadrat. Diese Zahl nennen Apple und Google unabhaengig voneinander,
     und sie steht so auch in WCAG 2.2 (2.5.8, Zielgroesse).

     Gemessen war die ganze Kopfzeile bei 38: Aussehen, Sprache, Download,
     Klappknopf. Vier Ziele nebeneinander, alle zu klein - genau die Ecke,
     in der ein Fehlgriff am teuersten ist, weil daneben "Download" liegt.

     Es geht dabei um die BERUEHRFLAECHE, nicht um die Optik: Der Knopf darf
     aussehen wie 38 Punkte, solange man 44 treffen kann. Deshalb wachsen
     Hoehe und Polsterung und nicht die Schrift. */
  .nav-cta .knopf,
  .nav-cta .btn,
  .burger,
  .theme-toggle,
  .lang-knopf { min-height: 44px; }
  .burger, .theme-toggle { min-width: 44px; }
  .burger span { left: 13px; }
  .burger span:nth-child(1) { top: 19px; }
  .burger span:nth-child(2) { top: 24px; }
  .burger[aria-expanded="true"] span:nth-child(1),
  .burger[aria-expanded="true"] span:nth-child(2) { top: 21.5px; }
  .nav-in { height: 60px; }

  /* Dasselbe in der Fusszeile: Die Verweise standen auf 34 Punkten, und dort
     unten liegen die Rechtstexte - also das, was jemand sucht, der etwas
     nachlesen WILL. */
  /* 12 und nicht 11: Die Verweise stehen jetzt in 13px Versalien statt in
     15px Gemischtschreibung, und damit kam die Beruehrflaeche bei 11 auf
     43 Punkte - einen unter dem Mass. Gemessen, nicht geschaetzt. */
  .fuss-spalte a { padding-block: 12px; }
  .zeitwahl-pr button { height: 44px; }

  /* Die Marke ist ein Verweis auf die Startseite und wurde als solcher
     uebersehen: 65 mal 22 Punkte, weil die Flaeche genau so gross war wie das
     Bild darin. Der Verweis, den man am haeufigsten braucht, wenn man sich
     verlaufen hat. */
  .nav-logo { min-height: 44px; align-items: center; }

  /* Die Zeichen der sozialen Netze standen bei 36 mal 41 - knapp daneben,
     und knapp daneben ist bei einem Daumen daneben. */
  .sozial .sz { min-width: 44px; min-height: 44px; }

  /* Auf der Kuendigungsseite waehlt man mit zwei Schaltern die Art der
     Kuendigung. Das Feld selbst ist 13 Punkte gross; anklickbar ist aber die
     ganze Beschriftung, weil sie ein <label> ist - und die war in einem Fall
     nur 23 Punkte hoch. Wer hier danebentrifft, kuendigt anders als gewollt. */
  .legal-radio { display: flex; align-items: center; gap: 10px; min-height: 44px; }
  .legal-radio input { width: 18px; height: 18px; flex: none; }
}

/* ══ 18c. Preisseite: Gruppen in der Tabelle und die Fragenliste ═══════════ */

/* Die Gruppenzeile ist eine Zwischenueberschrift IN der Tabelle. Zehn Zeilen
   am Stueck liest man von oben nach unten durch und vergisst in der Mitte,
   wonach man gesucht hat; fuenf Gruppen zu zwei bis drei Zeilen kann man
   anspringen.

   Als <th colspan> und nicht als zweiter <thead>: So bleibt es EINE Tabelle,
   und ein Vorleseprogramm liest die Gruppe als Zwischenueberschrift statt als
   neuen Tabellenkopf mit neuen Spalten. */
.tab .tab-gruppe th {
  padding-top: var(--a6);
  background: var(--papier);
  border-bottom: 1px solid var(--linie-klar);
  font-size: var(--gr-klein);
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--tinte-leise);
}
.tab .tab-gruppe:first-child th { padding-top: var(--a4); }

/* Die Fragenliste. Aufklappbar, weil man vor einem Preis EINE bestimmte Frage
   hat und nicht fuenf Antworten lesen will - aber ohne Zauberei: <details>
   kann das seit Jahren, funktioniert ohne Skript und ist fuer ein
   Vorleseprogramm von sich aus richtig ausgezeichnet. */
.faq-liste { display: grid; gap: 0; }
.faq-liste details { border-bottom: 1px solid var(--linie); }
.faq-liste details:first-of-type { border-top: 1px solid var(--linie); }
.faq-liste summary {
  display: flex; align-items: center; justify-content: space-between; gap: var(--a4);
  padding: var(--a5) 0;
  font-size: 17px; font-weight: 600; letter-spacing: -.01em;
  cursor: pointer; list-style: none;
}
.faq-liste summary::-webkit-details-marker { display: none; }
/* Das Zeichen dreht sich, statt zu wechseln: Ein Plus, das zu einem Minus
   wird, springt; eines, das sich dreht, zeigt die Bewegung selbst. */
.faq-liste summary::after {
  content: "";
  flex: none; width: 11px; height: 11px;
  border-right: 1.5px solid var(--tinte-leise);
  border-bottom: 1.5px solid var(--tinte-leise);
  transform: rotate(45deg) translate(-3px, -3px);
  transition: transform var(--zeit) var(--bogen);
}
.faq-liste details[open] summary::after { transform: rotate(225deg) translate(-2px, -2px); }
.faq-liste summary:focus-visible { outline: 2px solid var(--tinte); outline-offset: 3px; }
.faq-liste details p {
  margin: 0 0 var(--a5);
  max-width: 62ch;
  color: var(--tinte-still);
  line-height: 1.7;
}
@media (prefers-reduced-motion: reduce) {
  .faq-liste summary::after { transition: none; }
}

/* --- Knoepfe in einer fremden Markenfarbe ---
 *
 * Discord-Blau, YouTube-Rot: Diese Knoepfe zeigen auf eine fremde Marke, und
 * die Farbe IST der Hinweis darauf. Ihre Schrift ist weiss, in beiden
 * Fassungen.
 *
 * Ohne diese Zeilen gewinnt in der dunklen Fassung die allgemeine Regel
 * (:root[data-theme="dark"] .knopf, Spezifitaet 0,3,0) gegen die genauere
 * Hausregel (.faq-schluss .faq-dc, 0,2,0) - und dann steht dunkle Schrift auf
 * Discord-Blau, 4,16:1. Genau derselbe Fehler wie beim Schluss-Knopf, an einer
 * zweiten Stelle: Eine allgemeine Regel mit hoher Spezifitaet frisst die
 * Ausnahmen, die sie nicht kennt.
 *
 * Deshalb steht hier eine LISTE und keine Einzelkorrektur - kommt ein dritter
 * Marken-Knopf dazu, gehoert er hier hinein, und das faellt beim Lesen auf. */
.knopf.faq-dc, .knopf.show-yt,
:root[data-theme="dark"] .knopf.faq-dc,
:root[data-theme="dark"] .knopf.show-yt { color: #fff; }

/* --- Der helle Knopf --- 
   Auf der Downloadseite steht die Mac-Karte auf dunklem Grund. Ein schwarzer
   Knopf darauf waere unsichtbar; der einzige Knopf, der dort funktioniert, ist
   der umgedrehte. Dieselbe Umkehrung wie im Schluss-Abschnitt - deshalb
   dieselbe Regel und keine zweite. */
.knopf.hell { background: var(--papier); color: var(--dunkel); }
.knopf.hell:hover { background: #e8e8e8; }
:root[data-theme="dark"] .knopf.hell { background: var(--tinte); color: var(--papier); }

/* ══ 20. Der Logo-Lauf ══════════════════════════════════════════════════════
 *
 * Hier stand eine Reihe von acht Namen. Der Grund war gut gemeint (die
 * Zeichen stammen aus einem fremden Satz) und die Wirkung falsch: Acht Woerter
 * in Grau sagen nicht "es laeuft ueberall", sie sagen gar nichts.
 *
 * WAS VON DER VORLAGE UEBERNOMMEN IST: Deren Seite laeuft nicht ueber
 * @keyframes - Framer bewegt alles ueber JavaScript, im HTML steht keine
 * einzige Animation. Ablesbar ist nur die MACHART, und die ist eindeutig:
 * viele Elemente, durchgehende waagerechte Bewegung, weiche Raender, und beim
 * Zeigen hebt sich das einzelne Stueck heraus.
 *
 * Zwei Reihen in Gegenrichtung, nicht eine: Eine einzelne laufende Reihe liest
 * man als Band und schaut weg. Zwei, die sich gegeneinander bewegen, erzeugen
 * die Tiefe, um die es geht - und man bleibt haengen.
 */
.lauf { position: relative; overflow: hidden; }
/* Die weichen Raender. Ohne sie erscheinen und verschwinden die Zeichen an
   einer harten Kante, und dann sieht man den Trick statt der Bewegung. */
.lauf::before, .lauf::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: clamp(40px, 8vw, 140px);
  z-index: 2; pointer-events: none;
}
/* Der Verlauf muss GENAU die Farbe treffen, auf der das Band liegt - sonst
   sieht man statt eines weichen Randes einen hellen Balken. Deshalb erbt er
   sie, statt sie zu erraten: --lauf-grund steht am Abschnitt, und jeder
   Abschnitt setzt seinen eigenen.

   Vorher stand hier eine Liste von Ausnahmen (.feld:not(.feld-still) ...), und
   .feld-schmal war nicht darin - dort lag ein grauer Verlauf auf weissem
   Grund. Eine Liste von Ausnahmen ist immer unvollstaendig; ein geerbter Wert
   ist es nie. */
:root { --lauf-grund: var(--papier); }
.feld-still { --lauf-grund: var(--papier-still); }
.lauf::before { left: 0; background: linear-gradient(90deg, var(--lauf-grund), transparent); }
.lauf::after { right: 0; background: linear-gradient(270deg, var(--lauf-grund), transparent); }

.lauf-reihe { display: flex; gap: var(--a4); width: max-content; animation: laufen 46s linear infinite; }
.lauf-reihe + .lauf-reihe { margin-top: var(--a4); animation-direction: reverse; animation-duration: 58s; }
/* Der Inhalt steht zweimal im HTML. Nur so laeuft die Schleife ohne Sprung:
   Bei -50% ist die zweite Haelfte genau dort, wo die erste anfing. */
@keyframes laufen { from { transform: translate3d(0,0,0); } to { transform: translate3d(-50%,0,0); } }
/* Beim Zeigen haelt das Band an. Wer ein Zeichen ansieht, will es ansehen -
   ein Band, das unter dem Zeiger wegfaehrt, ist eine Zumutung. */
@media (hover: hover) { .lauf:hover .lauf-reihe { animation-play-state: paused; } }

/* Groesser, auf Ansage. Die Kachel waechst von 62 auf 84 Punkte, das Zeichen
   darin von 34 auf 48 - das Verhaeltnis bleibt, damit die Luft um das Zeichen
   herum dieselbe Wirkung hat. Auf schmalen Fenstern faellt sie wieder
   kleiner aus: Bei 84 Punkten passen auf ein Telefon vier Kacheln, und vier
   nebeneinander sehen nicht nach "viele" aus. */
.lauf-stueck {
  flex: none;
  width: 84px; height: 84px;
  display: grid; place-items: center;
  border-radius: var(--r-gross);
  background: var(--papier);
  box-shadow: inset 0 0 0 1px var(--linie);
  transition: transform var(--zeit) var(--bogen), box-shadow var(--zeit) var(--bogen);
}
.lauf-stueck img { width: 48px; height: 48px; border-radius: 11px; }
/* ---- Die zweite Reihe: jedes Zeichen in SEINER Markenfarbe ----
 *
 * Gemeldet, mit zwei Bildern: "die Logos haben keine Farbe, nicht die
 * originale Farbe" — und "manche machen sogar gar kein Logo, Lücke".
 *
 * Beides war meins, und beides hatte dieselbe Wurzel: Ich hatte die 31
 * Zeichen als <img> eingehaengt und mit filter:invert(1) umgedreht. Das macht
 * aus einem weissen Zeichen ein schwarzes — also aus einer Wortmarke eine
 * Silhouette. Und es macht aus den drei Dateien, die NICHT weiss sind
 * (apple, threads, tiktok), ein WEISSES Zeichen auf weisser Kachel: die
 * leeren Kacheln auf dem zweiten Bild. Eine Regel, die die Farbe der Datei
 * umdreht, muss die Farbe der Datei kennen — und genau das tut sie nicht.
 *
 * Jetzt wird das Zeichen nicht mehr als Bild GEZEIGT, sondern als MASKE
 * benutzt: Die Flaeche darunter traegt die Farbe, die Datei gibt nur die
 * Form. Damit ist die Farbe der Datei gleichgueltig — keine leeren Kacheln
 * mehr moeglich — und jede Marke steht in ihrer eigenen Farbe da, aus der
 * Gestaltungsrichtlinie der jeweiligen Firma und nicht geraten.
 *
 * Vier Marken SIND schwarz (Medium, Steam, Threads, TikTok). Die bekommen im
 * dunklen Thema ihr Gegenstueck, sonst waeren sie dort unsichtbar, derselbe
 * Fehler wie eben, nur andersherum. */
.lauf-stueck.glyph i {
  display: block; width: 48px; height: 48px;
  background: var(--marke);
  -webkit-mask: var(--zeichen) center / contain no-repeat;
  mask: var(--zeichen) center / contain no-repeat;
}
:root[data-theme="dark"] .lauf-stueck.glyph.schwarz i { background: #f2f2f2; }

/* Eine Maske kann nur EINE Farbe tragen. PayPals Zeichen sind zwei P, ein
   dunkelblaues hinten und ein hellblaues davor; als Maske wurde daraus ein
   einfarbiger Klumpen. Solche Marken kommen als fertiges Bild herein statt
   als Form, dann bringen sie ihre Farben selbst mit.

   Das gilt nur fuer Zeichen, die in ZWEI Farben stehen. Alles Einfarbige
   bleibt Maske: So kann keine Kachel leer bleiben, wenn eine Datei nicht
   weiss ist. */
.lauf-stueck.glyph.voll i {
  background: var(--zeichen) center / contain no-repeat;
  -webkit-mask: none;
  mask: none;
}
@media (max-width: 720px) {
  .lauf-stueck.glyph i { width: 36px; height: 36px; }
}
@media (max-width: 720px) {
  .lauf-stueck { width: 64px; height: 64px; }
  .lauf-stueck img { width: 36px; height: 36px; border-radius: 9px; }
}
@media (hover: hover) {
  .lauf-stueck:hover { transform: translateY(-4px) scale(1.06);
    box-shadow: inset 0 0 0 1px var(--linie-klar), 0 10px 24px rgba(20,20,20,.12); }
}
@media (prefers-reduced-motion: reduce) {
  .lauf-reihe { animation: none; }
  /* Steht das Band still, muss es trotzdem in die Breite passen. */
  .lauf-reihe { width: 100%; flex-wrap: wrap; justify-content: center; }
  .lauf-reihe + .lauf-reihe { display: none; }
  /* Und es darf nicht zum Block werden. Die Reihe traegt 76 Kacheln - 38
     Zeichen und ihre zweite Haelfte, die NUR die Schleife braucht. Steht die
     Schleife still, waeren das umgebrochen sechs Zeilen und ein halber
     Bildschirm voller Zeichen; aus einem Band wuerde eine Tapete. Zwanzig
     sagen dasselbe. */
  .lauf-stueck:nth-child(n+21) { display: none; }
}

/* ══ 21. Preiskarten wie in der App ═════════════════════════════════════════
 *
 * Die App hat dieselben drei Tarife und zeigt sie besser: Die Karte liegt auf
 * einem Verlauf statt auf einer Flaeche, traegt oben einen Lichtsaum, hebt
 * sich beim Zeigen sechs Punkte an, und EINMAL laeuft ein Lichtstreifen
 * darueber. Das ist der Unterschied zwischen einer Preistabelle und etwas,
 * das man anfasst.
 *
 * Uebernommen wird die BAUART, nicht die Farbe: Die App hat drei Themen und
 * einen frei waehlbaren Akzent, die Website zwei Fassungen. Die Werte kommen
 * also von hier, die Form von dort. */
.pr-card {
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--papier) 88%, var(--papier-still)) 0%, var(--papier) 100%);
  box-shadow: 0 1px 2px rgba(0,0,0,.05),
              0 8px 20px -8px rgba(0,0,0,.10),
              0 28px 56px -28px rgba(0,0,0,.14);
  transition: transform var(--zeit) var(--bogen), box-shadow var(--zeit) var(--bogen);
}
/* KEIN overflow:hidden an der Karte. Das lag hier, um den Lichtstreifen zu
   begrenzen - und schnitt dabei die Marke ab, die oben aus der Karte
   herausragt ("MOST POPULAR" sitzt auf top:-13px). Es war auch gar nicht
   noetig: Der Streifen ist ein ::after mit inset:0, sein Hintergrund endet
   ohnehin an seinem eigenen Rand. */
:root[data-theme="dark"] .pr-card {
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--papier-still) 88%, var(--papier)) 0%, var(--papier-still) 100%);
  box-shadow: 0 1px 2px rgba(0,0,0,.30),
              0 8px 20px -8px rgba(0,0,0,.45),
              0 28px 56px -28px rgba(0,0,0,.60);
}
/* Der Lichtsaum oben - die helle Kante, die die Karte vom Grund abhebt. */
.pr-card::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  pointer-events: none; z-index: 1;
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--tinte) 8%, transparent);
}
/* Der Lichtstreifen, der beim Zeigen EINMAL darueberlaeuft. Einmal, nicht in
   Schleife: Eine Karte, ueber die es dauernd blitzt, ist eine Leuchtreklame. */
.pr-card::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  pointer-events: none; z-index: 1; opacity: 0;
  background: linear-gradient(100deg, transparent 32%,
    color-mix(in srgb, var(--tinte) 7%, transparent) 47%, transparent 62%);
  background-size: 260% 100%; background-position: 160% 0;
}
@media (hover: hover) {
  .pr-card:hover::after { animation: prSchimmer .9s ease-out; }
  .pr-card:hover { transform: translateY(-6px);
    box-shadow: 0 1px 2px rgba(0,0,0,.06),
                0 16px 32px -12px rgba(0,0,0,.14),
                0 44px 84px -32px rgba(0,0,0,.20); }
  .pr-card:hover .price { transform: scale(1.035); }
  .pr-card:hover li::before { background: color-mix(in srgb, var(--tinte) 13%, transparent); }
}
@keyframes prSchimmer {
  0% { opacity: 1; background-position: 160% 0; }
  100% { opacity: 0; background-position: -60% 0; }
}
/* Alles im Inhalt ueber die beiden Schichten legen - nur die Marke nicht, die
   sitzt AUF der Kante und braucht ihre eigene Ebene. */
.pr-card > *:not(.pr-badge) { position: relative; z-index: 2; }
.pr-badge { z-index: 3; left: 50%; transform: translateX(-50%);
  box-shadow: 0 4px 12px -2px rgba(0,0,0,.35); }
.pr-card .price { transform-origin: left center;
  transition: transform var(--zeit) var(--bogen); }
/* Der Haken sitzt in einem runden Feld statt nackt im Text - ein blosser Haken
   liest sich wie ein Aufzaehlungszeichen aus einer Textverarbeitung.
   17 Punkte und nicht 18, Schrift 10,5 und nicht 11: Das sind die Werte aus
   src/renderer/settings.html. Hier standen einmal gerundete Zahlen, und
   gerundet heisst hier: anders als in der App. */
.pr-card li::before {
  content: "✓"; position: absolute; left: 0; top: 1px;
  width: 17px; height: 17px; display: grid; place-items: center;
  border-radius: 50%;
  background: color-mix(in srgb, var(--tinte) 7%, transparent);
  color: var(--tinte); font-size: 10.5px; font-weight: 700;
  transition: background var(--zeit) ease;
}
.pr-card li { padding-left: 26px; }

/* ---- Die Schrift der Karte, wie in der App ----
 *
 * Auf Ansage, mit einem Bild der eigenen App daneben. Die BAUART war schon
 * uebernommen (Verlauf, Lichtsaum, Schimmer, Anheben), die SCHRIFT nicht -
 * und genau daran sieht man den Unterschied zwischen zwei Oberflaechen
 * derselben Sache.
 *
 * Der Name ist der auffaelligste Punkt: In der App steht er auf 620, hier
 * stand er auf 700, weil Abschnitt 3 pauschal "h1, h2, h3, h4 { 700 }" setzt.
 * Zwischen 620 und 700 liegt genau der Eindruck, den man nicht benennen kann -
 * das eine liest sich wie ein Name, das andere wie eine Schlagzeile.
 *
 * Die Groessen sind NICHT eins zu eins uebernommen, und das ist kein
 * Widerspruch: Die Karten hier sind rund ein Drittel breiter als in der App.
 * Das Blatt der App sagt es selbst an seiner Preiszeile - dort stehen 38
 * Punkte statt der 44 von hier, "damit 3,49 € / Monat nicht umbricht". Gleich
 * aussehen heisst dasselbe VERHAELTNIS, nicht dieselbe Zahl. Uebernommen sind
 * deshalb die Staerken, die Sperrungen und die Formen. */
.pr-card h2 { font-size: 25px; font-weight: 620; letter-spacing: -.015em; }
.pr-card .price { letter-spacing: -.03em; }
/* 16 und nicht 15: In der App stehen 14 Punkte neben 38, hier 44 neben der
   Einheit - dasselbe Verhaeltnis sind 16. */
.pr-card .price small { font-size: 16px; font-weight: 500; }
/* Die Liste schiebt den Knopf nach unten, damit er in allen drei Karten auf
   derselben Linie sitzt. Ohne das haengt er an der Laenge der Liste. */
.pr-card ul { flex: 1; align-content: start; }
/* Der Knopf laeuft ueber die ganze Karte und ist ein weiches Rechteck, keine
   Pille: Auf einer Karte, die eine Entscheidung verlangt, ist er die Handlung
   und darf danach aussehen. In der App sind es 11 Punkte Radius bei 22 Punkten
   Polsterung; hier sind es 32, also 14. */
.pr-card .knopf {
  width: 100%; margin-top: auto;
  height: 50px; border-radius: 14px;
}
@media (prefers-reduced-motion: reduce) {
  .pr-card, .pr-card .price { transition: none; }
  .pr-card:hover { transform: none; }
  .pr-card:hover .price { transform: none; }
  .pr-card:hover::after { animation: none; }
}

/* ══ 22. Das Fenster: macOS und Windows ═════════════════════════════════════
 *
 * Die drei grauen Punkte waren weder das eine noch das andere. Die
 * Fensterknoepfe sind das Erste, woran man sieht, auf welchem System man ist -
 * ein neutrales Fenster wirkt auf beiden Systemen fremd, und die App laeuft
 * auf beiden.
 *
 * Die Farben sind die von macOS: #ff5f57 / #febc2e / #28c840. Sie stehen hier
 * als Zahlen und nicht als Werte des Systems, denn sie gehoeren nicht zu
 * unserer Farbwelt - sie zitieren eine fremde Oberflaeche, und genau das ist
 * ihre Aufgabe. */
.sys-wahl {
  display: flex; width: fit-content; margin: 0 auto var(--a5);
  padding: 4px; border-radius: var(--r-rund); background: var(--papier-tief);
}
.sys-wahl button {
  display: inline-flex; align-items: center; gap: 7px;
  height: 32px; padding-inline: var(--a4);
  border: 0; border-radius: var(--r-rund); background: transparent;
  color: var(--tinte-leise); font-size: 13px; font-weight: 600; cursor: pointer;
  transition: color var(--zeit-kurz) var(--bogen), background var(--zeit-kurz) var(--bogen);
}
/* Das Zeichen folgt der Schriftfarbe des Knopfes: Auf dem gewaehlten ist es
   dunkel, auf dem anderen leise. So gehoert es zum Wort und steht nicht als
   zweites Element daneben. */
.sys-wahl .sys-z { width: 15px; height: 15px; flex: none; }
/* Das Apfelzeichen laeuft optisch hoeher als ein Buchstabe, weil sein Blatt
   oben aus der Form herausragt. Ein Punkt nach unten stellt es auf dieselbe
   Linie wie das Wort daneben. */
.sys-wahl button[data-sys="mac"] .sys-z { margin-top: 1px; }
.sys-wahl button.an { background: var(--papier); color: var(--tinte);
  box-shadow: 0 1px 3px rgba(20,20,20,.10); }
.sys-wahl button:focus-visible { outline: 2px solid var(--tinte); outline-offset: 2px; }

.win-bar { display: flex; align-items: center; justify-content: space-between;
  padding: var(--a4) var(--a4) var(--a4) var(--a5); }
/* Die Ampel links (macOS), die Knoepfe rechts (Windows). Immer beide im
   Markup, immer nur eine sichtbar - so ist der Wechsel ein Umschalten und
   kein Nachladen. */
.win-ampel { display: none; gap: 8px; }
.win-ampel i { width: 12px; height: 12px; border-radius: 50%; display: block; }
/* i.a-zu und nicht .a-zu: Das Haus-Blatt faerbt den ersten Punkt hell
   (".win-bar i:first-child", Spezifitaet 0,2,1) - eine blosse Klasse (0,2,0)
   verliert dagegen, und der Schliessen-Punkt blieb grau statt rot. Mit dem
   Elementnamen davor steht es 0,2,1 zu 0,2,1, und die spaetere Datei gewinnt. */
.win-ampel i.a-zu    { background: #ff5f57; }
.win-ampel i.a-klein { background: #febc2e; }
.win-ampel i.a-gross { background: #28c840; }
.win-knoepfe { display: none; gap: 2px; margin-left: auto; }
.win-knoepfe svg { width: 34px; height: 26px; padding: 7px 11px; border-radius: 4px;
  fill: none; stroke: rgba(255,255,255,.72); stroke-width: 1.1;
  transition: background var(--zeit-kurz) var(--bogen); }
.win-knoepfe svg rect { fill: none; }
.win.sys-mac .win-knoepfe { display: none; }
.win.sys-mac .win-ampel { display: flex; }
.win.sys-win .win-knoepfe { display: flex; }
.win.sys-win .win-ampel { display: none; }
/* Der Schliessen-Knopf wird rot, die anderen hell - so macht es Windows. */
@media (hover: hover) {
  .win-knoepfe svg:hover { background: rgba(255,255,255,.10); }
  .win-knoepfe .w-zu:hover { background: #e81123; stroke: #fff; }
}

/* ══ 23. Die Aufnahme-Anzeige, wie sie in der App wirklich ist ══════════════
 *
 * Hier stand eine Pille mit dem Wort "Listening" und fuenf huepfenden
 * Strichen. Beides war erfunden.
 *
 * In der App steht waehrend der Aufnahme KEIN Wort. Die Begruendung steht
 * dort im Blatt und ist gut: Wer gerade spricht, liest nicht - er braucht nur
 * die Bestaetigung, dass gehoert wird. Deshalb tragen die Balken die Auskunft,
 * und Text erscheint erst, wenn es wirklich etwas zu sagen gibt (abgebrochen,
 * eingefuegt, Fehler).
 *
 * Uebernommen sind die Werte der App: fast schwarzer Grund, 1px Kante bei
 * neun Prozent Weiss, Radius 999, Polsterung 5/9, Unschaerfe dahinter - und
 * der atmende Ring, der die Frage beantwortet, die die Welle offen laesst:
 * In einer Sprechpause stehen die Balken still, und dann ist von aussen nicht
 * zu unterscheiden, ob noch aufgenommen wird oder ob es haengt. Der Ring
 * laeuft unabhaengig vom Ton weiter.
 *
 * Bewegt werden nur transform und opacity. Ein animierter box-shadow waere
 * hier derselbe Fehler wie damals in der App: Ein Schatten ist nichts, was
 * die Grafikkarte bewegen kann - jedes Bild hiesse "Flaeche samt Schatten neu
 * malen", und daraus entsteht der harte Rand, den man dort einmal gesehen
 * hat.
 *
 * DER WAHLSPRUCH IST ".pille.rec" UND NICHT ".win-foot .pille": Diese Anzeige
 * gehoerte anfangs dem Fenster im Aufmacher. Inzwischen steht sie auch unter
 * dem Schriftstueck im Befehlsmodus - dort hiess der Fuss anders, also griff
 * keine einzige dieser Regeln, und die Pille stand hell auf hell mit einer
 * fast weissen Welle darin: unsichtbar. Was die Anzeige ausmacht, ist nicht,
 * wo sie haengt, sondern DASS aufgenommen wird. Genau das sagt die Klasse
 * jetzt.
 *
 * ZWEI KLASSEN und nicht eine: .rec ist das AUSSEHEN der Anzeige, .hoert ist
 * der atmende Ring. Im Befehlsmodus wird nur waehrend des Zurufs aufgenommen -
 * haenge beides an derselben Klasse, faellt die Pille danach auf die
 * gewoehnliche graue Pille zurueck und die fast weisse Welle darin
 * verschwindet. */
.pille.rec {
  /* Hoehe und Abstand kommen NICHT aus Abschnitt 7. Die gewoehnliche Pille
     dort ist 26 Punkte hoch und hat 4 Punkte Abstand - das ist die Marke ueber
     einer Ueberschrift. Diese hier traegt eine 30 Punkte hohe Welle und zwei
     22er Knoepfe; mit 26 Punkten wurde sie zusammengedrueckt, und weil die
     Knoepfe oben und unten fast an den Rand stiessen, sahen die 9 Punkte
     Polsterung an den Seiten aus wie ein schwarzer Streifen daneben. Gemeldet
     als "das Schwarze geht weiter nach den Knoepfen" - und genau so war es.
     In der App steht keine Hoehe; die Pille ist so hoch wie ihr Inhalt. */
  height: auto;
  gap: 7px;
  position: relative;
  display: inline-flex; align-items: center;
  padding: 5px 9px;
  border-radius: 999px;
  background: rgba(14, 14, 17, 0.96);
  border: 1px solid rgba(255, 255, 255, 0.09);
  box-shadow: 0 10px 30px rgba(0,0,0,0.42), 0 2px 6px rgba(0,0,0,0.3);
  backdrop-filter: blur(24px) saturate(1.4);
  -webkit-backdrop-filter: blur(24px) saturate(1.4);
}
.pille.rec canvas { display: block; width: 76px; height: 30px; }

/* ---- Die beiden Knoepfe auf der Pille ----
 *
 * Hier stand nur die Welle. In der App steht links ein ✕ und rechts ein ✓,
 * und die Welle dazwischen - der Inhaber hat es an einem Bild seiner eigenen
 * App gezeigt. Wer die Pille sieht, soll sie auch bedienen koennen, ohne zur
 * Tastatur zu greifen; ohne die beiden Kreise ist sie eine Anzeige und kein
 * Bedienelement, und genau das sieht man ihr an.
 *
 * Die Werte sind aus src/renderer/overlay.html uebernommen und nicht
 * nachempfunden: 22 Punkte, Weiss bei zehn Prozent, Strichstaerke 2,8. Der
 * Haken ist der einzige gefuellte Kreis, und zwar bei NEUNZIG Prozent Weiss
 * und nicht bei hundert - die Begruendung steht dort im Blatt und stimmt: Auf
 * 22 Punkten neben einer weissen Welle ist reines Weiss ein Lichtfleck, der
 * den Blick genau dorthin zieht, wo waehrend des Sprechens am wenigsten
 * passiert.
 *
 * Es sind <span> und keine <button>: Auf der Website loesen sie nichts aus.
 * Ein Knopf, der sich nicht druecken laesst, ist ein Bild - und gehoert dann
 * auch nicht als Knopf ins Markup, sonst kuendigt ein Vorleseprogramm eine
 * Handlung an, die es nicht gibt. */
.pille .rund {
  flex: none; display: grid; place-items: center;
  width: 22px; height: 22px; border-radius: 50%;
  background: rgba(255, 255, 255, .10);
  color: rgba(255, 255, 255, .72);
}
.pille .rund svg {
  width: 11px; height: 11px;
  stroke: currentColor; fill: none;
  stroke-width: 2.8; stroke-linecap: round; stroke-linejoin: round;
}
.pille .rund.gut { background: rgba(255, 255, 255, .9); color: #0e0e11; }
/* Die Knoepfe kommen mit der Aufnahme, nicht vor ihr: erst die Welle, dann
   die beiden Kreise von innen heraus. Das ist die Reihenfolge, in der es auch
   in der App passiert - aufgenommen wird, und DANN kann man eingreifen. */
.pille.hoert .rund { animation: rund-rein .34s var(--bogen) backwards; }
.pille.hoert .rund:first-child { animation-delay: .18s; }
.pille.hoert .rund:last-child  { animation-delay: .26s; }
@keyframes rund-rein { from { opacity: 0; transform: scale(.4); } }

/* Die Pille sitzt MITTIG unter dem Fenster. Sie stand links am Rand, und dort
   sieht sie aus wie etwas, das dort abgelegt wurde; in der Mitte ist sie das,
   was gerade passiert. */
.win-foot { display: flex; justify-content: center; }
.pille.rec.hoert::after {
  content: ''; position: absolute; inset: -1px; border-radius: 999px;
  border: 1px solid rgba(255,255,255,0.16);
  pointer-events: none; z-index: -1;
  animation: atem 2.6s ease-in-out infinite;
  will-change: transform, opacity;
}
@keyframes atem {
  0%, 100% { transform: scale(1);    opacity: .75; }
  50%      { transform: scale(1.06); opacity: 0;   }
}
/* Wer Bewegung abbestellt hat, bekommt den Zustand als ruhenden Ring - die
   Auskunft bleibt, das Zappeln geht. Genau wie in der App. */
@media (prefers-reduced-motion: reduce) {
  .pille.hoert .rund { animation: none; }
  .pille.rec.hoert::after { animation: none; transform: scale(1.03); opacity: .5; }
}

/* ══ 24. Die zwei Betriebsarten ═════════════════════════════════════════════
 *
 * Hier standen zwei gleich breite Karten nebeneinander: links eine echte
 * Vorfuehrung, rechts vier graue Kaesten, in denen nichts weiter stand als
 * der Wortlaut eines Befehls. Das war die schwaechste Stelle der Seite - an
 * genau dem Punkt, an dem die zweite Betriebsart erklaert werden soll, stand
 * eine Aufzaehlung statt eines Bildes.
 *
 * Der Aufbau ist jetzt ein anderer: zwei BREITE Zeilen untereinander, die
 * zweite spiegelverkehrt. Zwei schmale Spalten koennen keine Darstellung
 * tragen, sie koennen nur Text tragen - das war der eigentliche Grund fuer
 * die vier Kaesten. Wer der Sache Platz gibt, bekommt sie auch gezeigt.
 *
 * Auf dem Telefon faellt das Spiegeln weg und der Text steht IMMER zuerst:
 * Eine Darstellung, die man sieht, bevor man weiss, wovon sie handelt, ist
 * ein Raetsel und keine Erklaerung. */
.wandel-reihe {
  display: grid;
  grid-template-columns: minmax(0, 0.86fr) minmax(0, 1fr);
  gap: clamp(32px, 5vw, 72px);
  align-items: center;
}
/* Mehr Luft zwischen den beiden Zeilen, auf Ansage. 96 Punkte reichten
   nicht: Jede Zeile ist ein eigener Vorgang (diktieren, umschreiben), und mit
   dem alten Abstand lasen sie sich als zwei Absaetze einer Sache. Der Abstand
   zwischen zwei Zeilen ist jetzt groesser als der zwischen Text und Vorfuehrung
   innerhalb einer - erst damit gehoert zusammen, was zusammengehoert. */
.wandel-reihe + .wandel-reihe { margin-top: clamp(96px, 12vw, 180px); }
/* Die gespiegelte Zeile: Buehne links, Wort rechts. Im Markup steht sie
   ebenso herum, also sind die Spalten nur andersherum gewichtet. */
.wandel-reihe.kehr { grid-template-columns: minmax(0, 1fr) minmax(0, 0.86fr); }

.wandel-nr {
  display: block; margin-bottom: var(--a3);
  font-size: var(--gr-klein); font-weight: 700; letter-spacing: .14em;
  color: var(--tinte-leise);
  font-variant-numeric: tabular-nums;
}
.wandel-wort > p { margin: var(--a3) 0 0; }
.wandel-liste { list-style: none; margin: var(--a5) 0 0; padding: 0;
  display: grid; gap: var(--a3); }
.wandel-liste li {
  position: relative; padding-left: 26px;
  font-size: 15px; line-height: 1.55; color: var(--tinte-still);
}
/* Der Haken als Zeichnung und nicht als Buchstabe: Ein Haken aus der Schrift
   sitzt in jeder Schriftart woanders auf der Zeile. */
.wandel-liste li::before {
  content: ''; position: absolute; left: 0; top: .42em;
  width: 11px; height: 6px;
  border-left: 1.6px solid var(--tinte); border-bottom: 1.6px solid var(--tinte);
  transform: rotate(-45deg);
}

/* --- Das Schriftstueck, in dem ein Satz markiert ist --- */
.schrift {
  background: var(--papier);
  border-radius: var(--r-gross);
  /* Eine echte Kante und KEIN innen liegender Schatten: Der Kopf und der Fuss
     der Karte haben einen eigenen Grund und liegen ueber dem Grund der Karte -
     ein inset-Schatten waere von ihnen verdeckt, und die Karte stuende oben
     und unten ohne Umriss auf einer Flaeche, die fast dieselbe Farbe hat. */
  border: 1px solid var(--linie-klar);
  box-shadow: 0 1px 2px rgba(20,20,20,.04), 0 18px 44px -28px rgba(20,20,20,.30);
  overflow: hidden;
}
.schrift-kopf, .schrift-fuss {
  display: flex; align-items: center; gap: var(--a3);
  padding: var(--a3) var(--a5);
  background: var(--papier-tief);
}
.schrift-kopf { justify-content: space-between; box-shadow: inset 0 -1px 0 var(--linie); }
.schrift-fuss { box-shadow: inset 0 1px 0 var(--linie); min-height: 62px; }
.schrift-titel { font-size: var(--gr-klein); font-weight: 600; color: var(--tinte); }
/* --tinte-still und nicht --tinte-leise: Der Kopf der Karte hat im dunklen
   Thema einen eigenen Grund (#242424), und darauf kommt --tinte-leise auf
   genau 4,50:1 - also auf die Schwelle und nicht darueber. */
.schrift-wahl  { font-size: 12.5px; color: var(--tinte-still); }
/* Die feste Hoehe ist hier kein Notbehelf: Der Satz wird durch vier Ergebnisse
   ersetzt, von denen eines drei Zeilen lang ist. Ohne sie waechst und faellt
   die Karte bei jedem Befehl, und der Rest der Seite ruckt mit. */
.schrift-leib { padding: var(--a6) var(--a5); min-height: 216px; }
.schrift-p { margin: 0 0 var(--a4); font-size: 15.5px; line-height: 1.65; color: var(--tinte-still); }
.schrift-p:last-child { margin-bottom: 0; }
.schrift-ziel {
  color: var(--tinte);
  white-space: pre-wrap;          /* die Strichliste braucht echte Zeilen */
  transition: opacity var(--zeit) var(--bogen);
}
/* Die Markierung: der Farbwert des Hauses bei zwoelf Prozent, nicht das Blau
   des Systems. box-decoration-break, damit auch ein Satz ueber zwei Zeilen an
   BEIDEN Enden rund ist und nicht nur am Anfang und am Ende des Blocks. */
.schrift-ziel.gewaehlt {
  background: var(--wahl-grund);
  border-radius: 4px;
  padding: .12em .16em; margin: -.12em -.16em;
  box-decoration-break: clone; -webkit-box-decoration-break: clone;
}
.schrift-ziel.verblasst { opacity: 0; }
.schrift-ziel.ersetzt { color: var(--tinte); font-weight: 500; }
.schrift-ziel.tippt::after {
  content: ''; display: inline-block; width: 1.5px; height: 1.05em;
  margin-left: 2px; background: var(--tinte); vertical-align: -.14em;
}
.schrift-sagt { font-size: 14.5px; color: var(--tinte-still); min-height: 1.5em; }

/* --- Die vier Befehle: Knoepfe, die wirklich etwas tun --- */
/* DIE BEFEHLSLEISTE steht UEBER dem Fenster und ist EIN Bauteil.

   Vorher lagen vier lose Pillen unter dem Fenster. Zwei Sachen stimmten daran
   nicht, und beide sind Aussagen und keine Geschmacksfragen:

   1. UNTER dem Fenster liest man sie als Bildunterschrift, also als etwas,
      das den Inhalt erklaert. Oben sind sie eine Leiste, also etwas, das man
      bedient. Es sind Knoepfe, die wirklich ausloesen - die zweite Lesart ist
      die richtige.
   2. Vier lose Pillen sind vier Sachen. Eine geteilte Leiste ist EINE Sache
      mit vier Stellungen, und genau das ist es: ein Befehl, vier Fassungen
      desselben Satzes. */
/* DIE LEISTE IST DUNKEL, NICHT HELLGRAU.
 *
 * Auf Ansage: "mach das mit der Tabelle schwarz oder grau, wo die vier
 * Optionen sind." Sie war hellgrau auf weissem Grund und damit kaum von der
 * Karte zu unterscheiden - eine Leiste, die man bedient, sah aus wie eine
 * Flaeche, auf der etwas steht.
 *
 * Die fuenf Farben stehen als Werte an der Leiste selbst und nicht verstreut
 * in den Regeln darunter. Damit dreht das dunkle Blatt sie an EINER Stelle
 * um, und man sieht beim Lesen sofort, was zusammengehoert.
 *
 * Im dunklen Blatt bleibt alles, wie es war: Dort ist die Seite ohnehin
 * dunkel, eine schwarze Leiste waere unsichtbar und eine weisse waere das
 * Lauteste auf dem Schirm. Die Werte dort sind genau die, die vorher fest in
 * den Regeln standen.
 *
 * Nachgerechnet: Die ruhende Schrift steht bei 8,0:1 auf dem dunklen Grund,
 * die gewaehlte bei 16,9:1. Beides deutlich ueber den 4,5:1, die WCAG fuer
 * Fliesstext verlangt. */
.cmd-leiste {
  --leiste-grund: #1c1c1c;
  --leiste-kante: #ffffff14;
  --leiste-schrift: #ffffffa8;
  --leiste-an-grund: #ffffff;
  --leiste-an-schrift: #141414;

  display: flex; flex-wrap: wrap;
  gap: 3px; padding: 3px; margin: 0 auto var(--a5);
  width: fit-content; max-width: 100%;
  border-radius: var(--r-rund);
  background: var(--leiste-grund);
  box-shadow: inset 0 0 0 1px var(--leiste-kante);
}
:root[data-theme="dark"] .cmd-leiste {
  --leiste-grund: var(--papier-tief);
  --leiste-kante: var(--linie);
  --leiste-schrift: var(--tinte-still);
  --leiste-an-grund: var(--papier);
  --leiste-an-schrift: var(--tinte);
}
.cmd-reihe { display: flex; flex-wrap: wrap; gap: var(--a2); margin-top: var(--a4); }
.cmd {
  min-height: 44px;               /* Daumenbreite, nicht Schriftgroesse */
  padding-inline: var(--a4);
  border: 1px solid var(--linie-stark);
  border-radius: var(--r-rund);
  background: var(--papier);
  color: var(--tinte-still);
  font-size: 14px; font-weight: 500; cursor: pointer;
  transition: background var(--zeit-kurz) var(--bogen),
              color var(--zeit-kurz) var(--bogen),
              border-color var(--zeit-kurz) var(--bogen);
}
.cmd.an { background: var(--dunkel); border-color: var(--dunkel); color: var(--papier); }
.cmd:focus-visible { outline: 2px solid var(--tinte); outline-offset: 2px; }
@media (hover: hover) { .cmd:not(.an):hover { border-color: var(--tinte); color: var(--tinte); } }

/* EINE KARTE AUF DEM PAPIER DER SEITE IST IM DUNKELN KEINE KARTE.
 *
 * .karte und .tempo-bild fuellen sich mit --papier, und im hellen Blatt
 * stimmt das: Weiss auf einem #fafafa-Abschnitt liest sich als erhoeht. Im
 * dunklen Blatt ist --papier die Farbe der SEITE, die Karte hatte also
 * denselben Grund wie ihr Untergrund - gemessen 1,00:1. Uebrig blieb die
 * duenne Linie, und die stand bei 1,19:1.
 *
 * Jetzt liegt die Karte eine Stufe hoeher, und die Linie darum ist deutlich.
 * Beides zusammen macht den Rand, nicht eines davon allein. */
/* --papier-tief und nicht --papier-still: Beide Karten stehen oft in einem
   Abschnitt, der selbst schon --papier-still traegt - dann waeren sie wieder
   so hell wie ihr Untergrund. Gemessen am Tempo-Bild: genau 1,00:1.
   --papier-tief liegt ueber beidem, ueber der Seite wie ueber dem Band. */
:root[data-theme="dark"] .karte,
:root[data-theme="dark"] .tempo-bild { background: var(--papier-tief); }

/* Die Wortwolke hatte gar keine Kante: #242424 auf #0f0f0f sind 1,23:1, und
   im hellen Blatt faellt es nicht auf, weil dort alles hell ist.
   outline statt box-shadow, weil der Schatten dieser Kacheln der WELLE
   gehoert - ein zweiter Ring darin waere in jedem Bild der Bildfolge zu
   fuehren, und wer eines vergisst, laesst ihn blinken. */
:root[data-theme="dark"] .chips span {
  outline: 1px solid var(--linie);
  outline-offset: -1px;
}

/* Das Pluszeichen sass mit 8 Prozent Weiss auf der Karte. Im hellen Blatt ist
   die Karte schwarz und das reicht; im dunklen ist sie #242424, und dann sind
   es 1,23:1. */
:root[data-theme="dark"] .fcard-head .plus { background: #ffffff24; }

/* WAS OBEN LIEGEN SOLL, LIEGT AUCH IM DUNKELN OBEN.
 *
 * Alle diese Flaechen fuellen sich mit --papier und liegen im hellen Blatt
 * weiss auf grau. Im Dunkeln war --papier die Farbe der Seite, sie lagen
 * also dunkler als ihr Untergrund. Gemessen zwischen 1,10 und 1,23:1, und
 * mit der falschen Richtung. */
:root[data-theme="dark"] .ae-card.you,
:root[data-theme="dark"] .fix-chip,
:root[data-theme="dark"] .t-card,
:root[data-theme="dark"] .mail-bar,
:root[data-theme="dark"] .lauf-stueck { background: var(--papier-hoch); }
/* Der Chip liegt AUF der Karte, die selbst schon erhoeht ist - mit demselben
   Wert waeren beide gleich. Im hellen Blatt loest das ein Schlagschatten,
   und der ist auf dunklem Grund nichts. Also eine Stufe hoeher und eine
   eigene Kante. */
:root[data-theme="dark"] .fix-chip {
  background: #3d3d3d;
  color: var(--tinte);
  box-shadow: inset 0 0 0 1px var(--linie-klar), 0 6px 16px rgba(0, 0, 0, .5);
}
:root[data-theme="dark"] .cmd-leiste { --leiste-an-grund: var(--papier-hoch); --leiste-an-schrift: var(--tinte); }
:root[data-theme="dark"] .sys-wahl button.an { background: var(--papier-hoch); }

/* UND WAS EINE FLAECHE IST, BEKOMMT EINE KANTE.
 *
 * Diese hier hatten gar keine: Im hellen Blatt sind sie dunkle Kaesten auf
 * weissem Grund und brauchen keine. Im dunklen Blatt stehen sie als
 * #242424 auf #0f0f0f, das sind 1,23:1 - man ahnt sie, mehr nicht. */
:root[data-theme="dark"] .win,
:root[data-theme="dark"] .fcard,
:root[data-theme="dark"] .schluss,
:root[data-theme="dark"] .sys-wahl,
:root[data-theme="dark"] .zeitwahl-pr,
:root[data-theme="dark"] .sz,
:root[data-theme="dark"] .rowp,
:root[data-theme="dark"] .pille.rec {
  box-shadow: inset 0 0 0 1px var(--linie);
}

/* Der gewaehlte Knopf im Systemschalter war im Dunkeln VERSENKT: --papier ist
   dort #0f0f0f, die Schiene #242424, die gewaehlte Stellung also dunkler als
   ihr Gleis. Im hellen Blatt ist es umgekehrt, dort liegt sie weiss und
   erhoeht darauf. Derselbe Schalter soll nicht zwei verschiedene Sachen
   sagen; im Dunkeln liegt sie deshalb ebenfalls oben. */
:root[data-theme="dark"] .sys-wahl button.an {
  background: #3a3a3a;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .4);
}

:root[data-theme="dark"] { --wahl-grund: #ffffff1f; }
:root[data-theme="dark"] .schrift { background: var(--papier-tief); }
:root[data-theme="dark"] .schrift-kopf,
:root[data-theme="dark"] .schrift-fuss { background: #242424; }
/* :not(.an) und nicht blosses .cmd: ":root[data-theme=dark] .cmd" ist 0,3,0
   und schlaegt ".cmd.an" (0,2,0). Der gewaehlte Knopf verlor damit seinen
   hellen Grund und behielt seine dunkle Schrift - 1,07:1, also gar nichts.
   Gefunden hat es die Kontrastmessung im dunklen Thema, nicht das Auge. */
:root[data-theme="dark"] .cmd:not(.an) { background: transparent; }

/* Kleine Fenster fuer Abschnitt 24. Dieser Block muss der LETZTE seiner Art in
   dieser Datei bleiben - eine @media-Regel, die vor dem Baustein steht, den
   sie aendern will, verliert gegen ihn. Genau das ist hier schon einmal
   passiert (Schalter und Fusszeile blieben zu klein). */
@media (max-width: 900px) {
  .wandel-reihe, .wandel-reihe.kehr { grid-template-columns: 1fr; gap: var(--a8); }
  /* Das Wort zuerst, auch in der gespiegelten Zeile: Eine Darstellung ohne
     Ueberschrift darueber ist auf dem Telefon ein Raetsel. */
  .wandel-reihe.kehr .wandel-wort { order: -1; }
}
@media (max-width: 720px) {
  .schrift-leib { padding: var(--a5) var(--a4); min-height: 244px; }
  .schrift-p { font-size: 15px; }
  .cmd { font-size: 13.5px; padding-inline: var(--a3); }
}

/* ══ 25. Das App-Fenster, die Schalter, die Anschluesse ═════════════════════
 *
 * Auf Ansage: "bau alles ein was meine App zu bieten kann". Bis dahin stand
 * auf der Startseite nur das Diktieren - also ungefaehr ein Drittel.
 *
 * DAS FENSTER IST DUNKEL, wie das im Aufmacher. Das Haus ist hell, und dabei
 * bleibt es; aber das Fenster IST hier der Gegenstand und nicht der Grund.
 * Zwei Fenster derselben App in zwei Farben auf einer Seite waeren der
 * eigentliche Bruch.
 *
 * DIE DREI WERTE fuer Text auf dunklem Grund stehen als eigene Werte da und
 * nicht als feste Farben. Grund: Im dunklen Thema wechselt der Grund des
 * Fensters von #141414 auf #1e1e1e. Weiss mit Deckkraft traegt ueber beide
 * Gruende, eine feste Graustufe nur ueber einen - genau daran ist die
 * Kontrastmessung hier schon einmal haengen geblieben. */
.app-win {
  --app-linie: rgba(255, 255, 255, .10);
  --app-still: rgba(255, 255, 255, .74);   /* ~9,9:1 auf #141414 */
  --app-leise: rgba(255, 255, 255, .58);   /* ~5,9:1 auf #141414 */
  max-width: 1060px;
}
.app-leib { display: grid; grid-template-columns: 196px minmax(0, 1fr); }
.app-leiste {
  display: flex; flex-direction: column; gap: 2px;
  padding: var(--a2) var(--a2) var(--a6);
  box-shadow: inset -1px 0 0 var(--app-linie);
}
.app-nav {
  min-height: 44px; text-align: left; padding-inline: var(--a3);
  border: 0; border-radius: var(--r-klein); background: transparent;
  color: var(--app-leise); font-size: 14px; font-weight: 500; cursor: pointer;
  transition: background var(--zeit-kurz) var(--bogen), color var(--zeit-kurz) var(--bogen);
}
.app-nav.an { background: rgba(255, 255, 255, .10); color: #fff; }
.app-nav:focus-visible { outline: 2px solid currentColor; outline-offset: -2px; }
@media (hover: hover) { .app-nav:not(.an):hover { color: #fff; } }

.app-inhalt { padding: var(--a6) var(--a8) var(--a8); min-height: 372px; }
.app-blatt { display: none; }
.app-blatt.an { display: block; animation: blatt-auf .42s var(--bogen) both; }
@keyframes blatt-auf { from { opacity: 0; transform: translate3d(0, 10px, 0); } }
.app-h { font-size: 19px; margin-bottom: var(--a1); }
.app-sub { margin: 0 0 var(--a5); max-width: 52ch; font-size: 14px; line-height: 1.55; color: var(--app-still); }

.app-zeile {
  display: flex; align-items: center; justify-content: space-between; gap: var(--a3);
  margin-bottom: var(--a2); padding: 11px var(--a4);
  border-radius: var(--r-klein); background: rgba(255, 255, 255, .05); font-size: 14px;
}
.app-l { display: flex; align-items: baseline; gap: var(--a2); min-width: 0; color: #fff; }
.app-l i { font-style: normal; font-size: 12.5px; color: var(--app-leise); }
.app-r { flex: none; font-size: 13.5px; color: var(--app-still); }
.app-r kbd {
  font: inherit; padding: 2px 7px; border-radius: 6px;
  background: rgba(255, 255, 255, .12); color: #fff;
}
.app-zeile.auf { justify-content: flex-start; }
.app-zeile.auf .app-r { margin-left: auto; }
/* Der Haken sitzt in einem Kreis und ist gezeichnet, nicht gesetzt: ein Haken
   aus der Schrift steht in jeder Schriftart woanders auf der Zeile. */
.app-hk { flex: none; position: relative; width: 18px; height: 18px; border-radius: 50%;
  box-shadow: inset 0 0 0 1.5px var(--app-leise); }
.app-hk.voll { background: var(--app-still); box-shadow: none; }
.app-hk.voll::after { content: ''; position: absolute; left: 5px; top: 5px; width: 8px; height: 4px;
  border-left: 1.6px solid #141414; border-bottom: 1.6px solid #141414; transform: rotate(-45deg); }
.app-zeile.fertig .app-l { color: var(--app-leise); text-decoration: line-through; }

.app-pillen { display: flex; flex-wrap: wrap; gap: var(--a2); margin-bottom: var(--a4); }
.app-pillen span { padding: 7px 12px; border-radius: var(--r-rund);
  background: rgba(255, 255, 255, .08); font-size: 13.5px; color: #fff; }
.app-knopfreihe { display: flex; flex-wrap: wrap; gap: var(--a2); margin-top: var(--a4); }
.app-mini { padding: 7px 12px; border-radius: var(--r-rund);
  box-shadow: inset 0 0 0 1px var(--app-linie); font-size: 13px; color: var(--app-still); }

.app-stil-reihe { display: flex; flex-wrap: wrap; gap: var(--a2); margin-bottom: var(--a4); }
.app-stil {
  min-height: 44px; padding-inline: var(--a4); border: 0; border-radius: var(--r-rund);
  box-shadow: inset 0 0 0 1px var(--app-linie); background: transparent;
  color: var(--app-still); font-size: 13.5px; font-weight: 500; cursor: pointer;
}
/* Feste Farben und keine Werte: Dieser Knopf liegt in BEIDEN Themen auf
   dunklem Grund, also darf er sich mit dem Thema nicht drehen. */
.app-stil.an { background: #f2f2f2; color: #141414; box-shadow: none; }
.app-stil:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }

.app-stil-karte { display: grid; gap: var(--a1); margin-bottom: var(--a2);
  padding: var(--a3) var(--a4); border-radius: var(--r-klein); background: rgba(255, 255, 255, .05); }
.app-stil-karte b { font-size: 12px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--app-leise); }
.app-stil-karte span { font-size: 15px; color: #fff; }
.app-notiz { padding: var(--a4) var(--a5); border-radius: var(--r-klein);
  background: rgba(255, 255, 255, .05); }
.app-notiz p { position: relative; margin: 0 0 10px; padding-left: 16px;
  font-size: 14.5px; color: var(--app-still); }
.app-notiz p:last-child { margin-bottom: 0; }
.app-notiz p::before { content: ''; position: absolute; left: 0; top: .62em;
  width: 5px; height: 5px; border-radius: 50%; background: var(--app-leise); }

/* --- Der Ein-Aus-Schalter, wie in der App --- */
.sw {
  flex: none; position: relative; width: 38px; height: 22px; margin-top: 2px;
  border-radius: var(--r-rund);
  /* Ein fester Grauwert und nicht --papier-tief: Der Schalter liegt auf
     --papier-still, und zwischen #fafafa und #f4f4f4 liegen anderthalb
     Prozent - der ausgeschaltete Schalter war schlicht nicht zu sehen. */
  background: #e4e4e4;
  transition: background var(--zeit) var(--bogen);
}
.sw::after {
  content: ''; position: absolute; top: 3px; left: 3px; width: 16px; height: 16px;
  border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(20, 20, 20, .3);
  transition: transform var(--zeit) var(--bogen);
}
.sw.an { background: var(--dunkel); box-shadow: none; }
.sw.an::after { transform: translate3d(16px, 0, 0); }
/* :not(.an) - derselbe Spezifitaetsfehler wie beim Befehlsknopf:
   ":root[data-theme=dark] .sw" ist 0,3,0 und schlaegt ".sw.an" (0,2,0).
   Der eingeschaltete Schalter behielt damit im dunklen Thema die dunkle
   Rinne und bekam einen dunklen Knopf dazu - an und aus sahen gleich aus. */
:root[data-theme="dark"] .sw:not(.an) { background: #3a3a3a; }
:root[data-theme="dark"] .sw.an::after { background: #141414; }
/* Im dunklen Fenster dreht sich der Schalter mit: hell auf dunkel. */
.app-win .sw { background: rgba(255, 255, 255, .14); box-shadow: none; }
.app-win .sw.an { background: #f2f2f2; }
.app-win .sw.an::after { background: #141414; }

/* --- Die Schalterliste --- */
/* VIER SPALTEN STATT ZWEI, UND KEINE ERKLAERUNG JE SCHALTER.
 *
 * Gemeldet: der Abschnitt nimmt zu viel Platz. Er tat es auch - sechzehn
 * Zeilen, jede mit Namen UND einem erklaerenden Satz darunter, in zwei
 * Spalten: rund zwoelfhundert Punkte Hoehe fuer einen Abschnitt, der eine
 * einzige Sache sagt.
 *
 * Und das ist der Punkt: Seine Aussage ist nicht, WAS jeder einzelne Schalter
 * tut, sondern DASS es so viele gibt und dass sie offen liegen. Dafuer
 * braucht es die Namen und die Schalter, nicht die Saetze. Die Erklaerung
 * steht in der App neben dem Schalter, und dort gehoert sie hin: Dort ist sie
 * eine Hilfe, hier war sie eine Textwand, die niemand liest.
 *
 * Vier Spalten und Zeilen ohne zweiten Absatz machen daraus rund
 * dreihundertfuenfzig Punkte. Man sieht sechzehn Schalter auf einen Blick,
 * und genau das war gemeint. */
.sch-raster {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--a4); align-items: start;
}
.sch-gruppe { padding: var(--a5); border-radius: var(--r-gross);
  background: var(--papier-still); box-shadow: inset 0 0 0 1px var(--linie); }
.sch-titel { margin: 0 0 var(--a2); font-size: 11px; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase; color: var(--tinte-leise); }
/* Die Zeile IST der Knopf, nicht nur der kleine Schalter daneben.
   Auf Ansage lassen sich die Schalter umlegen, und ein Ziel von 38 mal 22
   Punkten trifft auf einem Telefon niemand zuverlaessig. So ist die ganze
   Zeile das Ziel, mindestens 44 Punkte hoch, wie es sich gehoert.

   Ein <button> bringt eigene Schrift, eigenen Rahmen und eigene Ausrichtung
   mit; das muss hier alles wieder heraus, sonst steht die Zeile in 13,333px
   Arial mittig. */
.sch-zeile { display: flex; align-items: center; justify-content: space-between;
  gap: var(--a3); padding: 11px 0; min-height: 44px;
  width: 100%; margin: 0;
  border: 0; background: none; text-align: left;
  font: inherit; color: inherit; cursor: pointer;
  border-radius: var(--r-klein);
  transition: opacity var(--zeit-kurz) var(--bogen); }
.sch-zeile + .sch-zeile { box-shadow: inset 0 1px 0 var(--linie); }
.sch-zeile b { display: block; font-size: 14px; font-weight: 500;
  line-height: 1.35; color: var(--tinte); }
@media (hover: hover) { .sch-zeile:hover b { color: var(--tinte); } .sch-zeile:hover { opacity: .78; } }
.sch-zeile:active { opacity: .6; }
/* Der Tastaturweg muss sichtbar bleiben. Ohne das waere die Zeile fuer jeden,
   der nicht mit der Maus arbeitet, ein Knopf ohne Ort. */
.sch-zeile:focus-visible { outline: 2px solid var(--tinte); outline-offset: 3px; }

/* Der Hinweis darunter: leise, mittig, mit Abstand. Er sagt, dass hier nichts
   gespeichert wird, und das darf man lesen, ohne dass es sich vordraengt. */
.sch-hinweis { margin: var(--a8) auto 0; max-width: 46ch; text-align: center;
  font-size: 14px; color: var(--tinte-leise); }

@media (prefers-reduced-motion: reduce) {
  .app-blatt.an { animation: none; }
  .sw, .sw::after { transition: none; }
}

/* Kleine Fenster fuer Abschnitt 25. Dieser Block ist jetzt der LETZTE seiner
   Art in dieser Datei und muss es bleiben - siehe die Begruendung oben. */
@media (max-width: 1180px) {
  .sch-raster { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 620px) {
  .sch-raster { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 720px) {
  /* Die Seitenleiste wird zur Reiterzeile. Sieben Knoepfe untereinander
     schoeben den Inhalt auf dem Telefon aus dem Bild; nebeneinander mit
     Wischen bleibt beides sichtbar. */
  .app-leib { grid-template-columns: minmax(0, 1fr); }
  .app-leiste {
    flex-direction: row; gap: var(--a1); padding: var(--a2);
    overflow-x: auto; scrollbar-width: none;
    box-shadow: inset 0 -1px 0 var(--app-linie);
  }
  .app-leiste::-webkit-scrollbar { display: none; }
  .app-nav { flex: none; }
  .app-inhalt { padding: var(--a5) var(--a5) var(--a6); min-height: 400px; }
  .sch-gruppe { padding: var(--a5); }
}

/* Der Umschalter macOS/Windows wird auf Geraeten mit dem Finger groesser.
   30 Punkte reichen der Maus und sind unter dem, was ein Daumen sicher
   trifft; 44 ist das Mass, das die uebrigen Knoepfe dieser Seite einhalten.
   Nur unter (pointer: coarse), damit der Aufmacher am Rechner aussieht wie
   bisher - dort ist die Hoehe kein Problem, sondern Gestaltung. */
@media (pointer: coarse) {
  .sys-wahl button { min-height: 44px; }
}

/* ============================================================================
   26. DIE DOWNLOADSEITE
   ============================================================================

   Der Vorwurf lautete "unprofessionell", und er war berechtigt. Gemessen, was
   ihn ausgeloest hat:

   1. 143 PIXEL NICHTS zwischen der letzten Zeile des Aufmachers und der ersten
      Karte. Der Aufmacher war 459px hoch, die Schrift endete bei 409, die
      Karten fingen bei 552 an. Ein Loch dieser Groesse mitten auf einer Seite
      mit zwei Elementen liest sich nicht als Ruhe, sondern als Fehler.
   2. ZWEI KNOEPFE MIT UNGLEICHEM GEWICHT fuer zwei gleichwertige Wege - der
      eine weiss, der andere schwarz. Der schwarze gewinnt jeden Blickvergleich,
      und damit hat die Seite eine Empfehlung ausgesprochen, die niemand
      gemeint hat.
   3. GRAU AUF FAST-WEISS mit einer Linie bei 6 Prozent. Das ist die Gestalt,
      die ein Platzhalter hat, solange der Inhalt fehlt.

   Die Antwort ist EIN schwarzer Kasten mit zwei Haelften. Er loest alle drei
   auf einmal: Er hebt sich ab, er traegt zwei gleich helle Knoepfe, und er ist
   schwer genug, um den Aufmacher direkt an sich zu ziehen.

   WARUM SCHWARZ IN BEIDEN THEMEN. Der Kasten ist die Stelle, an der die Seite
   ihre einzige Frage stellt. Er soll auf jedem Bildschirm dasselbe Gewicht
   haben. Im dunklen Thema bekommt er dafuer eine helle Kante - ohne sie faende
   ihn dort niemand mehr. */

/* --- Aufmacher: Luft raus, Kasten ran --- */
.hero-banner.dl-auf {
  min-height: 0;
  padding-block: clamp(var(--a16), 10vw, 120px) 0;
}
.hero-banner.dl-auf h1 { font-size: var(--gr-riesig); }
.hero-banner.dl-auf .t-lies {
  /* 140px Ueberschrift und der Vorspann direkt darunter, ohne einen Pixel
     dazwischen - gemessen, nicht geschaetzt: Unterkante h1 332, Oberkante
     Vorspann 332. Grosse Schrift auf enger Zeile braucht darunter Luft,
     sonst liest sich der Vorspann als vierte Zeile der Ueberschrift. */
  margin: var(--a5) auto 0; max-width: 34rem;
  color: var(--tinte-still);
}

/* --- Der Kasten --- */
.dl-abschnitt { padding: var(--a10) 0 var(--a-abschnitt); }
/* ZWEI KARTEN, NICHT EIN GETEILTER KASTEN.
 *
 * Hier stand ein schwarzer Block, den eine senkrechte Linie in zwei Haelften
 * schnitt. Auf Ansage sind daraus zwei eigene Karten geworden, mit Abstand
 * dazwischen und runden Ecken an allen vier Seiten.
 *
 * Das ist auch die ehrlichere Form: Es sind zwei Entscheidungen, nicht eine
 * mit zwei Haelften. Wer einen Mac hat, liest die eine und nicht die andere.
 * Die Linie behauptete einen Zusammenhang, den es nicht gibt. */
.dl-kasten {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--a6);
  max-width: 1040px; margin: 0 auto;
  background: none; box-shadow: none;
}

/* DIE KARTEN FOLGEN DEM THEMA.
 *
 * Sie waren in BEIDEN Themen schwarz, mit #141414 als fester Zahl. Das kam
 * aus einem echten Fehler: Mit var(--dunkel) drehte sich die Flaeche im
 * dunklen Thema auf Weiss, die Schrift blieb weiss, und gemessen standen
 * 1,04:1 bis 1,12:1 im ganzen Kasten. Die Zahl war die schnelle Abhilfe.
 *
 * Sie war aber die falsche. Das Haus ist hell, und zwei schwarze Bloecke auf
 * einer weissen Seite sind ein Fremdkoerper. Richtig ist nicht "immer
 * schwarz", sondern "alles dreht sich gemeinsam": Flaeche, Schrift, Linien
 * und Knopf haengen jetzt alle an denselben Namen, und damit kann keine
 * Haelfte ohne die andere umkippen.
 *
 * Zu pruefen ist deshalb nicht mehr eine feste Farbe, sondern dass hier
 * ueberhaupt keine festen Farben fuer Flaeche und Schrift stehen. Genau das
 * tut test/downloadkasten.test.js. */
.dl-kasten .dl-karte {
  display: flex; flex-direction: column;
  padding: var(--a10) var(--a8) var(--a8);
  border: 0;
  border-radius: var(--r-flaeche);
  background: var(--papier);
  color: var(--tinte);
  box-shadow: inset 0 0 0 1px var(--linie-klar, var(--linie)),
              0 24px 70px -24px rgba(20, 20, 20, .18),
              0 2px 8px rgba(20, 20, 20, .06);
  transition: transform var(--zeit) var(--bogen), box-shadow var(--zeit) var(--bogen);
}
:root[data-theme="dark"] .dl-kasten .dl-karte {
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .12),
              0 24px 70px -30px rgba(0, 0, 0, .8);
}
/* Beim Zeigen hebt sich die Karte, die gemeint ist. Zwei gleich laute Wege
   nebeneinander: Der Zeiger sagt, welcher gerade der eigene ist. */
@media (hover: hover) {
  .dl-kasten .dl-karte:hover {
    transform: translateY(-4px);
    box-shadow: inset 0 0 0 1px var(--linie-klar, var(--linie)),
                0 34px 80px -24px rgba(20, 20, 20, .22),
                0 4px 12px rgba(20, 20, 20, .08);
  }
  :root[data-theme="dark"] .dl-kasten .dl-karte:hover {
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .18),
                0 34px 80px -28px rgba(0, 0, 0, .9);
  }
}
@media (prefers-reduced-motion: reduce) {
  .dl-kasten .dl-karte { transition: none; }
  .dl-kasten .dl-karte:hover { transform: none; }
}

.dl-kasten .dl-kopf { display: flex; align-items: center; gap: var(--a3); }
.dl-kasten .dl-sym {
  flex: none; display: grid; place-items: center;
  width: 46px; height: 46px; border-radius: 13px;
  background: var(--papier-tief);
  box-shadow: inset 0 0 0 1px var(--linie);
  color: var(--tinte);
}
.dl-kasten .dl-sym svg { width: 23px; height: 23px; }
.dl-kasten .dl-titel { min-width: 0; }
.dl-kasten .dl-titel h2 {
  margin: 0; font-size: 25px; font-weight: 620;
  letter-spacing: -.015em; line-height: 1.15; color: var(--tinte);
}
.dl-kasten .dl-plattform {
  display: block; margin-top: 2px; font-size: 13.5px;
  color: var(--tinte-still);
}

/* --- Fassung, Groesse, Datum --- */
.dl-kasten .dl-daten {
  display: flex; margin: var(--a6) 0 0;
  border-top: 1px solid var(--linie);
  border-bottom: 1px solid var(--linie);
}
.dl-kasten .dl-daten > div { flex: 1; min-width: 0; padding: var(--a3) 0; }
.dl-kasten .dl-daten > div + div {
  border-left: 1px solid var(--linie); padding-left: var(--a4);
}
.dl-kasten .dl-daten dt {
  font-size: 10.5px; font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: var(--tinte-leise);
}
.dl-kasten .dl-daten dd {
  margin: 3px 0 0; font-size: 15px; font-weight: 600; color: var(--tinte);
  font-variant-numeric: tabular-nums;
}
/* Solange /api/stand nicht geantwortet hat, steht hier nur ein Strich. main.js
   nimmt die Klasse ab, sobald ein echter Wert eintrifft; antwortet niemand,
   bleibt der Strich leise stehen, und genau so soll eine fehlende Auskunft
   aussehen. Leise heisst leiser als die Zahl daneben, nicht unlesbar. */
.dl-kasten .dl-daten dd.dl-wartet { color: var(--tinte-leise); }

/* --- Die vier Zusagen je Seite --- */
.dl-kasten .dl-liste {
  list-style: none; margin: var(--a6) 0 var(--a8); padding: 0;
  display: flex; flex-direction: column; gap: var(--a3);
  flex: 1; align-content: start;
}
.dl-kasten .dl-liste li {
  position: relative; padding-left: 26px;
  font-size: 14.5px; line-height: 1.5; color: var(--tinte-still);
}
/* Der Haken ist GEZEICHNET und kein Schriftzeichen. U+2713 stand hier zuerst
   und kam als senkrechter Strich mit Punkt heraus: Figtree fuehrt das Zeichen
   nicht, und was der Ersatz liefert, haengt am Rechner des Besuchers. Zwei
   Kanten eines gedrehten Kastens sehen ueberall gleich aus. */
.dl-kasten .dl-liste li::before {
  content: ""; position: absolute; left: 0; top: 2px;
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--papier-tief);
  box-shadow: inset 0 0 0 1px var(--linie);
}
.dl-kasten .dl-liste li::after {
  content: ""; position: absolute; left: 5px; top: 6px;
  width: 6px; height: 3px;
  border-left: 1.6px solid var(--tinte); border-bottom: 1.6px solid var(--tinte);
  transform: rotate(-45deg);
}

/* --- Die beiden Knoepfe ---
   Beide dunkel auf heller Karte, und im dunklen Thema drehen sie sich mit,
   weil --dunkel und --papier sich mitdrehen. Das ist der Kern der Sache: Die
   zwei Wege sind gleich laut, und keiner von beiden haengt an einer festen
   Farbe, die im anderen Thema falsch waere. */
.dl-kasten .dl-knopf {
  margin-top: auto; width: 100%;
  height: 52px; border-radius: 14px;
  background: var(--dunkel); color: var(--papier);
}
.dl-kasten .dl-knopf:hover { background: var(--dunkel-hoch, var(--dunkel)); opacity: .92; }
.dl-kasten .dl-knopf:focus-visible { outline: 2px solid var(--tinte); outline-offset: 3px; }
.dl-kasten .dl-knopf .ic { width: 17px; height: 17px; fill: currentColor; }
.dl-kasten .dl-fein {
  margin: var(--a3) 0 0; text-align: center;
  font-size: 12.5px; color: var(--tinte-leise);
}

/* --- Die Zusagen unter dem Kasten ---
   Sie standen vorher als "FREE" zweimal IM Kasten und zusaetzlich im
   Vorspann des Aufmachers. Dreimal dasselbe Versprechen ueberzeugt nicht
   dreimal so gut. */
.dl-zusage {
  list-style: none; margin: var(--a6) auto 0; padding: 0;
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: var(--a2) var(--a5); max-width: 1000px;
  font-size: 13.5px; color: var(--tinte-still);
}
.dl-zusage li { position: relative; }
.dl-zusage li + li::before {
  content: ""; position: absolute; left: calc(var(--a5) / -2); top: 50%;
  width: 3px; height: 3px; margin-top: -1.5px; border-radius: 50%;
  background: var(--tinte-leise);
}

/* --- Die Anforderungstabelle ---
   Sie bleibt hell. Sie ist Nachschlagewerk, nicht Entscheidung: Wer hier
   liest, sucht seine eigene Zeile und will sie nicht auf schwarzem Grund
   suchen muessen. */
.dl-ueber {
  margin: var(--a-abschnitt) 0 var(--a6);
  font-size: var(--gr-gross); font-weight: 700; letter-spacing: -.025em;
  text-align: center; color: var(--tinte);
}
.dl-tabelle {
  max-width: 1000px; margin: 0 auto; overflow-x: auto;
  border-radius: var(--r-flaeche); background: var(--papier);
  box-shadow: inset 0 0 0 1px var(--linie-klar);
}
.dl-tabelle table { width: 100%; border-collapse: collapse; min-width: 560px; }
.dl-tabelle th, .dl-tabelle td {
  text-align: left; padding: var(--a4) var(--a6); font-size: 14.5px;
  border-bottom: 1px solid var(--linie);
}
.dl-tabelle tbody tr:last-child td { border-bottom: 0; }
.dl-tabelle thead th {
  font-size: 10.5px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--tinte-leise);
}
.dl-tabelle tbody td:first-child { width: 26%; font-weight: 600; color: var(--tinte); }
.dl-tabelle tbody td { color: var(--tinte-still); }

@media (max-width: 860px) {
  /* Untereinander bleiben es zwei Karten, nur gestapelt. Hier stand frueher
     eine Regel, die aus der senkrechten Trennlinie eine waagerechte machte;
     die gibt es nicht mehr, der Abstand trennt jetzt. */
  .dl-kasten { grid-template-columns: minmax(0, 1fr); max-width: 520px; gap: var(--a5); }
  .dl-kasten .dl-karte { padding: var(--a8) var(--a6) var(--a6); }
}

/* Dieser Block ist jetzt der letzte 720er dieser Datei und muss es bleiben. */
@media (max-width: 720px) {
  .hero-banner.dl-auf { padding-block: var(--a16) 0; }
  .dl-abschnitt { padding-top: var(--a8); }
  .dl-kasten .dl-daten > div + div { padding-left: var(--a3); }
  .dl-kasten .dl-daten dd { font-size: 14px; }
  .dl-ueber { margin-top: var(--a20); }
  .dl-tabelle th, .dl-tabelle td { padding: var(--a3) var(--a4); }
}

/* ============================================================================
   27. DER FAECHER: DIE SIEBEN SEITEN DER APP
   ============================================================================

   Hier stand ein Fenster mit Ampel, Windows-Knoepfen und einer Reiterleiste,
   und darin sieben erfundene Inhalte: "This week 2,140 words", "Longest
   dictation 3 min 12 s", "Shortcut Fn held". Nichts davon steht so in der App.

   Drei Ansagen liegen dem hier zugrunde:

   1. ES SOLL DIE APP ZEIGEN, und zwar ihren AKTUELLEN Stand. Jede Karte ist
      deshalb aus src/renderer/settings.html abgelesen: dieselben sieben
      Zeichen (dieselben Pfade), dieselbe Reihenfolge, die Verbrauchskarte an
      derselben Stelle, die Ueberschriften der App.
   2. KEIN macOS/Windows. Die App sieht auf beiden Systemen gleich aus. Ein
      Rahmen mit Ampel sagt ueber die App nichts und behauptet nebenbei einen
      Unterschied, den es nicht gibt.
   3. ANKLICKEN, UND SIE GEHT GROSS AUF.

   WARUM EIN FAECHER UND KEIN RASTER. Sieben gleich grosse Kacheln
   nebeneinander sind ein Inhaltsverzeichnis: Man zaehlt sie und liest keine.
   Uebereinandergelegt sind sie ein Stapel, den jemand hingelegt hat - das
   Auge sieht zuerst das Ganze und dann eine einzelne. Genau das soll der
   Abschnitt sagen: EIN Programm, sieben Orte darin.

   WARUM DIE KARTE EIN <button> IST. Sie laesst sich anklicken. Ein <div> mit
   einem Klick-Horcher waere mit der Tabulatortaste nicht erreichbar und fuer
   ein Vorleseprogramm nicht als Bedienelement erkennbar - beides faellt
   niemandem auf, der eine Maus und Augen hat, und beiden anderen sofort. */

.faecher {
  /* Die Buehne. Perspektive macht aus dem Kippen eine Drehung im Raum statt
     einer Scherung in der Ebene; ohne sie sehen gekippte Karten aus wie
     schlecht gesetzte Rechtecke. */
  position: relative;
  display: flex; justify-content: center; align-items: flex-end;
  margin-top: var(--a8);
  perspective: 1800px;
  perspective-origin: 50% 40%;

  /* DREI ZAHLEN, UND ALLES ANDERE RECHNET DARAUS. Vorher stand die Breite an
     acht Stellen einzeln - in der Grundregel, im Schweben, in der
     Ausweich-Regel und das alles noch einmal je Bildschirmbreite. Wer eine
     aenderte, aenderte sie an sieben Stellen nicht mit.

     Die Karte ist jetzt QUER: Sie zeigt ein Bildschirmfoto der App, und die
     App ist breiter als hoch (1240 : 820). Ein hochkant stehender Rahmen
     haette das Bild beschnitten oder gequetscht.

     Die Luecke ist genau die HALBE Kartenbreite. Damit liegt von jeder Karte
     die Haelfte frei - bei 400 Punkten sind das 200, also mehr als die 162,
     die vorher im Hochformat frei lagen. Gemeldet war "man verklickt sich zu
     schnell auf andere"; was dabei zaehlt, ist die freie Breite in Punkten
     und nicht ihr Anteil.

     22vw als Deckel: Sieben Karten im Faecher sind zusammen vier Kartenbreiten
     breit (6 x 0,5 + 1). Bei 22vw sind das 88 Prozent des Fensters - es bleibt
     also links und rechts Luft, und die Seite bekommt nie einen waagerechten
     Rollbalken. */
  --fa-b: min(400px, 20.5vw);
  --fa-h: calc(var(--fa-b) / 1.512);
  --fa-lueck: calc(var(--fa-b) * .58);

  /* MEHR LUFT UND EINE SCHRAEGE. Auf Ansage, mit einem Bild daneben: "mit
     mehr Abstand, wie es gerade ist, ist gut, aber jetzt bisschen quer."
     Vorher lagen die Karten fast waagerecht in einer Reihe und ueberlappten
     sich um die halbe Breite.
     Zwei Zahlen machen das aus, und sie stehen hier oben, weil auch die
     Regeln fuers Zeigen mit ihnen rechnen:
       --fa-stufe  wie viel jede Karte hoeher liegt als ihre Vorgaengerin.
                   Aus 9 Punkten sind 21 geworden; erst damit laeuft die
                   Reihe sichtbar schraeg nach oben statt nur zu treppen.
       --fa-kipp   wie schief die Karte selbst steht. Fuer ALLE gleich, sonst
                   stuenden die Oberkanten auf sieben verschiedenen Schraegen
                   und der Stapel saehe umgefallen aus.
     Die Luecke waechst von der halben auf 0,58 Kartenbreiten. Sieben Karten
     sind damit 6 x 0,58 + 1 = 4,48 Kartenbreiten breit; bei 20,5vw sind das
     92 Prozent des Fensters, es bleibt also links und rechts Luft und die
     Seite bekommt keinen waagerechten Rollbalken. Die Karte wird dafuer
     schmaler - mehr Abstand bei gleicher Gesamtbreite geht nicht anders. */
  --fa-stufe: 21px;
  --fa-kipp: -4deg;

  /* Die Schraege und die hoehere Treppe brauchen Platz nach oben: 6 Stufen
     und die Drehung der breiten Reihe. */
  min-height: calc(var(--fa-h) + 155px);
}

.fa-karte {
  /* Alle Karten liegen aufeinander; auseinander treibt sie erst --i. */
  position: absolute; bottom: 0; left: 50%;
  width: var(--fa-b); height: var(--fa-h);
  margin: 0; padding: 0; border: 0; background: none;
  font: inherit; color: inherit; text-align: left;
  cursor: pointer;
  transform-origin: 50% 100%;
  --m: calc(var(--i) - 3);

  /* WELCHE KARTE VOR WELCHER LIEGT, UND WARUM DAS DIE GANZE FRAGE IST.

     Vorher lag die MITTLERE Karte vorn und die uebrigen traten nach beiden
     Seiten zurueck. Im Hochformat war das richtig. Mit den Bildschirmfotos
     ist es falsch geworden, und zwar sichtbar: Von einer Karte LINKS der
     Mitte liegt die linke Haelfte frei - dort stehen Seitenleiste und der
     Anfang des Inhalts. Von einer Karte RECHTS der Mitte liegt die RECHTE
     Haelfte frei, und das ist bei einer Oberflaeche der weisse Rand. Die
     drei rechten Karten sahen deshalb leer aus.

     Jetzt liegt jede Karte vor ihrer linken Nachbarin. Damit zeigt JEDE ihre
     linke Haelfte, und die letzte liegt ganz frei. Nebenbei liest sich die
     Reihe wie die Seitenleiste der App: Home, Diktate, Woerterbuch,
     Textbausteine, Stil, Notizblock, Aufgaben. */
  z-index: calc(var(--i) + 1);

  /* Die Treppe laeuft nach vorn hin nach UNTEN: Was naeher ist, steht tiefer.
     Gerechnet von hinten (6 - i), damit die vorderste Karte auf 0 sitzt und
     keine aus dem Kasten faellt.

     rotateY ist fuer ALLE Karten gleich, und das ist der Unterschied zwischen
     einem Regal und einem Haufen. Vorher hatte jede Karte ihren eigenen
     Winkel; die Oberkanten standen dann auf sieben verschiedenen Schraegen,
     und der Stapel sah aus, als waere er umgefallen. Mit einem Winkel fuer
     alle laufen die Kanten parallel - dieselbe Drehung, nur weiter vorne oder
     weiter hinten. Das ist auch der Grund, warum die Buehne eine Perspektive
     traegt: Ohne sie waere rotateY eine Scherung in der Ebene. */
  transform:
    translateX(calc(-50% + var(--m) * var(--fa-lueck)))
    translateY(calc((6 - var(--i)) * var(--fa-stufe) * -1))
    rotate(var(--fa-kipp))
    rotateY(15deg)
    scale(calc(.94 + var(--i) * .01));
  transition: transform .42s var(--bogen), filter .42s var(--bogen);
}

.fa-fenster {
  display: block; width: 100%; height: 100%;
  border-radius: 16px; overflow: hidden;
  background: #ffffff;
  /* Sieben weisse Karten auf fast weissem Grund verschwimmen sonst zu einer
     Flaeche - man sieht den Stapel, aber nicht, wo eine Karte aufhoert.
     Deshalb ein deutlicher Ring und ein Schatten, der nach LINKS faellt:
     Jede Karte liegt vor ihrer linken Nachbarin, also gehoert der Schatten
     dorthin, wo die Ueberlappung ist. */
  box-shadow: 0 1px 2px rgba(20,20,20,.08),
              -14px 22px 40px -18px rgba(20,20,20,.38),
              0 0 0 1px rgba(20,20,20,.11);
}
/* Das Bild hat GENAU das Verhaeltnis des Rahmens (1240 : 820, also 1,512).
   "cover" ist trotzdem da: Rundet der Browser die Hoehe um einen halben
   Punkt anders als die Breite, stuende sonst ein weisser Streifen an der
   Unterkante - sichtbar nur auf manchen Geraeten, und deshalb genau die Art
   Fehler, die keiner meldet. */
.fa-fenster img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* Hier standen Namen unter den Karten. Sie sind raus, und zwar nicht aus
   Geschmack: Die Karten liegen im Faecher auf verschiedenen Hoehen, also
   standen die Namen auf sieben verschiedenen Hoehen - und der Hinweissatz
   darunter lief mitten hindurch. Dazu kommt, dass jede Karte ihren Namen
   ohnehin traegt: als Ueberschrift im Inhalt und markiert in der
   Seitenleiste. Eine Beschriftung, die dasselbe noch einmal sagt, ist an
   jeder Stelle Beiwerk und an dieser auch noch im Weg. */

@media (hover: hover) {
  /* Die angezeigte Karte kommt nach vorn und steht gerade. Die uebrigen
     treten zurueck - ohne das hebt sich nichts ab, weil alle gleich hell
     bleiben. */
  .fa-karte:hover, .fa-karte:focus-visible {
    transform: translateX(calc(-50% + var(--m) * var(--fa-lueck)))
               translateY(calc((6 - var(--i)) * var(--fa-stufe) * -1 - 26px))
               rotate(0deg)
               rotateY(0deg) scale(1.06);
    z-index: 20;
  }
  /* Die Karten RECHTS von der angezeigten ruecken zur Seite. Damit liegt die
     angezeigte wirklich frei, statt nur oben zu liegen - wer sie sieht, trifft
     sie auch. Nach links geht das nicht: CSS kennt nur die nachfolgenden
     Geschwister. Deshalb ist die Verschiebung klein genug, dass sie als
     Ausweichen gelesen wird und nicht als Sprung. */
  /* Die Karten RECHTS von der angezeigten ruecken zur Seite. Sie sind es, die
     vor ihr liegen - ohne das Ausweichen bliebe die angezeigte halb verdeckt,
     obwohl sie hervorgehoben ist. Nach links braucht es das nicht: Dort liegt
     sie ohnehin oben. */
  .fa-karte:hover ~ .fa-karte, .fa-karte:focus-visible ~ .fa-karte {
    transform: translateX(calc(-50% + var(--m) * var(--fa-lueck) + 46px))
               translateY(calc((6 - var(--i)) * var(--fa-stufe) * -1))
               rotate(var(--fa-kipp))
               rotateY(15deg)
               scale(calc(.94 + var(--i) * .01));
  }
  .faecher:hover .fa-karte:not(:hover) { filter: brightness(.97) saturate(.9); }
}
.fa-karte:focus-visible .fa-fenster { outline: 2px solid #141414; outline-offset: 4px; }

/* Der Hinweissatz steht auf der SEITE und nicht auf einer Karte - er folgt
   dem Thema, im Gegensatz zu allem, was im Fenster liegt. */
.faecher-hinweis {
  margin: var(--a10) 0 0; text-align: center;
  font-size: 13px; color: var(--tinte-leise);
}

/* HIER STANDEN RUND 190 ZEILEN NACHBAU: Seitenleiste, Verbrauchskarte,
   Tempo-Bogen, Stil-Kacheln, Notizblatt - und dieselben Regeln noch einmal
   in gross. Sie sind ersatzlos weg.

   Der Grund ist gemeldet worden und er stimmte: Das AUSSEHEN war getroffen,
   die SACHE nicht - von dem, was in der App wirklich steht, waren vielleicht
   zwanzig Prozent da. Der Startseite fehlten vier ganze Kacheln.

   Ein Nachbau ist aber auch der falsche Aufbau, unabhaengig davon, wie gut er
   trifft: Jede Aenderung an der App muesste jemand von Hand hier nachziehen,
   und genau das passiert nie. Was hier steht, waere nach drei Wochen falsch,
   und nichts wuerde dabei kaputtgehen - es stuende nur etwas anderes da als
   in der App.

   Jetzt fotografiert werkzeug/app-bilder.js die echte Oberflaeche
   (src/renderer/settings.html, mit gestellter Bruecke zum Hauptprozess), und
   die Karte traegt nur noch das Bild. Wer die App aendert, laesst das
   Werkzeug laufen. */

/* --- Die grosse Fassung --- */
.fa-buehne { position: fixed; inset: 0; z-index: 120;
  display: grid; place-items: center; padding: var(--rand); }
/* DIESE ZEILE IST NICHT OPTIONAL.
   "display: grid" oben ist eine Klassenregel und schlaegt damit die Regel des
   Browsers fuer [hidden], die display:none setzt. Die Buehne blieb also mit
   hidden liegen - unsichtbar, weil nichts darin stand, aber ueber der GANZEN
   Seite und mit inset:0. Jeder Klick irgendwo auf der Startseite waere von ihr
   geschluckt worden: kein Verweis, kein Knopf, nichts.

   Gefunden hat das kein Hinsehen, sondern der Versuch, eine Karte
   anzuklicken - der Klick kam nie an. Ein Test haelt es jetzt fest. */
.fa-buehne[hidden] { display: none; }
.fa-buehne-grund { position: absolute; inset: 0;
  background: rgba(20, 20, 20, .55); backdrop-filter: blur(6px);
  animation: fa-grund .22s ease-out; }
@keyframes fa-grund { from { opacity: 0; } }
/* 1240 ist die Breite, in der die App fotografiert wird. Breiter als das
   waere das Bild hochgerechnet und unscharf. */
.fa-gross { position: relative; width: min(1240px, 100%); }
/* Die Karte waechst aus dem Stapel heraus statt aufzublitzen: Wer sie
   anklickt, soll sehen, dass es DIESE ist, die gross wird. */
.fa-gross-inhalt { animation: fa-auf .34s var(--bogen); transform-origin: 50% 55%; }
@keyframes fa-auf { from { opacity: 0; transform: scale(.86) translateY(18px); } }
/* Hier hat die HOEHE das Sagen und nicht die Breite: Auf einem flachen
   Bildschirm passt ein 1240 Punkte breites Bild in der Breite bequem, in der
   Hoehe aber nicht - es stuende unten ueber dem Rand hinaus, und der
   Schliessen-Knopf daueber laege ausserhalb des Fensters. Deshalb deckelt
   max-height die Hoehe, die Breite folgt ueber das Seitenverhaeltnis, und die
   Karte bleibt in jedem Fenster ganz zu sehen. */
.fa-gross .fa-fenster {
  width: auto; height: auto; max-width: 100%;
  margin: 0 auto; border-radius: 18px;
  box-shadow: 0 40px 100px -30px rgba(0,0,0,.6);
}
.fa-gross .fa-fenster img {
  width: auto; height: auto;
  max-width: 100%; max-height: min(820px, 78vh);
  object-fit: contain;
}

.fa-zu {
  position: absolute; top: -46px; right: 0;
  display: grid; place-items: center;
  width: 38px; height: 38px; border: 0; border-radius: 50%;
  background: rgba(255,255,255,.14); color: #fff; cursor: pointer;
  transition: background var(--zeit-kurz) var(--bogen);
}
.fa-zu svg { width: 17px; height: 17px; }
.fa-zu:hover { background: rgba(255,255,255,.26); }
.fa-zu:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }

@media (prefers-reduced-motion: reduce) {
  .fa-karte { transition: none; }
  .fa-gross-inhalt, .fa-buehne-grund { animation: none; }
}

@media (max-width: 1100px) {
  /* Unter dieser Breite waeren 22vw so schmal, dass auf der Karte nichts mehr
     zu erkennen ist. Dann lieber ein engerer Faecher: Die Karten bleiben
     lesbar gross und ueberlappen dafuer staerker. Frei liegen dann noch 42
     Prozent - immer noch mehr als die 39, bei denen gemeldet wurde, dass man
     sich verklickt, und mit dem Wischen auf dem Telefon darunter faellt der
     Faecher ohnehin weg. */
  /* Enger wird hier nur die Luecke, nicht die Schraege: Die Karten bleiben
     lesbar gross und ueberlappen dafuer staerker. */
  .faecher { --fa-b: min(320px, 23vw); --fa-lueck: calc(var(--fa-b) * .5);
             --fa-stufe: 17px; min-height: calc(var(--fa-h) + 130px); }
}

@media (max-width: 720px) {
  /* Auf dem Telefon ist ein Faecher nicht lesbar: Sieben Karten uebereinander
     auf 390 Punkten Breite sind sieben Raender. Sie stehen deshalb
     nebeneinander und werden gewischt - jede ganz zu sehen, eine nach der
     anderen. */
  .faecher {
    display: flex; flex-wrap: nowrap; justify-content: flex-start;
    gap: var(--a4); min-height: 0; perspective: none;
    overflow-x: auto; scroll-snap-type: x mandatory;
    /* Die Polsterung haelt die erste und die letzte Karte in der Mitte, wenn
       der Balken ganz links oder ganz rechts steht - sonst kleben sie am
       Rand, und das Einrasten sieht kaputt aus. Sie rechnet aus DERSELBEN
       Kartenbreite; vorher stand dort eine eigene Zahl, und wer die Breite
       aenderte, verschob die Reihe aus der Mitte. */
    padding: 0 calc(50% - var(--fa-b) / 2) var(--a4);
    scrollbar-width: none;
  }
  .faecher::-webkit-scrollbar { display: none; }
  /* So breit wie der Bildschirm es zulaesst: Ein Bildschirmfoto der ganzen
     App auf einem Telefon ist ohnehin klein, und jeder Punkt zaehlt. Wer mehr
     sehen will, tippt es an und bekommt es gross. */
  .fa-karte { position: static; flex: none;
    width: var(--fa-b); height: var(--fa-h);
    transform: none; scroll-snap-align: center; }
  .faecher { --fa-b: min(340px, 86vw); }
  .fa-zu { top: -44px; }
}

/* WARUM DER RAHMEN FESTE FARBEN TRAEGT UND KEINE TOKEN.

   Die Karte zeigt die App in ihrer hellen Fassung, und zwar in JEDEM Thema
   der Website - sie ist ein Bild von einem Programm und nicht ein Teil der
   Seite. Ihr Grund ist deshalb fest weiss.

   Als hier noch ein Nachbau stand, war das der Fehler, der zweimal passiert
   ist: var(--tinte) wird im dunklen Thema zu #f2f2f2, und gemessen stand dort
   weisse Schrift auf weisser Karte, 1,12:1, auf jeder der sieben Karten.
   Derselbe Fehler wie beim schwarzen Kasten der Downloadseite, zwei Tage
   vorher. Mit dem Bild kann er nicht wiederkommen - ein Bild dreht sich
   nicht mit dem Thema. Fuer den Rahmen darum gilt die Regel weiter, und ein
   Test haelt sie fest. */

/* ---- Das Mail-Fenster im Befehlsmodus ----
 *
 * Hier stand eine graue Flaeche mit drei Absaetzen. Die zeigt, DASS Text
 * ersetzt wird, aber nicht WO - und das ist die eigentliche Aussage des
 * Befehlsmodus: Es passiert in dem Programm, in dem du ohnehin bist, und
 * nicht in unserem. Kopfzeile, Empfaenger, Betreff und Fusszeile mit dem
 * Senden-Knopf sind deshalb da. Sie tun nichts; sie sagen, wo man ist.
 */
.cmd-leiste .cmd {
  min-height: 40px; border: 0; background: none;
  box-shadow: none; font-size: 13.5px;
  color: var(--leiste-schrift);
}
.cmd-leiste .cmd.an {
  background: var(--leiste-an-grund); color: var(--leiste-an-schrift); font-weight: 600;
  box-shadow: 0 1px 2px rgba(20,20,20,.18);
}
/* Die Regel :root[data-theme="dark"] .cmd:not(.an) weiter oben setzt einen
   eigenen Grund und ist mit 0,3,0 staerker als .cmd-leiste .cmd (0,2,0).
   Ohne diese Zeile traegt die ruhende Kachel im dunklen Blatt also einen
   Grund, den sie hier nicht haben soll. */
:root[data-theme="dark"] .cmd-leiste .cmd:not(.an) { background: none; }
@media (hover: hover) {
  .cmd-leiste .cmd:not(.an):hover {
    background: var(--leiste-kante);
    color: var(--leiste-an-grund);
    border-color: transparent;
  }
}

.mail-bar {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--a3) var(--a5);
  background: var(--papier-tief);
  box-shadow: inset 0 -1px 0 var(--linie);
}
.mail-titel { font-size: var(--gr-klein); font-weight: 600; color: var(--tinte); }
.mail-knoepfe { display: flex; gap: var(--a3); }
.mail-knoepfe svg { width: 14px; height: 14px; fill: none;
  stroke: var(--tinte-leise); stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; }

.mail-zeile {
  display: flex; align-items: center; gap: var(--a3);
  padding: 11px var(--a5);
  box-shadow: inset 0 -1px 0 var(--linie);
  font-size: 14px;
}
/* Feste Breite, damit "To" und "Subject" untereinander buendig stehen. Ohne
   sie ruecken die Werte um die Differenz der beiden Woerter auseinander, und
   zwei Zeilen, die fast gleich aussehen sollen, tun es dann nicht. */
.mail-feld { flex: none; width: 58px; color: var(--tinte-leise); }
.mail-wert { flex: 1; min-width: 0; color: var(--tinte);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mail-cc { flex: none; font-size: 13px; color: var(--tinte-leise); }

.mail-fuss {
  display: flex; align-items: center; gap: var(--a5);
  padding: var(--a3) var(--a5);
  box-shadow: inset 0 1px 0 var(--linie);
}
.mail-senden {
  padding: 9px var(--a6); border-radius: var(--r-rund);
  background: var(--dunkel); color: var(--papier);
  font-size: 14px; font-weight: 600;
}
.mail-werkzeug { display: flex; gap: var(--a4); }
.mail-werkzeug svg { width: 18px; height: 18px; fill: none;
  stroke: var(--tinte-leise); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }

/* Die Pille schwebt UNTER dem Fenster. In der App liegt sie ueber allem, was
   gerade offen ist - ein eigenes, randloses Fenster. Sie in das Mail-Fenster
   hineinzusetzen wuerde behaupten, sie gehoere dazu. */
.cmd-pille {
  display: flex; align-items: center; justify-content: center;
  /* Die Pille sass zur Haelfte IM Fenster und landete damit genau auf der
     Fusszeile: Sie lag ueber dem Senden-Knopf und den Werkzeug-Zeichen. Das
     sah nicht nach "schwebt darueber" aus, sondern nach zwei Sachen, die sich
     denselben Platz teilen.

     Jetzt steht sie ganz unter dem Fenster, mit Luft dazwischen. Der Abstand
     ist klein genug, dass sie noch dazugehoert, und gross genug, dass nichts
     darunter verschwindet. */
  gap: var(--a4); margin-top: var(--a4);
  position: relative; z-index: 2;
}

@media (max-width: 720px) {
  /* Die Leiste ist hier zweizeilig, also keine Pille mehr.
     999 Punkte Radius auf einem Kasten von 350 mal 96 ergeben zwei grosse
     runde Enden, und die schneiden in die Schrift der Eckpillen. Derselbe
     Fehler wie an der offenen Kopfleiste, nur kleiner. Dazu etwas mehr
     Polster, damit die Pillen nicht an der Kante kleben. */
  .cmd-leiste { width: 100%; border-radius: var(--r-karte); padding: 5px; gap: 5px; }
  .cmd-leiste .cmd { flex: 1 1 45%; font-size: 12.5px; padding-inline: var(--a2);
    border-radius: calc(var(--r-karte) - 4px); }
  /* 46 schnitt "Betreff:" um drei Punkte ab. min-width statt width: Das
     Wort bestimmt die Breite, nicht eine Zahl von 2023. */
  .mail-feld { width: auto; min-width: 46px; }
  .mail-cc { display: none; }
  .mail-werkzeug svg:nth-child(n+4) { display: none; }
  .cmd-pille { flex-direction: column; gap: var(--a2); }
}

/* ══ 28 · DER ZAHLUNGS-FUSS UNTER DEN PREISKARTEN ════════════════════════════
 *
 * Gemeldet: "mach diese klarna card etc. unter die pricing sachen bishen mit
 * space aber noch so wie frueher bei home und pricing".
 *
 * Die Reihe stand auf der Preisseite erst NACH dem Vergleich und auf der
 * Startseite ueberhaupt nicht - dort lagen die Zeichen unten im Fuss. Beides
 * ist eine Antwort an der falschen Stelle: Die Frage "womit bezahle ich, und
 * kommt noch etwas dazu" stellt sich, waehrend man auf den Preis sieht, und
 * nicht drei Abschnitte spaeter.
 *
 * .zahlblock ist von Haus aus eine ZEILE: Satz links, Zeichen rechts daneben.
 * Unter den Karten stehen jetzt aber vier Dinge, und drei davon sind Saetze -
 * nebeneinander waere das eine Textwand in Spalten. Hier wird daraus deshalb
 * ein Stapel, jeder Teil mittig, mit Luft dazwischen. Die Reihenfolge ist die
 * einer Frage und ihrer Antworten: Ist es sicher, was kostet es wirklich,
 * womit geht es, und wie komme ich wieder heraus.
 */
.zahlblock.preis-fuss {
  flex-direction: column; align-items: center; justify-content: center;
  gap: 0; text-align: center;
  /* "bishen mit space": Der Abstand zu den Karten ist groesser als der
     zwischen den Karten selbst. Sonst liest sich die Reihe wie eine vierte
     Karte, die nur ihren Rahmen verloren hat. */
  margin-top: var(--a10); padding-left: 0;
}
.zahlblock.preis-fuss > * { flex: none; max-width: 100%; }
.zahlblock.preis-fuss .preis-hinweis {
  margin-top: var(--a3); max-width: 62ch;
}
.zahlblock.preis-fuss .marken { margin-top: var(--a6); justify-content: center; }
/* Der Kuendigungssatz steht ABGESETZT und in der Textgroesse der Seite: Er
   ist kein Kleingedrucktes, sondern die Auskunft, auf die es beim Abschliessen
   ankommt - und der Verweis darin fuehrt zu den AGB. */
.zahlblock.preis-fuss .preis-kuendigen {
  margin-top: var(--a6); font-size: 15px; color: var(--tinte-still);
}
.zahlblock.preis-fuss .preis-kuendigen a {
  color: inherit; text-decoration: underline;
  text-underline-offset: 3px;
}
.zahlblock.preis-fuss .preis-kuendigen a:hover { color: var(--tinte); }

@media (max-width: 720px) {
  .zahlblock.preis-fuss { margin-top: var(--a8); }
  .zahlblock.preis-fuss .marken { gap: 8px; }
  .zahlblock.preis-fuss .marken .pm { width: 40px; }
}

/* ══ 29 · DIE TARIFKARTEN: DIE KARTE DER APP, IN DER BREITE DER WEBSITE ══════
 *
 * Zweimal falsch verstanden, und beide Male auf dieselbe Art: Ich habe die
 * ZAHLEN der App genommen, statt ihre VERHAELTNISSE.
 *
 *   Beim ersten Mal standen dort die Werte der Website, nur groesser gerechnet,
 *   weil die Seite breiter ist als das App-Fenster.
 *   Beim zweiten Mal standen die Werte der App unveraendert - und damit die
 *   Karte auch wirkt wie dort, habe ich sie auf die Breite des App-Fensters
 *   geschrumpft. Gemeldet: "du hast die gleiche Form gelassen, nur duenner.
 *   Dein Job war, es so dick und gleich wie in der App zu machen, aber mit
 *   der alten Breite."
 *
 * Das ist der Punkt, und er ist einfach: Eine Karte, die 373 Punkte breit ist,
 * bekommt nicht die Schriftgroessen einer, die 276 breit ist. Dann steht
 * dieselbe Schrift in einem groesseren Kasten, und genau das liest sich als
 * "duenner" - nicht die Schrift ist duenner geworden, die Flaeche um sie herum
 * ist groesser.
 *
 * Also: die Breite der Website, und jede Zahl der App mit dem Verhaeltnis der
 * beiden Breiten hochgerechnet. 373 zu 276 sind 1,35.
 *
 *   Preis      38 -> 51        Polster    22/20 -> 30/27
 *   Name       22 -> 30        Haken      17    -> 23
 *   Liste      13,5 -> 18      Knopf      13,5  -> 18
 *   Vorzeile   11,5 -> 15      Radius     18    -> 24
 *
 * Die DICKEN bleiben, wie sie in der App stehen, und werden nicht mitskaliert:
 * 700 beim Preis, 620 beim Namen, 600 in der Vorzeile. Eine Strichstaerke ist
 * keine Laenge.
 *
 * Diese Datei laedt NACH styles-light.css - die Werte dort bleiben stehen und
 * werden hier ueberschrieben. Wer die App wieder aendert, findet den
 * Unterschied an EINER Stelle.
 */
/* VIEL BREITER, auf Ansage - aber ueber die BAHN und nicht ueber die Karten.

   Hier stand vorher ein Ausbruch aus der Bahn:

     .pr-cards.three { width: min(1680px, 100vw - var(--rand)*2);
                       margin-inline: auto; }

   Das war falsch, und zwar auf eine Art, die bei 1440 Punkten Fensterbreite
   noch richtig aussieht. Die Bahn ist dort 1440 breit und traegt 40 Punkte
   Rand auf jeder Seite, ihr Inhalt also 1360 - und "100vw - 2*Rand" ergibt
   bei 1440 ebenfalls 1360. Genau gleich, kein Ueberstand, gemessen gruen.

   Ab 1441 Punkten wird der Wert groesser als der Platz im Elternteil. Und
   "margin-inline: auto" zentriert nur, solange etwas uebrig ist; ist das Kind
   BREITER als sein Elternteil, rechnen beide Raender zu null, und das Kind
   haengt nach rechts hinaus. Auf einem breiten Bildschirm stand die dritte
   Karte zur Haelfte ausserhalb des Bildes: "Command Mode, rewrite selected
   text by" hoerte mitten im Satz auf.

   Jetzt bekommt die BAHN dieses Abschnitts ihre groessere Breite. Damit
   bleiben Rand, Zentrierung und Ruecksprung auf schmalen Fenstern genau die,
   die auf jeder anderen Seite auch gelten, und es gibt nichts, was ueber
   irgendetwas hinausragen koennte. */
/* Zurueck auf die normale Bahnbreite. 1680 war ein Anlauf zu weit: Die Karten
   fuellten damit den ganzen Bildschirm, und ein Preis, der so breit steht wie
   der Aufmacher darueber, wirkt nicht wichtig, sondern laut. Gemeldet als "zu
   gross" - und das war es, obwohl vorher "viel breiter" richtig war. Die
   Bahn der Seite ist das Mass, an dem sich alles andere schon orientiert. */

.pr-cards.three {
  max-width: none;
  gap: 22px;
}
.pr-card {
  border-radius: 22px;
  padding: 30px 28px;
}
.pr-card .for {
  font-size: 13px; font-weight: 600; letter-spacing: .12em;
  margin-bottom: 12px;
}
/* In der App ist der Name ein <b> mit 620. Hier ist es ein <h2>, und ein h2
   bringt seine eigene Dicke mit - sie wird gleichgesetzt, sonst steht "Free"
   fetter da als in der App. */
.pr-card h2 {
  margin-top: 0;
  font-size: 26px; font-weight: 640; letter-spacing: -.02em; line-height: 1.1;
}
.pr-card .price {
  font-size: 44px; font-weight: 700; letter-spacing: -.035em;
  line-height: 1.05; margin: 6px 0 22px;
}
.pr-card .price small { font-size: 16px; font-weight: 500; }
.pr-card .price .jz { font-size: 13px; }
.pr-card ul { margin: 0 0 24px; gap: 13px; align-content: start; flex: 1; }
/* overflow-wrap steht auch in der App, und aus demselben Grund: "Command Mode,
   rewrite selected text by voice" passt in einer Spalte nicht in eine Zeile,
   und ohne diese Zeile stuende es ueber den Kartenrand hinaus. */
.pr-card li {
  font-size: 15.5px; line-height: 1.45; padding-left: 30px;
  overflow-wrap: anywhere;
}
.pr-card li::before {
  top: 2px; width: 20px; height: 20px; font-size: 12px;
  background: rgba(20,20,25,.07);
}
.pr-card:hover li::before { background: rgba(20,20,25,.13); }
/* Der Knopf laeuft ueber die ganze Karte - in der App wie hier. */
.pr-card .knopf, .pr-card .btn {
  width: 100%; margin-top: auto; height: auto;
  padding: 15px 20px; border-radius: 13px; font-size: 15.5px;
}
/* Die Marke haengt ueber der Oberkante und waechst mit. */
.pr-badge { top: -14px; font-size: 12px; padding: 7px 15px; }

@media (max-width: 920px) {
  /* Untereinander ist jede Karte so breit wie der Bildschirm, und die Schrift
     darf zurueck auf ein Mass, das auf 390 Punkten noch Zeilen ergibt statt
     Wortfetzen. Groesserer Abstand, weil die Marke "MOST POPULAR" 17 Punkte
     ueber die Oberkante hinaushaengt und sonst die Karte darueber beruehrt. */
  .pr-cards.three { gap: 38px; }
  .pr-card { padding: 24px 22px; border-radius: 20px; }
  .pr-card .for { font-size: 12.5px; margin-bottom: 9px; }
  .pr-card h2 { font-size: 24px; }
  .pr-card .price { font-size: 40px; margin: 6px 0 20px; }
  .pr-card .price small { font-size: 16px; }
  .pr-card ul { margin: 0 0 24px; gap: 13px; }
  .pr-card li { font-size: 15px; padding-left: 29px; }
  .pr-card li::before { width: 20px; height: 20px; font-size: 12px; }
  .pr-card .knopf, .pr-card .btn { padding: 15px 20px; font-size: 15.5px; }
}

/* ══ 30 · DIE VERGLEICHSTABELLE AUF DEM TELEFON ══════════════════════════════
 *
 * Am Schreibtisch stehen vier Spalten nebeneinander: die Sache links, drei
 * Tarife daneben. Auf 390 Punkten passt das nicht, und die Tabelle war
 * deshalb schon immer waagerecht zu rollen.
 *
 * Nur half das nichts. Was man sah, war die linke Haelfte: Zeilennamen, die
 * Spalte "Free", und rechts davon ein angeschnittenes "2,00" - eine Zahl, die
 * mitten im Wort aufhoert. Wer rollte, verlor dafuer die Zeilennamen aus dem
 * Bild und wusste nach der vierten Zeile nicht mehr, welcher Haken wozu
 * gehoert. Eine Vergleichstabelle, die entweder die Frage oder die Antwort
 * zeigt, vergleicht nichts.
 *
 * Zwei Sachen loesen das, und beide behalten den Aufbau des Schreibtischs,
 * statt auf dem Telefon etwas anderes zu bauen:
 *
 *   Die erste Spalte bleibt stehen. Sie ist die Frage; die Tarife rollen
 *   daran vorbei. Damit steht in jeder Lage links, worum es geht.
 *
 *   Es ist zu SEHEN, dass da noch etwas kommt. Ein Schatten an der rechten
 *   Kante der stehenden Spalte macht sichtbar, dass darunter etwas
 *   durchlaeuft - ohne ihn sieht die Tabelle abgeschnitten aus und nicht
 *   rollbar.
 */
@media (max-width: 720px) {
  /* KEIN ROLLEN MEHR, sondern vier Spalten, die hineinpassen.

     Der erste Anlauf war eine stehende erste Spalte und ein Schatten, der
     zeigt, dass rechts noch etwas kommt. Gemessen war das immer noch
     schlecht: Sichtbar blieben der Zeilenname und EIN Tarif. Eine
     Vergleichstabelle, die einen Tarif zeigt, vergleicht nichts - man muesste
     zwischen zwei Spalten hin und her rollen und sich die Haken merken.

     Vier Spalten passen aber, wenn man ihnen nichts aufzwingt: Die Antworten
     sind fast alle ein Haken oder ein Strich, und die drei Zahlen sind kurz.
     min-width raus, die Spalten teilen sich die Breite, der Zeilenname
     bekommt die Haelfte und darf umbrechen. Damit steht dieselbe Tabelle da
     wie am Schreibtisch, nur enger - und nichts liegt ausserhalb des Bildes. */
  /* Die Tabelle bekommt die volle Breite des Bildschirms. Sie sass in der
     Bahn und damit hinter deren Rand: 310 von 390 Punkten, also achtzig
     verschenkt - und an denen fehlte es genau dort, wo "Community" um fuenf
     Punkte nicht mehr in seine Spalte passte. Der negative Rand holt die
     Tabelle aus der Bahn heraus; das Polster gibt ihr innen den Abstand
     zurueck, den der Rahmen braucht. */
  .tab-huelle {
    overflow-x: visible;
    margin-inline: calc(var(--rand) * -1 + 8px);
  }
  .tab { min-width: 0; table-layout: fixed; }
  .tab th, .tab td { padding: var(--a3) var(--a2); }
  .tab thead th { font-size: 10px; letter-spacing: .04em; }
  /* Die Frage bekommt mehr als die Haelfte, die drei Antworten teilen sich den
     Rest. Bei gleichen Vierteln brach "Command Mode, rewrite selected text by
     voice" auf sechs Zeilen um und machte die Zeile hoeher als eine ganze
     Gruppe; die Antworten daneben sind fast alle ein einziges Zeichen.

     DIE BREITEN STEHEN AM KOPF, nicht am Koerper. Bei table-layout: fixed
     nimmt der Browser die Breiten aus der ERSTEN Zeile und sieht sich den
     Rest gar nicht mehr an - das ist der Sinn von "fixed". An .tab tbody th
     gesetzt, wie im ersten Anlauf, aendert sich deshalb gar nichts: Die
     Spalten blieben vier gleiche Viertel, und es sah aus, als haette die
     Regel nicht gegriffen. Sie hatte, nur an der falschen Zeile. */
  .tab thead th:first-child { width: 43%; }
  .tab thead th + th { width: 19%; }
  .tab tbody th { font-size: 13px; line-height: 1.35; }
  /* KEIN overflow-wrap: anywhere. Es stand hier und trennte mitten im Wort:
     "2,00 / 0", "40,0 / 00", "Com / munit / y". Eine Zahl, die auf zwei Zeilen
     steht, ist keine Zahl mehr, und "Priori / ty" liest niemand als Wort.
     Die drei Spalten sind stattdessen so bemessen, dass das laengste, was
     darin steht, in eine Zeile passt: 18 Prozent sind rund 66 Punkte, und
     "Community" braucht bei 12 Punkten Schrift etwa 62. */
  .tab td {
    font-size: 11.5px; text-align: center;
    padding-inline: var(--a1);
    white-space: nowrap; overflow-wrap: normal;
  }
  .tab .tab-gruppe th { width: auto; }
}

/* ══ 31. Was ist neu ════════════════════════════════════════════════════════
 *
 * Eine Fassungsliste ist eine Liste, kein Kartenteppich. Links steht die
 * Nummer mit ihrem Datum, rechts steht, was dazugekommen ist. Untereinander
 * rutscht die Nummer nach oben und wird zur Zeile.
 *
 * Der Trennstrich sitzt oben an jedem Eintrag und nicht unten: So schliesst
 * die Liste am Ende ohne einen Strich ins Leere.
 */
.cl-liste { display: grid; gap: 0; }

.cl-eintrag {
  display: grid;
  grid-template-columns: minmax(0, 210px) minmax(0, 1fr);
  gap: var(--a8);
  padding: var(--a8) 0;
  border-top: 1px solid var(--linie);
}
.cl-eintrag:first-child { border-top: 0; padding-top: var(--a4); }

.cl-marke { position: sticky; top: 96px; align-self: start; }
.cl-version {
  margin: 0; font-size: 22px; font-weight: 640; letter-spacing: -.02em;
  line-height: 1.15; color: var(--tinte); font-variant-numeric: tabular-nums;
}
.cl-datum {
  display: block; margin-top: 4px;
  font-size: 13.5px; color: var(--tinte-leise);
}

/* Eine Zeile, die ueber die ganze Breite laeuft, verliert das Auge beim
   Zurueckspringen. Deshalb ein Mass statt der vollen Bahn. */
.cl-inhalt { display: grid; gap: var(--a5); min-width: 0; max-width: 76ch; }
.cl-block { display: grid; gap: var(--a3); }

/* Die Ueberschrift der Gruppe ist ein Etikett, keine Zeile. "Neu" traegt die
   dunkle Fuellung, "Besser" und "Behoben" nur die Kante: Das Neue ist die
   Nachricht, der Rest die Pflege. */
.cl-art {
  justify-self: start; margin: 0;
  padding: 4px 11px; border-radius: 999px;
  font-size: 11.5px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
}
.cl-art-neu { background: var(--dunkel); color: var(--papier); }
.cl-art-besser, .cl-art-behoben {
  background: transparent; color: var(--tinte-still);
  box-shadow: inset 0 0 0 1px var(--linie-klar, var(--linie));
}

.cl-punkte { margin: 0; padding: 0; list-style: none; display: grid; gap: var(--a3); }
.cl-punkte li {
  position: relative; padding-left: 20px;
  font-size: 15.5px; line-height: 1.6; color: var(--tinte-still);
  overflow-wrap: anywhere;
}
.cl-punkte li::before {
  content: ""; position: absolute; left: 2px; top: 10px;
  width: 5px; height: 5px; border-radius: 50%; background: var(--tinte-leise);
}
.cl-leer, .cl-leer-seite { margin: 0; font-size: 15.5px; color: var(--tinte-leise); }
.cl-laedt { margin: 0; padding: var(--a8) 0; }

.cl-mehr-huelle { display: flex; justify-content: center; margin-top: var(--a8); }
/* Die Zahl ist eine Auskunft, keine Ansage: Sie steht leiser als die
   Beschriftung daneben. Getrennt gehalten wird sie, weil die
   Beschriftung uebersetzt wird und die Zahl nicht. */
.cl-zahl { color: var(--tinte-leise); font-variant-numeric: tabular-nums; }

@media (max-width: 820px) {
  .cl-eintrag { grid-template-columns: minmax(0, 1fr); gap: var(--a4); padding: var(--a6) 0; }
  /* Untereinander darf nichts kleben: Die Nummer steht als Zeile ueber dem
     Text, nicht als schmale Spalte daneben. */
  .cl-marke {
    position: static;
    display: flex; align-items: baseline; gap: var(--a3); flex-wrap: wrap;
  }
  .cl-version { font-size: 19px; }
  .cl-punkte li { font-size: 15px; }
}

/* ══ 32. Was ausserhalb des Bildes steht, ruht ══════════════════════════════
 *
 * Die Klasse setzt main.js, sobald eine der drei Dauerstellen aus dem Bild
 * gescrollt ist. Angehalten statt abgeschaltet: Die Bildfolge behaelt ihren
 * Stand, und wer zurueckkommt, sieht die Welle mitten im Lauf.
 *
 * Das ist der sparsame Ersatz fuer die alte Regel, die auf dem Handy JEDE
 * Animation abschaltete. Bewegung kostet jetzt nur dort etwas, wo sie auch
 * jemand sieht.
 */
.ruht-ausserhalb,
.ruht-ausserhalb * { animation-play-state: paused !important; }
