@charset "UTF-8";

/* ===========================================================================
   Hochzeitsseite — Stylesheet
   ===========================================================================

   Aufbau
     1. Schriften            lokal eingebundene WebFonts
     2. Gestaltungsvariablen Farben, Typografie, Abstände
     3. Grundlagen           Reset, Basistypografie, Fokus
     4. Bausteine            Schaltflächen, Formularfelder, Linien, Meldungen
     5. Seitenrahmen         Papierfläche und Aquarell-Anmutung
     6. Blumen                dekorative Aquarellgrafiken
     7. Passwortseite
     8. Navigation
     9. Hero
    10. Ablauf und Übernachtung
    11. Paar
    12. E-Mail-Anmeldung
    13. Fuss
    14. Bewegungsanimationen

   Konventionen
     - Mobile First: Basisregeln gelten für kleine Bildschirme, Erweiterungen
       ausschliesslich über `min-width`-Abfragen.
     - Benennung nach BEM: `.block`, `.block__element`, `.block--modifier`.
     - Breakpoints in `rem`, damit sie der Textgrösse des Nutzers folgen:
         44rem = 704 px   Tablet / breiteres Hochformat
         52rem = 832 px   dreispaltige Anordnung
         62rem = 992 px   Desktop mit abgesetzter Papierfläche
   =========================================================================== */


/* ===========================================================================
   1. Schriften
   ---------------------------------------------------------------------------
   Bewusst lokal ausgeliefert statt über das Google-Fonts-CDN: So entsteht beim
   Seitenaufruf keine Verbindung zu Dritten und es werden keine IP-Adressen an
   externe Server übermittelt.

   Die Dateien liegen nicht im Auslieferungsumfang — sie werden einmalig mit
   `php tools/fetch-fonts.php` geholt (siehe assets/fonts/FONTS.md). Solange sie
   fehlen, greifen die Ersatzschriften in den Variablen unter Punkt 2; die Seite
   bleibt dabei vollständig benutzbar.

   `font-display: swap` zeigt sofort die Ersatzschrift und tauscht sie aus,
   sobald die WebFont geladen ist — nie unsichtbarer Text.
   =========================================================================== */

/* Cinzel Decorative — Auszeichnungsschrift für Namen und Überschriften */
@font-face {
    font-family: "Cinzel Decorative";
    src: url("../fonts/cinzel-decorative-400.woff2") format("woff2");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

/* Cormorant Garamond — Lesetext mit Charakter, Daten und Zitate */
@font-face {
    font-family: "Cormorant Garamond";
    src: url("../fonts/cormorant-garamond-400.woff2") format("woff2");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Cormorant Garamond";
    src: url("../fonts/cormorant-garamond-400-italic.woff2") format("woff2");
    font-weight: 400;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: "Cormorant Garamond";
    src: url("../fonts/cormorant-garamond-500.woff2") format("woff2");
    font-weight: 500;
    font-style: normal;
    font-display: swap;
}

/* Jost — sachliche Grotesk für Bedienelemente und Kleintext */
@font-face {
    font-family: "Jost";
    src: url("../fonts/jost-300.woff2") format("woff2");
    font-weight: 300;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Jost";
    src: url("../fonts/jost-400.woff2") format("woff2");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}


/* ===========================================================================
   2. Gestaltungsvariablen
   =========================================================================== */

:root {

    /* --- Farben -----------------------------------------------------------
       Warmes, gebrochenes Weiss als Papierfläche; die Aquarellgrafik ist
       freigestellt und sitzt deshalb auf jedem dieser Töne sauber auf.        */
    --paper:       #FFFCF5;   /* Hauptfläche */
    --paper-tint:  #F7EFE1;   /* abgesetzter Bereich (E-Mail-Anmeldung) */
    --card:        #FDF9F1;   /* Karten und Felder */
    --surface:     #FFFFFF;   /* Fläche hinter der Papierbahn (nur Desktop) */

    --ink:         #211F1C;   /* Haupttext — Kontrast 15,4:1 auf --paper */
    --ink-soft:    #6E6B66;   /* Nebentext — Kontrast  5,3:1 auf --paper */
    --accent:      #C97B54;   /* Koralle; nur für Flächen, Rahmen, Fokus */
    --success:     #4F6B41;
    --error:       #9C4134;

    --line:        rgba(69, 59, 48, 0.15);   /* Haarlinien und Rahmen */

    /* --- Typografie -------------------------------------------------------
       Bewusst nur DREI Familien, jede mit klarer Aufgabe:
         display  Namen und Abschnittsüberschriften
         serif    Fliesstext, Daten, Zitate
         sans     Bedienelemente, Kleintext in Versalien

       Unterschiede innerhalb einer Aufgabe entstehen über Grösse, Laufweite
       und Versalien – nicht über weitere Schriftarten.

       Die Ersatzschriften sind formverwandt gewählt: Palatino/Georgia für die
       Serifen, Avenir/Century Gothic für die geometrische Grotesk. Fehlen die
       WebFonts, verschiebt sich die Anmutung dadurch kaum.                    */
    --font-display: "Cinzel Decorative", "Cormorant Garamond", "Iowan Old Style",
                    "Palatino Linotype", Palatino, Georgia, serif;
    --font-serif:   "Cormorant Garamond", "Iowan Old Style", Georgia,
                    "Times New Roman", serif;
    --font-sans:    "Jost", "Avenir Next", Avenir, "Century Gothic", system-ui,
                    -apple-system, "Segoe UI", sans-serif;

    /* --- Rhythmus ---------------------------------------------------------
       `clamp()` statt gestufter Media Queries: Abstände wachsen stufenlos mit
       dem Viewport, ohne an jedem Breakpoint nachgepflegt zu werden.          */
    --gutter:        clamp(1.25rem, 5vw, 3rem);
    --space-section: clamp(4rem, 11vw, 8rem);
    --measure:       34rem;    /* angenehme Lesebreite für Fliesstext */

    --radius:        2px;      /* fast rechtwinklig — ruhiger als runde Ecken */
    --ease:          cubic-bezier(0.22, 0.61, 0.36, 1);

    /* --- Aquarell-Anmutung ------------------------------------------------
       Sehr flache Farbwolken, die der Papierfläche Tiefe geben. Als Variable
       hinterlegt, weil Passwortseite und Inhaltsseite sie gemeinsam nutzen.   */
    --wash:
        radial-gradient(ellipse 46% 30% at 10%  6%,  rgba(255, 255, 253, 0.60), transparent 66%),
        radial-gradient(ellipse 40% 26% at 90% 14%,  rgba(224, 211, 184, 0.28), transparent 62%),
        radial-gradient(ellipse 48% 32% at  6% 46%,  rgba(250, 245, 233, 0.55), transparent 66%),
        radial-gradient(ellipse 42% 30% at 94% 54%,  rgba(214, 199, 168, 0.22), transparent 60%),
        radial-gradient(ellipse 50% 34% at 18% 88%,  rgba(224, 211, 184, 0.24), transparent 66%),
        radial-gradient(ellipse 44% 30% at 86% 94%,  rgba(255, 255, 253, 0.55), transparent 62%);
}


/* ===========================================================================
   3. Grundlagen
   =========================================================================== */

*,
*::before,
*::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

html {
    scroll-behavior: smooth;

    /* Verhindert, dass iOS im Querformat die Schrift eigenmächtig vergrössert. */
    -webkit-text-size-adjust: 100%;

    /* Sprungziele der Navigation nicht direkt unter den Bildschirmrand legen. */
    scroll-padding-top: 2rem;
}

body {
    background-color: var(--surface);
    color: var(--ink);
    font-family: var(--font-sans);
    font-weight: 300;
    font-size: 1rem;
    line-height: 1.65;

    /* Die Papierbahn ist auf dem Desktop schmaler als das Fenster; ohne diese
       Zeile könnte die Blumengrafik einen waagrechten Scrollbalken erzeugen.   */
    overflow-x: hidden;

    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

/* Die Passwortseite hat keine abgesetzte Papierbahn, sondern füllt den
   Bildschirm — deshalb trägt hier der Body selbst die Papierfläche.           */
body.gate-page {
    background-color: var(--paper);
    background-image: var(--wash);
}

/* Die Inhaltsseite stellt die Papierbahn auf eine helle Fläche; die Blumen
   liegen dahinter und reichen seitlich darüber hinaus (siehe Abschnitt 6).     */
body.page {
    background-color: var(--surface);
}

/* Text, der ausschliesslich Screenreadern gilt: sichtbar für Hilfsmittel,
   unsichtbar am Bildschirm. Bewusst NICHT `display: none` – das nähme ihn auch
   den Screenreadern.                                                          */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

img,
svg {
    display: block;
    max-width: 100%;
}

a {
    color: inherit;
    text-decoration: none;
}

button {
    font: inherit;
    color: inherit;
    background: none;
    border: none;
}

ul,
ol {
    list-style: none;
}

/* Ein durchgehend sichtbarer Fokusring — nur bei Tastaturbedienung, damit
   Mausklicks nicht optisch „hängen bleiben“.                                  */
:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
}

/* Vorratsblatt für wiederverwendete SVG-Symbole am Dokumentende. Es enthält nur
   <symbol>-Definitionen und darf keinen Platz einnehmen; `display: none` wäre
   hier falsch, weil manche Browser dann auch die Referenzen nicht auflösen.    */
.sprite {
    position: absolute;
    width: 0;
    height: 0;
    overflow: hidden;
}


/* ===========================================================================
   4. Bausteine
   =========================================================================== */

/* --- Namen ---------------------------------------------------------------
   Gemeinsamer Baustein von Passwortseite und Inhaltsseite: beide zeigen die
   Namen identisch. Deshalb steht die Gestaltung hier bei den Bausteinen und
   nicht in einem der beiden Seitenabschnitte.

   Zwei Zeilen, das Kaufmanns-Und schliesst die erste ab. Jede Zeile ist ein
   eigenes Element im Markup – dadurch fällt der Umbruch immer an derselben
   Stelle, unabhängig von Namenslänge und Fensterbreite.                        */

.names {
    display: flex;
    flex-direction: column;
    align-items: center;
    font-family: var(--font-display);
    font-weight: 400;
    font-size: clamp(2.5rem, 12vw, 4.5rem);
    line-height: 1.16;
    letter-spacing: 0.01em;
}

.names__line {
    display: block;
    white-space: nowrap;
}

/* Das Kaufmanns-Und übernimmt Schrift und Farbe der Namen – es wird bewusst
   nicht abgesetzt, sondern als Teil der Zeile gelesen. Gesetzt wird hier nur
   noch die etwas geringere Grösse, damit es die Namen nicht überragt.          */
.names__amp {
    font-size: 0.78em;
    margin-left: 0.04em;
}


/* --- Zierlinie ---------------------------------------------------------- */

.rule {
    width: 2.5rem;
    height: 1px;
    margin: 0 auto;
    background-color: var(--ink-soft);
    opacity: 0.4;
}

/* --- Abschnittsüberschrift ---------------------------------------------- */

.section__heading {
    font-family: var(--font-display);
    font-weight: 400;
    font-size: clamp(1.7rem, 3.6vw, 2.3rem);
    line-height: 1.3;
    letter-spacing: 0.03em;
    color: var(--ink);
    text-align: center;
    margin-bottom: clamp(2.5rem, 7vw, 4.5rem);
}

/* --- Schaltflächen ------------------------------------------------------ */

.button {
    display: inline-block;
    font-family: var(--font-sans);
    font-weight: 400;
    font-size: 0.8125rem;
    letter-spacing: 0.16em;
    line-height: 1;
    text-transform: uppercase;
    text-align: center;
    padding: 1.0625rem 2.25rem;
    border: 1px solid var(--ink);
    border-radius: 999px;
    cursor: pointer;
    transition: background-color 0.3s var(--ease),
                color 0.3s var(--ease),
                transform 0.15s var(--ease);
}

.button--outline {
    background-color: transparent;
    color: var(--ink);
}

.button--outline:hover {
    background-color: var(--ink);
    color: var(--paper);
}

.button--solid {
    background-color: var(--ink);
    color: var(--paper);
}

.button--solid:hover {
    background-color: #3B3630;
}

/* In Formularen sitzen die Schaltflächen neben rechtwinkligen Eingabefeldern;
   die Pillenform würde dort unruhig wirken.                                   */
.button--square {
    border-radius: var(--radius);
}

.button:active {
    transform: translateY(1px);
}

/* Schaltfläche, die wie ein Textlink aussieht (Abmelden). */
.text-button {
    font-family: var(--font-sans);
    font-size: 0.75rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--ink-soft);
    cursor: pointer;
    transition: color 0.25s var(--ease);
}

