/*
 * Die einfache Oberfläche — Liquid Glass.
 *
 * Regeln in DESIGN-EINFACH.md, Teil 1.
 *
 * Zwei Breiten sind gemeint:
 *   Laptop, ganz   1280–1600px   Seitenleiste links
 *   Laptop, halb    640– 960px   Leiste unten
 * Die Grenze liegt bei 900px: 1920 halbiert gibt 960, 1366 halbiert 683.
 *
 * ---------------------------------------------------------------------
 * Zum Glas, in drei Schichten — und was davon wo ankommt:
 *
 *   1. GRUND        Der Hintergrund muss Farbe haben, sonst ist Glas
 *                   nicht von Milchglas zu unterscheiden. Vier Verläufe
 *                   aus verschiedenen Richtungen, sehr blass.
 *   2. MATERIAL     backdrop-filter mit blur + saturate, dazu ein
 *                   heller Rand oben (specular). Das trägt den Eindruck.
 *                   Läuft überall.
 *   3. BRECHUNG     Ein SVG-Verzerrungsfilter (feTurbulence +
 *                   feDisplacementMap) als backdrop-filter. Das ist der
 *                   Effekt aus den Reels: Der Untergrund wird wirklich
 *                   verbogen, nicht nur weichgezeichnet.
 *
 * Schicht 3 ist ausdrücklich eine ZUGABE. `backdrop-filter: url(#…)`
 * ist noch nicht überall zu Hause — deshalb steht sie hinter einem
 * @supports und die Oberfläche sieht ohne sie vollständig aus.
 *
 * Und: Glas kommt an die Ränder (Leiste, Blatt, Streifen), nicht unter
 * langen Text. Was gelesen wird, steht auf fast deckendem Grund. Sonst
 * sieht es gut aus und liest sich schlecht.
 */

/* ============================================================== Größen */

:root {
    color-scheme: light dark;

    /*
     * E-08: Die Schrift des Systems. SF Pro lässt sich nicht
     * ausliefern — auf einem Mac wird es SF, auf Windows Segoe UI
     * Variable, auf Android Roboto. Apple-artig, nicht identisch.
     */
    --font: -apple-system, BlinkMacSystemFont, "SF Pro Text",
            "Segoe UI Variable Text", "Segoe UI", system-ui,
            Roboto, Helvetica, Arial, sans-serif;

    /* E-10: Basisgröße 17, nicht 13. Sarah liest, sie scannt nicht. */
    --t-large:    34px;
    --t-title:    22px;
    --t-headline: 17px;
    --t-body:     17px;
    --t-subhead:  15px;
    --t-footnote: 13px;

    /* E-11: 4er-Raster */
    --s1: 4px;  --s2: 8px;  --s3: 12px;
    --s4: 16px; --s5: 20px; --s6: 32px;

    /*
     * Ecken.
     *
     * Bedienelemente sind Kapseln — dieselbe Form wie der Umschalter,
     * die Auswahlkapseln und das Bild. Vorher war der Knopf 14px rund
     * und stand neben lauter Kapseln: ein Radius zu viel im System.
     *
     * Flächen behalten echte Radien: Eine Karte als Kapsel wäre albern.
     */
    --r-kapsel:  999px;
    --r-control: 14px;   /* Eingabefelder, mehrzeilig */
    --r-card:    20px;
    --r-sheet:   28px;

    /*
     * Höhen. Alles, was nebeneinander steht, ist gleich hoch — sonst
     * sieht eine Zeile aus, als wäre sie schiefgelaufen.
     *
     * Und zwar 44px, nicht 40: E-14 verlangt Berührungsziele von
     * mindestens 44px. Ein eigener kleinerer Wert wäre eine still
     * gebrochene eigene Regel gewesen.
     *
     * (Die Reihenfolge der Zeilen hier ist egal — CSS löst Variablen
     * bei der Benutzung auf, nicht beim Deklarieren.)
     */
    --h-control: var(--touch);

    --content: 700px;
    --sidebar: 232px;
    --touch: 44px;

    /*
     * Der untere Rand am Telefon — EINE Rechnung.
     *
     * Vorher standen hier drei: Die Leiste sass bei `s3`, ihre Hoehe
     * ergab sich aus Polster und Reiterhoehe, und der schwebende Knopf
     * rechnete voellig eigenstaendig `touch + s6`. Zufaellig kam
     * dasselbe heraus — 72 gegen 76 Pixel. Vier Pixel Abstand, und der
     * Schein des Knopfs lief ueber die Leiste.
     *
     * Solche Zahlen driften auseinander, sobald jemand eine davon
     * anfasst. Jetzt leiten sich alle aus derselben ab.
     */
    --leiste-h: calc(var(--touch) + var(--s2) * 2);
    --leiste-oben: calc(var(--s3) + var(--leiste-h) + env(safe-area-inset-bottom, 0px));
    --fab: 58px;
}

/* ============================================================== Farben */

:root {
    --fg:        #1a1a1f;
    --fg-2:      #3c3c47;
    --fg-3:      rgba(60, 60, 71, 0.62);
    --fg-4:      rgba(60, 60, 71, 0.28);

    --line:      rgba(60, 66, 100, 0.14);

    /*
     * Die feine Kante.
     *
     * Auf hellem Grund muss sie DUNKEL sein. Das war der Fehler: Die
     * Lichtkante ist weiss, und weiss auf weissem Glas über weissem
     * Grund ist nichts. In Dunkel trägt sie die ganze Kante, in Hell
     * verschwand sie — und weil der Schlagschatten bewusst weg ist,
     * hatten die Flächen gar keinen Rand mehr.
     *
     * Also andersherum gewichtet: unten die dunkle Haarlinie, darüber
     * nur ein Hauch Licht.
     */
    --rim: rgba(38, 44, 78, 0.13);

    /*
     * E-16: Indigo.
     *
     * Vorher stand hier das Orange der dichten Oberfläche — geerbt,
     * warm und deckend. Zwischen Glas wirkt es wie ein Aufkleber: Es
     * ist die einzige Farbe, durch die nichts hindurchscheint.
     *
     * Indigo liegt zwischen Blau und Violett und damit neben allen
     * vier Farbflecken des Grundes, statt in einem davon zu
     * verschwinden. Kühl, durchscheinend, und als „das kannst du
     * anfassen" sofort zu lesen.
     */
    --tint:      #5a4fd6;
    --tint-soft: rgba(90, 79, 214, 0.14);
    --tint-glow: rgba(90, 79, 214, 0.34);
    --on-tint:   #ffffff;

    /* E-17: drei Bedeutungsfarben, mehr nicht */
    --red:       #d70015;
    --green:     #248a3d;
    --blue:      #0071e3;

    /*
     * Das Glas selbst.
     *
     *   --glass       für Ränder: durchscheinend, Farbe kommt durch
     *   --glass-solid für Inhalt: fast deckend, damit Text ruhig steht
     *   --sheen       der helle Rand oben, der Licht einfängt
     */
    /*
     * Helles Glas muss WEISSER sein als sein Grund, nicht
     * durchsichtiger. Bei 22 % war die Leiste kaum vom Hintergrund zu
     * unterscheiden — in Dunkel funktioniert derselbe Wert, weil dort
     * jedes bisschen Weiss sofort heraussticht.
     */
    --glass:       rgba(255, 255, 255, 0.58);
    --glass-mitte: rgba(255, 255, 255, 0.72);
    --glass-solid: rgba(255, 255, 255, 0.86);
    --glass-schwebend: rgba(255, 255, 255, 0.88);
    --glass-hover: rgba(255, 255, 255, 0.82);

    /*
     * Die Lichtkante. Drei Farben statt einer: warm oben, neutral in
     * der Mitte, kühl unten. Das ist der Farbsaum, den echtes Glas an
     * der Kante wirft — bei 1px liest man ihn nicht als Farbe, sondern
     * als Glas.
     */
    /* Auf hellem Glas nur ein Hauch — die Kante trägt --rim. */
    --sheen:       rgba(255, 255, 255, 0.9);
    --sheen-2:     rgba(255, 255, 255, 0.5);

    /*
     * Schatten fast weg.
     *
     * Tiefe kommt bei Glas aus der Brechung, nicht aus einem Schlagschatten.
     * Ein kräftiger Schatten macht aus jeder Fläche eine Blase, die
     * obendrauf klebt — genau der Eindruck, den es nicht sein soll.
     */
    --shadow:
        0 1px 2px rgba(30, 38, 80, 0.05),
        0 4px 14px rgba(30, 38, 80, 0.06);
    --shadow-lift:
        0 1px 2px rgba(30, 38, 80, 0.06),
        0 10px 30px rgba(30, 38, 80, 0.12);

    /* Der Grund. Vier Richtungen, damit es sich nicht wie ein Farbverlauf liest. */
    --wash-1: rgba(255, 196, 150, 0.30);
    --wash-2: rgba(150, 180, 255, 0.38);
    --wash-3: rgba(206, 168, 255, 0.32);
    --wash-4: rgba(160, 232, 236, 0.32);
    --paper:  #eef0f7;
}

/*
 * Drei Helligkeiten, plus „wie das System".
 *
 *   hell     Papier. Dunkle Schrift, viel Licht.
 *   mittel   Schiefer. Helle Schrift auf mittlerem Grund — die Farben
 *            des Grundes tragen hier am weitesten, weil weder Weiss
 *            noch Schwarz sie schluckt.
 *   dunkel   Nacht. Helle Schrift, tiefer Grund.
 *
 * Ohne data-theme folgt die Seite dem System. Eine ausdrueckliche Wahl
 * gewinnt immer — deshalb `:root:not([data-theme])` in der @media-Regel
 * und nicht die frueher hier stehende Ausnahme fuer einen einzigen Wert.
 */

/* --- Mittel: die Werte, die beide anderen nicht haben ---------------- */

:root[data-theme="mittel"] {
    color-scheme: dark;

    --fg:        #f2f3f8;
    --fg-2:      #d3d6e2;
    --fg-3:      rgba(232, 236, 250, 0.62);
    --fg-4:      rgba(232, 236, 250, 0.30);

    --line:      rgba(226, 232, 250, 0.16);
    --rim:       rgba(255, 255, 255, 0.09);

    --tint:      #9d97ff;
    --tint-soft: rgba(157, 151, 255, 0.20);
    --tint-glow: rgba(157, 151, 255, 0.38);
    --on-tint:   #16143a;

    --red:       #ff6b64;
    --green:     #47d16a;
    --blue:      #63a9ff;

    /*
     * Auf mittlerem Grund darf das Glas heller sein als auf schwarzem:
     * Es hebt sich sonst nicht ab.
     */
    --glass:       rgba(255, 255, 255, 0.09);
    --glass-mitte: rgba(255, 255, 255, 0.13);
    --glass-solid: rgba(255, 255, 255, 0.16);
    /*
     * Nicht Weiss auf Weiss weiterdrehen: Auf mittlerem Grund
     * verschwindet ein duenner weisser Schleier. Die Leiste ist eine
     * hellere Fassung des Grundes selbst, mit genug Deckung, dass
     * dahinter nichts mehr durchkommt.
     */
    --glass-schwebend: rgba(58, 62, 80, 0.88);
    --glass-hover: rgba(255, 255, 255, 0.16);
    --sheen:       rgba(255, 255, 255, 0.34);
    --sheen-2:     rgba(255, 255, 255, 0.10);

    --shadow: 0 1px 2px rgba(0, 0, 0, 0.22);
    --shadow-lift:
        0 1px 2px rgba(0, 0, 0, 0.25),
        0 12px 34px rgba(0, 0, 0, 0.32);

    /* Die Farbflecken tragen hier am weitesten. */
    --wash-1: rgba(255, 178, 120, 0.26);
    --wash-2: rgba(120, 155, 255, 0.34);
    --wash-3: rgba(186, 140, 255, 0.30);
    --wash-4: rgba(130, 220, 226, 0.26);
    --paper:  #2b2e3c;
}

/* --- Dunkel ---------------------------------------------------------- */

@media (prefers-color-scheme: dark) {
    :root:not([data-theme]) {
        color-scheme: dark;

        --fg:        #f5f5f7;
        --fg-2:      #d8d8e0;
        --fg-3:      rgba(235, 235, 245, 0.58);
        --fg-4:      rgba(235, 235, 245, 0.26);

        --line:      rgba(235, 235, 245, 0.14);
        --rim:       rgba(255, 255, 255, 0.10);

        --tint:      #8b86ff;
        --tint-soft: rgba(139, 134, 255, 0.20);
        --tint-glow: rgba(139, 134, 255, 0.40);
        --on-tint:   #14122e;

        --red:       #ff453a;
        --green:     #30d158;
        --blue:      #0a84ff;

        --glass:       rgba(70, 70, 86, 0.26);
        --glass-mitte: rgba(46, 46, 58, 0.48);
        --glass-solid: rgba(34, 34, 44, 0.76);
        --glass-schwebend: rgba(38, 38, 50, 0.88);
        --glass-hover: rgba(90, 90, 110, 0.34);
        --sheen:       rgba(255, 255, 255, 0.28);
        --sheen-2:     rgba(255, 255, 255, 0.12);

        --shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
        --shadow-lift:
            0 1px 2px rgba(0, 0, 0, 0.4),
            0 12px 34px rgba(0, 0, 0, 0.5);

        --wash-1: rgba(160, 88, 40, 0.22);
        --wash-2: rgba(48, 72, 190, 0.36);
        --wash-3: rgba(110, 60, 175, 0.30);
        --wash-4: rgba(20, 110, 120, 0.26);
        --paper:  #0d0d12;
    }
}

