/*
  Erwein — gemeinsames Stylesheet für erwein.app

  Werte stammen aus dem Design-System der App, nicht aus dem Gefühl:
  Farben aus AccentColor.colorset und dem App-Icon, Radien und Abstände aus
  DesignTokens.swift (4pt-Raster, konzentrische Radien). Details im Brief
  erwein-design-brief.md.

  Bewusst ohne Framework, ohne Webfont und ohne externe Aufrufe. Dadurch setzt
  die Seite keine Cookies, lädt nichts von fremden Servern und braucht kein
  Consent-Banner. Wer hier eine Schrift oder ein Analytics-Skript einbaut, macht
  aus einer einwilligungsfreien Seite eine einwilligungspflichtige.

  Ausnahme: /user/index.html und /crew/index.html tragen ihr CSS absichtlich
  inline. Diese Seiten sind der Auffang für Universal Links und dürfen nicht von
  einer zweiten Datei abhängen. Die Farbwerte stehen dort also ein zweites und
  drittes Mal — bei einer Farbänderung alle DREI Dateien anfassen.

  Enthält am Ende einen @media-print-Block, vor allem für Impressum und
  Datenschutz: dunkle Flächen und zugeklappte Aufklapper taugen nicht auf Papier.
*/

:root {
    /* Marke. Das App-Icon folgt der hellen Akzentvariante (#A10037), deshalb
       ist die Seite magenta-crimson und nicht gold. */
    --accent: #e34a80;
    --accent-deep: #a10037;

    --bg: #120a0e;
    --surface: rgba(255, 255, 255, 0.04);
    --text: #f7eff2;
    --muted: #a8949c;
    --glass: rgba(255, 255, 255, 0.05);
    --hairline: rgba(255, 255, 255, 0.1);

    --ok: #4ba36b;
    --warn: #d98a3c;

    /* 4pt-Raster aus DS.Spacing */
    --s-xs: 4px;
    --s-s: 8px;
    --s-m: 12px;
    --s-l: 16px;
    --s-xl: 24px;
    --s-xxl: 32px;

    /* Konzentrische Radien aus DS.Radius */
    --r-chip: 12px;
    --r-nested: 20px;
    --r-card: 28px;
    --r-media: 32px;

    --measure: 68ch;
}

@supports (color: color(display-p3 1 1 1)) {
    :root {
        --accent: color(display-p3 0.855 0.318 0.478);
        --accent-deep: color(display-p3 0.631 0 0.216);
    }
}

* { box-sizing: border-box; }

html {
    scroll-behavior: smooth;

    /* PFLICHT, solange .topbar klebt. Ohne das landet jedes Sprungziel — auch
       das Ziel des Skip-Links — UNTER der Kopfleiste und ist unsichtbar.
       Der Wert ist die Leistenhöhe (32px Marke + 2 × 12px Polsterung) plus
       etwas Luft; beim Ändern von .topbar hier mitziehen. */
    scroll-padding-top: 72px;
}

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
}

body {
    margin: 0;
    min-height: 100vh;
    background: var(--bg);
    /* Zwei weiche Lichtquellen statt Flächenfarbe. */
    background-image:
        radial-gradient(ellipse 90% 40% at 50% 0%, rgba(227, 74, 128, 0.18), transparent 70%),
        radial-gradient(ellipse 70% 30% at 50% 100%, rgba(161, 0, 55, 0.12), transparent 70%);
    background-repeat: no-repeat;
    background-attachment: fixed;
    color: var(--text);
    font: 400 17px/1.6 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    -webkit-font-smoothing: antialiased;
}

/* ------------------------------------------------------------------ Struktur */

.wrap {
    width: 100%;
    max-width: 860px;
    margin: 0 auto;
    padding: 0 var(--s-l);
}

main {
    padding-bottom: var(--s-xxl);
}

section {
    margin: 0 0 var(--s-xxl);
}

/* ----------------------------------------------------- Sprachvorschlag-Leiste

   Wird von assets/lang.js eingesetzt, wenn die Browsersprache nicht zur Seite
   passt. Absichtlich eine Leiste und keine Umleitung — Begründung steht in
   lang.js. Ohne JavaScript erscheint sie nicht, was die Seite nicht schlechter
   macht als vorher.

   WARUM UNTEN UND FEST, NICHT OBEN IM FLUSS:
   Die Leiste entsteht erst, wenn das verzögerte Skript läuft — also nach dem
   ersten Bild. Stand sie im Fluss am Seitenanfang, schob sie die ganze Seite um
   ihre eigene Höhe nach unten, sichtbar als Ruck (Cumulative Layout Shift).
   `position: fixed` am unteren Rand nimmt keinen Platz im Fluss ein, also
   verschiebt sich nichts. Nebenwirkung, die auch ein Gewinn ist: das Skript
   hängt sie ans ENDE von <body>, damit steht sie nicht mehr vor dem Skip-Link
   in der Tab-Reihenfolge. */

.langhint {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 20;
    background: var(--accent-deep);
    color: #fff;
    font-size: 15px;
    /* Über dem Verlauf der Seite braucht die Leiste eine eigene Kante, sonst
       verschwimmt sie mit dem dunklen Grund darunter. */
    box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.35);
    /* Home-Indikator am iPhone nicht überdecken. */
    padding-bottom: env(safe-area-inset-bottom);
}

