/* ══════════════════════════════════════════════════════════════════════════
   Die Startseite: Aufbau und Rhythmus
   Gehoert zu templates/onboarding/landing.html, static/css/startseite-gravur.css,
   static/css/startseite-schrift.css, static/css/startseite-inhalt.css und
   static/js/startseite.js.
   ══════════════════════════════════════════════════════════════════════════

   **Der Schleier ist weg, ersatzlos.** Bis zum 2026-08-23 stand hier eine
   kantenlose Flaeche in --color-bg-base mit 0,90 Deckkraft zwischen Grund und
   Text, dazu zwei Schaechte und zwei Atem. Adrian dazu: *"Das Dunkle hinter
   allen Layern wie im Hero gefaellt mir eh nicht. Das wurde da bewusst
   weggelassen."*

   Den Kontrast traegt jetzt die Schrift selbst - siehe startseite-gravur.css.
   Diese Datei macht nur noch Aufbau: Breiten, Abstaende, Rhythmus.

   ── Warum der Aufmacher ohne alles auskommt ──────────────────────────────

   Gemessen ueber 22 Wellenlagen, hellster Bildpunkt je Zeile: **oberhalb von
   340 px hat das Feld gar keine Partikel.** Dort liegt nur der ruhige
   Verlauf, in jeder Wellenlage gleich, und weisser Text haelt 15,1:1. Ab
   346 px faellt es unter 7:1, ab 358 px unter 4,5:1, im Kamm auf 1,05:1.

   **Der erste Bildschirm funktioniert also nicht aus Glueck, sondern wegen
   der Wellengeometrie.** Wer den Aufmacher nach unten schiebt, verliert das -
   und merkt es nicht, weil im Stillstand oft trotzdem eine gute Zahl
   herauskommt.

   ── Der Satzspiegel wechselt die Seite ───────────────────────────────────

   Zwei Abschnitte stehen rechtsbuendig (`.c-rechts`). Das ist der einzige
   Ersatz fuer die Gliederung, die vorher die Schaechte gemacht haben: ohne
   Flaechen braucht das Auge etwas anderes, an dem es merkt, dass ein neuer
   Gedanke anfaengt. Auf schmalen Schirmen faellt es weg - dort ist die Spalte
   so breit wie der Schirm, und rechtsbuendiger Flattersatz waere nur unruhig.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Ein Abschnitt ───────────────────────────────────────────────────────
   **Die Hoehen des Entwurfs (900, 820, 560 ... px) sind KEINE festen Hoehen
   geworden.** Sie waren dort Platzhalter fuer "so viel Luft gehoert hier
   hin"; als feste Zahl brechen sie auf jedem Schirm, der nicht 1440x900 ist.
   Statt dessen traegt jeder Abschnitt seinen Innenabstand, und die Luft
   entsteht aus dem Inhalt. */
.c-abschnitt {
  position: relative;
  width: 100%;
  /* **Die Seite hat seit dem 2026-08-23 einen aeusseren Rand von 88rem.**
     Vorher lief jeder Abschnitt bis an den Fensterrand: bei 1440 waren das
     1208 Punkte Textbreite, bei 2560 aber 2328. Adrians Urteil dazu lautete
     *"Es ist viel zu breit alles"* - und der Satz stimmt genau dann, wenn der
     Bildschirm gross ist.

     **Die Grenze steht seit dem Pin am `<main>` und nicht mehr hier**
     (landing.html, Block `main_class`). Der Grund ist nicht Ordnung, sondern
     ein gemessener Fehler: `margin-inline: auto` an einem gepinnten Element
     wird von ScrollTrigger als Pixelwert auf seinen Abstandhalter kopiert und
     dort eingefroren. Bei 3440 px standen die drei gepinnten Abschnitte
     deshalb 453 Punkte links der Mitte, gemessen am 2026-08-23 von
     test_startseite_satzspiegel.py (am 2026-08-24 entfallen). Am `<main>`
     gibt es nichts einzufrieren, denn das wird nie gepinnt. */
  padding-left: clamp(1.25rem, 0.4rem + 4vw, 7.25rem);
  padding-right: clamp(1.25rem, 0.4rem + 4vw, 7.25rem);
  padding-top: clamp(4.5rem, 2rem + 9vw, 9rem);
  padding-bottom: clamp(4.5rem, 2rem + 9vw, 9rem);
  display: flex;
  flex-direction: column;
  justify-content: center;
  /* **`clip` und nicht `hidden`.** Der Ebenen-Aufbau schiebt Huellen aus dem
     Abschnitt heraus, und ein Transform nach rechts verlaengert sonst
     `scrollWidth` - auf 320 px waere das ein waagerechter Bildlauf, gemessen
     am 2026-08-23 von test_startseite_breite.py (am 2026-08-24 entfallen).
     `clip` schneidet ab, ohne einen
     Bildlaufbehaelter zu erzeugen; `hidden` taete beides und wuerde nebenbei
     jedes `position: sticky` weiter oben aushebeln. */
  overflow-x: clip;
}