.text-button:hover {
    color: var(--accent);
}

/* --- Formularfelder ----------------------------------------------------- */

.field + .field {
    margin-top: 1.25rem;
}

.field__label {
    display: block;
    font-size: 0.6875rem;
    font-weight: 400;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--ink-soft);
    margin-bottom: 0.5rem;
    text-align: left;
}

.field__input {
    display: block;
    width: 100%;
    padding: 0.9375rem 1.0625rem;
    font-family: var(--font-sans);
    font-weight: 300;

    /* Mindestens 16 px: Kleinere Werte lassen iOS beim Fokussieren
       ungefragt in das Feld hineinzoomen.                                     */
    font-size: 1rem;
    line-height: 1.4;
    color: var(--ink);
    background-color: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    transition: border-color 0.25s var(--ease), box-shadow 0.25s var(--ease);
}

.field__input::placeholder {
    color: var(--ink-soft);
    opacity: 0.65;
}

.field__input:hover {
    border-color: rgba(69, 59, 48, 0.3);
}

.field__input:focus {
    border-color: var(--ink);
    box-shadow: 0 0 0 3px rgba(33, 31, 28, 0.07);
}

.field__input--narrow {
    max-width: 8rem;
}


/* --- Passwort anzeigen -------------------------------------------------------
   Die Schaltfläche sitzt im Feldrahmen. Sie funktioniert nur mit JavaScript
   (nur ein Skript kann den Feldtyp umschalten), deshalb ist sie ohne `html.js`
   ausgeblendet – und das Feld braucht dann auch keinen Platz dafür.            */

.field__control {
    position: relative;
}

.field__reveal {
    display: none;
    position: absolute;
    top: 0;
    right: 0;
    place-items: center;
    width: 3rem;
    height: 100%;
    color: var(--ink-soft);
    cursor: pointer;
    transition: color 0.25s var(--ease);
}

.js .field__reveal {
    display: grid;
}

/* Platz für die Schaltfläche, damit lange Eingaben nicht darunter verschwinden. */
.js .field__input--with-action {
    padding-right: 3rem;
}

.field__reveal:hover {
    color: var(--ink);
}

.field__reveal-icon {
    width: 1.125rem;
    height: 1.125rem;
}

/* Umschalten der beiden Symbole allein über den Zustand der Schaltfläche –
   `aria-pressed` ist ohnehin für Screenreader nötig und dient hier gleich als
   Haken für das Aussehen. Das Skript setzt nur dieses eine Attribut.           */
.field__reveal[aria-pressed="false"] .field__reveal-icon--hide,
.field__reveal[aria-pressed="true"] .field__reveal-icon--show {
    display: none;
}

/* Fehlerhafte Eingaben erst kennzeichnen, NACHDEM der Nutzer etwas eingegeben
   oder abgeschickt hat.

   `:user-invalid` ist dafür der richtige Selektor. Das naheliegende `:invalid`
   greift bereits beim ersten Seitenaufbau, weil ein leeres `required`-Feld von
   Anfang an ungültig ist – ein unberührtes Passwortfeld wäre also sofort rot
   umrandet.                                                                   */
.field__input:user-invalid {
    border-color: var(--error);
}

/* --- Honeypot -----------------------------------------------------------
   Für Menschen unsichtbar, für Skripte aber ein normales Formularfeld.
   Ausserhalb des Sichtbereichs statt `display: none`, weil verbreitete Bots
   letzteres erkennen und das Feld dann überspringen.                          */