.langhint-inner {
    display: flex;
    flex-direction: column;
    gap: var(--s-s);
    padding-top: var(--s-m);
    padding-bottom: var(--s-m);
}

/* Hinweis links, Schließen rechts — beides in der ersten Zeile. Der Knopf
   darunter bekommt so die volle Breite für seine Mitte. */
.langhint-top {
    display: flex;
    align-items: center;
    gap: var(--s-m);
}

.langhint-top span { flex: 1; }

/* Sieht aus wie der Sprachumschalter in der Kopfleiste: gleiche Chip-Form,
   gleiche Schriftstärke. Die Weißwerte sind höher als --glass/--hairline,
   weil der Chip hier nicht auf dunklem Grund liegt, sondern auf --accent-deep;
   mit 5 % bzw. 10 % Weiß wäre auf dem Magenta nichts zu sehen. */
.langhint-cta {
    align-self: center;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    padding: 0 var(--s-l);
    background: rgba(255, 255, 255, 0.14);
    border: 1px solid rgba(255, 255, 255, 0.3);
    border-radius: var(--r-chip);
    color: #fff;
    font-size: 15px;
    font-weight: 600;
    line-height: 1.2;
    text-decoration: none;
}

.langhint-cta:hover {
    background: rgba(255, 255, 255, 0.22);
    color: #fff;
}

.langhint-close {
    background: none;
    border: 0;
    color: #fff;
    font-size: 22px;
    line-height: 1;
    cursor: pointer;
    opacity: 0.75;
    /* 44 × 44 als Trefferfläche, nicht nur das ×-Zeichen. Die negativen
       Ränder oben und unten halten die Fläche am Finger, lassen die Zeile
       aber nicht auf 44px aufgehen — die Leiste hat jetzt zwei Zeilen und
       würde sonst unnötig hoch. Der überstehende Teil liegt in der Polsterung
       der Leiste, trifft also nichts anderes. */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    padding: 0;
    margin: -8px -8px -8px 0;
    flex: none;
}

.langhint-close:hover { opacity: 1; }

/* Die feste Leiste nimmt keinen Platz im Fluss ein — das ist der Punkt, sonst
   ruckte die Seite. Kehrseite: Sie liegt über dem Seitenende und verdeckte die
   Links im Fuß. Also Platz schaffen, solange sie da ist.

   `:has()` statt einer Klasse auf <body>: Die Leiste wird von lang.js erzeugt
   und mit `remove()` wieder weggenommen; über `:has()` folgt die Polsterung dem
   von allein, ohne dass das Skript zwei Dinge gleichzeitig pflegen muss. Auf
   `section:has(.features)` verlässt sich dieses Stylesheet ohnehin schon. */
body:has(.langhint) {
    /* Zwei Zeilen (Hinweis + Knopf) plus Polsterung und Home-Indikator. Beim
       Ändern der Leistenhöhe hier mitziehen. */
    padding-bottom: 148px;
}

/* --------------------------------------------------------------- Kopfleiste */

.topbar {
    position: sticky;
    top: 0;
    z-index: 10;
    background: var(--glass);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    border-bottom: 1px solid var(--hairline);
    padding: var(--s-m) 0;
}

.topbar-inner {
    display: flex;
    align-items: center;
    gap: var(--s-l);
    flex-wrap: wrap;
}

.brand {
    display: flex;
    align-items: center;
    gap: var(--s-s);
    font-size: 19px;
    font-weight: 700;
    color: var(--text);
    text-decoration: none;
    margin-right: auto;
}

.brand img {
    width: 32px;
    height: 32px;
    display: block;
}

.nav {
    display: flex;
    gap: var(--s-l);
    flex-wrap: wrap;
}

.nav a {
    color: var(--muted);
    text-decoration: none;
    font-size: 15px;
    padding: var(--s-xs) 0;
}

.nav a:hover,
.nav a[aria-current="page"] {
    color: var(--text);
}

/* Am Finger bedient: 44 × 44 pt Mindestfläche, wie in der App. Mit der Maus
   bleibt die Leiste kompakt — dort trifft ein Zeiger auch 24px.
   `pointer: coarse` statt einer Breitenabfrage, weil es um das Eingabegerät
   geht und nicht um die Fenstergröße. */
@media (pointer: coarse) {
    .nav a {
        display: inline-flex;
        align-items: center;
        min-height: 44px;
        padding: 0;
    }

    .nav { gap: var(--s-xl); }
}

/* Sprachumschalter. Verlinkt auf die Schwesterseite in der anderen Sprache —
   kein JavaScript, keine automatische Umleitung. Automatik nach Browsersprache
   wäre möglich, würde aber geteilte Links unvorhersehbar machen: wer bewusst
   die deutsche Seite schickt, will nicht, dass sie beim Empfänger englisch
   aufgeht. */
.langswitch {
    display: inline-flex;
    align-items: center;
    gap: var(--s-xs);
    background: var(--glass);
    border: 1px solid var(--hairline);
    border-radius: var(--r-chip);
    padding: 2px;
    font-size: 13px;
    font-weight: 600;
}