:root[data-theme="dunkel"] {
    color-scheme: dark;

    --rim: rgba(255, 255, 255, 0.10);

    --fg:        #f5f5f7;
    --fg-2:      #d8d8e0;
    --fg-3:      rgba(235, 235, 245, 0.58);
    --fg-4:      rgba(235, 235, 245, 0.26);

    --line:      rgba(235, 235, 245, 0.14);

    --tint:      #8b86ff;
    --tint-soft: rgba(139, 134, 255, 0.20);
    --tint-glow: rgba(139, 134, 255, 0.40);
    --on-tint:   #14122e;

    --red:       #ff453a;
    --green:     #30d158;
    --blue:      #0a84ff;

    --glass:       rgba(70, 70, 86, 0.26);
    --glass-mitte: rgba(46, 46, 58, 0.48);
    --glass-solid: rgba(34, 34, 44, 0.76);
    --glass-schwebend: rgba(38, 38, 50, 0.88);
    --glass-hover: rgba(90, 90, 110, 0.34);
    --sheen:       rgba(255, 255, 255, 0.28);
    --sheen-2:     rgba(255, 255, 255, 0.12);

    --shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
    --shadow-lift:
        0 1px 2px rgba(0, 0, 0, 0.4),
        0 12px 34px rgba(0, 0, 0, 0.5);

    --wash-1: rgba(160, 88, 40, 0.22);
    --wash-2: rgba(48, 72, 190, 0.36);
    --wash-3: rgba(110, 60, 175, 0.30);
    --wash-4: rgba(20, 110, 120, 0.26);
    --paper:  #0d0d12;
}

/* --- Hell: ausdrücklich, gegen ein dunkles System --------------------- */

:root[data-theme="hell"] { color-scheme: light; }
* { box-sizing: border-box; }

/* ============================================================== Grund */

/*
 * Weiß mit Verläufen aus verschiedenen Richtungen.
 *
 * Ohne Farbe dahinter ist Glas nicht von Milchglas zu unterscheiden —
 * es gibt dann nichts, was gebrochen werden könnte. Vier weiche Flecken
 * aus vier Ecken, dazu ein sehr flacher Grundverlauf.
 *
 * `fixed`, damit der Grund stehen bleibt und die Flächen darüber
 * gleiten. Genau das lässt es nach Schichten aussehen statt nach Farbe.
 */
html, body {
    margin: 0;
    padding: 0;
    min-height: 100%;
    color: var(--fg);
    font-family: var(--font);
    font-size: var(--t-body);
    line-height: 1.45;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

body {
    background: var(--paper);
    overflow-x: hidden;   /* die driftenden Lagen ragen über den Rand */

    /*
     * Das eigene „Ziehen zum Neuladen" des Browsers bleibt aus.
     *
     * Sonst laufen zwei Gesten gleichzeitig: unsere Anzeige und die
     * des Browsers, und am Ende laedt die ganze Seite neu — was das
     * Gegenteil von dem ist, was hier passieren soll.
     */
    overscroll-behavior-y: contain;
}

/*
 * Der Grund: Farbe, die sich bewegt.
 *
 * Das Raster aus dem vorigen Anlauf ist wieder weg — es sollte die
 * Brechung sichtbar machen und sah aus wie Stoff. Die Verläufe allein
 * waren richtig.
 *
 * Sichtbar wird die Brechung stattdessen durch BEWEGUNG: Zwei Lagen
 * mit je zwei Farbflecken driften gegeneinander, sehr langsam und sehr
 * weit. Was sich unter dem Glas bewegt, verrät die Kante von selbst —
 * dafür braucht es keine Textur.
 *
 * Beide Lagen liegen fest im Fenster und werden mit `transform`
 * bewegt: Das läuft auf der Grafikkarte und kostet nichts.
 */
body::before, body::after {
    content: '';
    position: fixed;
    inset: -30%;
    z-index: -1;
    pointer-events: none;
    will-change: transform;
}

body::before {
    background:
        radial-gradient(46% 40% at 22% 26%, var(--wash-1), transparent 62%),
        radial-gradient(42% 38% at 78% 18%, var(--wash-2), transparent 60%);
    animation: e-drift-a 34s ease-in-out infinite alternate;
}

body::after {
    background:
        radial-gradient(48% 42% at 34% 82%, var(--wash-3), transparent 62%),
        radial-gradient(40% 36% at 84% 74%, var(--wash-4), transparent 60%);
    animation: e-drift-b 46s ease-in-out infinite alternate;
}

@keyframes e-drift-a {
    from { transform: translate3d(-4%, -3%, 0) scale(1.05) rotate(0deg); }
    to   { transform: translate3d( 5%,  4%, 0) scale(1.16) rotate(8deg); }
}

@keyframes e-drift-b {
    from { transform: translate3d( 4%,  3%, 0) scale(1.14) rotate(0deg); }
    to   { transform: translate3d(-5%, -4%, 0) scale(1.04) rotate(-7deg); }
}
a { color: var(--tint); text-decoration: none; }
a:hover { text-decoration: underline; }

button { font: inherit; color: inherit; background: none; border: none; padding: 0; cursor: pointer; }
input, textarea, select { font: inherit; color: inherit; }

/*
 * Der Fokusring folgt der Form des Elements — er gibt ihm keine.
 *
 * Hier stand `border-radius: 6px`. Das aendert nicht den Ring, sondern
 * das ELEMENT: Eine Kapsel waere beim Fokussieren auf 6px eckig
 * geworden. Moderne Browser ziehen den Umriss ohnehin der eigenen
 * Rundung nach.
 */
:focus-visible { outline: 2px solid var(--tint); outline-offset: 2px; }

/* ============================================================== Material */

/*
 * Liquid Glass in drei Lagen — nach dem Beispiel, das als Vorbild
 * diente (CodePen vEOpqMa von lassiterda).
 *
 * Der entscheidende Kniff steckt nicht im Aussehen, sondern in der
 * Reihenfolge der Filter:
 *
 *     backdrop-filter: blur(3px);     ← holt den Untergrund herein
 *     filter: url(#e-glas);           ← verbiegt DIESE Lage
 *
 * `backdrop-filter: url(#…)` kann so gut wie kein Browser — mein erster
 * Anlauf hing genau daran und hat die Verzerrung nie gezeigt. `filter`
 * auf einer eigenen Lage, die den weichgezeichneten Untergrund trägt,
 * können dagegen alle.
 *
 * Die drei Lagen, von hinten nach vorn:
 *
 *   ::before   der verzerrte Untergrund      (z-index -1)
 *   background der Farbschleier              (die Fläche selbst)
 *   Inhalt     Text, Knöpfe, Zeilen
 *   ::after    die Lichtkante                (z-index 2)
 *
 * ::before liegt hinter der eigenen Fläche, weil sein Untergrund die
 * Seite sein soll und nicht der Schleier darüber. Deshalb z-index: -1
 * und kein zusätzliches Element im HTML.
 */
.e-tabs, .e-card, .e-sheet, .e-toast, .e-avatar, .e-fab,
.e-btn, .e-choice, .e-input, .e-textarea, .e-prose, .e-seg,
.e-zieh,
.e-suche, .e-antwort, .e-senden, .e-erw-menue, .e-tour-karte,
.e-board-karte, .e-kal-tag {
    position: relative;
    overflow: hidden;
    background: var(--glass);
    isolation: isolate;
}

/* Lage 1: der verzerrte Untergrund. */
.e-tabs::before, .e-card::before, .e-sheet::before, .e-toast::before,
.e-avatar::before, .e-fab::before, .e-btn::before, .e-choice::before,
.e-zieh::before,
.e-input::before, .e-textarea::before, .e-prose::before, .e-seg::before,
.e-suche::before, .e-antwort::before, .e-senden::before,
.e-erw-menue::before, .e-tour-karte::before,
.e-board-karte::before, .e-kal-tag::before {
    content: '';
    position: absolute;
    inset: -30px;              /* über den Rand hinaus, sonst reißt die Kante */
    z-index: -1;
    -webkit-backdrop-filter: blur(3px) saturate(160%);
    backdrop-filter: blur(3px) saturate(160%);
    pointer-events: none;
}

/*
 * Lage 3: die Lichtkante.
 *
 * Zwei innere Schatten statt eines Verlaufs im Rand: hell von oben
 * links, ein zweiter Schimmer von unten rechts. Das ist die Fassung aus
 * der Vorlage, und sie liest sich besser als mein maskierter Verlauf —
 * weil echtes Glas an zwei gegenüberliegenden Kanten Licht fängt.
 */
.e-tabs::after, .e-card::after, .e-sheet::after, .e-toast::after,
.e-avatar::after, .e-fab::after, .e-btn::after, .e-choice::after,
.e-zieh::after,
.e-input::after, .e-textarea::after, .e-prose::after, .e-seg::after,
.e-suche::after, .e-antwort::after, .e-senden::after,
.e-erw-menue::after, .e-tour-karte::after,
.e-board-karte::after, .e-kal-tag::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 2;
    border-radius: inherit;
    box-shadow:
        inset 0 0 0 1px var(--rim, transparent),
        inset 2px 2px 1px 0 var(--sheen),
        inset -1px -1px 1px 1px var(--sheen-2);
    pointer-events: none;
}

/*
 * Die Verzerrung.
 *
 * Sie liegt auf der Lage mit dem Untergrund — nie auf dem Text. Wer
 * `filter` auf das ganze Element legt, verbiegt seine eigene Schrift
 * mit.
 */
