/* ─────────────────────────────────────────────────────────────────────────────
   Renyu · renyu.info
   Die Bildsprache der App (V3 „Calm Precision") auf dem Web. Alle Farben sind
   die echten Tokens aus Assets.xcassets/V3/ — wer hier etwas ändert, ändert es
   dort mit, sonst laufen App und Website auseinander.
   ───────────────────────────────────────────────────────────────────────────── */

@font-face {
    font-family: "Onest";
    src: url("fonts/Onest-Regular.ttf") format("truetype");
    font-weight: 400;
    font-display: swap;
}
@font-face {
    font-family: "Onest";
    src: url("fonts/Onest-Medium.ttf") format("truetype");
    font-weight: 500;
    font-display: swap;
}
@font-face {
    font-family: "Onest";
    src: url("fonts/Onest-SemiBold.ttf") format("truetype");
    font-weight: 600;
    font-display: swap;
}

:root {
    --grund: #FBF8F3;
    --flaeche: #FFFFFF;
    --tinte: #2A2620;
    --tinte-2: #6E6558;
    --tinte-3: #786F5F;
    --amber: #E09A34;
    --gruen: #4EA47C;
    --haarlinie: rgba(52, 42, 30, 0.07);
    --haarlinie-zart: rgba(52, 42, 30, 0.045);
    --spur: rgba(52, 42, 30, 0.05);
    /* Schrift auf Amber-Flächen. Amber bleibt in beiden Modi hell, deshalb bleibt
       auch die Schrift darauf dunkel — das ist kein vergessener Dunkelmodus-Wert. */
    --auf-amber: #2A2620;

    --mass: 68ch;
    --luft: clamp(1.25rem, 4vw, 2.5rem);
    --radius: 18px;
}

@media (prefers-color-scheme: dark) {
    :root {
        --grund: #161513;
        --flaeche: #23221F;
        --tinte: #F1EFEB;
        --tinte-2: #AAA499;
        --tinte-3: #989288;
        --amber: #DA8F2E;
        --gruen: #71B696;
        --haarlinie: rgba(246, 244, 240, 0.11);
        --haarlinie-zart: rgba(246, 244, 240, 0.075);
        --spur: rgba(246, 244, 240, 0.09);
    }
}

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

html {
    -webkit-text-size-adjust: 100%;
}

body {
    margin: 0;
    background: var(--grund);
    color: var(--tinte);
    font-family: "Onest", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
    font-weight: 400;
    font-size: clamp(1rem, 0.96rem + 0.2vw, 1.0625rem);
    line-height: 1.65;
    -webkit-font-smoothing: antialiased;
}

/* ── Gerüst ────────────────────────────────────────────────────────────────── */

.huelle {
    max-width: 62rem;
    margin: 0 auto;
    padding: 0 var(--luft);
}

.schmal {
    max-width: var(--mass);
}

/* ── Kopf ──────────────────────────────────────────────────────────────────── */

.kopf {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
    flex-wrap: wrap;
    padding: 1.5rem 0;
    border-bottom: 1px solid var(--haarlinie-zart);
}

.marke {
    display: inline-flex;
    align-items: center;
    gap: 0.7rem;
    text-decoration: none;
    color: inherit;
    font-weight: 600;
    font-size: 1.15rem;
    letter-spacing: -0.01em;
}

.marke img {
    width: 34px;
    height: 34px;
    border-radius: 9px;
    display: block;
}

.navigation {
    display: flex;
    gap: 0.35rem;
    flex-wrap: wrap;
    margin: 0;
    padding: 0;
    list-style: none;
}

/* 44 px ist Apples Mindestmaß für eine Fläche, die ein Daumen sicher trifft — die
   Navigation käme mit reiner Innenabstands-Rechnung auf knapp 43. */
.navigation a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0.4rem 0.85rem;
    border-radius: 999px;
    color: var(--tinte-2);
    text-decoration: none;
    font-size: 0.95rem;
    font-weight: 500;
}

.navigation a:hover,
.navigation a:focus-visible {
    background: var(--spur);
    color: var(--tinte);
}