.honeypot {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* --- Rückmeldungen -----------------------------------------------------
   Ohne Typ-Modifier ausgeblendet: Das Element ist immer im Dokument (nötig,
   damit `aria-live` von Screenreadern überwacht wird), wird aber erst
   sichtbar, wenn Server oder Skript eine Meldung setzen.                      */

.feedback {
    display: none;
    font-family: var(--font-serif);
    font-size: 1.0625rem;
    line-height: 1.5;
    margin-top: 1.125rem;
}

.feedback--success,
.feedback--error {
    display: block;
}

.feedback--success {
    color: var(--success);
}

.feedback--error {
    color: var(--error);
}


/* ===========================================================================
   5. Seitenrahmen
   ---------------------------------------------------------------------------
   Auf dem Desktop läuft der Inhalt in einer schmaleren Papierbahn mit weichem
   Schattenrand — das nimmt die Anmutung einer gedruckten Karte auf. Auf
   Mobilgeräten füllt sie die ganze Breite.
   =========================================================================== */

.shell {
    position: relative;   /* Bezugsrahmen für die absolut gesetzte Navigation */
    background-color: var(--paper);
    background-image: var(--wash);
}

@media (min-width: 62rem) {
    .shell {
        /* HIER die Breite der Papierbahn einstellen. `max-width` begrenzt sie
           zusätzlich auf sehr breiten Monitoren.                                */
        width: 68vw;
        max-width: 82rem;
        margin-inline: auto;
        box-shadow: 0 0 4rem rgba(33, 31, 28, 0.13);
    }
}


/* ===========================================================================
   6. Blumen
   ---------------------------------------------------------------------------
   Freigestellte Aquarelle, die am unteren Rand von Hero und Passwortseite
   aufsitzen.

   Zwei getrennte Grafiken – die linke und die rechte Blütengruppe der Vorlage.
   Sie wachsen von unten auf und reichen von den Fensterkanten nach innen.

   Zwei Stellschrauben, hier zentral gesetzt und in den Media Queries angepasst:

     --bloom-height   Höhe der Gruppen. Die Breite folgt daraus über das
                      Seitenverhältnis der Grafik (etwa 1:1,4) – höher heisst
                      deshalb automatisch auch breiter.

     --bloom-height-max  Obergrenze für diese Höhe, gilt über alle Breakpoints.

     --bloom-top      Nur Inhaltsseite auf schmalen Bildschirmen: Dort wird an
                      der Oberkante verankert statt unten, damit die Blüten oben
                      auf gleicher Höhe bleiben, wenn die Grafik kleiner wird.

     --bloom-visible  Breite des sichtbaren Streifens, gemessen von der
                      Fensterkante nach innen.

                      Für jede Seite einzeln: `--bloom-visible-left` bzw.
                      `--bloom-visible-right`; ohne Angabe gilt für beide der
                      gemeinsame Wert.

     --bloom-lift-…   Hebt eine Seite an, ohne ihre Grösse zu ändern:
                      `--bloom-lift-left` bzw. `--bloom-lift-right`. Der Rest der Gruppe liegt
                      ausserhalb des Bildes.

   Zur Verankerung: Positioniert wird die INNERE Kante der Grafik, nicht die
   äussere. Die Grafik wächst von dort nach aussen aus dem Bild heraus, und der
   sichtbare Streifen ist immer genau `--bloom-visible` breit – bei jeder
   Fenstergrösse.

   Der naheliegende Weg über einen negativen Versatz der äusseren Kante
   funktioniert NICHT verlässlich: Ein Versatz in `vw` hängt an der
   Fensterbreite, die Grafikbreite über `--bloom-height` aber an der
   Fensterhöhe. Zieht man das Fenster breiter, wächst der Versatz mit, die
   Grafik jedoch nicht – ab Breite ≈ 1,8 × Höhe schiebt sich die Gruppe
   vollständig aus dem Bild und ist schlagartig verschwunden.

   Das Element spannt die volle Fensterbreite, nicht nur die Papierbahn – auf
   dem Desktop liegen links und rechts der Bahn freie Randspalten.

   Grundverhalten (Mobilgeräte und Passwortseite): am unteren Rand des
   umgebenden Bereichs, scrollt mit. Auf dem Desktop wird daraus eine
   feststehende Hintergrundebene – siehe unten.
   =========================================================================== */

.bloom {
    /* Schmale Bildschirme: Es gibt keine Randspalten. Die Gruppen bleiben
       niedriger, damit die Mitte für Text und Scroll-Hinweis frei bleibt.      */
    --bloom-height: 36vh;
    --bloom-height-max: 700px;
    /* `--bloom-visible` gilt für beide Seiten. Zum Feinjustieren lässt sich jede
       Seite einzeln überschreiben, ohne die andere anzufassen.                  */
    --bloom-visible: 33vw;
    --bloom-visible-left: var(--bloom-visible);
    --bloom-visible-right: var(--bloom-visible);

    /* Senkrechter Versatz je Seite. Positive Werte heben die Gruppe an, ohne
       ihre Grösse zu verändern: Zusammen mit `height: 100%` verschiebt sich das
       Element als Ganzes nach oben.                                            */
    --bloom-lift-left: 0px;
    --bloom-lift-right: 0px;

    /* Verschiebt das ganze Band nach unten, ohne es zu vergrössern. Bewusst
       getrennt von der Sicherheitszugabe der Passwortseite: Jene macht das Band
       auch höher, und weil die Breite der Grafiken an ihrer Höhe hängt, würden
       die Sträusse dabei mitwachsen.                                            */
    --bloom-drop: 0px;

    position: absolute;
    bottom: 0;

    /* Obergrenze 500 px: Auf hohen Bildschirmen würden die Gruppen sonst über
       die halbe Fensterhöhe einnehmen. `min()` deckelt den Wert, ohne die
       Prozentangaben je Breakpoint anzutasten – die gelten weiterhin für alles
       darunter. Die Breite folgt automatisch mit, sie ergibt sich aus dem
       Seitenverhältnis der Grafik.                                            */
    /* Die tatsächlich verwendete Höhe – als Variable, weil die Passwortseite sie
       unten um eine Sicherheitszugabe erweitert.                               */
    --bloom-height-used: min(var(--bloom-height), var(--bloom-height-max));
    height: var(--bloom-height-used);

    /* Über `left` und `right` auf die volle Breite gezogen – bewusst NICHT über
       `width: 100vw`: `100vw` zählt die Breite des Scrollbalkens mit, das
       Element wäre dadurch um die halbe Scrollbalken-Breite nach links
       verschoben und die beiden Streifen links und rechts ungleich breit.      */
    left: 0;
    right: 0;

    z-index: 1;
    pointer-events: none;
}

/* Die Gruppe wird nicht beschnitten: Sie ist so breit, wie ihr Bild es vorgibt,
   und läuft nach aussen über den Bildschirmrand hinaus. Ein Beschnitt an der
   Innenkante würde einen harten senkrechten Schnitt mitten durch die Blüten
   ziehen – deshalb bewusst kein `overflow: hidden` und keine feste Breite.     */
.bloom__side {
    position: absolute;
    height: 100%;
}

.bloom__image {
    display: block;

    /* Höhe führt, Breite folgt dem Seitenverhältnis der Grafik. */
    height: 100%;
    width: auto;

    /* Hebt die Begrenzung aus der Basisregel für Bilder auf – sonst stauchte
       `max-width: 100%` die Grafik zusammen.                                  */
    max-width: none;
}

/* Verankerung an der INNEREN Kante. `100%` ist die Breite von `.bloom` und damit
   die Fensterbreite: `right: calc(100% - X)` setzt die rechte Kante der linken
   Gruppe X vom linken Bildschirmrand entfernt.

   HIER wird waagrecht positioniert – je Seite mit eigenem Wert, damit sich beide
   Gruppen unabhängig voneinander feinjustieren lassen.                          */
.bloom__side--left {
    right: calc(100% - var(--bloom-visible-left));
    bottom: var(--bloom-lift-left);
}

.bloom__side--right {
    left: calc(100% - var(--bloom-visible-right));
    bottom: var(--bloom-lift-right);
}

/* Inhaltsseite ohne Randspalten: hohe, schmale Streifen an den Bildschirmkanten
   statt eines breiten Bandes unten.

   Der Bereich endet bei 62rem – genau dort setzt die Papierbahn ein und es
   entstehen links und rechts weisse Balken. Solange die Bahn die ganze Breite
   füllt, gibt es keinen Platz für ein breites Band: Es liefe über die
   Schaltfläche und den Scroll-Hinweis, die dort die ganze Breite brauchen.

   Alle vier Werte sind FESTE Längen, keine Prozente: Über die Spanne von 320 bis
   992 Pixeln Breite bliebe eine Angabe in `vw` oder `vh` nicht ansatzweise
   gleich, und die Blüten sollen überall gleich gross und gleich hoch stehen.

   Ausnahme von der Mobile-First-Regel dieses Stylesheets: Die Werte gelten
   ausschliesslich UNTERHALB des Desktop-Breakpoints und nur für die
   Inhaltsseite – die Passwortseite behält bewusst ihr breites Band. Eine
   `min-width`-Abfrage könnte beides nicht gleichzeitig ausdrücken.             */
@media (max-width: 61.9375rem) {
    body.page .bloom {
        /* Hier wird an der OBERKANTE verankert, nicht am unteren Rand: Die
           Blüten sollen oben auf gleicher Höhe stehen. Bei Verankerung unten
           würde eine kleinere Grafik nach unten zusammenschrumpfen und die
           Oberkante mitwandern.

           Folge: Die Unterkante liegt oberhalb des Hero-Endes, unter den Stielen
           bleibt also Papierfläche frei.                                        */
        --bloom-top: 14px;

        /* Feste Höhe. Der zweite Wert greift nur auf sehr flachen Fenstern und
           hält die Grafik dort innerhalb des Hero-Bereichs, damit sie nicht in
           den nächsten Abschnitt hineinragt.                                    */
        --bloom-height: min(620px, calc(100svh - var(--bloom-top)));

        /* Schmaler Streifen je Seite: Die Blüten ragen sichtbar herein, lassen
           die Mitte aber frei.                                                  */
        --bloom-visible: 150px;

        /* Nur die LINKE Grafik steht weiter aussen. Grund: Sie trägt bis weit
           nach innen noch volle Blüten, die rechte dort nur noch dünne Stiele.
           Nachgemessen reicht substanzielle Blütenmasse links 54px weiter herein
           als rechts – bei gleichem Wert für beide Seiten wirkt die linke
           deshalb zu weit innen.

           27px Ausgleich, also die Hälfte des Unterschieds: Ein vollständiger
           Ausgleich (48 - 27 = 21px) liesse links kaum noch etwas stehen und die
           beiden Streifenbreiten sehr unterschiedlich aussehen.                */
        --bloom-visible-left: 63px;

        /* Die rechte Grafik reichte mit dem allgemeinen Wert (150px, s.o.) zu
           nah an den Titel heran. Eigener, etwas schmalerer Wert schafft
           Abstand, ohne den linken Streifen mit zu verschieben.                */
        --bloom-visible-right: 130px;

        /* Die rechte Gruppe sitzt 50px höher als die linke. Nur die Position
           verschiebt sich, die Grösse bleibt gleich.                           */
        --bloom-lift-right: 90px;

        top: var(--bloom-top);
        bottom: auto;
    }
}

/* Die Schaltfläche im Hero trägt den längsten Text der Seite. Nur auf wirklich
   schmalen Bildschirmen wird sie über engere Laufweite und weniger Innenabstand
   kompakter, damit sie zwischen die Blütenstreifen passt. Betrifft bewusst nur
   diese eine Schaltfläche, nicht `.button` allgemein.                          */
@media (max-width: 43.9375rem) {
    .hero__cta {
        letter-spacing: 0.1em;
        padding-inline: 1.5rem;
    }
}

@media (min-width: 44rem) {
    .bloom {
        --bloom-height: 44vh;
        --bloom-visible: 15vw;
    }
}

@media (min-width: 62rem) {
    /* Desktop: Die Gruppen sitzen direkt an den Fensterkanten und stehen hoch.
       Da die Vorlage ein unteres Randband ist – eine Gruppe ist im Verhältnis
       etwa 1:1,4 –, wird sie bei dieser Höhe breiter als die 13vw Randspalte
       und am Bildschirmrand angeschnitten. Das ist bewusst so gewählt: Die
       Alternative wäre eine vollständige, dafür deutlich niedrigere Gruppe.

       Sichtbar ist dadurch der äussere Teil der Gruppe in der Randspalte; der
       innere Teil liegt hinter der Papierbahn (siehe `z-index: -1` unten).      */
    .bloom {
        /* 66vh entspricht 78vh minus 15 %. Die Breite folgt automatisch mit,
           da sie sich aus dem Seitenverhältnis der Grafik ergibt.              */
        --bloom-height: 66vh;

        /* Nur ein schmaler Streifen der inneren Blüten steht im Bild, der
           übrige Strauss liegt draussen. 3rem entspricht den rund 50 px, die
           zuvor über `-25vw` entstanden sind – jetzt aber unabhängig von der
           Fenstergrösse und damit stabil.                                      */
        --bloom-visible: 14rem;
    }
}

/* ---------------------------------------------------------------------------
   Feststehende Hintergrundebene ab Desktop-Breite
   ---------------------------------------------------------------------------
   Ab hier ist die Papierbahn schmaler als das Fenster, links und rechts liegt
   freie Fläche. Erst dann ergibt eine eigene Hintergrundebene Sinn:

   `position: fixed` klebt das Band an den unteren Fensterrand – es bleibt beim
   Scrollen stehen, während sich die Papierbahn davor bewegt.

   `z-index: -1` schiebt es hinter die Hintergrundfläche der Papierbahn. Das
   funktioniert, weil weder `.hero` noch `.shell` einen eigenen Stapelkontext
   aufspannen (beide haben nur `position: relative`, kein `z-index`): Ein Kind
   mit negativem `z-index` wird deshalb bis hinter den Hintergrund dieser
   Vorfahren gezeichnet – aber noch vor die Grundfläche der Seite.

   Ergebnis: Die Blüten sind nur links und rechts neben der Bahn zu sehen, und
   die Bahn schiebt sich beim Scrollen darüber. Würde hier `z-index: 1` stehen,
   lägen die Blüten vor der Bahn und der Inhalt würde hinter ihnen wegscrollen.
   --------------------------------------------------------------------------- */

/* Passwortseite: Die Blumen kleben an der tatsächlichen Unterkante des
   Fensters, nicht am unteren Rand von `.gate`.

   Hintergrund: `.gate` ist `100svh` hoch – das ist die KLEINE Ansicht, also mit
   ausgefahrener Browserleiste. Fährt die Leiste beim Scrollen ein, wächst der
   sichtbare Bereich, und unter den Blumen bliebe ein leerer Streifen. Mit
   `position: fixed` entfällt das, weil die Grafik dann direkt am Fensterrand
   sitzt.

   Warum nicht einfach `100dvh` für `.gate`: Öffnet sich die Bildschirmtastatur
   für das Passwortfeld, schrumpft `dvh` stark – das Layout würde springen und
   das Eingabefeld womöglich aus dem Bild rutschen. `svh` bleibt dabei stabil.  */
body.gate-page .bloom {
    position: fixed;

    /* Sicherheitszugabe nach unten, damit dort unter keinen Umständen ein
       Streifen Papierfläche stehen bleibt.

       Warum überhaupt nötig: Wie der Browser den unteren Rand bemisst, hängt
       auf Mobilgeräten von mehreren Dingen ab – Home-Indikator, ein- und
       ausfahrende Adressleiste, `viewport-fit`. Statt sich auf eine dieser
       Grössen zu verlassen, ragt die Grafik einfach etwas über die Kante hinaus.

       `env(safe-area-inset-bottom)` liefert auf Geräten mit Home-Indikator die
       Höhe dieses Streifens; die 12px greifen, wenn kein Streifen gemeldet wird.

       Die Grafik wird um denselben Betrag HÖHER, nicht nur nach unten
       verschoben – so bleibt der oberhalb der Kante sichtbare Teil unverändert.
       Dass unten ein paar Pixel Stiel wegfallen, sieht man nicht: Sie sind in
       der Vorlage ohnehin angeschnitten.                                       */
    --bloom-bleed: max(env(safe-area-inset-bottom, 0px), 12px);
    bottom: calc(-1 * (var(--bloom-bleed) + var(--bloom-drop)));
    height: calc(var(--bloom-height-used) + var(--bloom-bleed));
}

/* Passwortseite auf schmalen Bildschirmen: Das Blumenband steht NICHT am Fenster
   fixiert, sondern als letztes Element im Textfluss – unterhalb des Formulars.

   Grund ist die Bildschirmtastatur. Ein fixiertes Band bezieht sich immer auf den
   Layout-Viewport, und der schrumpft nicht, wenn die Tastatur aufgeht: Das Band
   bleibt an der alten Unterkante hinter der Tastatur, darüber steht ein leerer
   Streifen, und weil es seine volle Höhe behält, ragt es gleichzeitig ins
   Passwortfeld. Jede Rechnung, die das nachträglich korrigiert, muss darauf
   wetten, wie der Browser seine Kanten bemisst – und das unterscheidet sich je
   nach Gerät, Browserleiste und Tastaturzeile.

   Im Textfluss stellt sich die Frage nicht mehr: Das Band liegt hinter der
   Eingabe im Dokument und kann sie deshalb gar nicht überdecken – unabhängig
   davon, wie hoch die Tastatur ausfällt.

   `min-height: 100dvh` hält es trotzdem an der Unterkante: `dvh` folgt der ein-
   und ausfahrenden Adressleiste (anders als das sonst verwendete `svh`, das die
   kleinste Ansicht meint und beim Einfahren einen Streifen frei lassen würde).
   Die Bildschirmtastatur verändert `dvh` nicht, das Layout springt also nicht.  */
@media (max-width: 61.9375rem) {
    /* Die Passwortseite füllt genau ein Fenster und wird nicht gerollt. Nötig,
       weil das Blumenband um seine Sicherheitszugabe unter die Kante ragt – ohne
       diese Zeile liesse sich die Seite um diese paar Pixel verschieben.
       Beschnitten wird am Fenster­rand, der Body hat keinen Innenabstand.        */
    body.gate-page {
    	overflow: hidden;
	}
	
	body.gate-page .gate {
        display: flex;
        flex-direction: column;
        align-items: center;

        /* Feste Höhe, nicht `min-height`: Nur bei einer festen Höhe kann das
           Blumenband schrumpfen, wenn der Platz knapp wird (kleine Geräte,
           Querformat). Mit `min-height` würde die Seite stattdessen wachsen und
           das Band unter die Fensterkante rutschen.                            */
        height: 115dvh;

        /* Das Band soll unten bündig anliegen; nach oben und zu den Seiten
           bleiben die Abstände aus der Grundregel erhalten.                    */
        padding-bottom: 0;

        /* Hier NICHT beschneiden: `overflow` schneidet an der Innenkante des
           Innenabstands ab, nicht an der Fensterkante. Ein fixiertes Band war
           davon nie betroffen – sein Bezug ist das Fenster –, ein Band im
           Textfluss dagegen schon: Beide Blütengruppen würden um den
           Innenabstand nach innen beschnitten und rückten zur Mitte.

           Das Beschneiden übernimmt jetzt das Band selbst (siehe unten). Es ist
           genau so breit wie das Fenster, schneidet also an der richtigen Kante. */
        overflow: visible;
    }

    body.gate-page .gate__inner {
        /* Statt Platz für ein darüberliegendes Band nur noch etwas Luft zum
           Bandanfang – das Band braucht seinen Raum jetzt selbst.              */
        padding-bottom: 2rem;
    }

    body.gate-page .bloom {
        position: relative;

        /* Im Textfluss zieht `left: 0; right: 0` aus der Grundregel keine Breite
           mehr auf – das gilt nur für absolut positionierte Elemente. Ohne
           `align-self: stretch` schrumpfte das Band auf null Breite (seine Kinder
           sind absolut positioniert) und beide Blütengruppen rutschten zur Mitte.

           Die negativen Ränder heben den seitlichen Innenabstand von `.gate`
           wieder auf: Das Band reicht damit bis an die Bildschirmkante, die
           Blüten sitzen also genauso weit außen wie zuvor.                     */
        align-self: stretch;
        margin-inline: calc(-1 * var(--gate-inset-left)) calc(-1 * var(--gate-inset-right));

        /* Verhindert waagrechtes Rollen: Was über die Fensterkante hinausragt,
           wird hier abgeschnitten. Die inneren Kanten der Grafiken bleiben davon
           unberührt – sie liegen innerhalb des Bandes.                         */
        overflow: hidden;

        /* Schiebt das Band an die Unterkante und den freien Raum darüber:
           Ein automatischer Rand hat Vorrang vor der Ausrichtung des Behälters. */
        margin-top: auto;

        /* Reicht der Platz nicht (kleine Geräte, Querformat), darf das Band
           schrumpfen, statt den Inhalt aus dem Bild zu schieben.               */
        min-height: 0;
    }
}

/* Feinjustierung der Passwortseite NUR auf Mobilgeräten – das schmale
   Browserfenster am Rechner bleibt bewusst unberührt.

   Unterschieden wird über `hover: none`: Das Merkmal trifft auf Geräte zu, deren
   Zeiger nicht schweben kann, also auf Touchbedienung. Ein schmal gezogenes
   Fenster am Rechner behält seinen Mauszeiger und fällt damit heraus. Das ist
   eine Eigenschaft der Bedienung, keine Abfrage des Gerätenamens – solche
   Abfragen veralten mit jedem neuen Modell.

   Alle drei Werte sind zum Nachjustieren gedacht:
     --bloom-height   Grösse der Sträusse; die Breite folgt dem Seitenverhältnis
     --bloom-drop     Unterkante tiefer setzen (verschiebt, ohne zu vergrössern)
     --bloom-visible  wie weit die Sträusse hereinreichen; kleiner = weiter aussen */
@media (max-width: 61.9375rem) and (hover: none) {

    /* Der Sperrbildschirm liegt fest: kein Wischen, kein Kneif- oder
       Doppeltipp-Zoom, kein elastisches Nachfedern am Rand.

       `touch-action: none` nimmt Berührungen ihre Roll- und Zoomfunktion,
       `overscroll-behavior: none` das Nachfedern. Das Rollen selbst unterbindet
       schon `overflow: hidden` weiter oben; diese beiden Zeilen schliessen die
       Gesten, die daran vorbeigehen.

       Bewusst kein `user-scalable=no` im Viewport-Tag: iOS Safari ignoriert die
       Angabe seit iOS 10, sie würde also genau dort nichts bewirken – und ein
       Meta-Tag kennt keine Medienabfrage, liesse sich also nicht auf
       Mobilgeräte und den Sperrbildschirm begrenzen.

       Tippen, Tastatur und die Augen-Schaltfläche bleiben unberührt: Sie lösen
       Klicks aus, keine Rollgesten.

       Die Sperre muss auch am `<html>`-Element hängen: Das Rollen des Fensters
       verantwortet dieses Element, nicht der Body. `overflow: hidden` am Body
       allein liess die Seite noch um die paar Pixel verschieben, die das Band
       unter die Kante ragt (nachgemessen: 12.5px). Ausgewählt wird es über
       `:has()`, damit dafür keine Klasse ins Markup muss; in älteren Browsern
       ohne `:has()` bleibt es einfach beim bisherigen Verhalten.                */
    html:has(body.gate-page),
	body.gate-page {
    	overflow: hidden;
    	touch-action: none;
    	overscroll-behavior: none;
	}

    body.gate-page .bloom {
        --bloom-height: 46vh;
        --bloom-drop: -15px;
        --bloom-visible: 40vw;
    }

    /* Die Inhaltsseite darf gerollt werden – aber nur senkrecht.

       `pan-y` erlaubt genau das und schliesst alles andere aus: waagrechtes
       Wischen ebenso wie Kneif-Zoom. Letzteres ist hier der eigentliche Punkt:
       Waagrecht rollen liesse sich die Seite ohnehin nicht (`overflow-x` am Body,
       siehe oben), wohl aber nach dem Vergrössern durch Schieben des Ausschnitts –
       und dabei kommt der Teil der Blumengrafik zum Vorschein, der absichtlich
       über den Bildschirmrand hinausragt.

       Bewusst NICHT zusätzlich `overflow-x` am `<html>`: Nötig ist es nicht, denn
       waagrecht rollen verhindert bereits `overflow-x: hidden` am Body – und die
       naheliegende Variante wäre schädlich. `hidden` auf einer Achse stellt die
       andere zwangsweise auf `auto` (nachgemessen: `hidden`/`visible` ergibt
       `hidden`/`auto`) und macht das Wurzelelement damit zu einem zweiten
       Rollbereich. `clip` hätte diesen Nebeneffekt nicht (`clip`/`visible` bleibt
       `clip`/`visible`), bringt hier aber keinen Gewinn.                         */
    body.page {
        touch-action: pan-y;
    }
}

/* Passwortseite im schmalen Browserfenster am Rechner: keine Blumen.

   Abgegrenzt über `hover: hover` – ein Zeiger, der schweben kann. Mobilgeräte
   fallen dadurch heraus und bleiben unverändert; dort zeigt der Sperrbildschirm
   seine Sträusse weiter (siehe Block darüber).

   Die Schwelle ist dieselbe 62rem (992px), an der die Randspalten wegfallen –
   bewusst kein zweiter, eigener Wert: So gibt es beim Schmalerziehen genau einen
   Übergang und nicht zwei.

   `justify-content` ist nötig, weil das Band im Textfluss stand und mit seinem
   automatischen Rand den freien Raum aufgeteilt hat. Ohne Band würde der Inhalt
   sonst oben kleben.                                                            */
@media (max-width: 61.9375rem) and (hover: hover) {
    body.gate-page .bloom {
        display: none;
    }

    body.gate-page .gate {
        justify-content: center;

        /* Zurück auf genau ein Fenster. Der grössere Wert weiter oben ist für das
           Blumenband gedacht, das unten hinausragen darf; ohne Band schöbe er den
           Inhalt nur nach unten und schnitte ihn unten an.                      */
        height: 100dvh;
    }
}

@media (min-width: 62rem) {
    body.page .bloom {
        position: fixed;
        z-index: -1;
    }
}


/* ===========================================================================
   7. Passwortseite
   =========================================================================== */

.gate {
    position: relative;
    display: grid;
    place-items: center;

    /* `svh` statt `vh`: berücksichtigt die ein- und ausfahrende Adressleiste
       mobiler Browser, sodass nichts abgeschnitten wird.                      */
    min-height: 100svh;

    /* Wegen `viewport-fit=cover` reicht die Seite bis an die Bildschirmkante.
       Der Inhalt hält über die sicheren Bereiche Abstand zu Notch, abgerundeten
       Ecken und Home-Indikator. Ohne Einkerbung sind diese Werte 0, dann bleibt
       es beim reinen `--gutter`.

       Die seitlichen Werte stehen als Variablen bereit, weil das Blumenband sie
       wieder aufheben muss: Es soll bis an die Bildschirmkante reichen, nicht nur
       bis an den Textrand.                                                     */
    --gate-inset-left: max(var(--gutter), env(safe-area-inset-left));
    --gate-inset-right: max(var(--gutter), env(safe-area-inset-right));
    padding: max(var(--gutter), env(safe-area-inset-top))
             var(--gate-inset-right)
             max(var(--gutter), env(safe-area-inset-bottom))
             var(--gate-inset-left);
    overflow: hidden;
}

.gate__inner {
    position: relative;
    z-index: 2;
    width: 100%;
    max-width: 26rem;
    text-align: center;

    /* Hebt die Eingabe über die Blumen. */
    padding-bottom: clamp(4rem, 20vh, 9rem);
}

.gate__eyebrow {
    font-size: 0.6875rem;
    letter-spacing: 0.34em;
    text-transform: uppercase;
    color: var(--ink-soft);
    margin-bottom: 1.125rem;
}

/* Überschrift der Einrichtungsseite. Dort stehen keine Namen, sondern ein
   einzelnes Wort – deshalb eine eigene, schlichtere Regel und nicht der
   gemeinsame `.names`-Baustein.                                                */
.gate__title {
    font-family: var(--font-display);
    font-weight: 400;
    font-size: clamp(1.75rem, 8vw, 2.5rem);
    line-height: 1.2;
    letter-spacing: 0.02em;
}

.gate__intro {
    font-family: var(--font-serif);
    font-size: clamp(1.0625rem, 3.4vw, 1.1875rem);
    line-height: 1.6;
    color: var(--ink-soft);
    margin-top: 1.5rem;
}

.gate .rule {
    margin-top: 1.75rem;
}

.gate__form {
    margin-top: 2.25rem;
}

/* Auf schmalen Bildschirmen fällt das Feld kompakter aus. Verkleinert wird
   ausschliesslich der Innenabstand, NICHT die Schriftgrösse: Unter 16 px zoomt
   iOS beim Antippen ungefragt in das Feld hinein und verschiebt das Layout.     */
.gate__form .field__input {
    padding-block: 0.6875rem;
}

.gate__form .button {
    width: 100%;
    margin-top: 1rem;
    padding-block: 0.875rem;
}

@media (min-width: 44rem) {
    .gate__form .field__input {
        padding-block: 0.9375rem;
    }

    .gate__form .button {
        padding-block: 1.0625rem;
    }
}

/* Auf Mobilgeräten wirkt die gefüllte Schaltfläche als schwarzer Balken zu
   schwer: Sie liegt dort direkt unter dem gleich breiten Eingabefeld, und beide
   zusammen nehmen einen guten Teil des kleinen Bildschirms ein.

   Deshalb hier dieselbe Gestalt wie die Schaltflächen im Inhalt: Umriss statt
   Fläche. Das Markup bleibt unverändert – es trägt weiterhin `button--solid`,
   und nur das Stylesheet entscheidet je Ansicht. Am Rechner bleibt die gefüllte
   Fassung, auch im schmalen Fenster.

   Der Rahmen steht auf `--ink-soft` statt `--ink`: Ein Umriss in voller
   Textstärke zöge auf der kleinen Fläche genauso viel Aufmerksamkeit auf sich
   wie zuvor die Füllung.

   Die Zeile für `:hover` ist nötig, weil die Grundregel dort die dunkle Füllung
   setzt. Auf Touchgeräten gibt es kein echtes Schweben, ein Antippen kann den
   Zustand aber hängen lassen – die Schaltfläche bliebe dann schwarz zurück.
   Rückmeldung beim Drücken gibt weiterhin `.button:active`.                     */
@media (max-width: 61.9375rem) and (hover: none) {
    .gate__form .button--solid,
    .gate__form .button--solid:hover {
        background-color: transparent;
        color: var(--ink);
        border-color: var(--ink-soft);
    }
}

.setup__steps {
    counter-reset: step;
    text-align: left;
    max-width: 22rem;
    margin: 2rem auto 0;
    font-size: 0.9375rem;
    color: var(--ink-soft);
}

.setup__steps li {
    counter-increment: step;
    position: relative;
    padding-left: 2rem;
}

.setup__steps li + li {
    margin-top: 0.75rem;
}

.setup__steps li::before {
    content: counter(step) ".";
    position: absolute;
    left: 0;
    font-family: var(--font-serif);
    color: var(--accent);
}

.setup__steps code {
    font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
    font-size: 0.875em;
    color: var(--ink);
}


/* ===========================================================================
   8. Navigation
   ---------------------------------------------------------------------------
   Aufgebaut als <details>/<summary>: klappt ohne JavaScript auf und zu, ist
   per Tastatur bedienbar und meldet ihren Zustand von sich aus an Screenreader.
   Das Skript ergänzt lediglich Komfortfunktionen.
   =========================================================================== */

.nav {
    position: absolute;

    /* Im Querformat liegt die Notch links; `env()` schiebt die Schaltfläche
       davon weg. Ohne Einkerbung sind die Werte 0.                             */
    top: max(var(--gutter), env(safe-area-inset-top));
    left: max(var(--gutter), env(safe-area-inset-left));
    z-index: 60;
}

.nav__toggle {
    display: grid;
    place-items: center;
    width: 2.75rem;
    height: 2.75rem;
    cursor: pointer;

    /* Entfernt das Aufklappdreieck, das Browser an <summary> zeichnen. */
    list-style: none;
}

.nav__toggle::-webkit-details-marker {
    display: none;
}

.nav__bars {
    display: grid;
    gap: 5px;
    width: 1.5rem;
}

.nav__bars span {
    display: block;
    height: 1.5px;
    background-color: var(--ink);
    transition: transform 0.3s var(--ease),
                opacity 0.2s var(--ease),
                background-color 0.3s var(--ease);
}

.nav__toggle:hover .nav__bars span {
    background-color: var(--accent);
}

/* Im geöffneten Zustand werden die drei Striche zum Kreuz.
   6,5 px entspricht Strichhöhe (1,5 px) plus Abstand (5 px).                  */
.nav[open] .nav__bars span:nth-child(1) {
    transform: translateY(6.5px) rotate(45deg);
}

.nav[open] .nav__bars span:nth-child(2) {
    opacity: 0;
}

.nav[open] .nav__bars span:nth-child(3) {
    transform: translateY(-6.5px) rotate(-45deg);
}

.nav__panel {
    position: absolute;
    top: calc(100% + 0.625rem);
    left: 0;
    min-width: 15rem;
    padding: 0.75rem 1.625rem 1.25rem;
    background-color: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius);

    /* Zwei Schatten übereinander: ein enger, schwacher für die Kante und ein
       weiter, weicher für die Tiefe. Das wirkt ruhiger als ein einzelner
       kräftiger Schatten.                                                      */
    box-shadow:
        0 0.125rem 0.5rem rgba(33, 31, 28, 0.05),
        0 1.5rem 3rem -1rem rgba(33, 31, 28, 0.20);

    /* Aufklappen aus der Ecke der Schaltfläche heraus. */
    transform-origin: top left;

    /* Eine `animation` läuft auch dann an, wenn das Element gerade von
       `display: none` auf sichtbar wechselt — eine `transition` würde das
       nicht tun. Genau der Fall beim Öffnen von <details>.                     */
    animation: panel-in 0.32s var(--ease) both;
}