.langswitch a,
.langswitch span {
    padding: var(--s-xs) var(--s-s);
    border-radius: var(--s-s);
    text-decoration: none;
    color: var(--muted);
    line-height: 1.2;
}

.langswitch a:hover { color: var(--text); }

/* Zwei Zeichen breit ist am Finger zu wenig — hier gilt dieselbe 44-pt-Regel
   wie in der Navigation darüber. */
@media (pointer: coarse) {
    .langswitch a,
    .langswitch span {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-width: 44px;
        min-height: 40px;
    }
}

/* Die aktive Sprache ist ein span, kein Link — ein Link auf die Seite, auf der
   man schon ist, ist eine Falle für Screenreader. */
.langswitch span[aria-current="true"] {
    background: var(--accent-deep);
    color: #fff;
}

/* ---------------------------------------------- Ausklappmenü (schmale Fenster)

   Am iPhone war die Kopfleiste drei Zeilen hoch: Marke, dann die umbrechende
   Navigation, dann der Sprachumschalter ganz unten links. Fünf Menüpunkte
   passen in der deutschen Fassung („Datenschutz", „Impressum") auch für sich
   allein nicht in eine Zeile — die Navigation muss also weg, nicht bloß
   umsortiert werden.

   Ab hier trägt die Kopfleiste am Telefon genau EINE Zeile: Marke links,
   Menüknopf und Sprachumschalter rechts. Der Knopf zeigt, wo man gerade ist
   („☰ Start"), damit die Leiste dieselbe Auskunft gibt wie die ausgeschriebene
   Navigation am Rechner.

   Der Knopf trägt NUR den Seitennamen — kein verstecktes „Menü:" davor. Das
   stand hier einmal für Screenreader und ist bewusst wieder raus: <summary>
   wird ohnehin als auf-/zuklappbar angesagt, und die Navigation darin trägt
   ihr eigenes aria-label.

   TECHNIK: <details>/<summary>, kein JavaScript. Damit funktioniert das Menü
   auch, wenn ein Skript scheitert oder blockiert ist, und es kostet keine
   zusätzliche Datei. Preis: ein Tipp neben das offene Menü schließt es nicht
   (nur ein zweiter Tipp auf den Knopf oder ein Klick auf einen Punkt). Das
   wäre nur mit JavaScript zu haben und war es nicht wert. */

/* Sichtbar ist die Voreinstellung, ausgeblendet die Ausnahme (siehe den
   @supports-Block weiter unten). Andersherum wäre der Knopf in jedem Browser
   weg, der die Ausnahme nicht anwenden kann — samt Navigation. */
.navmenu > summary {
    display: inline-flex;
    align-items: center;
    gap: var(--s-s);
    /* Gleiche Chip-Form wie der Sprachumschalter daneben. */
    background: var(--glass);
    border: 1px solid var(--hairline);
    border-radius: var(--r-chip);
    padding: 0 var(--s-m);
    /* Exakt so hoch wie der Sprachumschalter daneben: der setzt sich aus 2px
       Polsterung + 40px Innenhöhe + 2 × 1px Rahmen = 44px zusammen. Hier gibt
       es nur einen Rahmen, also 42 + 2 = 44. Wer eine der beiden Zahlen
       ändert, muss die andere mitziehen — sonst stehen zwei fast gleich hohe
       Chips nebeneinander, und „fast" sieht man. */
    min-height: 42px;
    color: var(--text);
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
    /* Das Dreieck der Voreinstellung ersetzt das eigene Symbol unten. */
    list-style: none;
}

.navmenu > summary::-webkit-details-marker { display: none; }

/* Menüsymbol aus drei Verläufen statt aus einer Grafik: kein zweiter Abruf,
   nimmt die Textfarbe an und skaliert mit der Schriftgröße nicht mit — bei
   16 × 11 px ist das gewollt, das Symbol soll neben dem Wort ruhig stehen. */
.navmenu > summary::before {
    content: "";
    flex: none;
    width: 16px;
    height: 11px;
    background-image:
        linear-gradient(currentColor, currentColor),
        linear-gradient(currentColor, currentColor),
        linear-gradient(currentColor, currentColor);
    background-size: 100% 1.5px;
    background-position: left top, left center, left bottom;
    background-repeat: no-repeat;
}