.navigation a[aria-current="page"] {
    background: var(--spur);
    color: var(--tinte);
}

/* ── Typografie ────────────────────────────────────────────────────────────── */

h1,
h2,
h3 {
    line-height: 1.2;
    letter-spacing: -0.02em;
    text-wrap: balance;
    margin: 0 0 0.6em;
    font-weight: 600;
    /* Deutsche Komposita sprengen schmale Schirme: „Lebensmitteldatenbank" ist in
       einer 2-rem-Überschrift breiter als ein 320-px-Display und schiebt sonst die
       ganze Seite zur Seite. Greift nur, wenn ein Wort wirklich nicht passt. */
    overflow-wrap: break-word;
}

h1 {
    font-size: clamp(2rem, 1.5rem + 2.4vw, 3.1rem);
}

h2 {
    font-size: clamp(1.35rem, 1.2rem + 0.7vw, 1.7rem);
    margin-top: 2.4em;
}

h3 {
    font-size: 1.1rem;
    margin-top: 2em;
}

p {
    margin: 0 0 1.1em;
    max-width: var(--mass);
}

.vorspann {
    font-size: clamp(1.1rem, 1.02rem + 0.4vw, 1.3rem);
    color: var(--tinte-2);
    line-height: 1.55;
}

a {
    color: var(--tinte);
    text-decoration-color: var(--amber);
    text-decoration-thickness: 2px;
    text-underline-offset: 3px;
}

a:hover {
    text-decoration-color: var(--tinte);
}

:focus-visible {
    outline: 2px solid var(--amber);
    outline-offset: 3px;
    border-radius: 4px;
}

/* ── Bausteine ─────────────────────────────────────────────────────────────── */

.aufmacher {
    padding: clamp(3rem, 8vw, 6rem) 0 clamp(2rem, 5vw, 3.5rem);
}

.karte {
    background: var(--flaeche);
    border: 1px solid var(--haarlinie);
    border-radius: var(--radius);
    padding: clamp(1.25rem, 3vw, 1.9rem);
}

.karten {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
    gap: 1rem;
    margin: 2rem 0;
    padding: 0;
    list-style: none;
}

.karten h3 {
    margin: 0 0 0.4em;
    font-size: 1.05rem;
}

.karten p {
    margin: 0;
    color: var(--tinte-2);
    font-size: 0.97rem;
}

.marker {
    display: inline-block;
    padding: 0.3rem 0.7rem;
    border-radius: 999px;
    background: var(--spur);
    color: var(--tinte-2);
    font-size: 0.82rem;
    font-weight: 500;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    margin-bottom: 1.2rem;
}

.knopf {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 48px;
    padding: 0.75rem 1.5rem;
    border-radius: 999px;
    background: var(--amber);
    color: var(--auf-amber);
    font-weight: 600;
    text-decoration: none;
}

.knopf:hover,
.knopf:focus-visible {
    filter: brightness(0.96);
}

/* Rechtstexte: ein Abschnitt je Überschrift, wie in der App. */

.abschnitt {
    padding: 1.6rem 0;
    border-top: 1px solid var(--haarlinie-zart);
}

.abschnitt:first-of-type {
    border-top: 0;
}

.abschnitt h2 {
    margin-top: 0;
    font-size: 1.2rem;
}

.abschnitt p:last-child {
    margin-bottom: 0;
}

.punkt {
    padding-left: 1.1rem;
    text-indent: -1.1rem;
}

dl.angaben {
    margin: 0;
}

dl.angaben dt {
    font-weight: 600;
    margin-top: 1.4rem;
}

dl.angaben dd {
    margin: 0.3rem 0 0;
    color: var(--tinte-2);
}

.hinweis {
    color: var(--tinte-3);
    font-size: 0.92rem;
}

code {
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: 0.9em;
    background: var(--spur);
    padding: 0.15em 0.4em;
    border-radius: 5px;
    word-break: break-all;
}

/* ── Fuß ───────────────────────────────────────────────────────────────────── */