/* Element-Selektor statt Klasse: Die Listenpunkte sind durch `.nav__panel`
   eindeutig eingegrenzt, eine eigene Klasse wäre ein Haken ohne Zusatznutzen.
   Die Haarlinie steht zwischen den Punkten, nicht darüber und darunter.        */
.nav__panel li + li {
    border-top: 1px solid var(--line);
}

/* Die Einträge fahren beim Öffnen leicht versetzt nacheinander ein. */
.nav__panel li,
.nav__logout {
    animation: nav-item-in 0.3s var(--ease) both;
}

.nav__panel li:nth-child(1) { animation-delay: 0.10s; }
.nav__panel li:nth-child(2) { animation-delay: 0.16s; }
.nav__panel li:nth-child(3) { animation-delay: 0.22s; }
.nav__panel li:nth-child(4) { animation-delay: 0.28s; }
.nav__logout                { animation-delay: 0.34s; }

.nav__link {
    position: relative;
    display: block;

    /* Der linke Einzug ist dauerhaft reserviert, damit der Hover-Indikator
       keinen Umbruch auslöst – der Text bleibt beim Überfahren stehen.          */
    padding: 0.8125rem 0 0.8125rem 1.375rem;
    font-size: 0.8125rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--ink);
    transition: color 0.25s var(--ease);
}