/* ── Die Buehne ──────────────────────────────────────────────────────────
   Ein Abschnitt mit `data-buehne` setzt sich beim Scrollen aus Ebenen
   zusammen (static/js/startseite-film.js). Der Fluchtpunkt steht hier und
   nicht an jeder Ebene: nur so teilen sich alle Ebenen EINEN Fluchtpunkt und
   wirken als Stapel statt als mehrere einzelne Zoomfahrten.

   **Er steht im Stylesheet und nicht im Skript**, damit er auch dann richtig
   ist, wenn nie eine Zeile JavaScript laeuft - dann bewegt sich schlicht
   nichts, und eine Perspektive ohne Transform ist wirkungslos.

   `perspective-origin` bei 40 % und nicht 50 %: der Blick auf eine Seite
   liegt hoeher als ihre Mitte, und eine Ebene, die von unten kommt, soll
   nach oben laufen und nicht auf den Leser zu. */
[data-buehne] {
  perspective: 1400px;
  perspective-origin: 50% 40%;
}

/* ══ Der Film ══════════════════════════════════════════════════════════════
   Seit dem 2026-08-25 ist die ganze Seite EIN gepinnter Film: elf Layer an
   einer Stelle, gebaut von static/js/startseite-film.js, Gerüst in
   templates/onboarding/landing.html.

   **Alles hier haengt an `html.st-film`, und die Klasse setzt das Skript
   erst, wenn der Film wirklich steht.** Fehlt sie - kein JavaScript,
   reduzierte Bewegung, ein Fehler beim Bauen, ein Flex-Elternteil -, dann ist
   `.st-film` ein gewoehnlicher Kasten und `.st-film-lage` elf Kaesten darin:
   elf Abschnitte untereinander, alle lesbar. **Kein Inhalt dieser Seite
   haengt an einer Klasse, die JavaScript setzen muss.**

   **Die Hoehe der Buehne steht nicht hier, sondern im Skript.** Sie ist
   Schirmhoehe minus gemessener Kopfzeile, und gemessen sind das 65 und nicht
   64 Punkte - ein `calc(100svh - 4rem)` liesse ein Pixel unten heraushaengen.
   Eine Zahl, zwei Quellen, waere eine zu viel. */
html.st-film .st-film {
  position: relative;
  /* Der Fluchtpunkt der Layer. Er steht an der Buehne und nicht am Layer:
     nur so teilen sich alle elf EINEN, und der Film liest sich als ein Raum
     statt als elf einzelne Zoomfahrten. Dieselbe Begruendung wie bei
     `[data-buehne]` weiter unten, eine Ebene hoeher. */
  perspective: 1500px;
  perspective-origin: 50% 42%;
  /* Was hinausfaehrt, wird abgeschnitten und nicht zum Bildlauf. `hidden`
     und nicht `clip`: die Layer fahren auch nach OBEN heraus, und der
     gepinnte Kasten darf davon keinen Rand bekommen. */
  overflow: hidden;
}