@media (max-width: 720px) {
    /* Eine Zeile, und zwar wirklich: ohne `nowrap` würde die Leiste beim
       kleinsten Platzmangel wieder umbrechen, statt den Menüknopf schmaler
       werden zu lassen. Der kleinere Abstand kauft die 16px, die auf einem
       375-pt-Gerät zwischen „Datenschutz" und einer zweiten Zeile stehen. */
    .topbar-inner {
        flex-wrap: nowrap;
        gap: var(--s-s);
    }

    /* Marke und Umschalter behalten ihre Größe, gekürzt wird nur der
       Menüknopf — „Erwe…" wäre ein schlechter Tausch für „Datenschu…". */
    .brand,
    .langswitch { flex: none; }

    .navmenu {
        /* Anker für die aufgeklappte Liste. */
        position: relative;
        min-width: 0;
    }

    .navmenu > summary { min-width: 0; }

    .navmenu-label {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    /* Rechts ausgerichtet, nicht links: der Knopf sitzt in der rechten Hälfte
       der Leiste, eine nach rechts geöffnete Liste liefe aus dem Bild. */
    .navmenu > .nav {
        position: absolute;
        top: calc(100% + var(--s-s));
        right: 0;
        z-index: 30;
        flex-direction: column;
        gap: 0;
        min-width: 200px;
        padding: var(--s-s);
        background: var(--bg);
        border: 1px solid var(--hairline);
        border-radius: var(--r-nested);
        box-shadow: 0 16px 40px rgba(0, 0, 0, 0.5);
    }

    .navmenu > .nav a {
        display: flex;
        align-items: center;
        min-height: 44px;
        padding: 0 var(--s-m);
        border-radius: var(--s-s);
    }

    .navmenu > .nav a[aria-current="page"] {
        background: var(--glass);
    }
}

/* Am Rechner gibt es keinen Knopf: die Navigation steht ausgeschrieben in der
   Leiste, wie bisher.

   `@supports selector(::details-content)` ist hier keine Vorsicht um ihrer
   selbst willen, sondern der Notausgang: Ein Browser, der die Auszeichnung
   nicht kennt, überspringt den ganzen Block und behält damit den Menüknopf —
   statt eine Navigation zu zeigen, die zugeklappt ist und deren Knopf wir
   gerade ausgeblendet haben. */
@supports selector(::details-content) {
    @media (min-width: 721px) {
        .navmenu > summary { display: none; }

        .navmenu::details-content {
            content-visibility: visible;
            block-size: auto;
        }
    }
}

/* ------------------------------------------------------------------ Typo */

h1, h2, h3 {
    line-height: 1.25;
    text-wrap: balance;
    margin: 0 0 var(--s-m);
}

h1 { font-size: clamp(32px, 6vw, 46px); font-weight: 700; letter-spacing: -0.01em; }
h2 { font-size: clamp(24px, 4vw, 30px); font-weight: 700; margin-top: var(--s-xxl); }
h3 { font-size: 19px; font-weight: 600; margin-top: var(--s-xl); }

p, ul, ol, dl {
    max-width: var(--measure);
    margin: 0 0 var(--s-l);
}

/* Verhindert einzelne Wörter in der letzten Zeile. Lohnt bei deutschem Text
   besonders, weil die Wörter lang sind und in schmalen Kartenspalten sonst
   gern allein unten stehen. Browser ohne Unterstützung ignorieren die Zeile. */
p, li { text-wrap: pretty; }

ul, ol { padding-left: var(--s-xl); }
li { margin-bottom: var(--s-s); }

.lead {
    font-size: clamp(18px, 2.6vw, 21px);
    color: var(--text);
}

.muted { color: var(--muted); }

small { font-size: 14px; color: var(--muted); }

a { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }
a:hover { color: var(--text); }

code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.92em;
    background: var(--glass);
    padding: 2px 6px;
    border-radius: var(--s-xs);
}

/* ------------------------------------------------------------------ Held */

.hero {
    text-align: center;
    padding: var(--s-xxl) 0;
}

.hero img.app-icon {
    width: 104px;
    height: 104px;
    display: block;
    margin: 0 auto var(--s-xl);
    /* Das Icon bringt Squircle und Hintergrund mit — kein Container drumherum,
       nur ein farbiger Schatten zum Abheben. */
    filter: drop-shadow(0 14px 34px rgba(161, 0, 55, 0.45));
}

.hero p { margin-left: auto; margin-right: auto; }

/* --------------------------------------------------------------- Flächen */

/* Tonale Inhaltsfläche — kein Rahmen, nur eine Stufe heller als der Grund.
   Entspricht tonalCard() in der App. */
.card {
    background: var(--surface);
    border-radius: var(--r-card);
    padding: var(--s-xl);
    margin-bottom: var(--s-l);
}

.card h3 { margin-top: 0; }
.card > :last-child { margin-bottom: 0; }

.features {
    display: grid;
    gap: var(--s-l);
    /* `min(260px, 100%)` statt nur `260px`: auf sehr schmalen Bildschirmen darf
       die Spalte unter 260px fallen, statt aus dem Viewport zu laufen. */
    grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
    /* Karten hören da auf, wo ihr Text aufhört. Ohne das streckt das Raster
       jede Karte auf die Höhe der längsten in ihrer Reihe, und unter den kurzen
       stehen große Leerflächen. */
    align-items: start;
}

.features .card {
    margin-bottom: 0;
    position: relative;
    isolation: isolate;
    /* Etwas engere Zeilen als im Fließtext: in einer schmalen Spalte wirken
       1.6 bei 17px zerrissen, weil deutsche Wörter lang sind. */
    font-size: 16px;
    line-height: 1.55;

    /* DIESE ZWEI ZEILEN NICHT ENTFERNEN.

       Rasterelemente haben eine automatische Mindestbreite in Höhe ihres
       min-content. Ein Foto mit 900px natürlicher Breite zieht die Spalte damit
       auf 900px auf — die Karten wurden dreimal zu breit und liefen ineinander.
       `min-width: 0` schaltet diese Automatik ab, sodass die Spalte die Breite
       bestimmt und nicht das Bild.

       `overflow: hidden` ist der Gürtel zum Hosenträger: Selbst wenn ein Bild
       einmal breiter gerät, wird es an der Kartenkante beschnitten statt über
       sie hinauszulaufen — und die Rundung der Karte schneidet es gleich mit. */
    min-width: 0;
    overflow: hidden;
}