/* Kurze Linie, die beim Überfahren von links hereinfährt. */
.nav__link::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 0;
    width: 0.75rem;
    height: 1px;
    background-color: var(--accent);
    opacity: 0;
    transform: translateX(-0.25rem);
    transition: opacity 0.25s var(--ease), transform 0.25s var(--ease);
}

.nav__link:hover,
.nav__link:focus-visible {
    color: var(--accent);
}

.nav__link:hover::before,
.nav__link:focus-visible::before {
    opacity: 1;
    transform: none;
}

.nav__logout {
    margin-top: 0.75rem;
    padding-top: 1rem;
    padding-left: 1.375rem;   /* auf einer Linie mit den Menüpunkten */
    border-top: 1px solid var(--line);
}


/* ===========================================================================
   9. Hero
   =========================================================================== */

.hero {
    position: relative;

    /* Zwei Zeilen: der Inhalt füllt den freien Raum und wird darin zentriert,
       der Scrollhinweis sitzt fest am unteren Rand.                            */
    display: grid;
    grid-template-rows: 1fr auto;
    min-height: 100svh;
    padding: calc(var(--gutter) * 2.5) var(--gutter) var(--gutter);
    text-align: center;

    /* Bewusst NICHT `overflow: hidden`: Die Blumen sollen seitlich über die
       Papierbahn hinausreichen. Gegen einen waagrechten Scrollbalken sichert
       `overflow-x: hidden` am `body` ab.                                       */
    overflow: visible;
}