.e-tabs::before, .e-sheet::before, .e-toast::before,
.e-avatar::before, .e-fab::before, .e-seg::before {
    filter: url(#e-glas);
}

.e-btn::before, .e-choice::before, .e-input::before, .e-textarea::before,
.e-board-karte::before, .e-kal-tag::before {
    filter: url(#e-glas-klein);
}

/*
 * Auch die Flächen in der Mitte sind Glas.
 *
 * Erst standen Karten und Fließtext auf fast deckendem Grund — aus
 * Sorge um die Lesbarkeit. Das Ergebnis waren dunkle Kästen zwischen
 * lauter Glas, und genau das sah nach „Blasen am Rand" aus.
 *
 * Jetzt sind sie Glas wie alles andere, nur ruhiger: mehr Schleier,
 * schwächere Verzerrung. Der Text bleibt scharf, weil verzerrt wird,
 * was HINTER der Fläche liegt — nie sie selbst.
 */
.e-card, .e-prose {
    background: var(--glass-mitte);
}
.e-card::before, .e-prose::before { filter: url(#e-glas-klein); }

/*
 * Eine Zeile leuchtet unter dem Finger auf.
 *
 * Kein Kasten, der die Farbe wechselt, sondern ein Lichtfleck, der der
 * Maus folgt — so verhält sich eine Flüssigkeit unter Druck. Die
 * Position setzt views.js über zwei Variablen.
 */
/*
 * overflow: hidden haelt das Licht unter dem Zeiger in der Zeile.
 * Der Ring der ueberfaelligen Zeile liegt innerhalb (inset: 3px)
 * und wird davon nicht angeschnitten.
 */
.e-row { position: relative; overflow: hidden; }

.e-row::after {
    content: '';
    position: absolute;
    inset: 0;
    opacity: 0;
    background: radial-gradient(120px 120px at var(--mx, 50%) var(--my, 50%),
        var(--sheen-2), transparent 70%);
    transition: opacity 260ms ease;
    pointer-events: none;
}
.e-row:hover::after { opacity: 1; }

/*
 * Tiefe von innen, nicht von unten.
 *
 * Ein kräftiger Schlagschatten macht aus jeder Fläche eine Blase, die
 * obendrauf klebt. Bei Glas kommt die Tiefe aus der Brechung.
 */
.e-tabs, .e-sheet, .e-toast {
    box-shadow: var(--shadow-lift);
}

/*
 * Leiste und Streifen liegen UEBER dem Inhalt, nicht neben ihm.
 *
 * Gemessen (Chrome, die echte Leiste ueber einer echten Liste): Die
 * Weichzeichnung greift, und drei Pixel waren zu wenig — aber der
 * eigentliche Grund war der Ton. `--glass` ist fuer Karten gedacht, die
 * neben dem Inhalt liegen und ruhig durchscheinen duerfen; unter einer
 * Leiste laufen dieselben Zeilen durch, waehrend man scrollt. Im
 * mittleren Thema stand sie bei neun Prozent Weiss.
 *
 * Deshalb ein eigener Ton statt einer weiteren Umdrehung an der
 * Weichzeichnung: Weichzeichnen verwischt die Schrift, deckt sie aber
 * nicht zu.
 */
.e-tabs, .e-toast {
    background: var(--glass-schwebend);
}

.e-tabs::before, .e-toast::before {
    -webkit-backdrop-filter: blur(24px) saturate(180%);
    backdrop-filter: blur(24px) saturate(180%);
}


/*
 * Wer Transparenz abbestellt hat, bekommt keine. Das ist kein
 * Feinschliff — auf manchen Augen ist durchscheinender Text unlesbar.
 */
@media (prefers-reduced-transparency: reduce) {
    .e-tabs, .e-card, .e-sheet, .e-toast, .e-avatar, .e-fab,
    .e-btn, .e-choice, .e-input, .e-textarea, .e-prose, .e-seg,
    .e-board-karte, .e-kal-tag {
        background: var(--paper);
        border: 1px solid var(--line);
        box-shadow: none;
    }
    .e-tabs::before, .e-card::before, .e-sheet::before, .e-toast::before,
    .e-avatar::before, .e-fab::before, .e-btn::before, .e-choice::before,
    .e-input::before, .e-textarea::before, .e-prose::before, .e-seg::before,
    .e-tabs::after, .e-card::after, .e-sheet::after, .e-toast::after,
    .e-avatar::after, .e-fab::after, .e-btn::after, .e-choice::after,
    .e-input::after, .e-textarea::after, .e-prose::after, .e-seg::after {
        display: none;
    }
}
/* ============================================================ Startbild */

.e-boot { max-width: var(--content); margin: 12vh auto; padding: 0 var(--s5); }
.e-boot-title, .e-boot-row {
    background: var(--glass);
    border-radius: var(--r-card);
    animation: e-pulse 1.2s ease-in-out infinite;
}
.e-boot-title { height: 34px; width: 45%; margin-bottom: var(--s6); }
.e-boot-row { height: 68px; margin-bottom: var(--s3); }
.e-boot-row:nth-of-type(3) { animation-delay: 0.15s; opacity: 0.7; }
.e-boot-row:nth-of-type(4) { animation-delay: 0.3s; opacity: 0.4; }

@keyframes e-pulse { 0%, 100% { opacity: 0.55; } 50% { opacity: 1; } }

/* ============================================================== Gerüst */

.e-app { display: grid; min-height: 100vh; grid-template-columns: 1fr; }

/*
 * Unten ist Platz fuer Leiste UND Knopf.
 *
 * Vorher endete der Inhalt vier Pixel ueber der Leiste — die letzte
 * Zeile lag damit unter dem schwebenden Knopf, und genau an ihrem
 * rechten Rand stehen Datum und Pfeil. Wer bis ans Ende scrollte,
 * kam an die letzte Aufgabe schlechter heran als an alle anderen.
 */
.e-main {
    min-width: 0;
    padding-bottom: calc(var(--leiste-oben) + var(--s4) + var(--fab) + var(--s2));
}

/*
 * Oben etwas mehr Luft — und Rueckicht auf die Kerbe.
 *
 * Am Telefon standen 16 Pixel zwischen der Leiste des Browsers und
 * einer 34 Pixel hohen Ueberschrift; am Rechner sind es 32. Genau
 * verkehrt: Auf dem kleinen Schirm klebt der Inhalt an der Kante, auf
 * dem grossen hat er ohnehin Platz ringsum.
 *
 * `safe-area-inset-top` fehlte ganz. Im Querformat und als
 * installierte Anwendung laeuft der Titel damit unter die Kerbe.
 */
.e-page {
    max-width: var(--content);
    margin: 0 auto;
    padding: calc(var(--s5) + env(safe-area-inset-top, 0px)) var(--s5) var(--s6);
}

/* Board und Kalender vertragen mehr als Textbreite. */
.e-page.is-breit { max-width: 1180px; }

/* ------------------------------------------------------- Bereichsleiste */

.e-tabs {
    position: fixed;
    left: var(--s3); right: var(--s3);
    bottom: calc(var(--s3) + env(safe-area-inset-bottom, 0px));
    z-index: 30;
    display: flex;
    justify-content: space-around;
    gap: var(--s1);
    padding: var(--s2);
    border-radius: var(--r-sheet);
    box-shadow: var(--shadow-lift);
}

.e-tab {
    flex: 1;
    min-height: var(--touch);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    color: var(--fg-3);
    font-size: 11px;
    border-radius: var(--r-control);
    transition: color 160ms ease, background 160ms ease;
}
.e-tab:hover { color: var(--fg-2); }

/* Das getönte Kissen wandert unter den aktiven Punkt. */
.e-tab.is-on { color: var(--tint); background: var(--tint-soft); }

.e-tab-icon { font-size: 20px; line-height: 1; }

/*
 * Die Zahl sitzt am Zeichen, nicht irgendwo.
 *
 * Vorher war sie absolut positioniert OHNE Bezugspunkt — der nächste
 * positionierte Vorfahr ist die ganze Leiste, nicht der Punkt darin.
 * Sie hing also am Rand der Leiste und wäre jetzt, wo die Leiste
 * `overflow: hidden` braucht, obendrein abgeschnitten worden.
 */
.e-tab { position: relative; }

.e-tab-badge {
    position: absolute;
    top: 2px;
    left: 50%;
    margin-left: 5px;
    background: var(--red);
    color: #fff;
    font-size: 11px;
    font-weight: 600;
    line-height: 1;
    padding: 3px 6px;
    border-radius: var(--r-kapsel);
}

/* -------------------------------------------------------------- Kopf */

.e-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--s4);
    margin-bottom: var(--s5);
}

.e-title {
    font-size: var(--t-large);
    font-weight: 700;
    letter-spacing: -0.024em;
    line-height: 1.15;
    margin: 0;
}
.e-subtitle { color: var(--fg-3); font-size: var(--t-subhead); margin: var(--s1) 0 0; }

.e-avatar {
    flex: 0 0 auto;
    width: var(--h-control);
    height: var(--h-control);
    border-radius: var(--r-kapsel);
    box-shadow: var(--shadow);
    color: var(--fg-2);
    font-size: var(--t-subhead);
    font-weight: 600;
    display: flex;
    align-items: center;
    justify-content: center;
}
.e-avatar:hover { background: var(--glass-hover); }

/* ============================================================== Listen */

.e-group { margin-bottom: var(--s6); }

.e-group-title {
    font-size: var(--t-footnote);
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: var(--fg-3);
    padding: 0 var(--s3) var(--s2);
}
/*
 * Ueberfaellig ist der einzige Zustand, der etwas verlangt.
 *
 * Rote Schrift allein geht in einer Liste unter, in der ohnehin viel
 * steht. Der Titel wird deshalb zu einer Kapsel, um die ein Licht
 * kreist — Bewegung faellt auf, bevor man ein Wort gelesen hat, und
 * eine kreisende Kante passt zum Material, waehrend ein blinkender
 * Kasten es zerschlagen wuerde.
 */
/*
 * Die Ueberschrift bleibt schlicht rote Schrift. Den Blick holt der
 * kreisende Ring um die ganze Gruppe — eine Kapsel um den Titel
 * zusaetzlich waeren zwei Marker fuer eine Aussage.
 */
.e-group-title.is-late { color: var(--red); }

/*
 * Das kreisende Licht.
 *
 * Nicht das Element dreht sich, sondern der Anfangswinkel des Kegels.
 * Das ist der Unterschied, an dem der erste Versuch haengenblieb: Ein
 * gedrehtes Element nimmt seine Maske mit, und dann laesst sich daraus
 * kein feststehender Ring mehr stanzen. Ausserdem braucht es so keine
 * deckende Fuellung, die ueber Glas immer falsch aussieht.
 *
 * Die Maske ist der uebliche Kniff fuer eine Kante: zweimal dieselbe
 * Flaeche, einmal bis zum Innenrand, und was sich ueberlagert, faellt
 * heraus. Uebrig bleibt genau der Saum.
 */
.e-group.is-late::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    padding: 2px;                  /* das ist die Ringdicke */
    background: conic-gradient(
        from var(--winkel, 0deg),
        transparent 0deg 200deg,
        color-mix(in srgb, var(--red) 45%, transparent) 290deg,
        var(--red) 345deg,
        color-mix(in srgb, var(--red) 70%, transparent) 358deg,
        transparent 360deg
    );
    -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;
    animation: e-kreisen 1.6s linear infinite;
    pointer-events: none;
    z-index: 1;
}

/*
 * Der Ring liegt um die ganze Gruppe — Ueberschrift und Karte
 * zusammen. Um jede einzelne Zeile waren es zwoelf Ringe im
 * Gleichtakt; das liest niemand mehr als Hinweis, das ist ein Alarm.
 *
 * Ein zarter roter Schein nach aussen dazu: Der Ring allein ist zwei
 * Pixel breit, und zwei Pixel gehen zwischen den Glaskanten unter.
 */
.e-group.is-late {
    position: relative;
    padding: var(--s3);
    border-radius: var(--r-card);
    isolation: isolate;
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--red) 14%, transparent),
                0 6px 26px -12px color-mix(in srgb, var(--red) 55%, transparent);
}


/*
 * Ohne @property waere --winkel fuer den Browser reiner Text: Er
 * spraenge von 0 auf 360, statt zu wandern. Wo es fehlt, bleibt ein
 * stehender roter Saum — immer noch besser als nichts.
 */
/*
 * Der Zug wird an der Anzeige gesetzt und im Ring darin gebraucht —
 * also muss er vererben. Mit `inherits: false` sah das Kind immer den
 * Anfangswert, und der Ring blieb leer, egal wie weit gezogen wurde.
 */
@property --zug {
    syntax: '<angle>';
    initial-value: 0deg;
    inherits: true;
}

@property --winkel {
    syntax: '<angle>';
    initial-value: 0deg;
    inherits: false;
}

@keyframes e-kreisen {
    to { --winkel: 360deg; }
}

.e-card {
    border-radius: var(--r-card);
    box-shadow: var(--shadow);
    overflow: hidden;
}

.e-row {
    display: flex;
    align-items: center;
    gap: var(--s3);
    width: 100%;
    min-height: 66px;
    padding: var(--s3) var(--s4);
    text-align: left;
    border-bottom: 1px solid var(--line);
    background: transparent;
    color: inherit;
    transition: background 140ms ease;
}
.e-row:last-child { border-bottom: none; }
.e-row:hover { background: var(--glass-hover); text-decoration: none; }

.e-row-body { flex: 1; min-width: 0; }

.e-row-title {
    font-size: var(--t-headline);
    font-weight: 600;
    letter-spacing: -0.01em;
    overflow-wrap: anywhere;
}
.e-row-sub { font-size: var(--t-subhead); color: var(--fg-3); margin-top: 2px; overflow-wrap: anywhere; }
.e-row.is-done .e-row-title { color: var(--fg-3); text-decoration: line-through; }