/* Jede Karte trägt ihre Kategoriefarbe als --tint (im HTML gesetzt) und bekommt
   davon einen weichen Schein aus der oberen linken Ecke. Das bindet die Palette
   der App ein, ohne die Flächen einzufärben. */
.features .card {
    background:
        /* Schein aus der UNTEREN linken Ecke, nicht der oberen: oben sitzt bei
           Karten mit Foto das Bild und würde ihn verdecken. */
        radial-gradient(110% 85% at 0% 100%,
            color-mix(in srgb, var(--tint, var(--accent)) 16%, transparent),
            transparent 62%),
        var(--surface);
}

/* Randloses Foto als Kartenkopf — "full bleed", wie Medien in der App.
   Die negativen Ränder heben die Polsterung der Karte genau auf, damit das Bild
   bis an die Kante läuft; die oberen Ecken übernehmen den Kartenradius, die
   unteren bleiben gerade, weil dort der Text anschließt.

   ACHTUNG Reihenfolge beim Hochladen: Erst die Bilder nach /img/, dann die
   HTML-Seiten. Fehlt eine Datei, zeigt der Browser ein kaputtes Bildsymbol. */
.card-media {
    display: block;
    /* Die Polsterung der Karte auf beiden Seiten aufheben, damit das Bild bis an
       die Kante läuft. `max-width` muss mit, sonst greift eine allgemeine
       `max-width: 100%`-Regel und das Bild bleibt schmaler als gewollt. */
    width: calc(100% + 2 * var(--s-xl));
    max-width: calc(100% + 2 * var(--s-xl));
    margin: calc(-1 * var(--s-xl)) calc(-1 * var(--s-xl)) var(--s-l);
    /* `height: auto` IST PFLICHT, NICHT KOSMETIK.

       Die Bilder tragen `width="900" height="600"` als HTML-Attribute, und
       Browser übersetzen die in CSS-Eigenschaften. Ohne `height: auto` stehen
       damit BEIDE Maße fest — und wenn Breite und Höhe definiert sind, wird
       `aspect-ratio` ignoriert. Das Foto wurde dann 265 breit und 600 hoch,
       also hochkant.

       Die Attribute im HTML sind trotzdem richtig und sollen bleiben: Sie
       verhindern, dass das Layout beim Nachladen springt. */
    height: auto;

    /* Anzeigeverhältnis, unabhängig davon, was die Datei mitbringt —
       `object-fit: cover` beschneidet den Rest. Deshalb funktioniert auch das
       quadratische drink@512x512 an dieser Stelle.

       Flacher gewünscht? Eine Zeile: `16 / 9` oder `2 / 1`. Bei 265px
       Kartenbreite ergibt 3/2 rund 177px Höhe, 16/9 etwa 149px, 2/1 etwa 133px. */
    aspect-ratio: 3 / 2;
    object-fit: cover;
    border-radius: var(--r-card) var(--r-card) 0 0;
    /* Fläche für die Zeit vor dem Laden, in der Kategoriefarbe angedeutet. */
    background: color-mix(in srgb, var(--tint, var(--accent)) 12%, var(--surface));
    /* Farbige Linie unter dem Foto: bindet das Bild an seine Kategorie, ohne
       das Foto selbst einzufärben. */
    border-bottom: 2px solid color-mix(in srgb, var(--tint, var(--accent)) 60%, transparent);
}

/* Lichtkante oben links, wie sie eine Glasfläche im Streiflicht hätte. Als
   Maske gezeichnet, damit nur der Rand leuchtet und nicht die Fläche. */
.features .card::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    padding: 1px;
    background: linear-gradient(150deg,
        rgba(255, 255, 255, 0.16),
        rgba(255, 255, 255, 0.02) 45%,
        transparent 70%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    pointer-events: none;
}

/* Farbige Lichtflecken hinter dem Kartenraster. Sie sind der Grund, warum das
   Glas unten überhaupt wirkt: ohne etwas Buntes dahinter hat backdrop-filter
   nichts zu verwischen und Glas sieht aus wie eine hellere Box. Die Farben
   stammen aus den Getränkekategorien der App. */
section:has(.features) {
    position: relative;
}

section:has(.features)::before {
    content: "";
    position: absolute;
    inset: -8% -15%;
    z-index: -1;
    background:
        radial-gradient(28% 38% at 12% 25%, rgba(140, 26, 46, 0.30), transparent 70%),
        radial-gradient(26% 34% at 88% 20%, rgba(117, 56, 158, 0.26), transparent 70%),
        radial-gradient(30% 36% at 45% 95%, rgba(0, 140, 148, 0.20), transparent 70%),
        radial-gradient(22% 30% at 70% 65%, rgba(235, 161, 33, 0.16), transparent 70%);
    filter: blur(48px);
    pointer-events: none;
}