.hero__content {
    position: relative;
    z-index: 2;
    align-self: center;
    width: 100%;
    max-width: 30rem;
    margin-inline: auto;
}

.hero__eyebrow {
    font-size: 0.6875rem;
    letter-spacing: 0.34em;
    text-transform: uppercase;
    color: var(--ink-soft);
    margin-bottom: 1.25rem;
}

/* Unter den Namen folgen vier Zeilen mit absteigender Gewichtung:
   Bezeichnung („Save the Date“) – Termine – Ort – Countdown. Die Termine sind
   die eigentliche Kernaussage und deshalb die kräftigste dieser Zeilen.        */

.hero__label {
    font-family: var(--font-serif);
    font-style: italic;
    font-size: clamp(1.125rem, 3vw, 1.375rem);
    letter-spacing: 0.03em;
    color: var(--ink-soft);
    margin-top: 1.75rem;
}

.hero__dates {
    margin-top: 0.5rem;
}

/* Je Festtag eine eigene Zeile. */
.hero__date {
    display: block;
    font-family: var(--font-serif);
    font-weight: 500;
    font-size: clamp(1.25rem, 3.6vw, 1.75rem);
    line-height: 1.35;
    letter-spacing: 0.01em;
    color: var(--ink);
    font-variant-numeric: lining-nums;
}

.hero__place {
    font-family: var(--font-serif);
    font-size: clamp(1.0625rem, 2.8vw, 1.25rem);
    color: var(--ink-soft);
    margin-top: 0.875rem;
}

/* Symbol und Text bilden zusammen die Klickfläche. `inline-flex` statt `flex`,
   damit sie nur so breit wird wie der Inhalt und nicht die ganze Zeile.        */
.hero__place-link {
    display: inline-flex;
    align-items: center;
    gap: 0.4375rem;
    transition: color 0.25s var(--ease);
}

/* Der Ort ist ein Link – das darf man sehen, ohne dass es aufdringlich wird:
   Unterstreichung mit Abstand zur Grundlinie, erst beim Überfahren kräftiger.  */
a.hero__place-link {
    text-decoration: underline;
    text-decoration-color: var(--line);
    text-decoration-thickness: 1px;
    text-underline-offset: 0.28em;
}

a.hero__place-link:hover {
    color: var(--ink);
    text-decoration-color: currentColor;
}

/* Gleiches Ortssymbol wie im Ablauf, hier etwas grösser passend zur Schrift. */
.hero__pin {
    flex: 0 0 auto;
    width: 0.9em;
    height: 0.9em;
}

.hero__countdown {
    font-family: var(--font-serif);
    font-size: clamp(1rem, 3.2vw, 1.1875rem);
    letter-spacing: 0.02em;
    color: var(--ink);
    margin-top: 2.25rem;

    /* Gleich breite Ziffern — sonst zappelt der Sekundenzähler. */
    font-variant-numeric: tabular-nums;
}

.hero__countdown strong {
    font-weight: 500;
}

.hero__cta {
    margin-top: 2.5rem;
}


/* ===========================================================================
   10. Ablauf und Übernachtung
   ---------------------------------------------------------------------------
   Gemeinsamer Rahmen für die beiden Textabschnitte zwischen Hero und Paarfoto.
   =========================================================================== */

.section {
    position: relative;
    z-index: 1;
    padding: var(--space-section) var(--gutter);
}

/* Zwei Abschnitte hintereinander sollen nicht den doppelten Abstand ergeben. */
.section + .section {
    padding-top: 0;
}


/* --- Begrüssung ---------------------------------------------------------
   Der Einleitungstext steht bewusst nicht im Hero, sondern als erster
   Abschnitt darunter: Die erste Bildschirmseite bleibt damit ruhig und zeigt
   nur Namen, Datum, Countdown und den Scroll-Hinweis.                        */

.intro {
    max-width: 35rem;
    margin-inline: auto;
    text-align: center;
}

.intro p {
    font-family: var(--font-serif);
    font-size: clamp(1rem, 2vw, 1.15rem);
    line-height: 1.7;
    color: var(--ink-soft);
    text-wrap: pretty;
}

.intro p + p {
    margin-top: 1rem;
}


/* --- Zeitleiste ---------------------------------------------------------
   Zentrierte Anordnung, passend zum übrigen Seitenaufbau: Zeit, Programmpunkt
   und Ort stehen mittig untereinander.

   Der Zusammenhang zwischen den Einträgen entsteht aus dem Trenner ÜBER jedem
   Eintrag – eine feine senkrechte Linie mit hohlem Punkt in ihrer Mitte. Das
   ergibt den Rhythmus Linie–Punkt–Linie–Text und ersetzt die frühere
   Markierungsspalte am linken Rand, die bei zentriertem Text unsymmetrisch
   gewirkt hätte.                                                             */

.schedule {
    max-width: 37.5rem;
    margin-inline: auto;
}

.schedule__day + .schedule__day {
    margin-top: 3.5rem;
}

/* Der eigene Charakter dieser Zeile kommt aus Versalien und weiter Laufweite,
   nicht aus einer eigenen Schriftart.                                          */
.schedule__label {
    font-family: var(--font-serif);
    font-weight: 500;
    font-size: clamp(0.9375rem, 2.4vw, 1.25rem);
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--ink-soft);
    text-align: center;
}

.schedule__item {
    text-align: center;
}

/* Trenner über dem Eintrag. Die Höhe bestimmt gleichzeitig den Abstand zum
   vorhergehenden Eintrag – ein zusätzlicher Aussenabstand ist nicht nötig.    */
.schedule__marker {
    position: relative;
    display: block;
    width: 1px;
    height: 3.25rem;
    margin: 0 auto 1.125rem;
    background-color: var(--line);
}

/* Der hohle Punkt sitzt mittig auf der Linie. */
.schedule__marker::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 9px;
    height: 9px;
    transform: translate(-50%, -50%);
    border: 1.3px solid var(--ink-soft);
    border-radius: 50%;
    background-color: var(--paper);
}

.schedule__time {
    font-family: var(--font-serif);
    font-size: 0.95rem;
    letter-spacing: 0.04em;
    color: var(--ink-soft);
}

.schedule__name {
    font-family: var(--font-serif);
    font-size: clamp(1.25rem, 2.3vw, 1.5rem);
    line-height: 1.3;
    color: var(--ink);
    margin-top: 0.25rem;
}

.schedule__place {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.375rem;
    font-size: 0.8125rem;
    font-weight: 300;
    color: var(--ink-soft);
    margin-top: 0.5rem;
}

.schedule__pin {
    flex: 0 0 auto;
    width: 13px;
    height: 13px;
}


/* --- Übernachtung ------------------------------------------------------- */

.stay {
    max-width: var(--measure);
    margin: 0 auto clamp(2.25rem, 6vw, 2.875rem);
    text-align: center;
}

.stay p {
    font-family: var(--font-serif);
    font-size: 1.05rem;
    line-height: 1.7;
    color: var(--ink-soft);
    text-wrap: pretty;
}

.stay p + p {
    margin-top: 1.125rem;
}

.stay strong {
    font-weight: 500;
    color: var(--ink);
}

/* Umrahmte Karte für die empfohlene Unterkunft. */
.hotel {
    max-width: 27.5rem;
    margin-inline: auto;
    padding: clamp(1.75rem, 5vw, 2.125rem) clamp(1.5rem, 5vw, 2.25rem);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    text-align: center;
}

.hotel__name {
    font-family: var(--font-serif);
    font-weight: 400;
    font-size: 1.35rem;
    color: var(--ink);
}