.e-check {
    flex: 0 0 auto;
    width: 27px; height: 27px;
    border-radius: var(--r-kapsel);
    border: 1.5px solid var(--fg-4);
    display: flex;
    align-items: center;
    justify-content: center;
    color: transparent;
    font-size: 15px;
    transition: background 180ms ease, border-color 180ms ease,
                color 180ms ease, transform 180ms cubic-bezier(0.32, 0.72, 0, 1);
}
.e-check:hover { border-color: var(--tint); color: var(--fg-4); transform: scale(1.08); }
.e-check.is-on { background: var(--green); border-color: var(--green); color: #fff; }

/*
 * Abhaken will gehalten werden.
 *
 * Der Haken sitzt am Zeilenanfang, wo der Zeiger ohnehin vorbeikommt —
 * als reiner Klick sah er aus wie etwas, das man im Vorbeigehen
 * antippt. Ein "wirklich?" kommt nach E-04 nicht in Frage, also
 * Widerstand: Der Ring fuellt sich, solange man haelt.
 *
 * touch-action: none — sonst nimmt der Browser den Druck als Beginn
 * einer Wischgeste und der Haltevorgang bricht sofort ab.
 */
.e-check { touch-action: none; }

.e-check::before {
    content: '';
    position: absolute;
    inset: -3px;
    border-radius: inherit;
    background: conic-gradient(var(--green) var(--fuellung, 0deg), transparent 0deg);
    opacity: 0;
    transition: opacity 140ms ease;
    pointer-events: none;
}

/*
 * Der Ring ist ein Ring, kein Kuchen: Die Mitte wird ausgestanzt.
 * Zwei Masken uebereinander, weil eine allein nur die Aussenkante
 * beschneidet.
 */
.e-check::before {
    -webkit-mask: radial-gradient(circle, transparent 62%, #000 64%);
    mask: radial-gradient(circle, transparent 62%, #000 64%);
}

.e-check.is-haelt {
    border-color: var(--green);
    transform: scale(1.12);
}
.e-check.is-haelt::before {
    opacity: 1;
    animation: e-fuellen 420ms linear forwards;
}

@keyframes e-fuellen {
    from { --fuellung: 0deg; }
    to   { --fuellung: 360deg; }
}

/*
 * Derselbe Widerstand am breiten Knopf.
 *
 * Am runden Haken laeuft ein Ring, hier ein Balken von links nach
 * rechts — ein Ring um eine Kapsel waere ein Rahmen, der blinkt, und
 * kein Fortschritt.
 *
 * scaleX statt einer wachsenden Breite: Breite laesst den Browser bei
 * jedem Bild neu rechnen, eine Transformation nicht.
 */
.e-halt { touch-action: none; }

/*
 * Ein echtes Kind, kein ::before: `.e-btn::before` traegt schon die
 * verzerrte Glaslage. Ein zweites ::before auf demselben Knopf haette
 * sie ueberschrieben und dem Knopf sein Material genommen.
 */
.e-halt-balken {
    position: absolute;
    inset: 0;
    z-index: 1;
    border-radius: inherit;
    background: color-mix(in srgb, #fff 26%, transparent);
    transform: scaleX(0);
    transform-origin: left center;
    opacity: 0;
    pointer-events: none;
}

/* Die Beschriftung bleibt ueber dem Balken. */
.e-halt-text {
    position: relative;
    z-index: 2;
}

.e-halt.is-haelt .e-halt-balken {
    opacity: 1;
    animation: e-fuellbalken 420ms linear forwards;
}

@keyframes e-fuellbalken {
    from { transform: scaleX(0); }
    to   { transform: scaleX(1); }
}

/*
 * Ohne @property waere --fuellung fuer den Browser reiner Text und
 * spraenge von 0 auf 360, statt zu wachsen. Wo es fehlt, bleibt die
 * groessere Kapsel und der gruene Rand als Rueckmeldung.
 */
@property --fuellung {
    syntax: '<angle>';
    initial-value: 0deg;
    inherits: false;
}

.e-row-when { flex: 0 0 auto; font-size: var(--t-footnote); color: var(--fg-3); white-space: nowrap; }
.e-row-when.is-late { color: var(--red); font-weight: 600; }

.e-chevron { flex: 0 0 auto; color: var(--fg-4); font-size: 18px; }

.e-empty { text-align: center; padding: var(--s6) var(--s5); color: var(--fg-3); }
.e-empty-mark { font-size: 44px; line-height: 1; margin-bottom: var(--s3); }
.e-empty-title { font-size: var(--t-title); font-weight: 600; color: var(--fg); margin-bottom: var(--s2); }
.e-empty-text { font-size: var(--t-subhead); max-width: 34ch; margin: 0 auto; }

/* ============================================================= Knöpfe */

.e-btn {
    min-height: var(--h-control);
    padding: 0 var(--s5);
    border-radius: var(--r-kapsel);
    font-size: var(--t-subhead);
    font-weight: 600;
    /*
     * Nicht umbrechen. „+ Neue Aufgabe" ist auf zwei Zeilen gebrochen
     * und damit doppelt so hoch geworden wie alles daneben.
     */
    white-space: nowrap;
    color: var(--tint);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--s2);
    box-shadow: var(--shadow);
    transition: transform 160ms cubic-bezier(0.32, 0.72, 0, 1),
                background 160ms ease, box-shadow 160ms ease;
}
.e-btn:hover { background: var(--glass-hover); text-decoration: none; }
.e-btn:active { transform: scale(0.97); }

/*
 * Der eine gefüllte Knopf (E-27). Er ist das einzige Stück auf dem
 * Schirm, das nicht durchscheint — deshalb sieht man ihn sofort.
 */
/*
 * Der eine gefüllte Knopf.
 *
 * Er scheint als einziges nicht durch (E-27) — dafür bekommt er einen
 * Schein in seiner eigenen Farbe statt eines grauen Schattens. So wirkt
 * er beleuchtet und nicht aufgeklebt.
 */
.e-btn.is-primary {
    background: linear-gradient(160deg,
        color-mix(in srgb, var(--tint) 88%, white),
        var(--tint) 60%);
    color: var(--on-tint);
    box-shadow: 0 2px 10px var(--tint-glow), inset 0 1px 0 rgba(255, 255, 255, 0.35);
}
.e-btn.is-primary::before { display: none; }
.e-btn.is-primary:hover { box-shadow: 0 4px 18px var(--tint-glow), inset 0 1px 0 rgba(255, 255, 255, 0.45); }

.e-btn.is-quiet {
    background: transparent;
    box-shadow: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
}
.e-btn.is-quiet::after { display: none; }

.e-btn.is-danger { color: var(--red); }
.e-btn[disabled] { color: var(--fg-4); cursor: default; box-shadow: none; }

/*
 * Aktionsleiste: gleich breite Knöpfe nebeneinander. Für Blätter und
 * die Aufgabenansicht.
 */
.e-btn-row { display: flex; gap: var(--s3); }
.e-btn-row > * { flex: 1; }

/*
 * Kopfleiste: Knöpfe in ihrer natürlichen Breite, alle gleich hoch, an
 * einer Linie. Nicht dasselbe wie eine Aktionsleiste — dort werden die
 * Kinder gestreckt, und genau das hat hier den Hauptknopf umbrechen
 * lassen und das Bild zum Oval gezogen.
 */
.e-head-actions {
    display: flex;
    align-items: center;
    gap: var(--s2);
    flex: 0 0 auto;
}
.e-head-actions > * { flex: 0 0 auto; }
.e-head-actions.is-spread { width: 100%; justify-content: space-between; }

/*
 * Der schwebende Knopf sitzt UEBER der Leiste, mit echtem Abstand.
 */
.e-fab {
    position: fixed;
    right: var(--s5);
    bottom: calc(var(--leiste-oben) + var(--s4));
    z-index: 25;
    width: var(--fab); height: var(--fab);
    border-radius: var(--r-kapsel);
    background: linear-gradient(160deg,
        color-mix(in srgb, var(--tint) 88%, white),
        var(--tint) 60%);
    color: var(--on-tint);
    font-size: 27px;
    line-height: 1;
    box-shadow: 0 4px 20px var(--tint-glow), inset 0 1px 0 rgba(255, 255, 255, 0.35);
    display: flex;
    align-items: center;
    justify-content: center;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    transition: transform 200ms cubic-bezier(0.32, 0.72, 0, 1);
}
/*
 * Das gezeichnete Plus im schwebenden Knopf.
 *
 * Die beiden Balken haengen an einem eigenen Kind, nicht an
 * `.e-fab::before` oder `::after` — die tragen die Glaslagen, und ein
 * zweites davon haette dem Knopf sein Material genommen.
 *
 * `currentColor`, damit es dieselbe Farbe hat wie eine Beschriftung.
 */
.e-plus {
    position: relative;
    display: block;
    width: 18px;
    height: 18px;
    flex: 0 0 auto;
}

/*
 * Duenn und mit runden Enden.
 *
 * Der erste Anlauf war 22 Pixel lang und 3 dick, mit geraden Enden —
 * kraeftiger als das getippte Zeichen und quer zum weichen Rest.
 * Entscheidung des Nutzers.
 */
.e-plus::before, .e-plus::after {
    content: '';
    position: absolute;
    background: currentColor;
    border-radius: var(--r-kapsel);
}

.e-plus::before {
    left: 0; right: 0;
    top: 50%;
    height: 2px;
    transform: translateY(-50%);
}

.e-plus::after {
    top: 0; bottom: 0;
    left: 50%;
    width: 2px;
    transform: translateX(-50%);
}

.e-fab:hover { transform: scale(1.06); }
.e-fab:active { transform: scale(0.94); }

/* ============================================================= Felder */

.e-field { margin-bottom: var(--s5); }

.e-label {
    display: block;
    font-size: var(--t-subhead);
    font-weight: 600;
    color: var(--fg-2);
    margin-bottom: var(--s2);
}

/*
 * Die Kante der Eingabefelder steht hier — nicht im Browser.
 *
 * Sie war nie festgelegt: Ein `input` behielt die Umrandung, die sein
 * Browser mitbringt, ein `button` bekam durch `button { border: none }`
 * gar keine. Nebeneinander sah dasselbe Feld deshalb verschieden aus,
 * je nachdem, woraus es gebaut war — und in jedem Browser wieder
 * anders.
 *
 * Jetzt tragen alle dieselbe, und keine haengt mehr davon ab, womit
 * jemand die Seite oeffnet.
 */
.e-input, .e-textarea, .e-suche, .e-antwort {
    width: 100%;
    min-height: var(--touch);
    padding: var(--s3) var(--s4);
    border: 1px solid var(--line);
    border-radius: var(--r-control);
    font-size: var(--t-body);
    outline: none;
    box-shadow: var(--shadow);
    transition: box-shadow 160ms ease, background 160ms ease;
}
.e-input:focus, .e-textarea:focus, .e-suche:focus, .e-antwort:focus {
    background: var(--glass-solid);
    box-shadow: var(--shadow), 0 0 0 2px var(--tint-soft);
}
.e-input::placeholder, .e-textarea::placeholder,
.e-suche::placeholder, .e-antwort::placeholder { color: var(--fg-4); }

.e-textarea { min-height: 110px; resize: vertical; line-height: 1.5; }

.e-hint { font-size: var(--t-footnote); color: var(--fg-3); margin-top: var(--s2); }

.e-choices { display: flex; flex-wrap: wrap; gap: var(--s2); }

.e-choice {
    min-height: var(--h-control);
    padding: 0 var(--s4);
    border-radius: var(--r-kapsel);
    font-size: var(--t-subhead);
    color: var(--fg-2);
    display: inline-flex;
    align-items: center;
    box-shadow: var(--shadow);
    transition: background 160ms ease, color 160ms ease,
                transform 160ms cubic-bezier(0.32, 0.72, 0, 1);
}
.e-choice:hover { background: var(--glass-hover); }
.e-choice:active { transform: scale(0.96); }
.e-choice.is-on {
    background: var(--tint);
    color: var(--on-tint);
    font-weight: 600;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
}

/* ================================================================ Suchen */

/*
 * Die Zeile mit dem Suchfeld. Sie sitzt zwischen Kopf und Liste und
 * bekommt denselben Abstand wie eine Gruppe — sonst klebt sie am Titel.
 *
 * Das Feld selbst teilt sich alle Regeln mit .e-input, auch die drei
 * Glaslagen: Es in die vorhandenen Listen aufzunehmen ist richtiger,
 * als die Regeln zu kopieren.
 */
.e-suchzeile {
    margin-bottom: var(--s5);
}

/*
 * Das Kreuzchen, das der Browser in ein type="search" malt, ist in
 * jedem Browser anders gross und ignoriert die Schriftfarbe. Auf Glas
 * sieht das wie ein Fehler aus — Escape raeumt das Feld ohnehin.
 */
.e-suche::-webkit-search-decoration,
.e-suche::-webkit-search-cancel-button,
.e-suche::-webkit-search-results-button {
    -webkit-appearance: none;
    appearance: none;
}

/* ============================================================ Skelette */

/*
 * Was dasteht, solange geladen wird.
 *
 * Der Schimmer laeuft ueber die Flaeche, nicht in ihr: eine
 * Verschiebung des Hintergrunds, keine Aenderung der Groesse.
 * Alles andere laesst den Browser bei jedem Bild neu rechnen.
 */
/*
 * Ein Geruest wartet, es reagiert nicht.
 *
 * Es benutzt die echten Kaesten — und damit auch deren Verhalten beim
 * Ueberfahren. Ein Schimmer, der auf den Mauszeiger reagiert, sieht
 * aus wie etwas, das man anklicken kann.
 */
.e-skelett { animation: e-fade 200ms linear; }
.e-skelett .e-row { cursor: default; }
.e-skelett .e-row:hover { background: transparent; }
.e-skelett .e-row:hover::after { opacity: 0; }
.e-skelett .e-chevron { opacity: 0.25; }

/*
 * Ein Platzhalter, der die Groesse eines Knopfs hat, ohne einer zu
 * sein: Er haelt den Platz frei, damit nichts nachrueckt.
 */
.e-skelett-still {
    opacity: 0.35;
    pointer-events: none;
    display: inline-flex;
}

.e-skelett-strich,
.e-skelett-blase,
.e-skelett-antwort,
.e-skelett-senden,
.e-skelett-fertig,
.e-skelett-haken,
.e-skelett-karte,
.e-skelett-tag {
    background: linear-gradient(
        100deg,
        var(--glass) 30%,
        var(--glass-solid) 50%,
        var(--glass) 70%
    );
    background-size: 300% 100%;
    animation: e-schimmer 1.4s ease-in-out infinite;
    border-radius: var(--r-control);
}

/*
 * Ein Balken steht fuer eine Zeile Text — also ist er so hoch wie
 * eine.
 *
 * `1em` statt einer festen Zahl: Der Balken sitzt IN dem Kasten, den
 * er vertritt (`.e-row-title`, `.e-row-sub`, `.e-group-title`), und
 * erbt dessen Schriftgroesse. Aendert jemand die Schrift, aendert
 * sich der Balken mit — und die Zeile bleibt so hoch wie die echte.
 */
.e-skelett-strich {
    display: block;
    height: 1em;
    width: 62%;
    border-radius: var(--r-kapsel);
}

.e-skelett-strich.is-kurz  { width: 40%; }
.e-skelett-strich.is-titel { width: 22%; }
.e-skelett-strich.is-wann  { width: 52px; }
.e-skelett-strich.is-gross { width: 68%; }

/*
 * Die Unterhaltung: eine Blase in Kartenhoehe und darunter das
 * Antwortfeld — beide so hoch wie ihre echten Gegenstuecke.
 */
.e-skelett-blase {
    height: 52px;
    width: 100%;
    margin-bottom: var(--s4);
}

.e-skelett-antwort {
    flex: 1;
    height: var(--touch);
    border-radius: var(--r-control);
}

/* Genau die Masse des echten Sende-Knopfs. */
.e-skelett-senden {
    flex: none;
    width: var(--h-control);
    height: var(--h-control);
    border-radius: var(--r-kapsel);
}

/* Und der Abschluss-Knopf darunter. */
.e-skelett-fertig {
    width: 160px;
    height: var(--h-control);
    margin-top: var(--s4);
    border-radius: var(--r-kapsel);
}

.e-skelett-haken {
    flex: 0 0 auto;
    display: block;
    width: 27px;
    height: 27px;
    border-radius: var(--r-kapsel);
}

.e-skelett-karte { height: 58px; margin-bottom: var(--s2); }
.e-skelett-tag { aspect-ratio: 1; border-radius: var(--r-control); }

@keyframes e-schimmer {
    from { background-position: 150% 0; }
    to   { background-position: -50% 0; }
}

/*
 * Wer Bewegung abbestellt hat, bekommt eine ruhige Flaeche — aber
 * immer noch die Form. Die @media-Regel weiter unten haelt die
 * Animation ohnehin an; hier steht nur, dass dann nichts fehlt.
 */
@media (prefers-reduced-motion: reduce) {
    .e-skelett-strich,
    .e-skelett-blase,
    .e-skelett-antwort,
    .e-skelett-senden,
    .e-skelett-fertig,
    .e-skelett-haken,
    .e-skelett-karte,
    .e-skelett-tag { background: var(--glass); }
}

/* ====================================================== Knopf, der tut */

/*
 * Zwischen Klick und Antwort passierte sichtbar nichts. Bei einer
 * schnellen Leitung merkt das niemand, bei einer langsamen klickt
 * man ein zweites Mal — und dann ist es zweimal abgeschickt.
 *
 * Die Beschriftung bleibt stehen und tritt zurueck. Sie durch
 * „Bitte warten" zu ersetzen laesst den Knopf springen und nimmt
 * einem die Auskunft, was man ueberhaupt angestossen hat.
 */
/*
 * Nicht nur .e-btn: Der Sendepfeil und der runde Haken sind eigene
 * Klassen und warten genauso auf den Server.
 */
.is-tut {
    color: transparent;
    pointer-events: none;
    position: relative;
}

/*
 * Ein eigenes Kind, kein ::after: `.e-btn::after` traegt schon die
 * Lichtkante des Glases. Ein zweites ::after haette sie ueberschrieben
 * und dem Knopf die Kante genommen — derselbe Fehler wie beim
 * Haltebalken, nur eine Ecke weiter.
 */
.e-lader {
    position: absolute;
    top: 50%;
    left: 50%;
    z-index: 3;
    width: 16px;
    height: 16px;
    margin: -8px 0 0 -8px;
    border-radius: var(--r-kapsel);
    border: 2px solid var(--on-tint);
    border-top-color: transparent;
    opacity: 0.9;
    animation: e-dreht 620ms linear infinite;
    pointer-events: none;
}

/*
 * Auf einem getoenten Knopf steht weisse Schrift, also auch ein
 * weisser Ring. Ueberall sonst die Schriftfarbe.
 */
.e-lader { border-color: var(--fg-2); border-top-color: transparent; }

.e-btn.is-primary .e-lader,
.e-senden.is-bereit .e-lader,
.e-check.is-on .e-lader { border-color: var(--on-tint); border-top-color: transparent; }

/* In einem kleinen runden Bedienelement passt der grosse Ring nicht. */
.e-check .e-lader,
.e-senden .e-lader {
    width: 13px;
    height: 13px;
    margin: -6.5px 0 0 -6.5px;
    border-width: 1.5px;
}

@keyframes e-dreht {
    to { transform: rotate(1turn); }
}

/* ============================================================ Antworten */

/*
 * Feld und Pfeil in einer Zeile.
 *
 * align-items: flex-end — das Feld waechst nach unten, der Pfeil soll
 * dabei unten buendig bleiben und nicht in der Mitte haengen.
 */
.e-antwortzeile {
    display: flex;
    align-items: flex-end;
    gap: var(--s3);
    margin-top: var(--s4);
}

.e-antwort {
    flex: 1;
    min-width: 0;              /* sonst schiebt der Text den Pfeil hinaus */
    resize: none;              /* die Hoehe regelt das Feld selbst */
    line-height: 1.4;
    max-height: 160px;

    /*
     * Nicht scrollbar, solange es waechst. Die Leiste schaltet
     * passeHoeheAn() erst zu, wenn die Hoehe wirklich am Anschlag ist
     * — sonst stand sie schon bei einer Zeile da.
     */
    overflow-y: hidden;
}

/*
 * Der Pfeil ist so hoch wie ein Bedienelement und genauso breit — eine
 * Kapsel, die zum Kreis wird. Alles andere neben einem Feld sieht aus
 * wie ein Versehen.
 */
.e-senden {
    flex: none;
    width: var(--h-control);
    height: var(--h-control);
    border-radius: var(--r-kapsel);
    display: grid;
    place-items: center;
    font-size: 17px;
    line-height: 1;
    cursor: pointer;
    transition: background 160ms ease, transform 160ms ease, opacity 160ms ease;
}

/*
 * Solange nichts dasteht, tritt er zurueck. Nicht ausblenden: Wer ihn
 * nie sieht, weiss auch nicht, dass es ihn gibt.
 */
.e-senden:disabled {
    opacity: 0.4;
    cursor: default;
}

/* Sobald etwas dasteht, ist er der Hauptknopf dieser Zeile. */
.e-senden.is-bereit {
    background: var(--tint);
    color: #fff;
}
.e-senden.is-bereit:hover { transform: translateY(-1px); }
.e-senden.is-bereit:active { transform: translateY(0) scale(0.96); }

/* ========================================================= Erwähnungen */

/*
 * Die Liste steht ueber dem Feld, nicht darunter: Unter dem Feld
 * sitzt auf dem Handy die Tastatur.
 */
.e-erw {
    position: relative;
    flex: 1;
    min-width: 0;
    display: flex;
}

/*
 * Der aeussere Kasten traegt das Glas und scrollt NICHT.
 *
 * Die Lage `::before` steht mit `inset: -30px` absichtlich ueber den
 * Rand hinaus, damit die Kante beim Weichzeichnen nicht reisst. In
 * einem Scroll-Behaelter zaehlen die 30 Pixel unter dem Kasten aber
 * als Inhalt — und genau die liessen sich scrollen, obwohl drei
 * Namen bequem hineinpassen.
 */
.e-erw-menue {
    position: absolute;
    bottom: calc(100% + var(--s2));
    left: 0;
    right: 0;
    z-index: 30;
    border-radius: var(--r-card);
    padding: var(--s2);
    box-shadow: var(--shadow-lift);
}

/* Gescrollt wird innen — und nur, wenn es wirklich zu viele sind. */
.e-erw-liste {
    max-height: 220px;
    overflow-y: auto;
}

.e-erw-eintrag {
    display: block;
    width: 100%;
    text-align: left;
    padding: var(--s2) var(--s3);
    border-radius: var(--r-control);
    background: transparent;
    color: inherit;
    font-size: var(--t-body);
    cursor: pointer;
    transition: background 120ms ease;
}
.e-erw-eintrag:hover,
.e-erw-eintrag.is-on { background: var(--tint-soft); }

/* =============================================================== Blatt */

.e-scrim {
    position: fixed;
    inset: 0;
    z-index: 40;
    background: rgba(20, 20, 35, 0.28);
    display: flex;
    align-items: flex-end;
    justify-content: center;
    animation: e-fade 240ms linear;
}
@supports (backdrop-filter: blur(6px)) {
    .e-scrim { -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
}

/*
 * Das Blatt scrollt nicht als Ganzes, sondern nur sein Rumpf.
 *
 * Vorher trug `.e-sheet` selbst `overflow-y: auto` und der Kopf hing an
 * `position: sticky`. Das sah bei kurzem Inhalt richtig aus und brach,
 * sobald das Konto-Blatt lang wurde: Ein klebender Kopf ohne eigenen
 * Hintergrund ist durchsichtig — der Inhalt lief sichtbar dahinter
 * durch, und die Ueberschrift stand mitten im Text.
 *
 * Ein Spaltenlayout loest beides auf einmal. Der Kopf steht fest, weil
 * er nicht im scrollenden Bereich liegt, und `.e-sheet` behaelt sein
 * `overflow: hidden` aus der Glasregel — die Rundung und die
 * Lichtkante bleiben damit heil, statt mitzuscrollen.
 */
.e-sheet {
    width: 100%;
    max-width: 620px;
    max-height: 92vh;

    display: flex;
    flex-direction: column;

    border-radius: var(--r-sheet) var(--r-sheet) 0 0;
    box-shadow: var(--shadow-lift);
    animation: e-rise 420ms cubic-bezier(0.32, 0.72, 0, 1);
    padding-bottom: env(safe-area-inset-bottom, 0px);
}

.e-grip,
.e-sheet-head { flex: 0 0 auto; }

.e-sheet-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s4);
    padding: var(--s4) var(--s5);
    border-bottom: 1px solid var(--line);
}

.e-sheet-title { font-size: var(--t-headline); font-weight: 600; }

.e-sheet-body {
    flex: 1 1 auto;

    /*
     * Ohne min-height: 0 waechst ein Flex-Kind ueber seinen Behaelter
     * hinaus, statt zu scrollen — die Vorgabe ist `auto`, und die
     * heisst hier „so hoch wie der Inhalt".
     */
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;

    padding: var(--s5);
}

/*
 * Griff und Kopf gehoeren der Zieh-Geste (E-46).
 *
 * `touch-action: none` nimmt dem Browser das Scrollen an dieser
 * Stelle ab — sonst entscheidet er sich fuer die Seite dahinter und
 * schickt uns keine Bewegungen. Genau daran lag es: Der Griff sah
 * aus wie ein Griff und war ein Loch.
 *
 * Der Griff bleibt so klein, wie er aussieht: Die Ziehflaeche ist der
 * ganze Kopf darunter, und der ist reichlich gross. Ihn zu polstern
 * haette den Kopf um zwei Dutzend Pixel nach unten geschoben — also
 * genau das Spacing verschlechtert, das gerade erst gerichtet wurde.
 */
.e-grip {
    width: 38px;
    height: 5px;
    border-radius: var(--r-kapsel);
    background: var(--fg-4);
    margin: var(--s2) auto 0;
    touch-action: none;
    cursor: grab;
}

.e-sheet-head { touch-action: none; }

/* Der Rumpf scrollt weiterhin — dort will man scrollen. */
.e-sheet-body { touch-action: pan-y; }

/*
 * Solange ein Blatt offen ist, haelt die Seite dahinter still.
 *
 * Ohne das scrollte sie mit, wenn man an einer nicht scrollenden
 * Stelle des Blattes zog. Von aussen sah das aus, als reagiere das
 * Blatt nicht.
 */
body.e-blatt-offen { overflow: hidden; }

@keyframes e-rise { from { transform: translateY(100%); } to { transform: none; } }
@keyframes e-fade { from { opacity: 0; } to { opacity: 1; } }

/* ========================================================== Einführung */

/*
 * Die Einführung läuft in der echten Oberfläche, nicht daneben.
 *
 * Die Hülle fängt deshalb KEINE Klicks ab (`pointer-events: none`) —
 * wer während der Führung etwas ausprobieren will, soll das können.
 * Nur die Karte selbst nimmt Klicks an.
 */
.e-tour {
    position: fixed;
    inset: 0;
    z-index: 60;
    pointer-events: none;
}

/*
 * Der Lichtkegel.
 *
 * Kein zweites Element, das den Rest abdeckt: ein Kasten um das Ziel
 * mit einem sehr grossen Schatten nach aussen. Das dunkelt alles
 * andere ab und lässt genau die Stelle hell — mit einer einzigen
 * Regel und ohne Masken.
 */
.e-tour-loch {
    position: fixed;
    border-radius: var(--r-card);
    box-shadow: 0 0 0 9999px rgba(16, 16, 30, 0.55),
                inset 0 0 0 2px var(--tint);
    transition: top 260ms cubic-bezier(0.32, 0.72, 0, 1),
                left 260ms cubic-bezier(0.32, 0.72, 0, 1),
                width 260ms cubic-bezier(0.32, 0.72, 0, 1),
                height 260ms cubic-bezier(0.32, 0.72, 0, 1);
    pointer-events: none;
}

/*
 * Ohne Ziel bleibt der Schleier, aber ohne Loch — sonst blitzt bei
 * jedem Schritt ohne Ziel ein Rahmen in der linken oberen Ecke auf.
 */
.e-tour-loch.is-aus {
    top: 50%;
    left: 50%;
    width: 0;
    height: 0;
    box-shadow: 0 0 0 9999px rgba(16, 16, 30, 0.55);
}

/*
 * Die Karte steht neben dem Ziel, nicht an einem festen Bildrand.
 *
 * Vorher klebte sie unten (oder oben) am Fenster und lag damit
 * regelmässig genau auf dem, worüber sie sprach — besonders in einem
 * langen Blatt, wo das Ziel in der Mitte liegt. `top`/`bottom` setzt
 * jetzt `setzeLicht()` aus der Lage des Ziels.
 */
.e-tour-karte {
    position: fixed;
    left: 50%;
    transform: translateX(-50%);
    width: min(440px, calc(100vw - var(--s5) * 2));

    padding: var(--s5);
    border-radius: var(--r-card);
    box-shadow: var(--shadow-lift);
    pointer-events: auto;
    animation: e-rise-small 260ms cubic-bezier(0.32, 0.72, 0, 1);

    transition: top 260ms cubic-bezier(0.32, 0.72, 0, 1),
                bottom 260ms cubic-bezier(0.32, 0.72, 0, 1);
}

/* Ohne Ziel steht sie in der Mitte — da stört sie nichts. */
.e-tour-karte.is-mitte {
    top: 50%;
    bottom: auto;
    transform: translate(-50%, -50%);
}

.e-tour-zaehler {
    font-size: var(--t-footnote);
    color: var(--fg-3);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    margin-bottom: var(--s2);
}

.e-tour-titel {
    font-size: var(--t-headline);
    font-weight: 600;
    margin-bottom: var(--s2);
}

.e-tour-text { color: var(--fg-2); line-height: 1.45; }

.e-tour-knoepfe {
    display: flex;
    gap: var(--s2);
    margin-top: var(--s5);
}

/* „Später" tritt zurück und schiebt die anderen nach rechts. */
.e-tour-knoepfe > :first-child { margin-right: auto; }

/* ================================================================ Tipps */

/*
 * Die Einmal-Sprechblase (tippEinmal in ui.js).
 *
 * Sie haengt am Element und ist bewusst KEIN Bedienelement des
 * Bildschirms im Sinne von E-27 — sie erscheint hoechstens einmal im
 * Leben eines Geraets und verschwindet beim ersten Antippen. Der
 * Akzent macht sie zur Aufforderung, das Glas haelt sie im Material.
 */
.e-tipp {
    position: fixed;
    z-index: 55;
    max-width: 260px;
    padding: var(--s3) var(--s4);
    border-radius: var(--r-card);
    background: var(--tint);
    color: #fff;
    font-size: var(--t-subhead);
    font-weight: 600;
    text-align: left;
    box-shadow: var(--shadow-lift);
    cursor: pointer;
    animation: e-rise-small 260ms cubic-bezier(0.32, 0.72, 0, 1);
}

/* Der kleine Zeiger nach oben, zum Element hin. */
.e-tipp::before {
    content: '';
    position: absolute;
    top: -5px;
    left: 18px;
    width: 10px;
    height: 10px;
    background: var(--tint);
    transform: rotate(45deg);
}

/* ===================================================== Ziehziel-Vorschau */

/*
 * Beim Anfassen einer Karte zeigen sich ALLE gueltigen Ziele auf
 * einmal (U6): jede Rinne und jede fremde Board-Kapsel bekommt eine
 * gestrichelte Kante. Vorher toente erst das dragover die eine Rinne
 * unter dem Zeiger — man zog ins Ungewisse.
 */
.e-board-cards.is-ziel-bereit {
    outline: 2px dashed var(--tint-glow);
    outline-offset: -2px;
    border-radius: var(--r-card);
}

.e-boardwahl .e-choice.is-ziel-bereit {
    outline: 2px dashed var(--tint-glow);
    outline-offset: 2px;
}

/* ============================================================ Streifen */

/*
 * Der Streifen sitzt UEBER dem schwebenden Knopf.
 *
 * Er hatte eine eigene, vierte Rechnung fuer den unteren Rand
 * (`touch + s6*2` = 108) und landete damit genau im Knopf, der von 88
 * bis 146 reicht — im Bild lag er halb darunter. Jetzt leitet er sich
 * aus derselben Groesse ab wie alles andere dort unten.
 *
 * Und die Polsterung ist gleichmaessig: Sie war links 20 und rechts 12
 * Pixel, weil rechts ein „Rueckgaengig" erwartet wurde. Steht dort
 * keins, sitzt der Text sichtbar aus der Mitte.
 */
.e-toast {
    position: fixed;
    left: 50%;
    bottom: calc(var(--leiste-oben) + var(--s4) + var(--fab) + var(--s4));
    transform: translateX(-50%);
    z-index: 50;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--s4);
    max-width: calc(100vw - 2 * var(--s5));
    padding: var(--s3) var(--s5);
    border-radius: var(--r-kapsel);
    box-shadow: var(--shadow-lift);
    font-size: var(--t-subhead);
    animation: e-rise-small 340ms cubic-bezier(0.32, 0.72, 0, 1);
}
.e-toast.is-error { color: var(--red); }

/* Mit „Rueckgaengig" rechts braucht es dort weniger Rand. */
.e-toast:has(.e-toast-undo) { padding-right: var(--s3); }

.e-toast-undo {
    color: var(--tint);
    font-weight: 600;
    padding: var(--s2) var(--s3);
    border-radius: var(--r-kapsel);
    white-space: nowrap;
}
.e-toast-undo:hover { background: var(--tint-soft); }

@keyframes e-rise-small {
    from { opacity: 0; transform: translate(-50%, 14px) scale(0.96); }
    to   { opacity: 1; transform: translate(-50%, 0) scale(1); }
}

/* ============================================================== Detail */

.e-back {
    display: inline-flex;
    align-items: center;
    gap: var(--s1);
    min-height: var(--h-control);
    color: var(--tint);
    font-size: var(--t-subhead);
    font-weight: 500;
    margin-left: calc(var(--s2) * -1);
    padding: 0 var(--s2);
}

.e-detail-title {
    font-size: var(--t-large);
    font-weight: 700;
    letter-spacing: -0.024em;
    line-height: 1.18;
    margin: var(--s3) 0;
    overflow-wrap: anywhere;
}

.e-facts { color: var(--fg-3); font-size: var(--t-subhead); margin-bottom: var(--s5); }
.e-facts .is-late { color: var(--red); font-weight: 600; }

.e-prose {
    border-radius: var(--r-card);
    box-shadow: var(--shadow);
    padding: var(--s4) var(--s5);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    margin-bottom: var(--s5);
}

.e-section-title {
    font-size: var(--t-footnote);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    color: var(--fg-3);
    margin: var(--s6) 0 var(--s2);
    padding: 0 var(--s3);
}

.e-msg { padding: var(--s3) var(--s4); border-bottom: 1px solid var(--line); }
.e-msg:last-child { border-bottom: none; }
.e-msg-who { font-size: var(--t-footnote); color: var(--fg-3); margin-bottom: 2px; }
.e-msg-text { white-space: pre-wrap; overflow-wrap: anywhere; }
.e-msg.is-system { color: var(--fg-3); font-size: var(--t-subhead); }

/*
 * Eine Nachfrage ist kein Kommentar — sie haelt die Aufgabe an.
 * Ein farbiger Streifen an der Kante reicht, um sie im Verlauf
 * wiederzufinden, ohne dass sie den Rest ueberstimmt.
 */
.e-msg.is-nachfrage {
    border-left: 3px solid var(--blue);
    padding-left: calc(var(--s4) - 3px);
}
.e-msg.is-nachfrage .e-msg-who { color: var(--blue); font-weight: 600; }

.e-msg.is-geklaert {
    border-left: 3px solid var(--green);
    padding-left: calc(var(--s4) - 3px);
}
.e-msg.is-geklaert .e-msg-who { color: var(--green); font-weight: 600; }

/*
 * Der Kasten, der sagt, worauf die Aufgabe wartet. Er steht direkt
 * unter den Fakten — vor dem Text, weil er beantwortet, warum
 * gerade nichts passiert.
 */
.e-warten {
    margin: var(--s4) 0;
    padding: var(--s4);
    border-radius: var(--r-card);
    border-left: 3px solid var(--blue);
    background: var(--glass);
}
.e-warten-kopf { font-weight: 600; margin-bottom: 4px; }
.e-warten-text { color: var(--fg-2); white-space: pre-wrap; }

.e-actions { display: flex; gap: var(--s3); padding: var(--s5) 0 0; }
.e-actions > * { flex: 1; }

.e-file {
    display: flex;
    align-items: center;
    gap: var(--s3);
    padding: var(--s3) var(--s4);
    border-bottom: 1px solid var(--line);
    color: var(--fg);
}
.e-file:last-child { border-bottom: none; }
.e-file:hover { text-decoration: none; background: var(--glass-hover); }
.e-file-size { margin-left: auto; color: var(--fg-3); font-size: var(--t-footnote); }

/* ====================================================== Ab 900 Pixeln */

@media (min-width: 900px) {
    .e-app { grid-template-columns: var(--sidebar) 1fr; }
    .e-main { padding-bottom: var(--s6); }

    /*
     * Am Rechner wird aus der Leiste eine schwebende Glasplatte links.
     * Sie klebt nicht am Rand, sie liegt darauf — das ist der ganze
     * Unterschied zwischen Glas und Milchglas.
     */
    .e-tabs {
        position: sticky;
        top: var(--s4);
        left: auto; right: auto; bottom: auto;
        margin: var(--s4) 0 var(--s4) var(--s4);
        height: calc(100vh - 2 * var(--s4));
        flex-direction: column;
        justify-content: flex-start;
        gap: var(--s1);
        padding: var(--s4) var(--s3);
        border-radius: var(--r-sheet);
    }

    .e-tab {
        flex: 0 0 auto;
        flex-direction: row;
        justify-content: flex-start;
        gap: var(--s3);
        padding: 0 var(--s3);
        font-size: var(--t-body);
        font-weight: 500;
    }
    .e-tab.is-on { font-weight: 600; }
    .e-tab-icon { font-size: 18px; }
    .e-tab-badge { position: static; transform: none; margin-left: auto; }

    .e-page { padding: var(--s6) var(--s5); }

    /* Am Rechner sitzt der Hauptknopf im Kopf, nicht schwebend. */
    .e-fab { display: none; }

    .e-actions > * { flex: 0 0 auto; min-width: 180px; }

    .e-toast { bottom: var(--s6); }
    .e-scrim { align-items: center; }
    .e-sheet { border-radius: var(--r-sheet); max-height: 84vh; }
    .e-grip { display: none; }
}

@media (min-width: 1500px) { :root { --sidebar: 260px; } }

.e-wide-only { display: none; }
@media (min-width: 900px) { .e-wide-only { display: inline-flex; } }

/*
 * Der Fuehrungs-Eintrag in der Leiste.
 *
 * Auf breiten Schirmen ist die Leiste eine Spalte am Rand — dort
 * hat ein vierter Eintrag Platz. Auf schmalen sitzt sie unten am
 * Daumen; dort macht jeder weitere Eintrag die anderen schmaler,
 * fuer etwas, das man im Sitzen tut. Dort steht er im Konto.
 */
.e-wide-only-tab { display: none; }
@media (min-width: 900px) { .e-wide-only-tab { display: flex; } }

/* Das Gegenstueck im Konto — zwei Tueren zum selben Raum waeren
 * eine zu viel, also zeigt immer nur eine. */
@media (min-width: 900px) { .e-narrow-only-row { display: none; } }


/* ------------------------------------------------- Schritte einer Aufgabe */

/*
 * Text und Zustaendige nebeneinander: Wer den Schritt schreibt, sagt
 * im selben Zug, wer ihn macht.
 */
.e-schritt-zeile {
    display: flex;
    gap: 8px;
    align-items: center;
    margin-bottom: 8px;
}

.e-schritt-zeile .e-input:first-child { flex: 1 1 auto; min-width: 0; }

/*
 * Der Knopf zum Entfernen ist ein gewoehnlicher Knopf.
 *
 * Ich hatte ihn erst an die Felder daneben angeglichen — eckig und
 * feldhoch. Damit gab es drei Formen statt zwei: Felder, Kapseln und
 * dieses eine Zwischending, direkt neben „+ Noch ein Schritt", das
 * eine Kapsel ist. Eine Zeile wird nicht ruhiger, wenn man ihr eine
 * neue Form hinzufuegt.
 *
 * Er darf nur nicht mitwachsen — sonst zieht ihn die Flex-Zeile
 * auseinander.
 */
.e-schritt-zeile .e-btn { flex: 0 0 auto; }

/*
 * Die Personenwahl sieht aus wie ein Feld und verhaelt sich wie das
 * @-Fenster: derselbe Ort fuer dieselbe Frage.
 */
.e-personenwahl-huelle { position: relative; }

.e-personenwahl {
    display: block;
    width: 100%;
    text-align: left;
    cursor: pointer;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.e-personenwahl.is-leer { color: var(--fg-3); }

/* Sie oeffnet nach oben wie die @-Liste — dort ist im Blatt Platz. */
.e-personenwahl-huelle .e-erw-menue { min-width: 180px; }

.e-schritt-wer { flex: 0 0 auto; width: 38%; max-width: 190px; }

/* Auf schmalen Schirmen untereinander — nebeneinander bliebe fuer
 * beides zu wenig. */
@media (max-width: 520px) {
    .e-schritt-zeile { flex-wrap: wrap; }
    .e-schritt-zeile .e-input:first-child { flex: 1 1 100%; }
    .e-schritt-wer { width: auto; flex: 1 1 auto; max-width: none; }
}
/* ============================================================= Anmelden */

/*
 * Anmelden, Firmenwahl, Einladung.
 *
 * Eine einzelne Karte, mittig, sonst nichts: Hier gibt es genau eine
 * Sache zu tun, und alles andere waere Ablenkung. Die Karte ist
 * dieselbe `.e-card` wie ueberall — sie bringt ihre drei Glasschichten
 * mit, hier wird nur die Groesse und der Platz bestimmt.
 */
.e-anmeldung {
    min-height: 100dvh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--s4);
}

.e-anmelde-karte {
    width: 100%;
    max-width: 380px;
    padding: var(--s5);
    text-align: center;
}

.e-anmelde-logo {
    max-height: 46px;
    max-width: 190px;
    margin: 0 auto var(--s3);
    display: block;
}

.e-anmelde-titel {
    font-size: 22px;
    font-weight: 600;
    letter-spacing: -0.01em;
    margin: 0;
}

.e-anmelde-sub {
    color: var(--fg-3);
    font-size: var(--t-subhead);
    margin-top: 6px;
}

/*
 * Die Felder stehen links, obwohl die Karte mittig ist: Eine
 * Beschriftung ueber einem Feld liest man am linken Rand, nicht in
 * der Mitte — sonst springt das Auge bei jedem Feld woanders hin.
 */
.e-anmelde-form {
    margin-top: var(--s4);
    text-align: left;
}

.e-anmelde-form .e-field { margin-bottom: var(--s3); }

.e-anmelde-knopf {
    width: 100%;
    margin-top: var(--s3);
    justify-content: center;
}

.e-anmelde-firma {
    width: 100%;
    margin-top: var(--s2);
    justify-content: center;
}

/*
 * Der Fehler steht ueber dem Knopf, nicht darunter: Man liest ihn,
 * bevor man wieder drueckt.
 */
.e-anmelde-fehler {
    color: var(--red);
    min-height: 0;
    margin-top: var(--s2);
    text-align: left;
}

.e-anmelde-fehler:empty { display: none; }
/* ==================================================== Wer arbeitet woran */

/*
 * Die Aufgaben einer Person, eingerueckt unter ihrer Zeile.
 *
 * Der Einzug und der ruhigere Grund sagen die Zugehoerigkeit —
 * ohne Linien, ohne Rahmen. Man sieht, dass diese Zeilen zu der
 * Person darueber gehoeren, weil sie eingerueckt sind.
 */
.e-team-aufgaben {
    padding-left: var(--s5);
    background: var(--glass-hover);
    border-bottom: 1px solid var(--line);
}
.e-team-aufgaben:last-child { border-bottom: none; }
.e-team-aufgaben .e-row { min-height: 54px; }


/* =========================================================== Umschalter */

/*
 * Liste · Board · Zeit. Drei Brillen für denselben Ort — deshalb sitzt
 * das hier im Bildschirm und nicht in der Leiste unten.
 *
 * Das getönte Kissen wandert unter die gewählte Sicht, statt dass drei
 * Knöpfe verschieden aussehen. Man sieht die Auswahl, ohne zu lesen.
 */
.e-seg {
    display: inline-flex;
    gap: 2px;
    padding: 3px;
    border-radius: var(--r-kapsel);
    margin-bottom: var(--s5);
    box-shadow: var(--shadow);
}

/*
 * Am Handy ueber die ganze Breite.
 *
 * Darunter stehen Suchfeld und Karten von Rand zu Rand — die Auswahl
 * war das Einzige, was in der Mitte aufhoerte. Nebenbei werden die drei
 * Flaechen groesser, und getippt wird hier mit dem Daumen.
 *
 * Am breiten Schirm bleibt sie inhaltsbreit: Ueber 900 Pixel gezogen
 * stuenden drei kurze Woerter in drei sehr langen Feldern.
 */
@media (max-width: 899px) {
    .e-seg { display: flex; }
    .e-seg-knopf { flex: 1; padding: 0 var(--s2); }
}

.e-seg-knopf {
    min-height: 34px;   /* im Kissen, deshalb 6px kleiner als aussen */
    padding: 0 var(--s4);
    border-radius: var(--r-kapsel);
    font-size: var(--t-subhead);
    font-weight: 500;
    color: var(--fg-3);
    transition: color 200ms ease, background 260ms cubic-bezier(0.32, 0.72, 0, 1);
}
.e-seg-knopf:hover { color: var(--fg-2); }
.e-seg-knopf.is-on {
    background: var(--glass-solid);
    color: var(--fg);
    font-weight: 600;
    box-shadow: var(--shadow);
}

/* ================================================================ Board */

/*
 * Spalten nebeneinander, waagerecht scrollbar. Auf halbem Schirm sind
 * zwei zu sehen und die dritte lugt hervor — das ist die Einladung zu
 * scrollen, ohne dass irgendwo „scrollen" steht.
 */
/*
 * Die Spalten teilen sich die Breite, statt zu ueberlaufen.
 *
 * Erst standen sie auf fester Breite in einer 700px-Spalte — bei drei
 * Spalten war die dritte angeschnitten und der Rest der Seite leer.
 * Jetzt wachsen sie mit; erst wenn es wirklich eng wird, wird
 * gescrollt.
 */
.e-board {
    display: flex;
    gap: var(--s3);
    align-items: stretch;
    overflow-x: auto;
    padding-bottom: var(--s4);
    scroll-snap-type: x proximity;
}

.e-board-spalte {
    flex: 1 1 0;
    min-width: 200px;
    max-width: 340px;
    scroll-snap-align: start;
    display: flex;
    flex-direction: column;
}

/* Auf schmalen Schirmen wieder feste Breite — sonst wird jede Spalte
   zu duenn zum Lesen, und man sieht die naechste hervorlugen. */
@media (max-width: 720px) {
    .e-board-spalte { flex: 0 0 78vw; max-width: none; }
}

.e-board-kopf {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--s2);
    padding: 0 var(--s3) var(--s2);
    font-size: var(--t-footnote);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    color: var(--fg-3);
}
.e-board-zahl { font-variant-numeric: tabular-nums; }