.fuss {
    margin-top: clamp(3rem, 8vw, 5rem);
    padding: 2rem 0 3rem;
    border-top: 1px solid var(--haarlinie-zart);
    color: var(--tinte-3);
    font-size: 0.92rem;
}

.fuss ul {
    display: flex;
    flex-wrap: wrap;
    gap: 0 1.4rem;
    margin: 0 0 0.6rem;
    padding: 0;
    list-style: none;
}

.fuss a {
    color: var(--tinte-2);
}

/* Auch die Fußzeilen-Links sind Ziele für einen Daumen, nicht nur Text. */
.fuss ul a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
}

/* ── Startseite ────────────────────────────────────────────────────────────────
   Die Startseite ist der einzige Ort mit eigenen Bausteinen. Alles hier baut auf
   denselben Tokens auf wie die Rechtstexte — ein Besucher soll nicht merken, dass
   er die Seite gewechselt hat.
   ───────────────────────────────────────────────────────────────────────────── */

/* Der Tagesbogen: dieselbe Kurve, nach der das Zimmer in der App sein Licht
   stellt. Kein Zierrat, sondern das Motiv der App als Kopfzeile.
   Die Beschriftung steht als echter Text daneben und nicht als <text> im SVG —
   der würde mit dem viewBox mitskalieren und auf einem Handy auf gut vier Pixel
   zusammenschrumpfen. */
.tagesbogen {
    margin: 0 0 clamp(2rem, 5vw, 3rem);
}

.bogen {
    display: block;
    width: 100%;
    height: auto;
    overflow: visible;
}

.tagesbogen figcaption {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    margin-top: 0.55rem;
    color: var(--tinte-3);
    font-size: 0.72rem;
    font-weight: 500;
    letter-spacing: 0.09em;
    text-transform: uppercase;
}

.bogen .kurve {
    fill: none;
    stroke: var(--amber);
    stroke-width: 1.5;
    opacity: 0.55;
}

.bogen .horizont {
    stroke: var(--haarlinie);
    stroke-width: 1;
}

.bogen .sonne {
    fill: var(--amber);
}

.aufmacher h1 {
    max-width: 18ch;
}

.aufmacher .vorspann {
    max-width: 46ch;
}

/* Was die App kann — bewusst Sätze statt Kennzahlen: wie viele Produkte in der
   Datenbank liegen, interessiert niemanden; dass das eigene Müsli dabei ist, schon. */
.koennen {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
    gap: 1.6rem 2.4rem;
    margin: 2.6rem 0 0;
    padding: 0;
    list-style: none;
    max-width: 52rem;
}

.koennen li {
    color: var(--tinte-2);
    font-size: 0.97rem;
    line-height: 1.55;
    padding-top: 0.9rem;
    border-top: 1px solid var(--haarlinie);
}

.koennen b {
    display: block;
    margin-bottom: 0.3rem;
    color: var(--tinte);
    font-size: 1.02rem;
    font-weight: 600;
    letter-spacing: -0.01em;
}

/* Ein Abschnitt der Startseite: großzügiger als ein Rechtstext-Abschnitt, mit
   einer Haarlinie als einzigem Trenner. */
.bahn {
    padding: clamp(2.5rem, 7vw, 4.5rem) 0;
    border-top: 1px solid var(--haarlinie-zart);
}

.bahn > h2 {
    margin-top: 0;
}

.bahn .vorspann {
    margin-bottom: 2rem;
}

/* Die vier Bereiche und die Merkmalsliste. Bewusst ohne Nummern: die Reihenfolge
   trägt keine Bedeutung, und eine erfundene Nummerierung würde eine behaupten. */
/* Fest zwei mal zwei statt auto-fit: bei 62 rem Hülle passten drei Spalten hinein,
   und die vierte Kachel stand allein in der zweiten Zeile. Vier gleichwertige
   Bereiche gehören in ein gleichmäßiges Feld. */
.saeulen {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 1px;
    margin: 2rem 0 0;
    padding: 0;
    list-style: none;
    background: var(--haarlinie);
    border: 1px solid var(--haarlinie);
    border-radius: var(--radius);
    overflow: hidden;
}