/* Ein Layer. Deckungsgleich uebereinander, alle so hoch wie die Buehne.

   **`min-height: 100%` ersetzt jede Rechnerei zum Mittigstellen.** Der
   Abschnitt darin ist ohnehin ein `flex`-Kasten mit `justify-content: center`
   (siehe `.c-abschnitt`) - ist die Huelle so hoch wie die Buehne, steht sein
   Inhalt mittig, und zwar ohne dass jemals ein `y`-Versatz gerechnet werden
   muesste. Ein hoeherer Layer waechst darueber hinaus, und das Skript
   schwenkt dann durch ihn hindurch.

   **`opacity` steht hier NICHT.** Sie gehoert der Zeitleiste, und ein
   Stylesheet, das Inhalt auf null setzt, ist genau der Weg, auf dem am
   2026-08-13 eine Startseite ohne Ueberschrift live ging. `pointer-events`
   darf hier stehen: sie versteckt nichts, sie verhindert nur einen Klick ins
   Leere, und das Skript schaltet sie fuer den laufenden Layer frei. */
html.st-film .st-film-lage {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  min-height: 100%;
  pointer-events: none;
  /* **Das `flex` hier ist erlaubt und das aus der Pin-Falle ist es nicht.**
     Die Falle lautet: ScrollTrigger schaltet `pinSpacing` still ab, wenn das
     ELTERNTEIL DES GEPINNTEN Elements ein Flex- oder Grid-Container ist.
     Gepinnt wird `.st-film`, sein Elternteil ist `<main>` - und das traegt
     seit landing.html kein `flex`. Hier steht es eine Ebene TIEFER und
     betrifft nur die Kinder dieser Huelle.

     Es steht hier, weil eine prozentuale Mindesthoehe gegen ein Elternteil
     mit `height: auto` nichts ergibt: der Abschnitt bekaeme seine
     Inhaltshoehe und stuende oben statt mittig. Als Flexkasten streckt sich
     das Kind auf die volle Huellenhoehe, und `.c-abschnitt` stellt seinen
     Inhalt mit dem eigenen `justify-content: center` mittig. */
  display: flex;
  flex-direction: column;
}

html.st-film .st-film-lage > .c-abschnitt {
  flex: 1 1 auto;
}

/* **Ein Layer holt seine Luft aus dem Film, nicht aus seinem Innenabstand.**
   Waehrend er im Bild steht, steht er allein da; ueber und unter ihm liegt
   Adrians Partikelfeld und kein Nachbar, von dem er sich absetzen muesste.
   Die 144 Punkte der aufgereihten Fassung waeren doppelte Luft - und sie
   machten jeden zweiten Layer hoeher als der Schirm, also zu einem Schwenk,
   den es nicht braucht. */
html.st-film .st-film-lage > .c-abschnitt {
  padding-top: clamp(2.5rem, 1.25rem + 3.5vw, 4.5rem);
  padding-bottom: clamp(2.5rem, 1.25rem + 3.5vw, 4.5rem);
}

/* Im Film IST die Buehne der erste Schirm, die Huelle sorgt fuer die Hoehe.
   `calc(100svh - 4rem)` ist um das eine Pixel zu hoch, das die Kopfzeile mehr
   misst als 4rem - und ein Punkt Ueberstand machte aus dem Aufmacher grundlos
   einen Schwenk. */
html.st-film .st-film-lage > .c-aufmacher {
  min-height: 0;
}

/* Der Aufmacher fuellt den ersten Schirm. `svh` und nicht `vh`: auf dem
   Telefon ist vh die Hoehe MIT eingeblendeter Adressleiste, und der erste
   Bildschirm waere unten abgeschnitten. 4rem sind die Kopfleiste. */
.c-aufmacher {
  min-height: calc(100svh - 4rem);
  /* Der Aufmacher ist keine `data-buehne` - er darf an keiner Zeile
     JavaScript haengen. Seinen Fluchtpunkt braucht er trotzdem: die dritte
     Zeile der Ueberschrift kommt aus der Tiefe, und das macht eine reine
     CSS-Animation (`--st-z`, siehe startseite-inhalt.css). Ohne diese Zeile
     waere die Verschiebung nicht falsch, sondern nur nicht zu sehen. */
  perspective: 1200px;
  perspective-origin: 50% 45%;
}