.e-board-cards {
    display: flex;
    flex-direction: column;
    gap: var(--s2);
    flex: 1;
    min-height: 140px;
    padding: var(--s2);
    border-radius: var(--r-card);

    /*
     * Eine flache Rinne, in der die Karten liegen. Ohne sie schwebt
     * eine halbleere Spalte im Nichts, und man sieht nicht, wo man
     * ablegen darf.
     */
    background: var(--rim, rgba(0, 0, 0, 0.04));
    transition: background 240ms ease, box-shadow 240ms ease;
}

/* Beim Ziehen leuchtet die Rinne — das ist die Einladung. */
.e-board-cards.is-ziel {
    box-shadow: inset 0 0 0 2px var(--tint);
}
.e-board-cards.is-ziel { background: var(--tint-soft); }

.e-board-leer {
    color: var(--fg-4);
    font-size: var(--t-footnote);
    text-align: center;
    padding: var(--s4) 0;
}

/*
 * Die Karten sind Glas wie alles andere.
 *
 * Vorher waren es flache Rechtecke mit Schatten — mitten zwischen
 * lauter Glas fiel genau das auf. Sie standen schlicht nicht in der
 * Glasgruppe.
 */
.e-board-karte {
    display: block;
    padding: var(--s3) var(--s4);
    border-radius: var(--r-card);
    background: var(--glass-mitte);
    color: inherit;
    cursor: grab;
    transition: transform 200ms cubic-bezier(0.32, 0.72, 0, 1);
}
.e-board-karte:hover { text-decoration: none; transform: translateY(-1px); }
.e-board-karte:active { cursor: grabbing; }