.saeulen li {
    background: var(--flaeche);
    padding: clamp(1.25rem, 3vw, 1.75rem);
}

.saeulen h3 {
    margin: 0 0 0.45em;
    font-size: 1.02rem;
}

/* Die Überschrift ist der Link zur Funktionsseite. Ohne Unterstreichung, weil vier
   unterstrichene Überschriften nebeneinander die Kacheln zerreißen — der Amber-Ton
   beim Überfahren zeigt trotzdem, dass hier etwas anklickbar ist. */
.saeulen h3 a {
    color: inherit;
    text-decoration: none;
}

.saeulen h3 a:hover,
.saeulen h3 a:focus-visible {
    color: var(--amber);
}

.saeulen p {
    margin: 0;
    color: var(--tinte-2);
    font-size: 0.95rem;
    line-height: 1.55;
}

.saeulen .zeichen {
    display: block;
    width: 22px;
    height: 22px;
    margin-bottom: 0.9rem;
    color: var(--amber);
}

/* Auf dem Handy steht ein Bereich unter dem anderen — zwei Spalten wären dort
   je knapp 160 px breit, und der Text bräche nach jedem zweiten Wort um. */
@media (max-width: 34rem) {
    .saeulen {
        grid-template-columns: 1fr;
    }
}

/* Der Kreislauf: Ziel → Gewohnheit → Tag → Messung → Ziel. Das ist der eine
   Gedanke, der Renyu von einer Sammlung von Trackern unterscheidet, deshalb
   bekommt er eine eigene Darstellung statt eines weiteren Kastens. */
.kreislauf {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr));
    gap: 1rem;
    margin: 2rem 0 0;
    padding: 0;
    list-style: none;
    counter-reset: schritt;
}

.kreislauf li {
    position: relative;
    padding-top: 1.6rem;
    border-top: 2px solid var(--amber);
    counter-increment: schritt;
}

.kreislauf li::before {
    content: counter(schritt);
    position: absolute;
    top: -0.85rem;
    left: 0;
    display: grid;
    place-items: center;
    width: 1.7rem;
    height: 1.7rem;
    border-radius: 999px;
    background: var(--amber);
    color: var(--auf-amber);
    font-size: 0.85rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.kreislauf h3 {
    margin: 0 0 0.35em;
    font-size: 1rem;
}

.kreislauf p {
    margin: 0;
    color: var(--tinte-2);
    font-size: 0.93rem;
    line-height: 1.55;
}

/* Bildschirmfotos: das Gerät gibt den Rahmen, die Bildunterschrift die Bedeutung.
   Auf schmalen Schirmen scrollt die Reihe seitlich, statt die Bilder auf
   Briefmarkengröße zu quetschen — ein Bildschirmfoto, das man nicht lesen kann,
   belegt nur Platz. */
.schau {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(13rem, 1fr);
    gap: clamp(1rem, 3vw, 1.6rem);
    margin: 2.5rem 0 0;
    padding: 0 0 0.5rem;
    list-style: none;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    overscroll-behavior-x: contain;
}

.schau > li {
    scroll-snap-align: start;
    min-width: 0;
}

.schau figure {
    margin: 0;
}

.schau img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: clamp(14px, 4vw, 26px);
    border: 1px solid var(--haarlinie);
    background: var(--flaeche);
}

.schau figcaption {
    margin-top: 0.85rem;
    color: var(--tinte-2);
    font-size: 0.92rem;
    line-height: 1.5;
}

.schau figcaption b {
    display: block;
    color: var(--tinte);
    font-weight: 600;
}

/* Die Datenschutz-Haltung. Grün statt Amber, weil sie eine Zusage ist und keine
   Handlungsaufforderung. */
.zusage {
    background: var(--flaeche);
    border: 1px solid var(--haarlinie);
    border-left: 3px solid var(--gruen);
    border-radius: var(--radius);
    padding: clamp(1.4rem, 3.5vw, 2rem);
    margin: 2rem 0 0;
}

.zusage h3 {
    margin-top: 0;
}

.zusage ul {
    margin: 1.2rem 0 0;
    padding: 0;
    list-style: none;
    display: grid;
    gap: 0.7rem;
}