/* Rechtsbuendig, aber erst wenn Platz dafuer da ist. */
@media (min-width: 900px) {
  .c-rechts { text-align: right; }
  .c-rechts .c-strang,
  .c-rechts .c-strang-weit,
  .c-rechts .c-strang-eng { margin-left: auto; margin-right: 0; }
  .c-rechts .c-tat { justify-content: flex-end; }
}

/* ── Die Straenge ────────────────────────────────────────────────────────
   Drei Breiten statt eines durchgehenden Satzspiegels. **Ohne Flaeche
   darunter darf das.** Beim Schleier war es ausdruecklich falsch: eine
   sichtbare Flaeche will gefuellt werden, ein halb leerer dunkler Kasten
   sieht kaputt aus. Diesen Grund gibt es nicht mehr - jetzt richtet sich die
   Breite nach der Zeilenlaenge und sonst nichts.

   ── `-weit` war 70rem und ist jetzt 50rem ────────────────────────────────

   1120 Punkte sind keine Zeilenlaenge, sondern die halbe Fensterbreite. Eine
   Ueberschrift in 63 px lief darin ueber die ganze Seite, und **genau das
   meinte Adrian mit "viel zu breit"**. 50rem sind 800 Punkte: eine
   Plakatzeile bricht dort nach drei bis vier Woertern um, und die
   Ueberschrift bekommt eine Silhouette statt eines Bandes.

   Wichtig dabei: `-weit` traegt jetzt **jede** grosse Ueberschrift. Vier von
   ihnen hatten vorher gar keine Breite und liefen mit 1288 Punkten noch
   breiter als die mit `-weit`. Eine Breitenangabe, die die Haelfte der Faelle
   auslaesst, ist keine. */
.c-strang { max-width: 39rem; }
.c-strang-weit { max-width: 50rem; }
.c-strang-eng { max-width: 31rem; }

/* Die eine Ausnahme, und sie hat eine Zahl. Der Aufmacher ist die einzige
   Zeile der Seite in 86 px; "AdenAI baut es mit dir." misst dort 830 Punkte
   und braeche in 50rem mitten im Satz um. Gemessen am 2026-08-23, nachdem
   genau das passiert war: aus drei Zeilen wurden vier. */
.c-strang-plakat { max-width: 55rem; }

/* ── Die Handlungszeile ──────────────────────────────────────────────────
   Knopf, Verweis und Kleingedrucktes nebeneinander, solange Platz ist. */
.c-tat {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: clamp(1rem, 0.6rem + 1.4vw, 1.625rem);
  margin-top: clamp(2rem, 1.2rem + 2.4vw, 2.375rem);
}

/* Ein Knopf, den man mit dem Daumen treffen soll, wird nicht schmaler als
   der Schirm. */
@media (max-width: 559px) {
  .c-tat > .btn { width: 100%; justify-content: center; }
}

/* ── Das dreispaltige Raster, das Fragen-Gitter, die Preise ──────────────
   Alle drei brechen auf eine Spalte, bevor die Spalten so schmal werden,
   dass die Gravur leidet: eine 18-px-Zeile in einer 180-px-Spalte bricht nach
   jedem zweiten Wort um, und **jeder Umbruch kostet den Hof seine
   Nachbarschaft** - genau der Effekt, an dem die 18-Lagen-Fassung gescheitert
   ist (siehe startseite-gravur.css). */
.c-drei,
.c-gitter,
.c-preise {
  display: grid;
  grid-template-columns: 1fr;
}

/* Die drei Raster bekommen seit dem 2026-08-23 eine Obergrenze. Sie liefen
   vorher ueber die volle Abschnittsbreite, waehrend die Ueberschrift darueber
   bei 50rem endet - das las sich wie zwei verschiedene Seiten uebereinander.
   Ein Raster darf breiter sein als sein Text, aber es darf nicht aussehen,
   als gehoere es zu etwas anderem. */
/* **Die drei Schritte haben seit dem 2026-08-23 eine Flaeche, und das aendert
   ihr Raster** - genau wie bei den Preisen einen Absatz weiter unten. Ohne
   Kante brauchten die Spalten viel Luft, damit man sah, wo eine aufhoert (74
   Punkte auf 1440). Mit Kante ist dieselbe Luft zu viel: drei Schritte, die
   ein Argument bilden, gehoeren zusammen. Der Grund fuer die Flaeche steht
   bei `.c-stufe` in startseite-inhalt.css. */