/* Das Original wird geisterhaft, solange sein Abbild unterwegs ist —
   bei Maus-Drag wie beim Finger-Zug dieselbe Klasse. */
.e-board-karte.is-zieht { opacity: 0.4; }

/*
 * Finger-Ziehen (siehe sichten.js).
 *
 * touch-action bleibt hier absichtlich beim Scrollen: Anders als der
 * Haken (.e-check, touch-action: none) fängt eine Karte den Finger
 * nicht ab — erst das Halten macht aus der Berührung einen Zug, bis
 * dahin gehört die Bewegung dem Scrollen. manipulation nimmt nur den
 * Doppeltipp-Zoom weg, damit der Tipp ohne Verzögerung ankommt.
 *
 * Der lange Druck darf außerdem keine Link-Vorschau und keine
 * Textauswahl aufreißen — die Karte ist ein Link, gemeint ist der Zug.
 */
.e-board-karte {
    touch-action: manipulation;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    user-select: none;
}

/*
 * Der Klon, der unter dem Finger fliegt: angehoben, mit Schatten,
 * eine Spur größer (das scale steht inline, weil translate und scale
 * im selben transform wandern müssen).
 *
 * pointer-events: none, damit elementFromPoint die Rinne DARUNTER
 * findet und nicht den Klon selbst. Und keine Glaskurve auf transform
 * — 420ms Nachlauf hieße, die Karte zockelt dem Finger hinterher.
 */