.zusage li {
    padding-left: 1.7rem;
    position: relative;
    color: var(--tinte-2);
    font-size: 0.97rem;
}

.zusage li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.55em;
    width: 0.7rem;
    height: 0.35rem;
    border-left: 2px solid var(--gruen);
    border-bottom: 2px solid var(--gruen);
    transform: rotate(-45deg);
}

.aktionen {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.8rem 1.4rem;
    margin-top: 1.8rem;
}

/* Frage und Antwort auf der Hilfeseite. <details> statt eigenem Zuklapp-Code:
   ohne JavaScript, mit Tastatur bedienbar und von VoiceOver verstanden. */
.fragen {
    margin: 0.6rem 0 2.2rem;
}

/* Zwölf Fragen am Stück liest niemand. Die Gruppenüberschrift ist die einzige
   Struktur, die eine Liste aus Aufklappern verträgt — ein Kasten drumherum
   würde sie in vier Inseln zerlegen. */
.abschnitt > h3 {
    margin-top: 2.2rem;
    font-size: 0.82rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--tinte-3);
}

.fragen details {
    border-top: 1px solid var(--haarlinie-zart);
    padding: 0.2rem 0;
}

.fragen details:last-of-type {
    border-bottom: 1px solid var(--haarlinie-zart);
}

.fragen summary {
    cursor: pointer;
    padding: 1rem 2rem 1rem 0;
    font-weight: 500;
    list-style: none;
    position: relative;
}

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

.fragen summary::after {
    content: "";
    position: absolute;
    right: 0.4rem;
    top: 1.45rem;
    width: 0.55rem;
    height: 0.55rem;
    border-right: 2px solid var(--tinte-3);
    border-bottom: 2px solid var(--tinte-3);
    transform: rotate(45deg);
    transition: transform 0.18s ease;
}

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

.fragen details > *:not(summary) {
    color: var(--tinte-2);
    font-size: 0.97rem;
}

.fragen details > p:last-child {
    margin-bottom: 1.2rem;
}

/* Tabellen (Prüfsummen, Dateilisten) dürfen scrollen, die Seite nicht. */
.tabellenrahmen {
    overflow-x: auto;
    margin: 1.5rem 0;
    border: 1px solid var(--haarlinie);
    border-radius: var(--radius);
}

table {
    border-collapse: collapse;
    width: 100%;
    font-size: 0.93rem;
}

th,
td {
    text-align: left;
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--haarlinie-zart);
    vertical-align: top;
}

th {
    font-weight: 600;
    white-space: nowrap;
}

tbody tr:last-child td {
    border-bottom: 0;
}

td code {
    background: none;
    padding: 0;
    color: var(--tinte-2);
}

/* Der Download. Größe und Prüfsumme stehen am Knopf, nicht im Kleingedruckten —
   18 MB sind an einem Mobilfunkvertrag eine Information, keine Fußnote. */
.bezug {
    background: var(--flaeche);
    border: 1px solid var(--haarlinie);
    border-radius: var(--radius);
    padding: clamp(1.4rem, 3.5vw, 2rem);
    margin: 2rem 0;
}

.bezug h2 {
    margin-top: 0;
}

.bezug .knopf {
    margin-top: 0.5rem;
}

.bezug .hinweis {
    margin: 1rem 0 0;
}

pre {
    overflow-x: auto;
    background: var(--flaeche);
    border: 1px solid var(--haarlinie);
    border-radius: 12px;
    padding: 1rem 1.1rem;
    margin: 1.2rem 0;
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: 0.86rem;
    line-height: 1.6;
}

pre code {
    background: none;
    padding: 0;
    word-break: normal;
}

/* Sprungmarke für Tastatur und VoiceOver: sichtbar erst, wenn sie den Fokus hat. */
.sprung {
    position: absolute;
    left: -9999px;
    top: 0;
    padding: 0.7rem 1.1rem;
    background: var(--amber);
    color: var(--auf-amber);
    border-radius: 0 0 10px 0;
    font-weight: 600;
    text-decoration: none;
    z-index: 10;
}