.hotel__desc {
    font-size: 0.875rem;
    line-height: 1.65;
    color: var(--ink-soft);
    margin-top: 1rem;
    text-wrap: pretty;
}

.hotel__note {
    font-family: var(--font-serif);
    font-style: italic;
    font-size: 0.78125rem;
    color: var(--ink-soft);
    margin-top: 1rem;
}


/* ===========================================================================
   11. Paar
   =========================================================================== */

.couple {
    position: relative;
    z-index: 1;
    display: grid;
    gap: clamp(2.25rem, 6vw, 4rem);
    align-items: center;
    max-width: 66rem;
    margin-inline: auto;
    padding: 0 var(--gutter) var(--space-section);
}

@media (min-width: 52rem) {
    .couple {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    }
}

/* Schmaler Passepartout-Rand — nimmt die Anmutung eines eingerahmten
   Abzugs auf, ohne aufdringlich zu werden.                                    */
.couple__figure {
    justify-self: center;
    width: 100%;
    max-width: 21rem;
    padding: 0.5rem;
    background-color: var(--card);
    border: 1px solid var(--line);
    box-shadow: 0 1rem 2.5rem -1rem rgba(33, 31, 28, 0.18);
}

.couple__image {
    width: 100%;
    height: auto;
}

.couple__text {
    max-width: var(--measure);
    text-align: center;
}

@media (min-width: 52rem) {
    .couple__text {
        text-align: left;
    }

    .couple__text .rule {
        margin-inline: 0;
    }
}

.couple__text p {
    font-family: var(--font-serif);
    font-style: italic;
    font-size: clamp(1.125rem, 3vw, 1.3125rem);
    line-height: 1.65;
    color: var(--ink-soft);
    margin-top: 1.5rem;
    text-wrap: pretty;
}


/* ===========================================================================
   12. E-Mail-Anmeldung
   =========================================================================== */

.signup {
    position: relative;
    z-index: 1;
    padding: var(--space-section) var(--gutter);
    background-color: var(--paper-tint);
    text-align: center;
}

.signup__inner {
    max-width: 32rem;
    margin-inline: auto;
}

.signup__heading {
    font-family: var(--font-display);
    font-weight: 400;
    letter-spacing: 0.02em;
    font-size: clamp(1.625rem, 5vw, 2.125rem);
    line-height: 1.25;
}

.signup__lead {
    font-size: 0.9375rem;
    line-height: 1.7;
    color: var(--ink-soft);
    margin-top: 1rem;
    text-wrap: pretty;
}

.signup__form {
    margin-top: 2.25rem;
}

/* Untereinander auf schmalen Bildschirmen, nebeneinander ab etwa 30rem. */
.signup__row {
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
}

@media (min-width: 30rem) {
    .signup__row {
        flex-direction: row;
    }

    /* `min-width: 0` hebt die Mindestbreite auf, die Eingabefelder von sich aus
       mitbringen — ohne sie liesse sich das Feld nicht schmaler stauchen.       */
    .signup__row .field__input {
        flex: 1 1 auto;
        min-width: 0;
    }

    .signup__row .button {
        flex: 0 0 auto;
    }
}

.signup__privacy {
    font-size: 0.75rem;
    line-height: 1.6;
    color: var(--ink-soft);
    text-align: left;
    margin-top: 1.125rem;
    opacity: 0.9;
}


/* ===========================================================================
   13. Fuss
   =========================================================================== */

.footer {
    position: relative;
    z-index: 1;
    padding: clamp(3rem, 8vw, 4.5rem) var(--gutter);

    /* Zusätzlicher Abstand über dem Home-Indikator, damit der letzte Text nicht
       unter dessen Streifen rutscht (siehe `viewport-fit=cover` im <head>).     */
    padding-bottom: calc(clamp(3rem, 8vw, 4.5rem) + env(safe-area-inset-bottom));
    text-align: center;
}

.footer__monogram {
    font-family: var(--font-display);
    font-size: 1.125rem;
    letter-spacing: 0.1em;
}

.footer__line {
    font-family: var(--font-serif);
    font-style: italic;
    font-size: 0.9375rem;
    color: var(--ink-soft);
    margin-top: 0.5rem;
}

.footer__contact {
    font-size: 0.8125rem;
    margin-top: 1rem;
}

.footer__contact a {
    color: var(--ink-soft);
    border-bottom: 1px solid var(--line);
    transition: color 0.25s var(--ease);
}

.footer__contact a:hover {
    color: var(--accent);
}


/* ===========================================================================
   14. Bewegungsanimationen
   =========================================================================== */

/* Einzug der Hero-Elemente.
   `both` als fill-mode ist hier wesentlich: Während der Verzögerung gilt der
   `from`-Zustand, das Element ist also noch unsichtbar. Weil die Deckkraft
   nirgends fest auf 0 gesetzt ist, bleibt alles sichtbar, sobald die Animation
   entfällt — etwa bei reduzierter Bewegung (siehe unten).                      */
@keyframes rise-in {
    from {
        opacity: 0;
        transform: translateY(1rem);
    }
}

@keyframes fade-in {
    from { opacity: 0; }
}

@keyframes panel-in {
    from {
        opacity: 0;
        transform: translateY(-0.5rem) scale(0.97);
    }
}

@keyframes nav-item-in {
    from {
        opacity: 0;
        transform: translateX(-0.375rem);
    }
}

.hero__eyebrow   { animation: rise-in 0.9s var(--ease) 0.15s both; }
.hero .names     { animation: rise-in 1.1s var(--ease) 0.30s both; }
.hero__label     { animation: rise-in 0.9s var(--ease) 0.50s both; }
.hero__dates     { animation: rise-in 0.9s var(--ease) 0.62s both; }
.hero__place     { animation: rise-in 0.9s var(--ease) 0.76s both; }
.hero__countdown { animation: rise-in 0.9s var(--ease) 0.90s both; }
.hero__cta       { animation: rise-in 0.9s var(--ease) 1.05s both; }
.bloom           { animation: fade-in 1.6s var(--ease) 0.25s both; }

.gate__eyebrow   { animation: rise-in 0.9s var(--ease) 0.10s both; }
.gate .names,
.gate__title     { animation: rise-in 1.1s var(--ease) 0.22s both; }
.gate__intro     { animation: rise-in 0.9s var(--ease) 0.45s both; }
.gate__form      { animation: rise-in 0.9s var(--ease) 0.58s both; }

/* Einblenden beim Scrollen.
   Greift nur, wenn JavaScript aktiv ist (`html.js` wird von assets/js/head.js
   gesetzt). Ohne JavaScript stehen die Inhalte unverändert sichtbar da.        */
.js .reveal {
    opacity: 0;
    transform: translateY(1.25rem);
    transition: opacity 0.8s var(--ease), transform 0.8s var(--ease);
}

.js .reveal.is-visible {
    opacity: 1;
    transform: none;
}

/* Wer im Betriebssystem reduzierte Bewegung eingestellt hat, bekommt die
   Inhalte ohne jede Animation — unmittelbar und vollständig sichtbar.          */
@media (prefers-reduced-motion: reduce) {

    html {
        scroll-behavior: auto;
    }

    *,
    *::before,
    *::after {
        animation: none !important;
        transition: none !important;
    }

    .js .reveal {
        opacity: 1;
        transform: none;
    }
}


/* ===========================================================================
   15. Adminbereich (adressen.php)
   ---------------------------------------------------------------------------
   Eigener Abschnitt, weil diese Ansicht nur intern zu sehen ist: Sie folgt der
   Typografie der Seite, verzichtet aber auf Blumen, Animationen und alles
   Dekorative. Was zählt, ist Lesbarkeit einer Liste.

   Bewusst keine eigene CSS-Datei: `head.php` lädt genau ein Stylesheet, und das
   soll so bleiben.
   =========================================================================== */

.admin {
    padding: var(--space-section) var(--gutter);
}

.admin__head {
    text-align: center;
    padding-bottom: 2rem;
    border-bottom: 1px solid var(--line);
}

.admin__eyebrow {
    font-size: 0.6875rem;
    letter-spacing: 0.34em;
    text-transform: uppercase;
    color: var(--ink-soft);
    margin-bottom: 1rem;
}

.admin__title {
    font-family: var(--font-display);
    font-weight: 400;
    font-size: clamp(1.5rem, 5vw, 2.125rem);
    line-height: 1.2;
}

.admin__count {
    font-family: var(--font-serif);
    font-size: 1.0625rem;
    color: var(--ink-soft);
    margin-top: 0.875rem;
}

/* Die Zahl selbst darf auffallen – sie ist der Grund, warum man die Seite
   aufruft.                                                                    */
.admin__count strong {
    font-weight: 500;
    color: var(--ink);
}

/* ---------------------------------------------------------------------------
   Tabelle

   `table-layout: fixed` mit einer schmalen zweiten Spalte: Ohne diese Angabe
   verteilt der Browser die Breite nach dem längsten Inhalt, und eine einzige
   lange Adresse drückte die Datumsspalte zusammen.
   --------------------------------------------------------------------------- */

.admin__table {
    width: 100%;
    border-collapse: collapse;
    margin-top: 2rem;
    font-family: var(--font-serif);
    font-size: 1.0625rem;
}

.admin__table th {
    font-family: var(--font-sans);
    font-weight: 400;
    font-size: 0.6875rem;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--ink-soft);
    text-align: left;
    padding-bottom: 0.75rem;
    border-bottom: 1px solid var(--line);
}

.admin__table td {
    padding-block: 0.8125rem;
    border-bottom: 1px solid var(--line);

    /* Alles in der Zeile senkrecht mittig: Adresse, Datum und Mülleimer.

       Nicht `baseline`: Daran wird die Schriftgrundlinie ausgerichtet, und der
       Mülleimer ist ein 38 px hoher Kasten ohne Text – er rutschte dadurch nach
       oben. Mittig ist auch dann richtig, wenn eine lange Adresse zweizeilig
       umbricht: Datum und Symbol stehen dann in der Mitte der beiden Zeilen.    */
    vertical-align: middle;
}

/* Lange Adressen dürfen umbrechen, statt die Tabelle zu verbreitern. */
.admin__mail {
    overflow-wrap: anywhere;
}