.e-board-karte.is-fliegt {
    position: fixed;
    z-index: 45;
    margin: 0;
    pointer-events: none;
    box-shadow: var(--shadow-lift);
    transition: none;
}

/* Beim Abbruch gleitet der Klon an seinen Platz zurück. */
.e-board-karte.is-fliegt.is-zurueck {
    transition: transform 220ms cubic-bezier(0.32, 0.72, 0, 1);
}

.e-board-titel { font-size: var(--t-subhead); font-weight: 600; overflow-wrap: anywhere; }
.e-board-wann { font-size: var(--t-footnote); color: var(--fg-3); margin-top: var(--s1); }
.e-board-wann.is-late { color: var(--red); font-weight: 600; }

/*
 * Die Board-Wahl. Sie sitzt ueber den Spalten und benutzt dieselben
 * Kapseln wie jede andere Auswahl — hier ist nichts neu, nur an einer
 * anderen Stelle.
 */
.e-boardwahl {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s2);
    margin-bottom: var(--s4);
}

/*
 * Ein Board-Knopf ist zugleich Ablageflaeche: Eine Karte darauf zu
 * ziehen legt sie auf dieses Board. Beim Ueberfahren muss man das
 * sehen — sonst zielt man ins Ungewisse.
 */
.e-boardwahl .e-choice.is-ziel {
    box-shadow: inset 0 0 0 2px var(--tint);
    transform: scale(1.06);
}

/* ============================================================= Kalender */

/*
 * Kein Gantt. Die dichte Oberfläche hat eins, und für jemanden, der
 * Balken lesen kann, ist es richtig. Hier lautet die Frage „wann wird
 * es eng?" — darauf antwortet ein Kalender besser.
 *
 * Ein Punkt je Aufgabe: Der Tag mit vier Punkten fällt auf, bevor man
 * eine Zahl gelesen hat.
 */
.e-kalender {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: var(--s1);
    margin-bottom: var(--s5);
}

.e-kal-kopf {
    text-align: center;
    font-size: var(--t-footnote);
    font-weight: 600;
    color: var(--fg-3);
    padding-bottom: var(--s1);
}

.e-kal-tag {
    aspect-ratio: 1;
    min-height: 40px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    border-radius: var(--r-control);
    background: var(--glass);
    color: var(--fg);
    font-size: var(--t-subhead);
    transition: background 180ms ease, transform 180ms cubic-bezier(0.32, 0.72, 0, 1);
}
.e-kal-tag:hover { background: var(--glass-hover); transform: scale(1.04); }
.e-kal-tag.is-frei { background: transparent; color: var(--fg-4); }
.e-kal-tag.is-frei::after { opacity: 0.4; }
.e-kal-tag.is-vorbei { opacity: 0.45; }

/* Heute trägt den Akzent — „hier bist du" ist derselbe Gedanke wie überall. */
.e-kal-tag.is-heute {
    background: var(--tint);
    color: var(--on-tint);
    font-weight: 700;
}

/*
 * Der gewählte Tag bekommt einen Ring, keine Füllung.
 *
 * Zwei Fragen, zwei Antworten: „Welcher Tag ist heute?" beantwortet
 * die Füllung, „welchen sehe ich gerade an?" der Ring. Bekämen beide
 * dieselbe Füllung, wären es zwei gleich aussehende Tage — und man
 * wüsste wieder nicht, welcher gemeint ist.
 *
 * Fällt beides zusammen, liegt der Ring mit einem hellen Zwischenraum
 * auf der Füllung: Ein Akzentring auf Akzentgrund waere unsichtbar.
 */
.e-kal-tag.is-gewaehlt {
    box-shadow: 0 0 0 2px var(--tint);
    opacity: 1;
}

.e-kal-tag.is-heute.is-gewaehlt {
    box-shadow: 0 0 0 2px var(--on-tint), 0 0 0 4px var(--tint);
}

/* Ein vergangener Tag ist blass — der gewählte nie, sonst sucht man ihn. */
.e-kal-tag.is-vorbei.is-gewaehlt { opacity: 1; }

.e-kal-zahl { line-height: 1; font-variant-numeric: tabular-nums; }