.sprung:focus {
    left: 0;
}

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
    }

    /* Der Wink bleibt bedienbar, er bewegt sich nur nicht: ein Tipp stellt die
       Figur in die fertige Winkhaltung, ein zweiter zurück. Das ist dieselbe
       Lösung wie in der App (§6.5) — die Regung wird zur Haltung, nicht
       weggelassen. Der Streifen springt dafür ohne Übergang auf das Bild mit der
       erhobenen Hand, statt an ihm vorbeizulaufen.

       Der Gruß beim Laden entfällt hier ersatzlos: Er ist nicht angefordert, und
       ungefragte Bewegung ist genau das, was diese Einstellung abbestellt. */
    .winker-streifen {
        animation: none;
    }

    /* Die Hälfte des Streifens ist die Mitte des Winks — unabhängig davon, wie
       viele Bilder der nächste Export hat. */
    .winker-schalter:checked + .winker-flaeche .winker-streifen {
        animation: none;
        transform: translateX(-50%);
    }
}

/* Ein einziger Abstands-Helfer statt eines style-Attributs: Inline-Styles
   verletzen die Content-Security-Policy der Seite und werden vom Browser
   verworfen — der Abstand wäre schlicht verschwunden. */
.abstand-oben {
    margin-top: 1.5rem;
}

/* ── Der winkende Avatar ───────────────────────────────────────────────────────
   Dieselbe Figur wie in der App, und derselbe Wink: `Werkzeuge/Render/MiiRender`
   exportiert die Bildfolge aus der echten Rig-Geometrie (`MiiWaveExport`), die
   Seite blättert sie nur um. Deshalb kann die Website nicht vom Avatar der App
   abdriften — es gibt keine zweite Zeichnung.

   Das Umblättern läuft über eine Checkbox, ohne eine Zeile JavaScript. Nicht aus
   Sportsgeist: die Seite verspricht „keine fremden Server, kein Tracking" und hält
   `script-src 'none'` in ihrer Content-Security-Policy — ein Skript für den Wink
   hätte diese Zusage aufgeweicht.

   Die Bilder liegen als waagerechter Streifen nebeneinander; ein Fenster darüber
   zeigt genau eines, und der Streifen rückt in Stufen weiter. Der erste Versuch
   stapelte sie stattdessen übereinander und blendete jedes einzeln per
   `animation-delay` und `steps(1, end)` aus. Das stimmt nach Norm und läuft in
   Blink — in WebKit blieben alle Bilder auf ihrem Startwert stehen und standen
   gleichzeitig übereinander. Der Streifen braucht weder `animation-fill-mode` noch
   Verzögerungen noch eine Stufenfunktion auf einer SVG-Gruppe: eine Transformation
   auf einem HTML-Element, das Einfachste, was ein Browser bewegen kann.
   ───────────────────────────────────────────────────────────────────────────── */

.winker {
    /* Muss zur Zahl der exportierten Bilder passen; `funktionsseiten.py` bricht ab,
       wenn Streifen und Stylesheet auseinanderlaufen. 40 Bilder je Sekunde ergeben
       bei 1,15 s Wink 48 Bilder — zehn je Armschwung statt fünf. */
    --bilder: 48;
    --winkdauer: 1.15s;
    justify-self: center;
    width: min(100%, 21rem);
}

/* Die Checkbox selbst ist der Schalter, aber nichts zum Ansehen. Nicht
   `display: none` — das nähme ihr den Tastaturfokus und damit die Bedienbarkeit. */