/* Erst wenn der Browser Glas kann, wird aus der tonalen Fläche echtes Material.
   Ohne Unterstützung bleibt es bei der Abstufung von oben — die Seite sieht
   dann ruhiger aus, aber nie kaputt. */
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .features .card {
        background:
            radial-gradient(130% 90% at 0% 0%,
                color-mix(in srgb, var(--tint, var(--accent)) 18%, transparent),
                transparent 62%),
            rgba(255, 255, 255, 0.06);
        -webkit-backdrop-filter: blur(24px) saturate(150%);
        backdrop-filter: blur(24px) saturate(150%);
    }
}

/* Farbiger Akzentpunkt je Funktionsblock, gespeist aus den Kategoriefarben
   der App (DrinksCategory.swift). Mit Schein, sonst liest er sich als Fussel. */
.dot {
    display: inline-block;
    width: 11px;
    height: 11px;
    border-radius: 50%;
    margin-right: var(--s-s);
    vertical-align: 1px;
    /* Farbe kommt von der Karte (--tint), damit Punkt, Eckenschein und
       Lichtkante garantiert dieselbe sind und nicht auseinanderlaufen. */
    background: var(--tint, var(--accent));
    color: var(--tint, var(--accent));
    box-shadow: 0 0 10px 1px currentColor;
}

/* ------------------------------------------------- Getränkekategorie-Chips

   Die neun Kategorien der App mit ihren echten Farben (DrinksCategory.swift:38,
   im Brief unter „Getränkekategorien"). Zwei Aufgaben: der Seite Farbe geben,
   ohne ein weiteres Stockfoto zu brauchen, und sichtbar machen, dass es nicht
   nur um Alkohol geht — genau die Frage, die in der FAQ steht.

   Neun seit dem Katalog-Umbau im September 2026: „Energy" ist zu „Andere"
   geworden, Tee ist eine eigene Kategorie. Die Liste selbst steht im HTML
   beider Startseiten, hier steht nur ihre Begründung.

   Jeder Chip trägt seine Farbe im HTML als --cat. Die Farbe ist NICHT die
   Chipfläche: eingefärbte Flächen mit Text darauf wären bei neun verschiedenen
   Tönen nicht durchgängig kontraststark. Stattdessen ein farbiger Punkt plus
   ein Hauch der Farbe im Grund — dieselbe Regel wie in der App, wo Farbe
   Zuordnung markiert und keine Fläche füllt. */

.cat-chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-s);
    list-style: none;
    padding: 0;
    margin: 0 0 var(--s-l);
    max-width: none;
}

.cat-chips li {
    display: inline-flex;
    align-items: center;
    gap: var(--s-s);
    min-height: 36px;
    padding: 0 var(--s-l) 0 var(--s-m);
    border-radius: var(--r-chip);
    font-size: 15px;
    font-weight: 600;
    margin-bottom: 0;
    background:
        linear-gradient(color-mix(in srgb, var(--cat) 14%, transparent),
                        color-mix(in srgb, var(--cat) 14%, transparent)),
        var(--surface);
    border: 1px solid color-mix(in srgb, var(--cat) 35%, transparent);
}

.cat-chips li::before {
    content: "";
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--cat);
    box-shadow: 0 0 8px 1px var(--cat);
    flex: 0 0 auto;
}

/* -------------------------------------------------------------- Aktionen */

/* Wird sowohl als <a> als auch als <button> verwendet — der Held trägt einen
   deaktivierten Knopf, solange es keine App-Store-Adresse gibt, und das
   Kontaktformular einen Absendeknopf. Deshalb müssen hier die Voreinstellungen
   des Browsers für <button> mit abgeräumt werden: `font-family: inherit`, sonst
   setzt Safari eine eigene Schrift, und `line-height`, sonst ist der Knopf
   einen Hauch flacher als der Link daneben. */
.cta {
    display: inline-block;
    background: linear-gradient(160deg, var(--accent), var(--accent-deep));
    color: #fff;
    font-family: inherit;
    font-size: 17px;
    font-weight: 600;
    line-height: 1.4;
    text-align: center;
    text-decoration: none;
    padding: var(--s-l) var(--s-xl);
    border-radius: var(--r-chip);
    border: 0;
    cursor: pointer;
    transition: opacity 0.15s ease, transform 0.15s ease;
}