.e-kal-punkte { display: flex; gap: 2px; }
.e-kal-punkt {
    width: 4px; height: 4px;
    border-radius: var(--r-kapsel);
    background: var(--fg-3);
}
.e-kal-tag.is-heute .e-kal-punkt { background: var(--on-tint); }

.e-kal-detail { margin-bottom: var(--s5); }

/* Am Rechner darf der Kalender atmen. */
@media (min-width: 900px) {
    .e-kal-tag { min-height: 58px; }
}

/* ============================================================ Bewegung */

/* E-26: Wer Bewegung abbestellt hat, bekommt keine. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

/* ============================================================== Flüssig */

/*
 * Was Glas von einer Platte unterscheidet, ist nicht nur, wie es
 * aussieht, sondern wie es sich verhält: Es gibt nach, es schwappt,
 * das Licht wandert.
 *
 * Alle Kurven hier sind dieselbe: cubic-bezier(0.32, 0.72, 0, 1). Sie
 * startet schnell und läuft weich aus — wie etwas, das Masse hat.
 */

/* Eine Karte hebt sich unter dem Zeiger und wird eine Spur heller. */
.e-card, .e-board-karte, .e-choice, .e-btn, .e-avatar {
    transition:
        transform 420ms cubic-bezier(0.32, 0.72, 0, 1),
        box-shadow 420ms cubic-bezier(0.32, 0.72, 0, 1),
        background 300ms ease;
}

.e-card:hover { transform: translateY(-1px); }

/* Und gibt beim Drücken nach, statt nur die Farbe zu wechseln. */
.e-row:active { transform: scale(0.995); }
.e-board-karte:active { transform: scale(0.97); }

/*
 * Der Haken füllt sich, statt umzuschalten.
 *
 * Eine kurze Überdehnung (scale 1.18) und zurück — das ist der
 * Unterschied zwischen „an" und „geschafft".
 */
.e-check.is-on { animation: e-quell 460ms cubic-bezier(0.32, 0.72, 0, 1); }

@keyframes e-quell {
    0%   { transform: scale(0.7); }
    45%  { transform: scale(1.18); }
    100% { transform: scale(1); }
}

/*
 * Das Kissen im Umschalter wandert, statt zu springen. Die Kurve
 * überschwingt leicht — wie etwas Flüssiges, das anhält.
 */
.e-seg-knopf {
    transition:
        color 220ms ease,
        background 460ms cubic-bezier(0.34, 1.4, 0.5, 1),
        box-shadow 460ms cubic-bezier(0.34, 1.4, 0.5, 1);
}

/*
 * Der schwebende Knopf atmet — sehr langsam, sehr wenig. Man sieht es
 * nicht, man merkt es.
 */
.e-fab { animation: e-atmen 7s ease-in-out infinite; }

@keyframes e-atmen {
    0%, 100% { transform: scale(1); }
    50%      { transform: scale(1.035); }
}
.e-fab:hover { animation: none; transform: scale(1.06); }

/* Eine neue Zeile fällt herein, statt zu erscheinen. */
.e-card .e-row { animation: e-einlauf 460ms cubic-bezier(0.32, 0.72, 0, 1) backwards; }
.e-card .e-row:nth-child(2) { animation-delay: 40ms; }
.e-card .e-row:nth-child(3) { animation-delay: 80ms; }
.e-card .e-row:nth-child(4) { animation-delay: 120ms; }
.e-card .e-row:nth-child(n+5) { animation-delay: 160ms; }

@keyframes e-einlauf {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: none; }
}

/* ========================================================= Aufgabenliste */

/*
 * Die Unteraufgaben einer Aufgabe. Sie fehlten ganz — „2 von 4" stand
 * in der Liste, in der Ansicht aber nichts davon.
 */
.e-section-title {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--s3);
}

.e-fortschritt-zahl { font-variant-numeric: tabular-nums; text-transform: none; letter-spacing: 0; }

/* Ein Balken sagt schneller als eine Zahl, wie weit es ist. */
.e-fortschritt {
    height: 4px;
    border-radius: var(--r-kapsel);
    background: var(--rim, rgba(0, 0, 0, 0.1));
    overflow: hidden;
    margin: 0 var(--s3) var(--s2);
}

.e-fortschritt-fuell {
    display: block;
    height: 100%;
    border-radius: var(--r-kapsel);
    background: var(--tint);
    transition: width 520ms cubic-bezier(0.32, 0.72, 0, 1);
}

/* Eine Unteraufgabe ist keine eigene Aufgabe — sie führt nirgends hin. */
.e-unteraufgabe { min-height: 52px; cursor: default; }
.e-unteraufgabe:hover { background: transparent; }
.e-unteraufgabe:hover::after { opacity: 0; }

/*
 * Gesperrt heißt: Erst ist etwas anderes dran (A-04). Das steht als
 * Satz daneben, nicht als Fachwort — und der Haken lässt sich schlicht
 * nicht drücken.
 */
.e-unteraufgabe.is-gesperrt { opacity: 0.5; }
.e-unteraufgabe.is-gesperrt .e-check { cursor: not-allowed; }

/* Mehrere Stufen bekommen eine Zwischenzeile, eine einzelne nicht. */
.e-stufe {
    font-size: var(--t-footnote);
    font-weight: 600;
    color: var(--fg-3);
    padding: var(--s3) var(--s4) var(--s1);
    border-bottom: 1px solid var(--line);
}

/* ======================================================= Sicht wechseln */

/*
 * Der Umschalter bekommt ein wanderndes Kissen statt dreier Knöpfe,
 * die einzeln die Farbe wechseln. Das ist der Unterschied zwischen
 * „umgeschaltet" und „hinübergeglitten".
 *
 * Seine Lage wird aus dem Layout gelesen, nicht gerechnet — die
 * Beschriftungen sind verschieden lang.
 */
.e-seg { position: relative; }

.e-seg-kissen {
    position: absolute;
    top: 3px;
    left: 0;
    bottom: 3px;
    z-index: 0;
    opacity: 0;
    border-radius: var(--r-kapsel);
    background: var(--glass-solid);
    box-shadow: var(--shadow);
    transition:
        transform 460ms cubic-bezier(0.34, 1.32, 0.5, 1),
        width 460ms cubic-bezier(0.34, 1.32, 0.5, 1),
        opacity 200ms ease;
    pointer-events: none;
}

/* Die Beschriftungen liegen über dem Kissen. */
.e-seg-knopf { position: relative; z-index: 1; background: transparent; }
.e-seg-knopf.is-on { background: transparent; box-shadow: none; color: var(--fg); font-weight: 600; }

/*
 * Der Inhalt kommt von der Seite herein, in die man gegangen ist.
 * Nach rechts umgeschaltet heißt: der neue Inhalt kommt von rechts.
 * Ohne das ist ein Wechsel ein harter Austausch, und man verliert das
 * Gefühl, wo man ist.
 */
.e-wechsel { animation: 380ms cubic-bezier(0.32, 0.72, 0, 1) both; }
.e-wechsel.is-rechts { animation-name: e-von-rechts; }
.e-wechsel.is-links  { animation-name: e-von-links; }

@keyframes e-von-rechts {
    from { opacity: 0; transform: translateX(26px); }
    to   { opacity: 1; transform: none; }
}

@keyframes e-von-links {
    from { opacity: 0; transform: translateX(-26px); }
    to   { opacity: 1; transform: none; }
}

/* ==================================================== Erscheinungsbild */

/*
 * Das Logo der Firma steht über den Bereichen — dort, wo man den Namen
 * eines Hauses erwartet. Es ist kein Bedienelement und zählt deshalb
 * nicht gegen E-27.
 */
.e-logo {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--s2) var(--s3) var(--s4);
}

.e-logo img {
    max-width: 100%;
    max-height: 40px;
    object-fit: contain;
}

@media (max-width: 899px) {
    /*
     * Unten in der Leiste ist kein Platz dafuer.
     *
     * Im Seitenkopf stand es kurz — und nahm der Ueberschrift so viel
     * Breite, dass der Gruss auf einem Pixel 5 auf drei Zeilen umbrach.
     * Am Handy tragen Farbe und Reitername das Erscheinungsbild.
     */
    .e-logo { display: none; }
}

/* In den Einstellungen: eine kleine Vorschau statt eines Dateinamens. */
.e-logo-probe {
    flex: 0 0 auto;
    width: var(--h-control);
    height: var(--h-control);
    object-fit: contain;
    border-radius: var(--r-control);
    background: var(--glass);
}

/*
 * Der Farbwähler ist der eingebaute des Browsers — er kennt die
 * Farbauswahl des Systems, und die ist besser als jedes Rad, das ich
 * hier nachbaue.
 */
.e-farbwahl {
    flex: 0 0 auto;
    width: var(--h-control);
    height: var(--h-control);
    padding: 2px;
    border: none;
    border-radius: var(--r-kapsel);
    background: var(--glass);
    cursor: pointer;
}
.e-farbwahl::-webkit-color-swatch-wrapper { padding: 0; }
.e-farbwahl::-webkit-color-swatch { border: none; border-radius: var(--r-kapsel); }
.e-farbwahl::-moz-color-swatch { border: none; border-radius: var(--r-kapsel); }

/* ====================================================== Ziehen zum Neuladen */

/*
 * Zum Aktualisieren nach unten ziehen.
 *
 * Die Anzeige haengt oben ausserhalb des Bildes und kommt mit dem
 * Finger herein. Der Ring fuellt sich, waehrend man zieht — dieselbe
 * Bauart wie am Haken (E-04): Widerstand, den man sieht, statt einer
 * Rueckfrage.
 */
.e-zieh {
    position: fixed;
    top: calc(-44px + env(safe-area-inset-top, 0px));
    left: 50%;
    z-index: 40;
    width: 34px;
    height: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--r-kapsel);
    background: var(--glass-schwebend);
    box-shadow: var(--shadow-lift);
    opacity: 0;
    pointer-events: none;
    transform: translate(-50%, var(--zug-weg, 0px));
}

/*
 * Die Seite geht mit. Dieselbe Zahl, damit beides zusammen laeuft und
 * die Anzeige in dem Platz steht, den der Zug freimacht.
 */
.e-main {
    transform: translateY(var(--zug-weg, 0px));
}

body:not(.e-zug-zieht) .e-main {
    transition: transform 320ms cubic-bezier(0.32, 0.72, 0, 1);
}

/*
 * Ohne Finger federt sie zurueck. Waehrend des Ziehens nicht — sonst
 * liefe die Anzeige der Hand hinterher.
 */
body:not(.e-zug-zieht) .e-zieh {
    transition: transform 320ms cubic-bezier(0.32, 0.72, 0, 1), opacity 220ms ease;
}

/*
 * Der Ring als Kuchenstueck, in der Mitte ausgestanzt — wie am Haken.
 * Zwei Masken, weil eine allein nur die Aussenkante beschneidet.
 */
.e-zieh-ring {
    width: 18px;
    height: 18px;
    border-radius: var(--r-kapsel);
    background: conic-gradient(var(--fg-2) var(--zug, 0deg), transparent 0deg);
    -webkit-mask: radial-gradient(circle, transparent 58%, #000 61%);
    mask: radial-gradient(circle, transparent 58%, #000 61%);
}

/* Weit genug: Der Ring nimmt die Farbe des Hauses an. */
.e-zieh.is-bereit .e-zieh-ring {
    background: conic-gradient(var(--tint) var(--zug, 0deg), transparent 0deg);
}

/*
 * Losgelassen: Die Anzeige bleibt stehen und der Ring dreht sich, bis
 * die Antwort da ist. Jetzt ist es ein Rand mit Luecke, kein
 * Kuchenstueck — sonst waere nicht zu sehen, dass er sich dreht.
 */
.e-zieh.is-laeuft { opacity: 1; }

.e-zieh.is-laeuft .e-zieh-ring {
    background: none;
    -webkit-mask: none;
    mask: none;
    border: 2px solid var(--tint);
    border-top-color: transparent;
    animation: e-dreht 620ms linear infinite;
}

/*
 * Der Schlussmoment: Der Ring schliesst sich und geht mit der Seite
 * nach oben. Ohne ihn endet die Geste damit, dass etwas verschwindet.
 */
.e-zieh.is-fertig {
    opacity: 1;
    animation: e-zug-fertig 420ms cubic-bezier(0.32, 0.72, 0, 1) forwards;
}

.e-zieh.is-fertig .e-zieh-ring {
    background: conic-gradient(var(--tint) 360deg, transparent 0deg);
}

@keyframes e-zug-fertig {
    from { opacity: 1; transform: translate(-50%, 56px) scale(1); }
    60%  { opacity: 1; transform: translate(-50%, 30px) scale(1.08); }
    to   { opacity: 0; transform: translate(-50%, -10px) scale(0.8); }
}

/*
 * Wer Bewegung abbestellt hat, bekommt einen stehenden Ring statt
 * eines drehenden — und keinen Abflug, sondern ein Ausblenden.
 */
@media (prefers-reduced-motion: reduce) {
    .e-zieh.is-laeuft .e-zieh-ring { animation: none; }
    .e-zieh.is-fertig { animation: none; opacity: 0; }
}