.winker-schalter {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.winker-flaeche {
    display: block;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

/* Kein Kasten hinter der Figur, nur ein weicher Schatten unter den Füßen: ein
   gefüllter Kasten sähe aus wie ein Platzhalter, der vergessen wurde. */
.winker-buehne {
    display: block;
    position: relative;
    padding: 0 clamp(0.5rem, 2vw, 1rem);
    background: radial-gradient(34% 3.5% at 50% 96%, var(--spur), transparent 72%);
}

/* Das Guckloch: genau ein Bild breit, alles andere abgeschnitten. */
.winker-fenster {
    display: block;
    overflow: hidden;
}

/* So breit wie alle Bilder zusammen. Die Höhe stellt sich von selbst ein — sie
   folgt dem Seitenverhältnis der Grafik, statt als Zahl im Stylesheet zu stehen,
   die beim nächsten Umbau des Rigs still falsch würde.

   Die Animation steht hier und nicht erst unter `:checked`: so grüßt die Figur
   einmal, wenn die Seite geladen ist. Einmal, nicht in Schleife — ein dauernd
   winkender Avatar wäre nach zehn Sekunden ein Ärgernis, und das Auge braucht
   die Ruhe für die Überschrift daneben. */
.winker-streifen {
    display: block;
    width: calc(var(--bilder) * 100%);
    animation: wink var(--winkdauer) steps(48);
}

.winker-figur {
    display: block;
    width: 100%;
    height: auto;
}

.winker-hinweis {
    display: block;
    margin-top: 0.9rem;
    text-align: center;
    color: var(--tinte-3);
    font-size: 0.86rem;
    font-weight: 500;
}

.winker-schalter:focus-visible + .winker-flaeche .winker-buehne {
    outline: 2px solid var(--amber);
    outline-offset: 3px;
}

/* Der Wink. `steps(1, end)` hält jedes Bild seinen ganzen Schritt lang und springt
   dann weiter — ohne das Stufen-Timing würde die Deckkraft überblenden und zwei
   Armstellungen lägen gleichzeitig übereinander. */
/* Ein Sprung je Bild, sonst nichts. `steps()` haelt jedes Bild seinen ganzen
   Schritt lang und rueckt dann weiter; ohne die Stufen wuerde der Streifen
   gleitend durchlaufen und zwei Armstellungen laegen halb uebereinander.

   Kein `forwards`: laeuft der Wink aus, faellt der Streifen auf seine
   Ausgangslage zurueck — und die zeigt Bild 0, die Ruhehaltung. Die Rueckkehr
   kostet damit keine eigene Regel und kann auch nicht mit ihr auseinanderlaufen. */
@keyframes wink {
    to {
        transform: translateX(-100%);
    }
}

/* Zwei Namen für dieselbe Bewegung, und darin liegt der ganze Trick: Ein Browser
   startet eine Animation neu, wenn ihr *Name* wechselt — nicht, wenn dieselbe
   noch einmal zugewiesen wird. Mit nur einem Namen liefe der zweite Tipp ins
   Leere, weil die Animation längst abgelaufen ist. So winkt er bei jedem Tipp,
   hin wie zurück. */
@keyframes wink-erneut {
    to {
        transform: translateX(-100%);
    }
}

.winker-schalter:checked + .winker-flaeche .winker-streifen {
    animation-name: wink-erneut;
}

/* ── Funktionsseiten ─────────────────────────────────────────────────────────── */

/* Der Aufmacher der Startseite: Text links, Avatar rechts. Erst ab 50 rem, denn
   darunter stünden zwei Spalten mit je gut 20 Zeichen Zeilenlänge nebeneinander. */
.aufmacher-raster {
    display: grid;
    gap: clamp(2rem, 5vw, 3.5rem);
    align-items: center;
}

@media (min-width: 50rem) {
    .aufmacher-raster {
        grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
    }
}

/* Ein Bildschirmfoto im Geräterahmen. Der Rahmen ist bewusst nur eine Haarlinie
   und ein Radius statt einer gezeichneten iPhone-Attrappe: die Attrappe veraltet
   mit jedem Gerätejahrgang, die Kante nicht. */
.geraet {
    margin: 0;
    border-radius: clamp(20px, 5vw, 34px);
    border: 1px solid var(--haarlinie);
    background: var(--flaeche);
    overflow: hidden;
    box-shadow: 0 18px 45px -30px rgba(52, 42, 30, 0.55);
}

.geraet img {
    display: block;
    width: 100%;
    height: auto;
}

/* Die Reiter-Übersicht: eine Kachel je Seite, mit ihrem eigenen Bildschirmfoto.
   Die Kachel ist ganz ein Link — ein Ziel, das man auf dem Handy nicht verfehlt. */
.reiter {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
    gap: clamp(1rem, 2.5vw, 1.5rem);
    margin: 2.5rem 0 0;
    padding: 0;
    list-style: none;
}

.reiter > li {
    min-width: 0;
}

.reiter a {
    display: grid;
    grid-template-rows: auto 1fr;
    height: 100%;
    padding: clamp(1rem, 2.5vw, 1.4rem);
    border: 1px solid var(--haarlinie);
    border-radius: var(--radius);
    background: var(--flaeche);
    color: inherit;
    text-decoration: none;
}

.reiter a:hover,
.reiter a:focus-visible {
    border-color: var(--amber);
}

.reiter .vorschau {
    margin: 0 0 1rem;
    border-radius: 12px;
    border: 1px solid var(--haarlinie-zart);
    overflow: hidden;
    /* Nur der Kopf des Bildschirmfotos: der zeigt, worum es geht, ohne dass die
       Kachel zur Litfaßsäule wird. */
    aspect-ratio: 4 / 3;
}

.reiter .vorschau img {
    display: block;
    width: 100%;
    height: auto;
}

/* Sieben Kacheln gehen in keinem gleichmäßigen Raster auf — eine bliebe immer
   allein in der letzten Zeile stehen. Die letzte bekommt deshalb die ganze Breite
   und legt Bild und Text nebeneinander. Das ist keine Notlösung: „Avatar & Zimmer"
   ist die Startseite der App und verträgt die Betonung. */
@media (min-width: 46rem) {
    .reiter > li:last-child {
        grid-column: 1 / -1;
    }

    .reiter > li:last-child a {
        grid-template-rows: none;
        grid-template-columns: minmax(0, 13rem) minmax(0, 1fr);
        gap: clamp(1.2rem, 3vw, 2.2rem);
        align-items: center;
    }

    .reiter > li:last-child .vorschau {
        margin: 0;
        aspect-ratio: 3 / 4;
    }
}

.reiter h3 {
    margin: 0 0 0.35em;
    font-size: 1.05rem;
}

.reiter p {
    margin: 0;
    color: var(--tinte-2);
    font-size: 0.95rem;
    line-height: 1.55;
}

/* Der Kopf einer Funktionsseite: Bild und Erklärung nebeneinander, gestapelt,
   sobald die Spalten zu schmal für beides würden. */
.reiter-kopf {
    display: grid;
    gap: clamp(1.75rem, 4vw, 3rem);
    align-items: start;
    margin-top: 2.5rem;
}

@media (min-width: 48rem) {
    .reiter-kopf {
        grid-template-columns: minmax(0, 15rem) minmax(0, 1fr);
    }
}

/* Die Merkmalsliste einer Funktionsseite. Kein Kasten, nur Haarlinien — der Text
   soll sich lesen lassen wie ein Absatz, nicht wie ein Datenblatt. */
.merkmale {
    display: grid;
    gap: 1.4rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.merkmale li {
    padding-top: 1rem;
    border-top: 1px solid var(--haarlinie);
    color: var(--tinte-2);
    font-size: 0.97rem;
    line-height: 1.55;
}

.merkmale b {
    display: block;
    margin-bottom: 0.25rem;
    color: var(--tinte);
    font-size: 1.02rem;
    font-weight: 600;
    letter-spacing: -0.01em;
}

/* Brotkrume: wo bin ich, und wie komme ich eine Ebene höher. */
.krume {
    margin: 0 0 0.8rem;
    color: var(--tinte-3);
    font-size: 0.9rem;
}

.krume a {
    color: var(--tinte-2);
}

/* Weiterblättern am Fuß einer Funktionsseite — wer eine Funktion gelesen hat,
   will meistens die nächste, nicht zurück zur Übersicht und wieder hinein. */
.weiter {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 1rem;
    margin-top: clamp(2.5rem, 6vw, 4rem);
    padding-top: 1.5rem;
    border-top: 1px solid var(--haarlinie-zart);
    font-size: 0.95rem;
}

.weiter a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    color: var(--tinte-2);
}