.cta:hover { opacity: 0.9; color: #fff; }
.cta:active { transform: scale(0.99); }

.cta[aria-disabled="true"],
.cta:disabled {
    background: var(--glass);
    border: 1px solid var(--hairline);
    color: var(--muted);
    pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
    .cta { transition: none; }
}

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

/* FAQ-Aufklapper. Bekommen dieselbe Lichtkante wie die Funktionskarten, aber
   kein echtes Glas: Hinter der FAQ-Liste liegt nichts Buntes, das sich zu
   verwischen lohnt, und zwanzig Flächen mit backdrop-filter kosten beim Scrollen
   spürbar Leistung. Material dort, wo es etwas zu spiegeln gibt — Kanten
   überall.

   `:not(.navmenu)` in jedem Selektor dieses Abschnitts: Das Ausklappmenü der
   Kopfleiste ist ebenfalls ein <details> und soll KEINE Karte werden — weder
   Fläche noch Lichtkante noch Aufklappwinkel. Wer hier eine Regel ergänzt,
   muss die Ausnahme mitnehmen. */
details:not(.navmenu) {
    background: var(--surface);
    border-radius: var(--r-nested);
    padding: var(--s-l) var(--s-xl);
    margin-bottom: var(--s-m);
    position: relative;
    isolation: isolate;
}

details:not(.navmenu)::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    padding: 1px;
    background: linear-gradient(150deg,
        rgba(255, 255, 255, 0.12),
        rgba(255, 255, 255, 0.02) 40%,
        transparent 65%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    pointer-events: none;
}

/* Sprungziel: Jede Frage trägt eine id, damit man sie einzeln verlinken kann
   („steht in der FAQ unter …"). Das scroll-padding-top von <html> sorgt dafür,
   dass das Ziel nicht unter der Kopfleiste landet. */
details:not(.navmenu):target {
    outline: 2px solid var(--accent);
    outline-offset: 4px;
}

/* Flex statt `float: right` für das Aufklappzeichen. Bei einer zweizeiligen
   deutschen Frage rutschte der gefloatete Glyph in die letzte Zeile hinein;
   im Flex-Layout bleibt er oben rechts und die Frage umbricht daneben. */
details:not(.navmenu) > summary {
    cursor: pointer;
    font-weight: 600;
    list-style: none;
    display: flex;
    align-items: flex-start;
    gap: var(--s-m);
    /* Am Finger bedienbar, ohne die Zeile optisch aufzublasen. */
    min-height: 32px;
}

details:not(.navmenu) > summary::-webkit-details-marker { display: none; }

/* Winkel aus zwei Rändern gezeichnet statt als Textzeichen: dreht sich beim
   Aufklappen, statt zwischen + und – zu springen, und sitzt auf jeder
   Schriftgröße gleich. */
details:not(.navmenu) > summary::after {
    content: "";
    flex: 0 0 auto;
    width: 8px;
    height: 8px;
    margin-left: auto;
    /* Auf die erste Textzeile ausgerichtet, nicht auf die Blockmitte. */
    margin-top: 7px;
    border-right: 2px solid var(--muted);
    border-bottom: 2px solid var(--muted);
    transform: rotate(45deg);
    transition: transform 0.2s ease;
}

details:not(.navmenu)[open] > summary::after { transform: rotate(-135deg); }

details:not(.navmenu) > summary:hover::after { border-color: var(--text); }

/* Am Finger dieselbe 44-pt-Regel wie in der Navigation. Bewusst über Polsterung
   und nicht über `min-height`: Bei einer einzeiligen Frage wüchse die Zeile
   sonst nach unten und der Text klebte oben in einem halbleeren Kasten. Die
   Polsterung lässt ihn mittig stehen, und mehrzeilige Fragen wachsen weiter von
   selbst — `align-items: flex-start` bleibt also richtig. */
@media (pointer: coarse) {
    details:not(.navmenu) > summary { padding: 9px 0; }
}

@media (prefers-reduced-motion: reduce) {
    details:not(.navmenu) > summary::after { transition: none; }
}

details:not(.navmenu) > summary + * { margin-top: var(--s-m); }
details:not(.navmenu) > :last-child { margin-bottom: 0; }

/* Inhaltsverzeichnis der FAQ. Bei knapp zwanzig Fragen ist Scrollen keine
   Navigation — die Liste bringt einen ganzen Abschnitt in Reichweite eines
   Klicks. Bewusst nur die Abschnitte, nicht jede einzelne Frage: sonst wäre
   das Verzeichnis so lang wie die Seite. */
.faq-toc {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-s);
    list-style: none;
    padding: 0;
    margin: 0 0 var(--s-xl);
    max-width: none;
}

.faq-toc a {
    display: inline-flex;
    align-items: center;
    min-height: 40px;
    padding: 0 var(--s-l);
    background: var(--glass);
    border: 1px solid var(--hairline);
    border-radius: var(--r-chip);
    color: var(--text);
    text-decoration: none;
    font-size: 15px;
    font-weight: 600;
}

.faq-toc a:hover {
    background: var(--surface);
    border-color: var(--accent);
}

.faq-toc li { margin-bottom: 0; }

/* --------------------------------------------------------------- Formular */

form { max-width: var(--measure); }

.field { margin-bottom: var(--s-l); }

label {
    display: block;
    font-size: 15px;
    font-weight: 600;
    margin-bottom: var(--s-s);
}

input[type="text"],
input[type="email"],
select,
textarea {
    width: 100%;
    background: var(--glass);
    border: 1px solid var(--hairline);
    border-radius: var(--r-chip);
    color: var(--text);
    font: inherit;
    padding: var(--s-m) var(--s-l);
}

textarea { min-height: 160px; resize: vertical; }

input:focus-visible,
select:focus-visible,
textarea:focus-visible,
a:focus-visible,
button:focus-visible,
summary:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* Honeypot — für Menschen unsichtbar, für einfache Bots ein Pflichtfeld.
   Nicht display:none, das erkennen manche Bots. */