.c-drei {
  gap: clamp(1rem, 0.6rem + 1.4vw, 1.75rem);
  margin-top: clamp(3rem, 1.8rem + 3.5vw, 4.75rem);
  max-width: 68rem;
  /* Dieselben zwei Zeilen wie bei den Preisen: die Huelle des Ebenen-Aufbaus
     liegt zwischen Raster und Flaeche, und `stretch` reicht genau eine Ebene
     tief. Ohne sie haengt die Unterkante einer Stufe in der Luft, sobald in
     einer anderen Spalte eine Zeile umbricht. */
  align-items: stretch;
}

.c-drei > [data-lage] {
  display: flex;
}

.c-drei > [data-lage] > .c-stufe {
  flex: 1 1 auto;
}

.c-gitter {
  gap: clamp(2.5rem, 1.4rem + 4vw, 5.25rem) clamp(2.5rem, 1rem + 5vw, 7.5rem);
  margin-top: clamp(3rem, 1.8rem + 3.5vw, 4.125rem);
  max-width: 64rem;
}

/* **Die Preise haben seit dem 2026-08-23 eine Flaeche, und das aendert ihr
   Raster.** Ohne Kante brauchten die Spalten viel Luft, damit man ueberhaupt
   sah, wo eine aufhoert - 74 Punkte auf 1440. Mit Kante ist dieselbe Luft zu
   viel: drei Tafeln, die man vergleichen soll, gehoeren zusammen und nicht
   einzeln ueber die Seite verteilt. Der Grund fuer die Flaeche steht bei
   `.c-tafel` in startseite-inhalt.css. */
.c-preise {
  gap: clamp(1rem, 0.6rem + 1.4vw, 1.75rem);
  margin-top: clamp(3rem, 1.8rem + 3.5vw, 4rem);
  /* `stretch` statt `start`: die drei Tafeln einer Reihe sind gleich hoch.
     Sonst haengt die Unterkante der Dev-Tafel in der Luft, sobald in einer
     anderen Spalte eine Zeile umbricht - "Modelle: Haiku, Sonnet, Opus,
     Fable" tut das schon auf 1000 px. */
  align-items: stretch;
  max-width: 68rem;
}

/* Die Huelle des Ebenen-Aufbaus liegt zwischen Raster und Tafel. Ohne diese
   zwei Zeilen bekaeme sie die Rasterhoehe und die Tafel darin nur ihre
   eigene - `align-items: stretch` reicht genau eine Ebene tief. */
.c-preise > [data-lage] {
  display: flex;
}

.c-preise > [data-lage] > .c-tafel {
  flex: 1 1 auto;
}

@media (min-width: 760px) {
  .c-gitter { grid-template-columns: 1fr 1fr; }
  .c-preise { grid-template-columns: repeat(3, 1fr); }
}

@media (min-width: 1000px) {
  .c-drei { grid-template-columns: repeat(3, 1fr); }
}

/* ── Der Hinweis zum Weiterscrollen ──────────────────────────────────────
   Er sitzt am unteren Rand des ersten Bildschirms und nicht im Textfluss:
   sonst schoebe er den Aufmacher nach oben, und die 340-Pixel-Zone (siehe
   Kopf) ist genau das, was ihn traegt. `pointer-events: none` - er ist ein
   Hinweis, kein Bedienelement. */
.c-pfeil {
  position: absolute;
  left: 0;
  right: 0;
  bottom: clamp(1.25rem, 0.4rem + 2.4vw, 3.5rem);
  text-align: center;
  pointer-events: none;
}

.c-pfeil svg {
  display: block;
  margin: 0.5rem auto 0;
}

/* Unter 700 px Schirmhoehe faellt er weg: dort streitet der Hinweis mit dem
   Knopf um denselben Platz, und der Knopf gewinnt. */
@media (max-height: 700px) {
  .c-pfeil { display: none; }
}