.admin__link {
    color: var(--ink);
    text-decoration: none;
    border-bottom: 1px solid var(--line);
}

.admin__link:hover {
    border-bottom-color: var(--ink);
}

.admin__date {
    color: var(--ink-soft);
    font-size: 0.9375rem;
    text-align: right;
    white-space: nowrap;
    padding-left: 1rem;
}

/* ---------------------------------------------------------------------------
   Entfernen

   Die Rückfrage steht in derselben Zeile wie die Adresse – so bleibt kein
   Zweifel, welcher Eintrag gemeint ist. Sie ist serverseitig gelöst und braucht
   deshalb kein JavaScript.
   --------------------------------------------------------------------------- */

.admin__tools {
    /* Nur so breit wie nötig – die Adressspalte soll den Platz bekommen. */
    width: 1%;
    padding-left: 1rem;
    text-align: right;
    white-space: nowrap;
}

/* Der Mülleimer bleibt zurückhaltend, bis der Zeiger darüber steht: Löschen ist
   nichts, das sich in den Vordergrund drängen soll.                           */
.admin__trash {
    /* Feste Grösse statt Innenabstand – und darin zentriert. Genau das Muster
       von `.field__reveal` (Augen-Schaltfläche), das sich bewährt hat.

       Der Grund ist wichtig: Die Grundregel gibt allen Grafiken
       `max-width: 100%`. Hängt die Breite des Eltern-Elements selbst vom Inhalt
       ab, ist das ein Zirkelschluss – Safari löst ihn zu 0 auf, das Symbol war
       dort nur noch ein Strich. Mit fester Grösse bezieht sich `100%` auf einen
       bekannten Wert.                                                          */
    display: grid;
    place-items: center;
    width: 2.375rem;
    height: 2.375rem;

    color: var(--ink-soft);
    opacity: 0.55;
    transition: opacity 0.2s var(--ease), color 0.2s var(--ease);
}

.admin__row:hover .admin__trash {
    opacity: 1;
}

.admin__trash:hover,
.admin__trash:focus-visible {
    opacity: 1;
    color: var(--error);
}

.admin__trash-icon {
    width: 1.5rem;
    height: 1.5rem;

    /* Hebt `max-width: 100%` aus der Grundregel auf – zweite Absicherung gegen
       das Zusammenfallen, unabhängig davon, wie der Browser die Elternbreite
       auflöst.                                                                 */
    max-width: none;
}

/* Die befragte Zeile wird hervorgehoben, damit die Rückfrage nicht übersehen
   wird.                                                                       */
.admin__row--asking {
    background-color: var(--paper-tint);
}

/* Zelle der Rückfrage: übernimmt Datums- und Werkzeugspalte (`colspan="2"`),
   das Datum entfällt in dieser Zeile. So bleibt die Adresse links einzeilig.   */
.admin__ask {
    padding-left: 1rem;
}

.admin__confirm {
    display: flex;
    align-items: center;
    justify-content: flex-end;

    /* Umbricht auf schmalen Bildschirmen, statt die Adressspalte zu verdrängen. */
    flex-wrap: wrap;
    gap: 0.625rem 0.875rem;
}

.admin__question {
    font-family: var(--font-serif);
    font-size: 0.9375rem;
    color: var(--ink-soft);
    white-space: nowrap;
}

/* Bestätigen und Abbrechen sind bewusst gleich gross und gleich ruhig: Keine
   der beiden Möglichkeiten soll den Klick an sich ziehen. Unterschieden wird
   über die Farbe, nicht über das Gewicht.                                      */
.admin__yes,
.admin__no {
    font-family: var(--font-sans);
    font-size: 0.6875rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    padding: 0.4375rem 0.75rem;
    border: 1px solid currentColor;
    border-radius: var(--radius);
    cursor: pointer;
    transition: background-color 0.2s var(--ease), color 0.2s var(--ease);
}

.admin__yes {
    color: var(--error);
    background-color: transparent;
}

.admin__yes:hover {
    color: var(--paper);
    background-color: var(--error);
}

.admin__no {
    color: var(--ink-soft);
}

.admin__no:hover {
    color: var(--ink);
}

.admin__feedback {
    /* `.feedback` ist standardmässig ausgeblendet und wird erst durch die
       Zustandsklasse sichtbar – hier ist die Meldung immer gemeint, wenn sie
       überhaupt im Markup steht.                                              */
    display: block;
    text-align: center;
    margin-top: 1.5rem;
}

/* ---------------------------------------------------------------------------
   Block zum Kopieren
   --------------------------------------------------------------------------- */

.admin__block {
    margin-top: 3rem;
}

.admin__subtitle {
    font-family: var(--font-sans);
    font-weight: 400;
    font-size: 0.6875rem;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--ink-soft);
}

.admin__hint {
    font-family: var(--font-serif);
    font-size: 1rem;
    color: var(--ink-soft);
    margin-top: 0.625rem;
}

.admin__copy {
    display: block;
    width: 100%;
    margin-top: 1rem;
    padding: 0.875rem 1rem;
    font-family: var(--font-sans);
    font-size: 0.875rem;
    line-height: 1.6;
    color: var(--ink);
    background-color: var(--paper-tint);
    border: 1px solid var(--line);
    border-radius: var(--radius);

    /* Nur senkrecht grösser ziehbar: Waagrecht würde die Spalte sprengen. */
    resize: vertical;
}

.admin__actions {
    margin-top: 2rem;
    text-align: center;
}

/* ---------------------------------------------------------------------------
   Fussbereich
   --------------------------------------------------------------------------- */

.admin__foot {
    display: flex;
    justify-content: center;

    /* Beide Schaltflächen auf eine Grundlinie: „Zur Seite“ ist ein Verweis,
       „Abmelden“ eine Schaltfläche in einem Formular. Ohne diese Zeile
       unterscheiden sich ihre Höhen, weil ein <a> und ein <button> ihre Höhe
       unterschiedlich aus Schrift und Zeilenabstand herleiten.                 */
    align-items: stretch;

    gap: 2rem;
    margin-top: 3.5rem;
    padding-top: 1.75rem;
    border-top: 1px solid var(--line);
}

/* Das Formular ist nur die Hülle um die Schaltfläche und darf keine eigene
   Höhe mitbringen.                                                            */
.admin__logout {
    display: flex;
}

/* Gleiche Kastengrösse für Verweis und Schaltfläche: Beide werden zu einem
   Flex-Kasten mit demselben Innenabstand und derselben Zeilenhöhe.            */
.admin__foot .text-button {
    display: inline-flex;
    align-items: center;
    padding: 0.25rem 0;
    line-height: 1;
}

.admin__foot .text-button:hover {
    color: var(--ink);
}

/* ---------------------------------------------------------------------------
   Schmale Liste: ohne Datumsspalte

   Die Klasse setzt `assets/js/main.js` (Baustein 6), sobald eine Adresse nicht
   mehr auf eine Zeile passt. Bewusst gemessen statt an einer Fensterbreite
   festgemacht: Wie viel Platz nötig ist, hängt an der Länge der eingetragenen
   Adressen – eine 50-stellige braucht 372 px, eine kurze 130 px. Ein fester
   Umbruchpunkt würde das Datum entweder zu früh ausblenden oder zu spät.

   Wann jemand sich eingetragen hat, ist die unwichtigste der drei Angaben; im
   CSV-Export steht sie weiterhin.

   Ohne JavaScript bleibt die Spalte sichtbar – dann brechen lange Adressen um,
   die Liste ist aber vollständig lesbar.
   --------------------------------------------------------------------------- */

.admin__table--compact .admin__date,
.admin__table--compact .admin__date-head {
    display: none;
}

/* Auf Touchgeräten eine grössere Fläche zum Antippen: 44 px ist die Grösse, die
   sich mit dem Finger zuverlässig treffen lässt. Am Rechner genügen 38 px, dort
   zielt der Zeiger genauer.                                                    */
@media (hover: none) {
    .admin__trash {
        width: 2.75rem;
        height: 2.75rem;
    }
}


/* ===========================================================================
   16. Sprachumschalter
   ---------------------------------------------------------------------------
   Zwei Kürzel nebeneinander, getrennt durch eine Haarlinie. Die aktive Sprache
   steht in Tintenfarbe und ohne Verweis, die andere zurückhaltend – so ist auf
   einen Blick erkennbar, wo man ist und wohin es geht.

   Bewusst klein und ohne Rahmen: Der Umschalter ist eine Randnotiz, nicht das
   erste, was ins Auge fällt. Auf der Hochzeitsseite sitzt er im Menü, auf der
   Passwortseite unter dem Formular.
   =========================================================================== */

.lang {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    font-family: var(--font-sans);
    font-size: 0.6875rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
}

.lang__item {
    color: var(--ink-soft);
    transition: color 0.25s var(--ease);

    /* Grosszügige Trefferfläche, ohne den Text zu verschieben: Der Abstand liegt
       innen, die Kürzel sind nur zwei Zeichen lang und wären sonst schwer zu
       treffen – besonders mit dem Finger.                                      */
    padding: 0.375rem 0.125rem;
}

.lang__item:hover {
    color: var(--ink);
}

/* Die aktuelle Sprache: kein Verweis, deshalb auch kein Zeigerwechsel. */
.lang__item--current {
    color: var(--ink);
}

/* Haarlinie zwischen den Kürzeln. Über `::before` am zweiten Element, damit sie
   nicht am Rand des Umschalters hängt und bei einer dritten Sprache von selbst
   mitwächst.                                                                   */
.lang__item + .lang__item::before {
    content: "";
    display: inline-block;
    width: 1px;
    height: 0.6875rem;
    margin-right: 0.75rem;
    vertical-align: -0.0625rem;
    background-color: var(--line);
}

/* ---------------------------------------------------------------------------
   Im Menü der Hochzeitsseite: unter der Abmelde-Schaltfläche, gleicher Einzug
   wie die Menüpunkte.
   --------------------------------------------------------------------------- */

.lang--nav {
    margin-top: 0.5rem;
    padding-left: 1.375rem;
}

/* ---------------------------------------------------------------------------
   Auf der Passwortseite: unter dem Formular, mittig.
   --------------------------------------------------------------------------- */

.lang--gate {
    justify-content: center;
    margin-top: 2rem;
}