.hp {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

.notice {
    border-radius: var(--r-nested);
    padding: var(--s-l) var(--s-xl);
    margin-bottom: var(--s-xl);
    border-left: 3px solid var(--muted);
    background: var(--surface);
}

.notice.ok { border-left-color: var(--ok); }
.notice.warn { border-left-color: var(--warn); }
.notice > :last-child { margin-bottom: 0; }

/* Die Rückmeldungen des Formulars tragen ein h2, weil sie auf der Seite vor dem
   ersten Abschnitt stehen — ein h3 dort wäre ein übersprungener Rang, und wer
   per Überschrift navigiert, stolpert darüber.

   Rang ist Semantik, Größe ist Gestaltung: Der Rang bleibt h2, die Größe kommt
   hier auf das Maß eines kleinen Titels zurück. Ohne diese Regel stünde ein
   30-px-Titel in einem schmalen Hinweiskasten. */
.notice h2 {
    font-size: 19px;
    font-weight: 600;
    margin-top: 0;
    margin-bottom: var(--s-s);
}

/* Für Platzhalter in Impressum und Datenschutz, die noch gefüllt werden müssen. */
.todo {
    background: rgba(217, 138, 60, 0.12);
    border-left: 3px solid var(--warn);
    border-radius: var(--r-chip);
    padding: var(--s-m) var(--s-l);
    margin-bottom: var(--s-l);
    font-size: 15px;
}

/* ------------------------------------------------------------------ Fuß */

footer {
    border-top: 1px solid var(--hairline);
    margin-top: var(--s-xxl);
    padding: var(--s-xl) 0 var(--s-xxl);
    color: var(--muted);
    font-size: 15px;
}

footer .nav { margin-bottom: var(--s-m); }

/* ------------------------------------------------------- Barrierefreiheit */

.skip {
    position: absolute;
    left: -9999px;
}

.skip:focus {
    left: var(--s-l);
    top: var(--s-l);
    z-index: 100;
    background: var(--bg);
    padding: var(--s-m) var(--s-l);
    border-radius: var(--r-chip);
}


table {
    width: 100%;
    border-collapse: collapse;
    margin-bottom: var(--s-l);
    font-size: 16px;
}

th, td {
    text-align: left;
    padding: var(--s-m);
    border-bottom: 1px solid var(--hairline);
    vertical-align: top;
}

th { font-weight: 600; }

/* ------------------------------------------------------------------ Druck

   Impressum und Datenschutzerklärung werden gesichert und ausgedruckt — das
   sind die beiden Seiten, bei denen jemand ein Papier oder PDF haben will.
   Ungebremst wäre das eine schwarze Seite voll Farbe, und die Aufklapper der
   FAQ wären zugeklappt, also leer.

   Deshalb hier: auf Weiß drehen, Bedienelemente weglassen, alles ausklappen.
   Die Marken-Verläufe entfallen bewusst; auf Papier trägt Farbe nichts. */

@media print {
    /* Verläufe und Lichtquellen abschalten. `!important` ist hier richtig:
       Diese Regeln müssen die Farbwerte aus dem Bildschirm-Stylesheet
       überschreiben, auch die aus @supports-Blöcken. */
    body {
        background: #fff !important;
        background-image: none !important;
        color: #000 !important;
        font-size: 11pt;
    }

    .card,
    details,
    .notice,
    .todo,
    .cat-chips li {
        background: #fff !important;
        backdrop-filter: none !important;
        -webkit-backdrop-filter: none !important;
        border: 1px solid #999 !important;
        border-radius: 4px;
        /* Einen Rechtsabschnitt nicht über den Seitenumbruch reißen. */
        break-inside: avoid;
    }

    .features .card::before,
    details::after,
    section:has(.features)::before {
        display: none !important;
    }

    /* Was auf Papier keine Funktion hat. */
    .topbar,
    .langhint,
    .langswitch,
    .skip,
    .cta,
    form,
    footer .nav,
    .faq-toc,
    .card-media {
        display: none !important;
    }

    /* Aufklapper offen drucken — zugeklappt wäre eine ausgedruckte FAQ leer.
       Zwei Wege, weil Browser das Verbergen unterschiedlich lösen:

       `::details-content` ist der aktuelle Weg. Der Inhalt eines zugeklappten
       <details> steckt dort und wird mit `content-visibility: hidden`
       versteckt — nur das lässt sich per CSS wieder aufmachen.

       Die Regel darunter ist der Rückfall für ältere Browser, die den Inhalt
       noch über `display: none` auf den Kindern verbergen. Sie allein genügt
       NICHT mehr; wer sie für ausreichend hält, druckt leere Kästen. */
    details::details-content {
        content-visibility: visible !important;
        display: block !important;
    }

    details > summary { list-style: none; }
    details > summary::after { display: none; }

    details > :not(summary) { display: block !important; }

    a {
        color: #000 !important;
        text-decoration: underline;
    }

    /* Ziel eines Links steht auf Papier nicht in der Statuszeile. Nur echte
       Adressen ausschreiben, nicht die Sprungmarken innerhalb der Seite. */
    main a[href^="http"]::after,
    main a[href^="mailto"]::after {
        content: " (" attr(href) ")";
        font-size: 9pt;
        word-break: break-all;
    }

    h1, h2, h3 { break-after: avoid; }
    p, li { orphans: 2; widows: 2; }
}
