/* Schulportal-App — bewusst ohne Framework, damit der Upload zu IONOS
   aus reinem Kopieren besteht und nichts gebaut werden muss.

   Zielgeräte sind große iPhones (rund 400-440 CSS-Pixel Breite). Das Layout
   ist fließend und funktioniert auch deutlich darunter. */

:root {
    --bg: #f2f4f7;
    --surface: #ffffff;
    --surface-alt: #f7f9fc;
    --border: #dfe4ec;
    --border-strong: #c9d2e0;
    --text: #16202e;
    --text-muted: #64748b;
    --text-faint: #6c7787;
    --accent: #12253f;
    --accent-text: #ffffff;

    /* Kopfbereich: schwarz in beiden Modi. Damit sitzt die Statusleiste des
       Telefons auf derselben Fläche und der Übergang fällt nicht auf. */
    --header-bg: #000000;
    --header-text: #ffffff;
    --header-quiet: rgba(255, 255, 255, .62);
    --header-fill: rgba(255, 255, 255, .14);

    --entfall: #d64545;
    --vertretung: #1f7a4d;
    --raum: #b7791f;
    --hinweis: #4a6fa5;

    --radius: 14px;
    --shadow: 0 1px 2px rgba(16, 32, 56, .06), 0 4px 16px rgba(16, 32, 56, .06);
    --safe-top: env(safe-area-inset-top, 0px);
    --safe-bottom: env(safe-area-inset-bottom, 0px);

    /* Breite der Zeitspalte — bestimmt, dass Fach, Lehrkraft und Raum in
       allen Karten an derselben Stelle beginnen. */
    --when-width: 58px;
}

/* Ohne ausdrücklich gewähltes Thema folgt die App dem Telefon. Die
   Einschränkung auf :not([data-theme]) ist wichtig: Sonst würde die
   Systemeinstellung eine Wahl aus den Einstellungen überstimmen. */
@media (prefers-color-scheme: dark) {
    html:not([data-theme]) {
        --bg: #000000;
        --surface: #0e0f12;
        --surface-alt: #16171c;
        --border: #24262d;
        --border-strong: #34373f;
        --text: #f0f1f4;
        --text-muted: #9a9ea8;
        --text-faint: #777b84;
        --accent: #f0f1f4;
        --accent-text: #000000;

        --entfall: #ff7a7a;
        --vertretung: #55d08d;
        --raum: #e5b563;
        --hinweis: #8fb0e6;

        --shadow: none;
        --header-fill: rgba(255, 255, 255, .1);
    }
}

/* ---------- Farbthemen ----------
   Auswahl in den Einstellungen. Ein gesetztes data-theme überstimmt die
   Systemeinstellung; ohne Auswahl greift der Block oben. Die Rollenfarben
   (entfall/vertretung/raum/hinweis) sind je Thema nachjustiert, damit der
   Kontrast auf der jeweiligen Fläche reicht. */

html[data-theme="papier"] {
    --bg: #f5f4f1; --surface: #ffffff; --surface-alt: #f8f7f4;
    --border: #e3e1dc; --border-strong: #cfccc4;
    --text: #1f1f1d; --text-muted: #6b6a64; --text-faint: #77766f;
    --accent: #2b2a27; --accent-text: #ffffff;
    --header-bg: #000000; --header-text: #ffffff;
    --entfall: #c53b3b; --vertretung: #257a4c; --raum: #9a6a15; --hinweis: #3f6ea6;
    --shadow: 0 1px 2px rgba(32, 30, 26, .05), 0 4px 14px rgba(32, 30, 26, .05);
}

html[data-theme="tiefschwarz"] {
    --bg: #000000; --surface: #121212; --surface-alt: #1a1a1a;
    --border: #262626; --border-strong: #3a3a3a;
    --text: #ececec; --text-muted: #a3a3a3; --text-faint: #7d7d7d;
    --accent: #e8e8e8; --accent-text: #111111;
    --header-bg: #000000; --header-text: #ffffff;
    --entfall: #ff7a76; --vertretung: #4fd08c; --raum: #e0b25c; --hinweis: #8ab4f8;
    /* Schatten sind auf Schwarz unsichtbar — die Ränder übernehmen. */
    --shadow: none;
    --header-fill: rgba(255, 255, 255, .1);
}

html[data-theme="waldnacht"] {
    --bg: #0f1613; --surface: #16211c; --surface-alt: #1c2a23;
    --border: #29392f; --border-strong: #3b5244;
    --text: #e7efe9; --text-muted: #9db4a6; --text-faint: #758b7c;
    --accent: #245c43; --accent-text: #ffffff;
    --header-bg: #0b120e; --header-text: #ffffff;
    --entfall: #f28b82; --vertretung: #57c98c; --raum: #e3b75f; --hinweis: #7fb3d5;
    --shadow: 0 1px 2px rgba(0, 0, 0, .35), 0 4px 16px rgba(0, 0, 0, .28);
    --header-fill: rgba(255, 255, 255, .12);
}

html[data-theme="pflaume"] {
    --bg: #171221; --surface: #201933; --surface-alt: #281f3f;
    --border: #362b52; --border-strong: #4a3d6b;
    --text: #ece7f5; --text-muted: #a99fc4; --text-faint: #8980a3;
    --accent: #5b46a8; --accent-text: #ffffff;
    --header-bg: #0f0a1a; --header-text: #ffffff;
    --entfall: #ff7b7b; --vertretung: #5bd096; --raum: #e5b566; --hinweis: #8fb4ee;
    --shadow: 0 1px 2px rgba(10, 5, 25, .4), 0 4px 16px rgba(10, 5, 25, .3);
    --header-fill: rgba(255, 255, 255, .12);
}

html[data-theme="sandstein"] {
    --bg: #f6efe4; --surface: #fffdf8; --surface-alt: #f9f3e8;
    --border: #e6dcc8; --border-strong: #d0c3a8;
    --text: #2b241a; --text-muted: #6e6353; --text-faint: #7f7465;
    --accent: #8a4b2e; --accent-text: #ffffff;
    --header-bg: #201812; --header-text: #ffffff;
    --entfall: #bf3f34; --vertretung: #256e46; --raum: #9c6410; --hinweis: #3e6796;
    --shadow: 0 1px 2px rgba(70, 55, 35, .07), 0 4px 16px rgba(70, 55, 35, .07);
}

html[data-theme="nordlicht"] {
    --bg: #eef4f4; --surface: #ffffff; --surface-alt: #f2f8f8;
    --border: #d7e3e3; --border-strong: #b9cccc;
    --text: #14262a; --text-muted: #52696e; --text-faint: #677a7e;
    --accent: #0e5f66; --accent-text: #ffffff;
    --header-bg: #0b2a2e; --header-text: #ffffff;
    --entfall: #c8453e; --vertretung: #1f7a4d; --raum: #a5731c; --hinweis: #2f6f9f;
    --shadow: 0 1px 2px rgba(15, 45, 50, .06), 0 4px 16px rgba(15, 45, 50, .07);
}

html[data-theme="dotter"] {
    --bg: #ffcf33; --surface: #fffdf2; --surface-alt: #fff3c9;
    --border: #e0b93e; --border-strong: #a88a1a;
    --text: #241c00; --text-muted: #6b5c14; --text-faint: #7d6b26;
    --accent: #241c00; --accent-text: #ffd84d;
    --header-bg: #1a1400; --header-text: #ffd84d;
    /* raum ist nach Braun abgedunkelt — reines Amber ertrinkt im gelben Grund. */
    --entfall: #c22f22; --vertretung: #1d7a3f; --raum: #8a5a00; --hinweis: #2456a6;
    --shadow: 0 1px 2px rgba(90, 70, 0, .14), 0 4px 14px rgba(90, 70, 0, .12);
}

html[data-theme="tiefsee"] {
    --bg: #04252b; --surface: #073540; --surface-alt: #0a4250;
    --border: #10586a; --border-strong: #1a7286;
    --text: #e4f6f8; --text-muted: #9fd0d8; --text-faint: #74b2bd;
    --accent: #ff7a59; --accent-text: #2b0d02;
    --header-bg: #021a1f; --header-text: #e4f6f8;
    --entfall: #ff8577; --vertretung: #4ade80; --raum: #ffc266; --hinweis: #8fb9ff;
    --shadow: 0 1px 2px rgba(0, 10, 12, .5), 0 4px 16px rgba(0, 10, 12, .4);
    --header-fill: rgba(255, 255, 255, .14);
}

html[data-theme="minze"] {
    --bg: #e4f2ea; --surface: #ffffff; --surface-alt: #eff8f3;
    --border: #c9e2d5; --border-strong: #a4cab7;
    --text: #0f2619; --text-muted: #486255; --text-faint: #5d7668;
    --accent: #0c6a4d; --accent-text: #ffffff;
    --header-bg: #0a2a20; --header-text: #ffffff;
    /* vertretung ist deutlich abgedunkelt: Das übliche Grün liegt zu nah am
       Minzgrund und die Pille verschwände darin. Dunkelgrün trägt auch als
       Text auf der hellen Fläche. */
    --entfall: #c4382c; --vertretung: #11663a; --raum: #96650f; --hinweis: #2a5fa8;
    --shadow: 0 1px 2px rgba(15, 60, 40, .07), 0 4px 16px rgba(15, 60, 40, .08);
}

html[data-theme="himmel"] {
    --bg: #e7f1fb; --surface: #ffffff; --surface-alt: #f1f7fd;
    --border: #cddfef; --border-strong: #a6c4e2;
    --text: #0f2137; --text-muted: #45607c; --text-faint: #5b748f;
    --accent: #0f5493; --accent-text: #ffffff;
    --header-bg: #0a2036; --header-text: #ffffff;
    /* hinweis wandert ins Indigo: Als Blau läge er auf dem blauen Grund und
       die getönten Flächen wären nicht mehr abzugrenzen. */
    --entfall: #c33a2c; --vertretung: #146b3d; --raum: #93630e; --hinweis: #4340a8;
    --shadow: 0 1px 2px rgba(15, 40, 70, .07), 0 4px 16px rgba(15, 40, 70, .08);
}

/* ---------- Die drei dunklen Gegenstücke vom 12.09.2026 ----------
   Seit die Themen Paare bilden (THEMEN_PAARE in app.js), braucht jedes
   helle Thema ein dunkles in derselben Farbfamilie. Drei hatten keins.
   Alle Werte gegen die Fläche gerechnet: text-faint über 5,5:1, die
   Rollenfarben über 7:1, Kopfzeile über 16:1. */

/* Mitternacht: das dunkle Gegenstück zu Himmel. Marineblau statt
   Hellblau, der Akzent ein helles Blau, das auf der Fläche als Text
   trägt (7,5:1). */
html[data-theme="mitternacht"] {
    --bg: #0b1626; --surface: #12203a; --surface-alt: #182a48;
    --border: #24395e; --border-strong: #35507f;
    --text: #e8eefb; --text-muted: #a9b8d6; --text-faint: #8497bb;
    --accent: #7fb2ff; --accent-text: #061225;
    --header-bg: #070f1d; --header-text: #e8eefb;
    --entfall: #ff8a80; --vertretung: #5fd39a; --raum: #f0c46c; --hinweis: #9ec1ff;
    --shadow: 0 1px 2px rgba(0, 5, 20, .5), 0 4px 16px rgba(0, 5, 20, .4);
    --header-fill: rgba(255, 255, 255, .14);
}

/* Rinde: das dunkle Gegenstück zu Sandstein. Warmes Braun, der Akzent
   ein Bernsteinorange. */
html[data-theme="rinde"] {
    --bg: #1b120c; --surface: #27190f; --surface-alt: #332214;
    --border: #4a3320; --border-strong: #654630;
    --text: #f6ebdf; --text-muted: #cdb59e; --text-faint: #a89079;
    --accent: #f0a35a; --accent-text: #241203;
    --header-bg: #120b06; --header-text: #f6ebdf;
    --entfall: #ff8d7a; --vertretung: #74cf8e; --raum: #ffcb6b; --hinweis: #9fbfff;
    --shadow: 0 1px 2px rgba(10, 4, 0, .5), 0 4px 16px rgba(10, 4, 0, .4);
    --header-fill: rgba(255, 255, 255, .14);
}

/* Bernstein: das dunkle Gegenstück zu Dotter. Dotter ist laut und
   gelb; nachts dreht sich das um — dunkler Grund, das Gelb bleibt als
   Akzent. raum ist bewusst gedämpfter als der Akzent, sonst wären zwei
   Gelbs auf einer Karte nicht auseinanderzuhalten. */
html[data-theme="bernstein"] {
    --bg: #171410; --surface: #221e16; --surface-alt: #2d281d;
    --border: #433c29; --border-strong: #5c5236;
    --text: #f7f1dc; --text-muted: #c9bf9f; --text-faint: #a39a7c;
    --accent: #ffcf33; --accent-text: #1a1400;
    --header-bg: #0f0d08; --header-text: #f7f1dc;
    --entfall: #ff8a7a; --vertretung: #6fd39a; --raum: #e0b25c; --hinweis: #98b8ff;
    --shadow: 0 1px 2px rgba(5, 4, 0, .5), 0 4px 16px rgba(5, 4, 0, .4);
    --header-fill: rgba(255, 255, 255, .14);
}

/* Das Hausthema. Warmes Dunkelgrau, waagerechte Schichten, eine kupferne
   Linie als Akzent — die Handschrift von taher.de.

   Die Streifen laufen nur über den Grund, nicht über die Karten: Dort steht
   Text, und eine Textur darunter macht ihn schwerer lesbar. So rahmt die
   Schichtung den Inhalt, statt mit ihm zu konkurrieren. */
html[data-theme="taher"] {
    --bg: #3a3937;
    --bg-bild: repeating-linear-gradient(
        to bottom,
        rgba(255, 255, 255, .035) 0,
        rgba(255, 255, 255, .035) 1px,
        transparent 1px,
        transparent 4px
    );
    --surface: #46443f; --surface-alt: #403e3a;
    --border: #57544e; --border-strong: #706c65;
    --text: #f3f1ed; --text-muted: #b7b2aa; --text-faint: #b8b2a9;
    /* Das Kupfer der Linie aus der Vorlage, aufgehellt bis es als Text auf
       der Karte trägt: #c08f68 kam nur auf 3,4:1. Die anderen dunklen Themen
       liegen beim Akzent noch niedriger, weil er dort fast nur als Fläche
       vorkommt — an ein paar Stellen ist er aber Text ("Ganze Nachricht
       lesen", die Hausaufgabenmarke), und dort zählt es. */
    --accent: #dcb18e; --accent-text: #241f1a;
    --header-bg: #2b2a28; --header-text: #f3f1ed;
    /* Auf warmem Grau brauchen die Statusfarben mehr Helligkeit als auf
       Schwarz — sonst sinken sie in den Grund ein. */
    --entfall: #ff9384; --vertretung: #7ad9a4; --raum: #e8bc6b; --hinweis: #9cc2e8;
    --shadow: 0 1px 2px rgba(0, 0, 0, .28), 0 4px 16px rgba(0, 0, 0, .24);
}

/* Dasselbe Haus bei Tageslicht. Warmes Papiergrau statt warmes Dunkelgrau,
   dieselbe Schichtung — nur als dunkle Linien auf hellem Grund statt
   umgekehrt.

   Das Kupfer geht hier in die andere Richtung als im dunklen Thema: Dort
   musste es aufgehellt werden (#dcb18e), hier abgedunkelt (#9a5a2f), damit
   es auf der Fläche trägt. Beides ist dieselbe Farbe der Vorlage, jeweils
   so weit gedreht, dass sie als Text lesbar bleibt.

   Die Kopfzeile bleibt das dunkle Warmgrau des Hausthemas. Sie ist das
   Wiedererkennungszeichen, und die anderen hellen Themen halten es
   genauso. */
html[data-theme="taher-hell"] {
    --bg: #e6e3dd;
    --bg-bild: repeating-linear-gradient(
        to bottom,
        rgba(0, 0, 0, .030) 0,
        rgba(0, 0, 0, .030) 1px,
        transparent 1px,
        transparent 4px
    );
    --surface: #f7f5f1; --surface-alt: #efece6;
    --border: #d5d1c9; --border-strong: #b3aea4;
    --text: #2a2724; --text-muted: #5f5a53; --text-faint: #726c63;
    --accent: #9a5a2f; --accent-text: #ffffff;
    --header-bg: #2b2a28; --header-text: #f3f1ed;
    --entfall: #c03a2b; --vertretung: #1f7048; --raum: #8a5f0e; --hinweis: #2a6296;
    --shadow: 0 1px 2px rgba(58, 57, 55, .08), 0 4px 16px rgba(58, 57, 55, .09);
}

html[data-theme="beere"] {
    --bg: #f5cfe0; --surface: #fdf3f8; --surface-alt: #f9e4ee;
    --border: #e3aac6; --border-strong: #c97fa5;
    --text: #3a0f24; --text-muted: #82365a; --text-faint: #9a5274;
    --accent: #a81b5e; --accent-text: #ffffff;
    --header-bg: #2b0a1b; --header-text: #ffd9ea;
    /* entfall ist Zinnober statt Karmin — Karminrot verschwimmt mit Beere. */
    --entfall: #c93a1d; --vertretung: #1e7a46; --raum: #96610d; --hinweis: #3757a8;
    --shadow: 0 1px 2px rgba(90, 20, 50, .12), 0 4px 16px rgba(90, 20, 50, .1);
}

* { box-sizing: border-box; }

/*
 * Kein Doppeltipp-Zoom in der ganzen App.
 *
 * Zwei schnelle Berührungen versteht Safari als "heranzoomen". Beim
 * Abhaken, beim Blättern durch die Tage, beim Antippen zweier Karten kurz
 * nacheinander springt die Seite dann heran, und man tippt ins Leere.
 * Bisher stand das nur an der Fassungsnummer, wo es für das versteckte
 * Spiel gebraucht wurde; die Begründung gilt überall.
 *
 * Der Stern und nicht html/body: touch-action VERERBT SICH NICHT. Auf
 * body gesetzt bliebe auf jeder Karte und jedem Knopf "auto" stehen —
 * also genau dort, wo doppelt getippt wird.
 *
 * Ohne Klasse, damit jede benannte Regel gewinnt: Die Spielfläche
 * braucht "none" und behält es.
 *
 * "manipulation" schaltet GENAU den Doppeltipp ab. Wischen, Scrollen und
 * die Lupe mit zwei Fingern bleiben. Anders als user-scalable=no im Kopf
 * der Seite: Das nähme auch das Vergrössern, und wer schlecht sieht, soll
 * vergrössern können — Safari übergeht es seit iOS 10 ohnehin.
 */
* { touch-action: manipulation; }

/*
 * Links im Fließtext.
 *
 * Ohne diese Regel nimmt der Browser sein eigenes Blau (#0000ee). Auf
 * hellem Grund geht das gerade noch; auf den dunklen Themen kam ein
 * Kontrast von 1,4:1 heraus — am 05.09.2026 gemessen, nötig sind 4,5:1.
 * Betroffen waren die Quellenangabe in "Über die App", die Anschriften
 * unter Impressum und Datenschutz, und jeder Link, den eine Lehrkraft in
 * einen Elternbrief schreibt.
 *
 * color: inherit statt einer eigenen Farbe: Die App hat dreizehn Themen,
 * und eine feste Linkfarbe wäre in mindestens einem davon wieder falsch.
 * Die Textfarbe stimmt in jedem, und der Unterstrich zeigt den Link.
 *
 * Nur der Elementselektor, damit jede Klasse mit eigener Farbe gewinnt —
 * die Knöpfe, die als <a> gebaut sind, behalten ihr Aussehen.
 */
a {
    color: inherit;
    text-decoration: underline;
    text-underline-offset: 2px;
}

/*
 * Formularelemente erben die Schrift der App.
 *
 * Ohne diese Regel nehmen button, input und select die Vorgabe des
 * Browsers — auf dem iPhone Arial statt San Francisco. Am 07.09.2026
 * über die ganze App gemessen: alle Eingabefelder, alle Auswahlfelder,
 * das ×-Schliessen in achtzehn Blättern, der Zurück-Pfeil der
 * Einstellungen, das Auge am Passwortfeld und die ‹ › zum Blättern im
 * Tagesplan. Nur textarea war richtig gesetzt.
 *
 * Es ist dasselbe Versehen, das schon dreimal einzeln gemeldet und
 * dreimal einzeln repariert wurde — an der Terminzeile, am Portal-Knopf,
 * an den Kontakt-Wegen. Hier steht es jetzt an einer Stelle für alle.
 *
 * NUR font-family, nicht die Sammeleigenschaft font: Die Symbole sind
 * in rem bemessen (1,3rem für das ×, 1,6rem für den Pfeil) und tragen
 * ein eigenes line-height. "font: inherit" nähme beides mit.
 */
button,
input,
select,
textarea {
    font-family: inherit;
}

/*
 * Und Eingabefelder nie unter 16 Pixel.
 *
 * Safari auf dem iPhone zoomt beim Antippen in jedes Feld hinein, das
 * kleiner gesetzt ist — die Seite springt, und der Nutzer muss sie von
 * Hand zurückziehen. Die Formularzeilen der Einstellungen laufen auf
 * 0,88rem; ein Feld, das das erbt, läge bei 14.
 */
input,
select,
textarea {
    font-size: max(16px, 1rem);
}

html, body {
    margin: 0;
    padding: 0;
    /* Zwei Angaben, nicht eine: Ein Thema darf über die Farbe hinaus eine
       Textur mitbringen. Gebraucht wird das für "taher.de", dessen
       Kennzeichen die waagerechten Schichten sind. Alle anderen Themen
       setzen --bg-bild nicht und bekommen über den Rückfall "none" genau
       das, was sie vorher hatten. */
    background-color: var(--bg);
    background-image: var(--bg-bild, none);
    color: var(--text);
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
    font-size: 16px;
    line-height: 1.45;
    -webkit-text-size-adjust: 100%;
}

[hidden] { display: none !important; }

/* ---------- Anmeldung ---------- */

.login {
    min-height: 100dvh;
    display: grid;
    place-items: center;
    padding: 24px;
}

.login__box {
    width: 100%;
    max-width: 360px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 28px 24px;
}

.login__title { margin: 0 0 4px; font-size: 1.4rem; }
.login__hint { margin: 0 0 20px; color: var(--text-muted); font-size: .92rem; }
.login__label { display: block; font-size: .85rem; color: var(--text-muted); margin-bottom: 6px; }

.login__input,
.login__button {
    width: 100%;
    font-size: 1rem;
    border-radius: 10px;
    padding: 12px 14px;
    border: 1px solid var(--border);
}

.login__input { background: var(--surface-alt); color: var(--text); margin-bottom: 16px; }
.login__input:focus { outline: 2px solid var(--hinweis); outline-offset: 1px; }

.login__button {
    background: var(--accent);
    color: var(--accent-text);
    border-color: var(--accent);
    font-weight: 600;
    cursor: pointer;
}

.login__error { margin: 14px 0 0; color: var(--entfall); font-size: .9rem; }

/* ---------- Passwortfelder mit Auge ---------- */

/* Der Wrapper nimmt den Platz des Feldes ein — auch in den Zeilen der
   Formulare, die nebeneinander liegen. */
.pw {
    position: relative;
    display: block;
    flex: 1;
    min-width: 0;
}

/* Der Abstand wandert an den Wrapper, sonst säße das Auge zu hoch. */
.login__box .pw { margin-bottom: 16px; }
.login__box .pw .login__input { margin-bottom: 0; }

.pw input { width: 100%; padding-right: 46px; }

.pw__eye {
    position: absolute;
    top: 50%;
    right: 4px;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    padding: 0;
    background: none;
    border: 0;
    border-radius: 8px;
    color: var(--text-muted);
    cursor: pointer;
}

.pw__eye:hover { color: var(--text); }
.pw__eye svg { width: 20px; height: 20px; display: block; }

/* Safari blendet in Passwortfeldern selbst ein Symbol ein — das würde
   doppelt stehen. */
.pw input::-ms-reveal,
.pw input::-webkit-credentials-auto-fill-button { display: none; }

/* Da, aber unsichtbar: display:none oder visibility:hidden würde die
   Passwortverwaltung dazu bringen, das Feld zu übergehen. */
.login__ghost {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    border: 0;
    opacity: 0;
    pointer-events: none;
}

.login__remember {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: -4px 0 18px;
    font-size: .88rem;
    color: var(--text-muted);
    cursor: pointer;
}

.login__remember input { width: 18px; height: 18px; flex: none; }

/* Zweite Möglichkeit neben dem Passwort — sichtbar, aber nicht die Hauptsache. */
.login__button--ghost {
    margin-top: 12px;
    background: none;
    color: var(--text);
    border-color: var(--border-strong);
}

/* Zwischenüberschrift im Einrichtungsformular */
.login__section {
    margin: 22px 0 14px;
    padding-top: 16px;
    border-top: 1px solid var(--border);
    font-size: .85rem;
    font-weight: 600;
    color: var(--text);
}

.login__link {
    display: block;
    width: 100%;
    margin-top: 16px;
    padding: 10px;
    background: none;
    border: 0;
    color: var(--hinweis);
    font-size: .9rem;
    text-decoration: underline;
    cursor: pointer;
}

/*
 * Impressum und Datenschutz unter dem Anmeldebildschirm.
 *
 * Kleiner und blasser als die Knöpfe darüber: Sie müssen zu finden sein,
 * aber niemand kommt hierher, um sie zu suchen. Die Fußzeile steht
 * außerhalb der Formulare und damit unter jedem von ihnen.
 */
.login__fuss {
    margin: 20px 0 0;
    text-align: center;
    color: var(--hinweis);
    font-size: .82rem;
}

.login__fuss-link,
.ueber__link {
    padding: 6px 4px;
    background: none;
    border: 0;
    color: inherit;
    font: inherit;
    text-decoration: underline;
    cursor: pointer;
}

/* Etwas Luft nach oben: Die Zeile schließt "Über die App" ab. */
.ueber__zeile--recht {
    margin-top: 14px;
}

/*
 * Impressum und Datenschutz im Blatt.
 *
 * Fließtext, den jemand wirklich liest — also schmaler als das Blatt und
 * mit mehr Zeilenabstand als die Listen der App. Die Zwischentitel sind
 * die einzige Gliederung; sie tragen die Last, dass niemand so einen Text
 * von oben nach unten liest, sondern die Stelle sucht, die ihn angeht.
 */
.recht {
    padding: 0 4px 8px;
    line-height: 1.55;
}

.recht h3 {
    margin: 22px 0 6px;
    font-size: 1rem;
}

.recht p {
    margin: 0 0 10px;
}

.recht ul {
    margin: 0 0 12px;
    padding-left: 20px;
}

.recht li {
    margin-bottom: 6px;
}

.recht__klein {
    color: var(--hinweis);
    font-size: .85rem;
}

/* Eine Anschrift wird gelesen wie eine Anschrift, nicht wie ein Satz. */
.recht__adresse {
    line-height: 1.5;
}

/* Das Formular kann länger als der Bildschirm sein — dann oben beginnen
   statt mittig, sonst schneidet die Mitte-Ausrichtung den Anfang ab. */
.login--tall { align-items: start; }

/* ---------- Der Start in der Handschrift von taher.de (12.09.2026) ----------

   Nur, was VOR der Anmeldung zu sehen ist: Anmeldemaske, Einrichtungs-
   Assistent, Zurücksetzen. Alles hier hängt an #login und an sonst nichts.
   Drinnen gilt das Farbthema der Familie, und daran ändert dieser Block
   nichts — das war die Vorgabe.

   Die Palette ist die der Startseite taher.de: warmes Dunkelgrau,
   Cremeweiß, Lehm als Akzent, waagerechte Schichtlinien wie ein Druckbett.
   Bewusst unabhängig vom gewählten Thema: Der Start ist die Visitenkarte,
   nicht die Wohnung.

   Die Schriften liegen im Paket (assets/fonts), nicht bei Google: Die
   Inhaltsrichtlinie der App lässt nichts von außen zu, und das soll so
   bleiben. Archivo und IBM Plex stehen unter der SIL Open Font License.
   Variable Dateien: eine Datei trägt Archivo 600 und 700, eine Plex Sans
   400 und 500. Geladen werden sie erst, wenn der Start sie braucht.

   Kontraste gerechnet: Text 8,6:1, gedämpfter Text 5,1:1, Verweise 5,1:1,
   Fehler 4,8:1 — alle auf dem Grund. Der Lehm selbst trägt keinen Text
   (3,8:1); er ist Rand und Fläche. */

@font-face {
    font-family: "Archivo";
    font-style: normal;
    font-weight: 600 700;
    font-display: swap;
    src: url("fonts/archivo-700.woff2") format("woff2");
}
@font-face {
    font-family: "IBM Plex Sans";
    font-style: normal;
    font-weight: 400 500;
    font-display: swap;
    src: url("fonts/ibm-plex-sans-400.woff2") format("woff2");
}
@font-face {
    font-family: "IBM Plex Mono";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("fonts/ibm-plex-mono-400.woff2") format("woff2");
}
@font-face {
    font-family: "IBM Plex Mono";
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url("fonts/ibm-plex-mono-500.woff2") format("woff2");
}

/* Der Grund UNTER dem Start: html und body tragen sonst das Farbthema, und
   das scheint oben hinter der Statusleiste (viewport-fit=cover) und unten
   beim Überziehen durch. Die Klasse setzt app.js, solange der Start offen
   ist. Die einzige Regel dieses Blocks, die nicht an #login hängt — sie
   muss darüber liegen, um darunter zu wirken. */
html.start-offen,
html.start-offen body {
    background: #454340;
    background-image: none;
}

#login {
    --s-paper: #454340;
    --s-ink: #F0EFEB;
    --s-muted: #BDBAB3;
    --s-rule: #5C5955;
    --s-accent: #CE9468;
    --s-accent-text: #E3B08A;
    --s-feld: #524f4b;
    --s-fehler: #FF9A8A;
    --s-line: rgba(255, 255, 255, .05);
    --s-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, monospace;

    position: relative;
    background: var(--s-paper);
    color: var(--s-ink);
    color-scheme: dark;
    font-family: "IBM Plex Sans", system-ui, -apple-system, sans-serif;
    -webkit-font-smoothing: antialiased;
}

/* Schichtlinien über der ganzen Fläche, wie auf taher.de. Fixiert, damit
   sie beim Scrollen eines langen Assistenten stehen bleiben; ohne
   Zeigerereignisse, damit kein Feld darunter verdeckt ist. */
#login::before {
    content: "";
    position: fixed;
    inset: 0;
    background: repeating-linear-gradient(to bottom, var(--s-line) 0 1px, transparent 1px 5px);
    pointer-events: none;
    z-index: 2;
}

/* Kein Kasten mehr: Die Startseite kennt keine Karten, nur Fläche, Linie
   und Schrift. */
#login .login__box {
    position: relative;
    z-index: 3;
    max-width: 440px;
    padding: 20px 6px 24px;
    background: none;
    border: 0;
    box-shadow: none;
}

#login .login__logo { height: 34px; margin: 0 0 22px; }

#login .login__eyebrow,
#login .login__label,
#login .assistent__zaehler,
#login .login__fuss {
    font-family: var(--s-mono);
    font-size: .72rem;
    font-weight: 500;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--s-muted);
}
#login .login__eyebrow { margin: 0 0 12px; }
#login .login__label { margin-bottom: 8px; }
#login .assistent__zaehler { color: var(--s-accent-text); }

#login .login__title {
    font-family: "Archivo", "Helvetica Neue", Arial, sans-serif;
    font-weight: 600;
    font-size: 1.55rem;
    line-height: 1.1;
    letter-spacing: -.02em;
    margin: 0 0 10px;
}

/* Der Schriftzug: baut sich einmal von unten auf, mit den feinen
   Schichtkanten darüber — die Handschrift der Startseite. */
#login .login__title--marke {
    position: relative;
    font-weight: 700;
    font-size: clamp(3rem, 16vw, 4.6rem);
    line-height: .9;
    letter-spacing: -.045em;
    margin: 0 0 18px;
    clip-path: inset(100% 0 0 0);
    animation: start-build 1.1s cubic-bezier(.2, .7, .2, 1) .15s forwards;
}
#login .login__title--marke::after {
    content: "";
    position: absolute;
    inset: -2px;
    background: repeating-linear-gradient(to bottom, var(--s-paper) 0 1px, transparent 1px 4px);
    opacity: .55;
    pointer-events: none;
}
@keyframes start-build { to { clip-path: inset(0 0 0 0); } }

/* Die Messlatte: ein Stück Lehm, dann die Linie. */
#login .login__rule { display: flex; height: 2px; margin: 0 0 22px; }
#login .login__rule-accent { flex: none; width: 38%; background: var(--s-accent); }
#login .login__rule-rest { flex: 1; background: var(--s-rule); }

#login .login__hint { color: var(--s-muted); line-height: 1.55; }
#login .login__hint strong { color: var(--s-ink); font-weight: 500; }
#login .login__hint kbd { background: rgba(255, 255, 255, .12); border: 1px solid rgba(255, 255, 255, .25); }

#login .login__input {
    background: var(--s-feld);
    color: var(--s-ink);
    border: 1px solid var(--s-rule);
    border-radius: 8px;
}
#login .login__input::placeholder { color: #A7A49D; }
#login .login__input:focus { outline: 2px solid var(--s-accent); outline-offset: 1px; }

/* Knöpfe wie auf taher.de: Lehm als Rand und Hauch von Fläche, Pille. */
#login .login__button {
    background: rgba(206, 148, 104, .16);
    color: var(--s-ink);
    border: 2px solid var(--s-accent);
    border-radius: 30px;
    font-weight: 600;
    transition: background .25s ease;
}
#login .login__button:hover,
#login .login__button:focus-visible { background: rgba(206, 148, 104, .36); }
#login .login__button--ghost,
#login .login__button--still {
    background: transparent;
    border-color: var(--s-rule);
    color: var(--s-ink);
}
#login .login__button--ghost:hover,
#login .login__button--still:hover { background: rgba(255, 255, 255, .06); }

#login .login__link,
#login .login__fuss-link {
    color: var(--s-accent-text);
    text-decoration: none;
    border-bottom: 1px solid transparent;
    transition: border-color .25s ease;
}
#login .login__link:hover,
#login .login__link:focus-visible,
#login .login__fuss-link:hover,
#login .login__fuss-link:focus-visible { border-color: var(--s-accent); }
#login .login__link { display: inline-block; width: auto; padding: 8px 0 3px; }
#login .login__fuss { margin-top: 26px; }
#login .login__fuss-link { font: inherit; letter-spacing: inherit; text-transform: inherit; }

#login .login__error { color: var(--s-fehler); }
#login .login__error--warten { color: var(--s-muted); border-left-color: var(--s-accent); }
#login .login__hint--warnung {
    background: rgba(255, 154, 138, .12);
    border-left-color: var(--s-fehler);
    color: var(--s-ink);
}
#login .login__remember { color: var(--s-muted); }
#login input[type="checkbox"],
#login input[type="radio"] { accent-color: var(--s-accent); }
#login .login__section { border-top-color: var(--s-rule); color: var(--s-ink); }
#login .pw__eye { color: var(--s-muted); }
#login .pw__eye:hover { color: var(--s-ink); }

#login .druckwahl__knopf {
    background: var(--s-feld);
    border-color: var(--s-rule);
    color: var(--s-muted);
}
#login .druckwahl__knopf.is-aktiv { border-color: var(--s-accent); color: var(--s-ink); }

#login :focus-visible { outline: 2px solid var(--s-accent); outline-offset: 3px; }

@media (prefers-reduced-motion: reduce) {
    #login .login__title--marke { clip-path: none; animation: none; }
}

/* ---------- Kopfbereich ---------- */

.header {
    position: sticky;
    top: 0;
    z-index: 10;
    background: var(--header-bg);
    color: var(--header-text);
    border-bottom: 1px solid rgba(255, 255, 255, .08);
    /* Seitlich keine Polsterung: Die tragen Zeile und Reiter selbst, damit
       sie auf dieselbe Spalte gehen wie der Inhalt. Die Fläche der Leiste
       soll aber über die ganze Breite laufen — sonst endet das Schwarz
       mitten im Bildschirm. */
    padding: calc(var(--safe-top) + 14px) 0 0;
}

/*
 * Kopfzeile und Reiter auf derselben Spalte wie der Inhalt.
 *
 * Ohne das spannen sie über die ganze Breite, während .main bei 720 Punkten
 * zentriert steht — auf einem iPad quer saß das Zahnrad damit 180 Punkte
 * neben allem, worauf es sich bezieht.
 *
 * Bewusst keine Medienabfrage: Die Grenze ist nicht eine Gerätebreite,
 * sondern die Lesespalte. Auf einem Telefon (390 Punkte) tut die Regel
 * nichts, weil 390 kleiner als 720 ist. Deshalb dieselben 720 und dieselben
 * 16 Punkte Polsterung wie .main, samt border-box — sonst stünde die
 * Kopfzeile um genau diese 16 Punkte versetzt.
 */
.header__row,
.tabs {
    box-sizing: border-box;
    max-width: 720px;
    margin-left: auto;
    margin-right: auto;
    padding-left: 16px;
    padding-right: 16px;
}

.header__row {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
}

/* Logo und Titel als Einheit. Der Titel darf schrumpfen, das Logo nicht. */
.header__brand {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}

.header__logo {
    flex: none;
    /* Die Marke ist quadratisch; Höhe festlegen genügt. 30px, weil das
       Raster darunter sonst zu einem Farbfleck zusammenläuft. */
    height: 30px;
    width: auto;
}

.header__title {
    margin: 0;
    font-size: 1.02rem;
    font-weight: 650;
    line-height: 1.2;
    /* Hier steht der Name des Kindes. Kurz, aber nicht kalkulierbar —
       Doppelnamen kommen vor. Umbrechen ist besser, als die Knöpfe zu
       verdrängen. */
    overflow-wrap: anywhere;
}
/* Gedämpft über die Farbe, nicht über opacity: Die Warnung zum Alter der
   Daten steht in derselben Zeile und darf nicht mitgedämpft werden. */
.header__subtitle { margin: 2px 0 0; font-size: .85rem; color: var(--header-quiet); }

.header__actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: none;
}

.header__icon {
    background: var(--header-fill);
    color: inherit;
    border: 0;
    border-radius: 10px;
    width: 40px;
    height: 40px;
    font-size: 1.2rem;
    line-height: 1;
    cursor: pointer;
    flex: none;
    /* Bezugspunkt für den Neuigkeiten-Punkt. */
    position: relative;
}

/* Gezeichnete Symbole in der Kopfzeile: 20 Pixel, mittig, in der Farbe des
   Knopfs. Dieselbe Höhe, die die Schriftzeichen der Nachbarn einnehmen. */
.header__svg {
    display: block;
    width: 20px;
    height: 20px;
    margin: 0 auto;
}
.header__svg[hidden] { display: none; }

/* Ein Punkt, keine Zahl: Wie viele Neuigkeiten es sind, hilft niemandem —
   dass es welche gibt, schon. Er sitzt am Rand des Zahnrads und nicht darauf,
   damit das Symbol lesbar bleibt. */
.header__punkt {
    position: absolute;
    top: 6px;
    right: 6px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--entfall);
}

#refresh.is-busy { animation: spin .9s linear infinite; }

@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- Reiter ---------- */

.tabs {
    display: flex;
    gap: 2px;
    margin-top: 12px;
    overflow-x: auto;
    scrollbar-width: none;
}

.tabs::-webkit-scrollbar { display: none; }

.tabs__tab {
    flex: 1 1 auto;
    min-width: 0;
    background: none;
    border: 0;
    border-bottom: 3px solid transparent;
    color: var(--header-quiet);
    font: inherit;
    font-size: .85rem;
    padding: 10px 6px;
    cursor: pointer;
    white-space: nowrap;
}

.tabs__tab.is-active {
    color: var(--header-text);
    border-bottom-color: var(--header-text);
    font-weight: 600;
}

.badge {
    display: inline-block;
    min-width: 16px;
    margin-left: 1px;
    padding: 0 4px;
    border-radius: 9px;
    background: var(--entfall);
    color: #fff;
    font-size: .72rem;
    font-weight: 700;
    line-height: 18px;
    text-align: center;
}

/* ---------- Inhalt ---------- */

.main {
    padding: 16px 16px calc(var(--safe-bottom) + 16px);
    max-width: 720px;
    margin: 0 auto;
}

.panel { display: none; }
.panel.is-active { display: block; }

.notice {
    background: color-mix(in srgb, var(--raum) 14%, var(--surface));
    border: 1px solid color-mix(in srgb, var(--raum) 35%, var(--border));
    border-radius: var(--radius);
    padding: 12px 14px;
    margin: 0 0 16px;
    font-size: .9rem;
}

/* "Im Schulportal als erledigt markiert." Steht anstelle des Knopfes —
   gedämpft, weil es eine Feststellung ist und keine Handlung. */
.card__note {
    margin: 10px 0 0;
    font-size: .85rem;
    color: var(--muted);
}

/* Der einmalige Hinweis auf Face ID. Bewusst in der Akzentfarbe und nicht
   in der Warnfarbe: Es ist ein Angebot, kein Problem. */
.hinweis-karte {
    background: color-mix(in srgb, var(--accent) 12%, var(--surface));
    border: 1px solid color-mix(in srgb, var(--accent) 35%, var(--border));
    border-radius: var(--radius);
    padding: 14px;
    margin: 0 0 16px;
}

/*
 * Die Karte, bei der jemand anderes wartet.
 *
 * Alle übrigen Karten sind Angebote an den Betrachter — diese ist eine
 * Bitte von jemandem, der ohne eine Antwort nicht weiterkommt. Deshalb
 * der Ton des Entfalls statt der ruhigen Akzentfarbe: dieselbe Farbe,
 * die in dieser App überall "hier musst du hinsehen" heisst.
 */
.hinweis-karte--wartet {
    background: color-mix(in srgb, var(--entfall) 10%, var(--surface));
    border-color: color-mix(in srgb, var(--entfall) 40%, var(--border));
}

.hinweis-karte__text {
    margin: 0 0 12px;
    font-size: .9rem;
    line-height: 1.45;
}

/* Die Schritte einer Anleitung — auf dem iPhone der einzige Weg zum
   Vollbild, weil Apple dafür keine Schnittstelle anbietet. Nummeriert,
   weil die Reihenfolge zählt, und mit Luft zwischen den Zeilen: Wer
   danebenher am Telefon hantiert, verliert sonst die Zeile. */
.hinweis-karte__schritte {
    margin: 0 0 12px;
    padding-left: 1.3em;
    font-size: .88rem;
    line-height: 1.5;
    color: var(--text-muted);
}

.hinweis-karte__schritte li { margin-bottom: 6px; }
.hinweis-karte__schritte li:last-child { margin-bottom: 0; }

.hinweis-karte__knoepfe {
    display: flex;
    gap: 10px;
    /* Auf einem schmalen Telefon nebeneinander, sonst umbrechen — zwei
       halbe Knöpfe sind schlechter zu treffen als zwei ganze. */
    flex-wrap: wrap;
}

.hinweis-karte__ja,
.hinweis-karte__nein {
    flex: 1 1 auto;
    min-height: 44px;
    padding: 10px 16px;
    border-radius: var(--radius);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

.hinweis-karte__ja {
    background: var(--accent);
    border: 0;
    color: var(--accent-text);
}

.hinweis-karte__nein {
    background: none;
    border: 1px solid var(--border);
    color: inherit;
}

.notice--inline {
    background: color-mix(in srgb, var(--entfall) 12%, var(--surface));
    border-color: color-mix(in srgb, var(--entfall) 35%, var(--border));
    margin-bottom: 12px;
}

.hint {
    margin: 10px 0 0;
    font-size: .78rem;
    color: var(--text-muted);
}

.hint--right { text-align: right; margin-top: 4px; }

.section-title {
    margin: 24px 0 10px;
    font-size: .82rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--text-muted);
}

.section-title:first-child { margin-top: 0; }

/* Offene Fehlstunden in der Abschnittszeile: derselbe Ton wie beim
   Entfall — "hier musst du hinsehen". Ist nichts offen, bleibt die Zeile
   gedämpft wie jede andere Überschrift; die Entwarnung steht dann im
   Wortlaut ("alle entschuldigt") und braucht keine Farbe. */
.section-title--achtung {
    color: var(--entfall);
}


/* ---------- Tagesnavigation ---------- */

/* Datum, Schulschluss und Alter der Daten in einem Block: Es sind alles
   Aussagen über diesen Tag. Einzeln untereinander sah der Schulschluss aus,
   als hätte ihn jemand nachträglich zwischen die Stunden geschoben. */
.tagkopf {
    margin-bottom: 14px;
    padding: 12px 12px 10px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}

.daynav {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* Innerhalb des Kopfes tragen die Pfeile keinen eigenen Rahmen mehr —
   zwei Rahmen ineinander wirken unruhig. */
.tagkopf .daynav__step {
    background: var(--surface-alt);
    border-color: transparent;
}

.daynav__step {
    flex: none;
    width: 44px;
    height: 44px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--surface);
    color: var(--text);
    font-size: 1.4rem;
    line-height: 1;
    cursor: pointer;
}

.daynav__step:disabled { opacity: .35; cursor: default; }

.daynav__current {
    flex: 1;
    min-width: 0;
    text-align: center;
}

/* Nur sichtbar, wenn ein anderer Tag als heute angezeigt wird.
   Vorher war er durchsichtig, dünn umrandet und gedämpft — er sah aus wie
   eine Bemerkung, nicht wie etwas zum Drücken. Jetzt gefüllt in der
   Akzentfarbe, mit Pfeil und in Daumengröße. Er steht nur da, wenn man
   woanders ist, darf also deutlich sein. */
.daynav__heute {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin-top: 5px;
    /* 32 px hoch und 12 px Innenabstand: Vorher waren es 2 px, und damit
       war der Knopf mit dem Daumen kaum zu treffen. */
    min-height: 32px;
    padding: 0 13px;
    background: var(--accent);
    border: 0;
    border-radius: 999px;
    color: var(--accent-text);
    font: inherit;
    font-size: .8rem;
    font-weight: 650;
    cursor: pointer;
}

.daynav__heute:active { transform: scale(.96); }

.daynav__heute svg {
    width: 14px;
    height: 14px;
    flex: none;
}

.daynav__label {
    display: block;
    /* Ziffern gleich breit: Beim Blättern springen Datum und Pfeile sonst
       unter dem Daumen weg. */
    font-variant-numeric: tabular-nums;
    font-weight: 650;
    font-size: 1rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.daynav__meta {
    display: block;
    font-size: .78rem;
    color: var(--text-muted);
}

/* ---------- Anlagen an den Kursmappen ---------- */

/* Zeilen, keine Kacheln: Dateinamen sind lang und ungleich lang. Nebeneinander
   gesetzt bricht jeder zweite um, und die Reihe franst aus. */
.anlagen {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-top: 10px;
}

.anlage {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface-alt);
    color: var(--text);
    text-decoration: none;
    font-size: .84rem;
}

/* Die Endung als Marke — sie sagt in drei Zeichen, was einen erwartet, und
   erspart das Suchen im Dateinamen. */
.anlage__typ {
    flex: none;
    min-width: 2.6em;
    padding: 2px 5px;
    border-radius: 5px;
    background: color-mix(in srgb, var(--accent) 16%, transparent);
    color: var(--accent);
    font-size: .66rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .04em;
    text-align: center;
}

.anlage__name {
    flex: 1 1 auto;
    min-width: 0;
    /* Ein langer Name schiebt sonst den Pfeil aus der Zeile. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.anlage__pfeil { flex: none; color: var(--text-faint); }

/* Im Blatt zur Stunde sitzen sie im Fussbereich, der schon eine eigene
   Fläche hat — dort wäre ein zweiter Rahmen einer zu viel. */
.sheet__aktion .anlagen { margin-top: 0; }

/* ---------- Nachricht schreiben ---------- */

/* Der Knopf über der Nachrichtenliste. Er tut etwas, statt nur wohin zu
   führen — deshalb die Akzentkante. */
/* Eine Karte, die zu etwas auffordert — "Nachricht schreiben".
   Vorher nur ein drei Pixel schmaler Balken links: Zwischen einem Dutzend
   gleich aussehender Karten ging sie unter, und wer eine Lehrkraft
   anschreiben wollte, suchte danach. Jetzt trägt sie die Akzentfarbe im
   Rahmen, im Titel und im Pfeil, dazu einen Hauch davon im Hintergrund.

   Bewusst NICHT flächig gefüllt: Das ist in dieser App den grossen
   Entscheidungen vorbehalten ("Fach wählen", "Video ansehen"). Eine
   Karte, die immer dasteht, darf nicht so laut sein wie eine Frage, die
   beantwortet werden will. */
.menu--tun {
    border-color: var(--accent);
    border-left-width: 3px;
    background:
        linear-gradient(0deg,
            color-mix(in srgb, var(--accent) 12%, transparent),
            color-mix(in srgb, var(--accent) 12%, transparent)),
        var(--surface-alt);
}

.menu--tun .menu__titel { color: var(--accent); font-weight: 700; }
.menu--tun .menu__pfeil { color: var(--accent); }

.empfaenger { display: flex; flex-wrap: wrap; gap: 6px; margin: 2px 0 6px; }

.empfaenger__marke {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 10px;
    border: 1px solid var(--border-strong);
    border-radius: 999px;
    background: var(--surface-alt);
    font: inherit;
    font-size: .84rem;
    color: var(--text);
    cursor: pointer;
}

.treffer {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
    margin-bottom: 8px;
}

.treffer__eintrag {
    padding: 10px 13px;
    background: var(--surface);
    border: 0;
    text-align: left;
    font: inherit;
    font-size: .9rem;
    color: var(--text);
    cursor: pointer;
}

.treffer__eintrag + .treffer__eintrag { border-top: 1px solid var(--border); }

/* Der Knopf, der etwas auslöst, hebt sich von dem ab, der nur umschaltet. */
.sheet__knopf--tun {
    background: var(--accent);
    color: var(--accent-text);
    border-color: var(--accent);
    font-weight: 700;
}

/* ---------- Dokumente der Schule ---------- */

.dokumente { display: flex; flex-direction: column; }

.dokument {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 11px 2px;
    border-bottom: 1px solid var(--border);
    color: inherit;
    text-decoration: none;
}

/* Die Endung als Etikett statt eines Symbols: Sie sagt genauer, was
   einen erwartet — eine docx will man am Telefon vielleicht gar nicht
   erst öffnen. */
.dokument__typ {
    flex: none;
    min-width: 42px;
    padding: 3px 6px;
    border-radius: 5px;
    background: var(--surface-alt);
    border: 1px solid var(--border);
    font-size: .66rem;
    font-weight: 800;
    letter-spacing: .04em;
    text-align: center;
    color: var(--text-muted);
}

.dokument__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.dokument__name { font-size: .92rem; line-height: 1.3; }
.dokument__meta { font-size: .78rem; color: var(--text-muted); }
.dokument__pfeil { margin-left: auto; color: var(--text-faint); }

/* ---------- Umschalten zwischen Kindern ---------- */

/* Der Name in der Kopfzeile wird zur Schaltfläche, sobald es ein zweites
   Kind gibt — vorher sieht und tut er nichts anderes als bisher. */
.header__title--wahl {
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 7px;
}

.header__title--wahl::after {
    content: '';
    width: 7px;
    height: 7px;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: translateY(-2px) rotate(45deg);
    opacity: .55;
}

/* Hängt unter der Kopfzeile statt als eigenes Blatt: Umschalten ist ein
   Griff, keine Entscheidung, die eine ganze Fläche verdient. */
.kindwahl {
    position: absolute;
    z-index: 40;
    margin-top: 6px;
    min-width: 200px;
    max-width: min(88vw, 320px);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: 0 12px 32px rgba(0, 0, 0, .28);
    overflow: hidden;
}

.kindwahl__eintrag {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 1px;
    width: 100%;
    padding: 11px 14px;
    background: none;
    border: 0;
    text-align: left;
    font: inherit;
    color: var(--text);
    cursor: pointer;
}

.kindwahl__eintrag + .kindwahl__eintrag { border-top: 1px solid var(--border); }

.kindwahl__eintrag--aktiv { background: var(--surface-alt); }

.kindwahl__name { font-weight: 650; font-size: .95rem; }
.kindwahl__login { font-size: .8rem; color: var(--text-muted); }

/* Die Liste auf der Kinderseite. */
.kindzeile {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 0;
    border-bottom: 1px solid var(--border);
}

.kindzeile__text { display: flex; flex-direction: column; gap: 2px; }
.kindzeile__text small { color: var(--text-muted); font-size: .8rem; }

.kindzeile__marke {
    font-size: .72rem;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--text-faint);
}

.kindzeile__weg {
    background: none;
    border: 1px solid var(--border-strong);
    border-radius: 999px;
    padding: 5px 12px;
    font: inherit;
    font-size: .82rem;
    color: var(--entfall);
    cursor: pointer;
}

/* ---------- Fehlzeiten ---------- */

/* Eine Liste zum Nachschlagen, kein Handlungsbedarf — deshalb Zeilen statt
   Karten. Nur die offenen Stunden treten hervor: Sie bedeuten, dass eine
   Entschuldigung fehlt. */
.fehlzeiten {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
}

.fehlzeit {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 13px;
    background: var(--surface);
    font-size: .88rem;
}

.fehlzeit + .fehlzeit { border-top: 1px solid var(--border); }

.fehlzeit__fach {
    font-weight: 650;
    color: var(--fach, var(--text));
}

.fehlzeit__zahlen {
    color: var(--text-muted);
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.fehlzeit__zahlen b { color: var(--text); font-weight: 700; }

/* Ohne Entschuldigung: dieselbe Farbe wie der Entfall, der Ton für "hier
   musst du hinsehen". */
.fehlzeit__offen {
    display: block;
    color: var(--entfall);
    font-weight: 650;
}

/*
 * Die offenen Stunden als grosse Zahl.
 *
 * Sie stehen dort, wo vorher die gefehlten standen — und übernehmen
 * deren Gewicht mitsamt der Warnfarbe. Grösser als der Rest der Zeile,
 * weil sie die einzige Zahl ist, auf die jemand reagieren muss: Für sie
 * fehlt noch eine Entschuldigung.
 *
 * Kein eigenes display: block wie bei .fehlzeit__offen — die Zahl steht
 * im Fluss der Zeile, direkt vor "ohne Entschuldigung".
 */
/*
 * Der Selektor nennt das b ausdrücklich mit.
 *
 * ".fehlzeit__zahlen b" setzt die Textfarbe und ist mit Klasse PLUS
 * Element spezifischer als eine Klasse allein — eine Regel nur auf
 * .fehlzeit__offen-zahl verlor deshalb, und die Zahl kam in der
 * gewöhnlichen Textfarbe heraus statt im Warnton. Am 05.09.2026 im
 * Browser gemessen: rgb(228,246,248) statt der Entfall-Farbe. Am
 * Quelltext war das nicht zu sehen.
 */
.fehlzeit__zahlen b.fehlzeit__offen-zahl {
    color: var(--entfall);
    font-weight: 700;
    font-size: 1.15em;
}

/* Die Schulveranstaltung ist keine Fehlstunde — sie steht nur da, damit
   der Vergleich mit dem Portal aufgeht. Also leise: kein Warnton. */
.fehlzeit__extra {
    display: block;
    color: var(--text-muted);
    font-weight: 500;
}

/*
 * Das Fehlerprotokoll in der Betreiberansicht.
 *
 * Bewusst nüchtern: Wer hier nachsieht, sucht eine Uhrzeit und will den
 * Wortlaut — nicht eine hübsche Aufbereitung, die etwas weglässt. Die
 * Meldung steht deshalb ungekürzt und darf umbrechen; Route und
 * Fundstelle sind klein daneben.
 */
/* Der Rückweg, wenn die Zwischenablage nicht will: Der Text steht in
   einem Feld und ist ausgewählt. Klein und einfarbig — er ist zum
   Kopieren da, nicht zum Lesen. */
.protokoll__roh {
    width: 100%;
    min-height: 120px;
    margin: 8px 0;
    padding: 8px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--surface-alt);
    color: var(--text-muted);
    font-family: ui-monospace, Menlo, monospace;
    font-size: .75rem;
}

/*
 * Der Kopier-Knopf je Eintrag.
 *
 * Rechts oben in der Zeile und blass: Meistens liest man das Protokoll,
 * ohne etwas weitergeben zu wollen — dann soll der Knopf nicht mitlesen.
 * Beim Zeigen wird er deutlich.
 *
 * Alle Knopf-Vorgaben zurückgesetzt, nicht nur der Rahmen: Hintergrund
 * und Textfarbe kommen sonst vom Browser. Genau daran ist am 06.09.2026
 * die antippbare Terminzeile gescheitert — sie stand als weisser Kasten
 * zwischen dunklen Zeilen.
 */
.protokoll__kopie {
    float: right;
    margin-left: 8px;
    padding: 2px 6px;
    border: 0;
    background: none;
    color: var(--text-faint);
    font: inherit;
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    opacity: .55;
}

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

/* Der Haken nach dem Kopieren — an der Stelle, an der getippt wurde.
   Er ersetzt die Meldung, die vorher zwei Bildschirmhöhen weiter oben
   erschien und dort drangeklatscht wirkte. */
.protokoll__kopie.is-kopiert {
    opacity: 1;
    /* --accent gibt es in jedem Farbschema; eine eigene "Erfolg"-Farbe
       nicht, und eine einzuführen wäre für 1,6 Sekunden Haken zu viel. */
    color: var(--text);
}

/*
 * Die Kopfzeile über der Liste: wie viele Vorfälle, und der Knopf fürs
 * Ganze.
 *
 * Beide zurückhaltend. Hier stand ein grosser Hauptknopf "In die
 * Zwischenablage" — dabei ist der seltenere Fall, dass jemand wirklich
 * alles braucht. Die Knöpfe an den einzelnen Vorfällen sind die
 * wichtigeren, und die sind blass.
 */
.protokoll__kopf {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin: 0 0 8px;
    color: var(--text-muted);
    font-size: .8rem;
}

.protokoll__alle {
    padding: 0;
    border: 0;
    background: none;
    color: var(--text-muted);
    font: inherit;
    text-decoration: underline;
    cursor: pointer;
}

.protokoll__alle:hover,
.protokoll__alle:focus-visible {
    color: var(--text);
}

/* Wie oft und seit wann — die zwei Angaben, die aus einer Wiederholung
   eine Lage machen. "3× in einer Minute" ist etwas anderes als "40×
   seit gestern Abend". */
.protokoll__oft {
    margin-left: 8px;
    padding: 1px 6px;
    border-radius: 6px;
    background: var(--surface);
    border: 1px solid var(--border-strong);
    color: var(--text);
    font-size: .78rem;
    font-variant-numeric: tabular-nums;
}

.protokoll__seit {
    margin-left: 6px;
    color: var(--text-faint);
    font-size: .78rem;
}

.protokoll__zeile {
    padding: 8px 10px;
    border-left: 3px solid var(--border-strong);
    background: var(--surface-alt);
    border-radius: 0 8px 8px 0;
    margin-bottom: 8px;
    font-size: .85rem;
    line-height: 1.45;
}

.protokoll__wann {
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.protokoll__wo {
    margin-left: 8px;
    padding: 1px 6px;
    border-radius: 6px;
    background: var(--accent);
    color: var(--accent-text);
    font-size: .78rem;
}

.protokoll__was {
    display: block;
    margin-top: 4px;
    color: var(--text);
    /* Lange Portalmeldungen dürfen umbrechen, aber nicht aus dem Kasten
       laufen — sie enthalten Adressen ohne Leerzeichen. */
    overflow-wrap: anywhere;
}

.protokoll__quelle {
    display: block;
    margin-top: 3px;
    color: var(--text-faint);
    font-size: .78rem;
    overflow-wrap: anywhere;
}

/*
 * Der Hinweis, der beim Einrichten nach sechs Sekunden erscheint.
 *
 * Er sitzt in der Fehlerzeile, ist aber keiner — deshalb der ruhige Ton
 * statt der Warnfarbe. Wer hier liest, hat nichts falsch gemacht; er
 * wartet nur auf das Schulportal.
 */
.login__error--warten {
    color: var(--text-muted);
    border-left: 3px solid var(--hinweis);
    padding-left: 10px;
    text-align: left;
}

/*
 * Die anstehende Arbeit als Knopf.
 *
 * Sie sieht aus wie jede andere Terminzeile — bis auf den Pfeil rechts.
 * Mehr braucht es nicht: Wer die Zeile liest, sieht den Pfeil, und wer
 * ihn nicht sieht, verliert nichts. Ein hervorgehobener Knopf mitten in
 * der Terminliste hiesse dagegen, dass diese eine Zeile wichtiger ist
 * als der Termin, den sie beschreibt.
 */
/* Die Hausaufgabe unter dem Thema — leiser als das Thema selbst. */
.chronik__hausaufgabe {
    margin: 4px 0 0;
    color: var(--text-muted);
    font-size: .85rem;
}

/* ---------- Konten nach Schulen ----------
   Mit vier Schulen in einer Reihe sucht man die Zeile, die einen angeht,
   und sieht nicht, wie sich die Nutzung verteilt. Die Überschrift trägt
   den Namen der Schule und rechts daneben, wie viele Konten dort hängen.
   Dieselbe Tonlage wie die übrigen Abschnittszeilen — es ist eine
   Gliederung, keine Meldung. */
.konten-gruppe {
    margin: 18px 0 8px;
    font-size: .82rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--text-muted);
    display: flex;
    align-items: baseline;
    gap: 8px;
}

.konten-gruppe:first-child { margin-top: 0; }

.konten-gruppe__zahl {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    opacity: .75;
}

/* ---------- Der schwebende Knopf zum Schreiben ----------
   Im Reiter "Nachrichten" stand "Nachricht schreiben" als Karte ganz
   oben. Wer die Liste herunterscrollte, verlor sie aus dem Blick — und
   wer eine neue Nachricht schreiben wollte, musste erst zurück nach
   oben. Jetzt bleibt der Knopf stehen.

   z-index 40: unter dem Blatt (50), über der Liste. Ausgeblendet wird er
   trotzdem, sobald ein Blatt offen ist — verdeckt genügt nicht, denn auf
   dem Weg zum "Schliessen" träfe der Daumen sonst genau ihn. */
.fab {
    position: fixed;
    right: 16px;
    /* Über der Fusszeile, und auf dem iPhone über dem Balken der
       Home-Geste: Ohne safe-area liegt der Knopf sonst darunter. */
    bottom: calc(16px + env(safe-area-inset-bottom, 0px));
    z-index: 40;
    width: 56px;
    height: 56px;
    border: none;
    border-radius: 50%;
    background: var(--accent);
    color: var(--accent-text);
    display: grid;
    place-items: center;
    box-shadow: 0 6px 18px rgba(0, 0, 0, .45);
    cursor: pointer;
}

.fab svg { width: 24px; height: 24px; }

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

/* Damit die letzte Nachricht nicht unter dem Knopf verschwindet. Der
   Platz steht nur da, wo der Knopf auch schwebt. */
.panel[data-panel="nachrichten"].is-active { padding-bottom: 84px; }

/* ---------- Wie sich die Familien auf die Schulen verteilen ----------
   Ein Kuchen aus einem einzigen Kreis: stroke-dasharray schneidet ihn in
   Stücke, und bei r = 15,9155 ist der Umfang genau 100 — jeder Anteil ist
   direkt sein Prozentwert. Keine Bogenrechnung, keine Bibliothek. */
.kuchen {
    display: flex;
    align-items: center;
    gap: 14px;
    margin: 0 0 14px;
    padding: 14px;
    background: var(--surface-alt);
    border: 1px solid var(--border);
    border-radius: 12px;
}

.kuchen__bild { flex: none; width: 104px; height: 104px; }

/* Keine Drehung hier: Der Anfang wird über den dashoffset gesetzt (25
   von 100 entspricht einer Vierteldrehung, also zwölf Uhr). Beides
   zusammen drehte den Ring um 90 Grad zu weit — der erste Anteil begann
   auf neun Uhr. Am 04.09.2026 im Bild gesehen. */

.kuchen__zahl { font-size: 6.5px; font-weight: 700; fill: var(--text); }
.kuchen__wort { font-size: 2.8px; fill: var(--text-muted); }

.kuchen__legende { flex: 1; min-width: 0; font-size: .82rem; }

.kuchen__zeile { display: flex; align-items: center; gap: 7px; margin-bottom: 5px; }
.kuchen__zeile:last-child { margin-bottom: 0; }

.kuchen__punkt { width: 10px; height: 10px; border-radius: 3px; flex: none; }

/* Lange Schulnamen kürzen statt umbrechen: Eine Legende, in der jede
   Zeile zwei hoch ist, verliert ihren Zusammenhang. */
.kuchen__name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.kuchen__legende small {
    margin-left: auto;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

/* "Nie angemeldet" ist eine stille Gruppe — sie soll auffallen, ohne zu
   mahnen. */
.konten-gruppe--ruht { color: var(--text-faint); }

/* ---------- Die eigene Kennung ----------
   Sie steht ganz oben in den Einstellungen und ersetzt in der Übersicht
   des Betreibers den Familiennamen. Deshalb muss sie ablesbar sein wie
   eine Telefonnummer: gross, mit gleich breiten Ziffern, damit man sie
   am Telefon vorlesen kann, ohne sich zu verhaspeln. */
.kennung {
    margin: 0 0 18px;
    padding: 12px 14px;
    border-radius: 12px;
    background: var(--surface-2, rgba(255, 255, 255, .04));
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.kennung__wort {
    font-size: .74rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--text-muted);
}

.kennung__wert {
    font-size: 1.25rem;
    font-weight: 700;
    letter-spacing: .08em;
    font-variant-numeric: tabular-nums;
    color: var(--text);
}

.kennung__hinweis {
    font-size: .82rem;
    line-height: 1.35;
    color: var(--text-muted);
}

/* In der Liste des Betreibers steht sie an der Stelle des Namens — dort
   kleiner, aber mit denselben gleich breiten Ziffern. */
.planner__name--kennung {
    font-variant-numeric: tabular-nums;
    letter-spacing: .04em;
}

/* Der Rahmentext der Betrachterzeile ("Nichts zu sehen? … die App bleibt
   offen.") ist Beiwerk — die Knöpfe daneben sind die Sache. Also gedämpft,
   damit "Öffnen oder sichern" sich davon abhebt. Er wird bei einer
   Word-Vorschau ausgeblendet, die Knöpfe bleiben stehen. */
.viewer__hint-text {
    color: var(--text-muted);
}

.fehlzeiten__leer {
    color: var(--text-muted);
    font-size: .88rem;
    padding: 2px 0 4px;
}

/* ---------- Abgaben mit Frist ---------- */

/* Karten wie die Kursmappen, aber mit einem Streifen, dessen Farbe die
   Dringlichkeit trägt. Die Fachfarbe steht als Punkt daneben — links ist
   hier die Frist wichtiger als das Fach, und zwei Bedeutungen an derselben
   Kante liest niemand auseinander. */
.abgaben { display: flex; flex-direction: column; gap: 8px; }

.abgabe {
    background: var(--surface);
    border: 1px solid var(--border);
    border-left: 3px solid var(--border-strong);
    border-radius: var(--radius);
    padding: 11px 13px;
}

/* Rot für überfällig und heute, Bernstein für bald. Nicht Grün: Das heißt
   in dieser App "Vertretung" und liest sich wie "alles in Ordnung" — an
   einer Frist, die morgen abläuft, wäre das die falsche Auskunft. */
.abgabe--vorbei { border-left-color: var(--entfall); }
.abgabe--heute  { border-left-color: var(--entfall); }
.abgabe--bald   { border-left-color: var(--raum); }

/* Erledigtes tritt zurück, verschwindet aber nicht: Es steht nur noch da,
   wenn eine Rückmeldung dranhängt — und die will man lesen. */
.abgabe--fertig {
    background: var(--surface-alt);
    border-left-color: var(--border-strong);
}

.abgabe--fertig .abgabe__titel { color: var(--text-muted); }

.abgabe__kopf {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 3px;
}

.abgabe__fach {
    font-size: .76rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--fach, var(--text-muted));
}

.abgabe__titel { font-size: .95rem; line-height: 1.35; }

.abgabe__rueckmeldung {
    margin-top: 6px;
    padding-left: 9px;
    border-left: 2px solid var(--border);
    font-size: .85rem;
    color: var(--text-muted);
}

/* ---------- Ausblick auf die nächsten Tage ---------- */

/* Dezent, aber nicht zu übersehen: Der farbige Strich ist derselbe, den die
   Arbeit-Marke trägt, damit beide erkennbar dasselbe meinen. Kein eigener
   Kasten — die Zeile gehört zum Tageskopf und soll ihn nicht aufblähen. */
.ausblick {
    margin: 8px -12px 0;
    padding: 8px 12px 0;
    border-top: 1px solid var(--border);
}

.ausblick__zeile {
    display: flex;
    align-items: baseline;
    gap: 8px;
    padding-left: 11px;
    border-left: 3px solid var(--entfall);
    font-size: .82rem;
    line-height: 1.35;
}

.ausblick__zeile + .ausblick__zeile { margin-top: 5px; }

/* Steht nur eine Lernkontrolle an, tritt die Zeile zurück. Sie soll
   erinnern, nicht alarmieren. */
.ausblick__zeile--lernkontrolle {
    border-left-color: color-mix(in srgb, var(--entfall) 45%, transparent);
}

.ausblick__zeile--lernkontrolle .ausblick__wann {
    font-weight: 600;
    color: color-mix(in srgb, var(--entfall) 75%, var(--text-muted));
}

.ausblick__wann {
    flex: none;
    font-weight: 700;
    color: var(--entfall);
}

.ausblick__was {
    color: var(--text-muted);
    /* Drei Arbeiten an einem Tag sind selten, aber dann soll die Zeile
       umbrechen statt den Kopf zu sprengen. */
    min-width: 0;
}

/* ---------- Schulschluss ---------- */

/* Kein weiterer Unterrichtsblock: keine Kartenfläche, kein Schatten, dafür
   ein Strich an der Kante und die Uhrzeit als das, was man sucht. Die Zeile
   beantwortet die Frage, wegen der man morgens in die App schaut. */
.schluss {
    display: grid;
    grid-template-columns: auto 1fr;
    grid-template-areas: "zeit marke" "zeit wo";
    align-items: baseline;
    column-gap: 12px;
    /* Sitzt im Tageskopf und teilt sich dessen Fläche — abgesetzt nur durch
       eine Linie, nicht durch einen eigenen Kasten. */
    margin: 10px -12px 0;
    padding: 10px 12px 2px;
    border-top: 1px solid var(--border);
    font-variant-numeric: tabular-nums;
}

/* Der farbige Strich sitzt links neben der Uhrzeit, nicht am Blockrand. */
.schluss__zeit { border-left: 3px solid var(--border-strong); padding-left: 11px; }
.schluss--frueher .schluss__zeit { border-left-color: var(--vertretung); }
.schluss--satz { border-left: 0; }

.schluss__zeit {
    grid-area: zeit;
    align-self: center;
    font-size: 1.5rem;
    font-weight: 600;
    line-height: 1.1;
    letter-spacing: -.01em;
}

.schluss__zeit small { font-size: .8rem; font-weight: 400; color: var(--text-muted); }

.schluss__marke {
    grid-area: marke;
    font-size: .7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--text-faint);
}

.schluss__wo {
    grid-area: wo;
    margin-top: 1px;
    font-size: .82rem;
    color: var(--text-muted);
}

/* Endet der Tag früher als geplant, ist das die Nachricht des Tages. */
.schluss--frueher { border-left-color: var(--vertretung); }
.schluss--frueher .schluss__zeit,
.schluss--frueher .schluss__marke { color: var(--vertretung); }

/* Und beginnt er später, erst recht — morgens ist das die dringendere
   Auskunft. Dieselbe Form wie der Schluss, damit man beides mit einem Blick
   liest; die Farbe des Hinweises statt der der Vertretung, weil es eine
   Ansage ist und kein Ausfall. */
.schluss--spaeter {
    margin-bottom: 8px;
    border-left-color: var(--hinweis);
}
.schluss--spaeter .schluss__zeit,
.schluss--spaeter .schluss__marke { color: var(--hinweis); }

/* Fällt alles aus, gibt es keine Uhrzeit — dann bleibt es beim Satz. */
.schluss--satz {
    display: block;
    padding: 11px 13px;
    border-left-color: var(--entfall);
    font-size: .95rem;
    font-weight: 600;
}

/* ---------- Wetter im Tageskopf ---------- */

/* Eine ruhige Zeile unter dem Schulschluss, keine Karte: Das Wetter gehört
   zur selben Morgen-Frage (Regenjacke, Fahrrad oder Bus?), aber es ist eine
   Zugabe — es soll den Blick nicht vom Plan wegziehen. */
.tagwetter {
    display: flex;
    align-items: baseline;
    gap: 8px;
    /* Die negativen Ränder ziehen die Trennlinie über die volle Breite der
       Karte. Als Knopf braucht die Zeile die Breite ausdrücklich: Ein
       Absatz füllt von selbst, ein <button> nicht. */
    width: calc(100% + 24px);
    margin: 8px -12px 0;
    padding: 8px 12px 0;
    background: none;
    border: 0;
    border-top: 1px solid var(--border);
    border-radius: 0;
    font: inherit;
    font-size: .82rem;
    text-align: left;
    color: var(--text-muted);
    cursor: pointer;
}

.tagwetter:active { opacity: .6; }

/* Das Zeichen, das sagt: hier steckt mehr dahinter. Ganz leise, denn das
   Wetter ist eine Zugabe und soll den Blick nicht vom Plan wegziehen. */
.tagwetter__arrow {
    flex: none;
    margin-left: auto;
    padding-left: 4px;
    color: var(--text-faint);
}

/* ---------- Der ganze Tag, Stunde für Stunde (Blatt) ---------- */

/* Luft nach unten: Sonst klebt die Quellenangabe an der letzten
   Stunde und liest sich wie eine weitere Zeile der Liste. */
.wstunden { margin: 0 0 14px; padding: 0; list-style: none; }

.wstunde {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 5px 8px;
    border-radius: 8px;
    font-size: .88rem;
    color: var(--text-muted);
}

/* Die Schulzeit samt Wegen — der Bezug zur Zeile im Tagesplan, die genau
   diese Stunden zusammenfasst. Ohne die Hervorhebung wäre das Blatt eine
   zweite, widersprüchliche Auskunft statt einer Erweiterung. */
.wstunde--schulzeit {
    background: var(--surface-alt);
    color: var(--text);
    font-weight: 500;
}

.wstunde__uhr { flex: none; width: 56px; font-variant-numeric: tabular-nums; }
.wstunde__zeichen { flex: none; width: 20px; text-align: center; }

/* Macht die Form des Tages sichtbar — dafür ist das Blatt da. Die Breite
   spannt zwischen kältester und wärmster Stunde DIESES Tages, nicht über
   eine feste Skala: Ein Tag zwischen 8 und 11 Grad hat auch eine Form.

   Die FARBE dagegen liegt auf einer festen Skala von kalt nach warm
   (WAERME_SKALA in app.js) und kommt als Inline-Stil je Stunde. Zwei
   Fragen, zwei Mittel: die Breite sagt "wann war es am wärmsten?", die
   Farbe sagt "ist das warm?". */
.wstunde__balken {
    flex: 1 1 auto;
    min-width: 24px;
    height: 8px;
    background: var(--border);
    border-radius: 4px;
    overflow: hidden;
}

/* Der Rückfall, falls die Farbe einmal ausbleibt: sichtbar bleibt der
   Balken so oder so. Der Inline-Stil überschreibt ihn. */
.wstunde__balken i {
    display: block;
    height: 100%;
    background: var(--accent);
    border-radius: 4px;
}

.wstunde__temp {
    flex: none;
    width: 56px;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* Nur ab 20 % überhaupt gezeigt: Eine Zehn-Prozent-Angabe in jeder Zeile
   ist Rauschen, das die eine Stunde verdeckt, auf die es ankommt. */
.wstunde__regen {
    flex: none;
    width: 44px;
    text-align: right;
    font-variant-numeric: tabular-nums;
    color: var(--hinweis);
}

.tagwetter__symbol { font-size: 1rem; line-height: 1; }

/* Darf schrumpfen und umbrechen — das Zeichen daneben nicht. */
.tagwetter__text { min-width: 0; }

/* Wofür die Vorhersage gilt: erste Stunde minus Schulweg bis Schluss plus
   Heimweg. Noch leiser als die Zeile selbst — eine Fussnote, kein Wert.
   Als Block unzertrennlich: "7:20 bis" ohne "11:40 Uhr" wäre Rätselraten. */
.tagwetter__fenster { color: var(--text-faint); white-space: nowrap; }

/* Wann die Datei angehängt wurde — über der Kachel, klein. Ein Lernplan
   vom Schuljahresanfang ist etwas anderes als das Blatt von gestern. */
.dok__wann {
    margin: 10px 0 4px;
    font-size: .78rem;
    color: var(--text-muted);
}

/* ---------- Gelesene Dokumente im Betrachter ---------- */

/* Ein Lernplan wird gelesen, nicht angesehen: Textbreite, Zeilenabstand,
   ruhiger Hintergrund. Das Blatt scrollt für sich — der Kopf mit "Zurück"
   bleibt stehen, sonst wäre man in einem Dokument gefangen. */
/* Wie der Rahmen und die gezeichneten Seiten: Der Körper ist
   position:relative, die Inhalte legen sich hinein. Ohne das endete das
   Blatt mitten auf dem Bildschirm und darunter klaffte der Hintergrund. */
.viewer__text {
    position: absolute;
    inset: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: 18px 16px 40px;
    background: var(--surface);
    color: var(--text);
    line-height: 1.55;
}

.dok__ueberschrift {
    margin: 22px 0 8px;
    font-size: 1.05rem;
    font-weight: 700;
    line-height: 1.3;
}
.viewer__text > .dok__ueberschrift:first-child { margin-top: 0; }

.dok__absatz { margin: 0 0 10px; }

/* Listenpunkte kommen als einzelne Absätze — der Punkt davor macht sie
   erst zur Liste. */
.dok__punkt {
    margin: 0 0 6px;
    padding-left: 18px;
    position: relative;
}
.dok__punkt::before {
    content: "•";
    position: absolute;
    left: 4px;
    color: var(--text-faint);
}

/* Tabellen sind in Lernplänen die Hauptsache (Woche | Thema | bis wann).
   Sie scrollen in sich, damit die Seite es nicht tut. */
.dok__tabelle {
    display: block;
    overflow-x: auto;
    width: 100%;
    margin: 12px 0 16px;
    border-collapse: collapse;
    font-size: .88rem;
}
.dok__tabelle th,
.dok__tabelle td {
    /* In einer Word-Zelle stehen oft mehrere Absätze ("1", "August
       10-14", "Part A"). Der Leser trennt sie mit einem Umbruch — hier
       wird er sichtbar. */
    white-space: pre-line;
    border: 1px solid var(--border);
    padding: 6px 9px;
    text-align: left;
    vertical-align: top;
    min-width: 90px;
}
.dok__tabelle th {
    background: var(--surface-alt);
    font-weight: 600;
}

.viewer__textleer {
    margin: 0;
    color: var(--text-muted);
    font-size: .9rem;
}

/* ---------- Unterrichtsstunden ---------- */

.lessons {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

/* Immer derselbe Aufbau: Zeit links, Angaben in der Mitte, Status rechts.
   Die Mitte hat drei Zeilen (Fach, Lehrkraft, Raum) — auch wenn eine leer
   ist. Dadurch sind alle Karten gleich hoch und man findet jede Angabe
   ohne Suchen. */
.lesson {
    display: grid;
    grid-template-columns: var(--when-width) 1fr auto;
    align-items: start;
    gap: 12px;
    background: var(--surface);
    border: 1px solid var(--border);
    /* Die Kante gehört dem Fach. Nur der Ausfall nimmt sie sich — siehe
       unten.

       Vorher nahm jede Abweichung sie: Vertretung und Raumwechsel färbten
       sie grün. Das kostete die Karte ihre Fach-Identität für eine Auskunft,
       die daneben schon als Pille steht ("Vertretung", "Raum"), und beim
       Überfliegen des Tages war nicht mehr zu sehen, welches Fach wann
       liegt. Jetzt ist die Regel einfacher: Fachfarbe, und rot heisst
       "findet nicht statt". */
    border-left: 4px solid var(--fach, var(--border-strong));
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 11px 13px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

.lesson:active { background: var(--surface-alt); }

@media (prefers-reduced-motion: no-preference) {
    .lesson { transition: transform 90ms ease, background-color 90ms ease; }
    .lesson:active { transform: scale(.985); }
}
.lesson:focus-visible { outline: 2px solid var(--hinweis); outline-offset: 2px; }

/* Der Ausfall behält die rote Kante. Er ist die einzige Änderung, bei der
   die Stunde gar nicht stattfindet — und die Karte tritt dabei ohnehin
   zurück (gedämpfter Text). Ohne die Kante wäre die folgenreichste Meldung
   des Tages die leiseste.

   .lesson--changed trägt bewusst keine Farbe mehr: Vertretung und
   Raumwechsel sagen es über ihre Pille. Die Klasse bleibt als Anker im
   Markup — sie kostet nichts und beschreibt den Zustand. */
.lesson--entfall { border-left-color: var(--entfall); }

/* Die laufende Stunde.

   Nicht über die linke Kante: Die gehört dem Fach, und das ist Absicht
   (siehe oben). Ein aufgehellter Grund und ein kräftigerer Rahmen sagen
   dasselbe, ohne der Karte ihre Fach-Identität zu nehmen. */
.lesson--jetzt {
    background: color-mix(in srgb, var(--accent) 9%, var(--surface));
    border-color: var(--accent);
}

.tag--jetzt {
    background: var(--accent);
    color: var(--accent-text);
    font-weight: 800;
}

/* "Gleich" ist die schwächere Auskunft und sieht auch so aus: nur eine
   Pille, kein eingefärbter Grund. */
.tag--gleich {
    background: color-mix(in srgb, var(--accent) 18%, transparent);
    color: var(--accent);
}
.lesson--plain { border-left-color: var(--border-strong); }

.lesson__when {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    padding-top: 1px;
    font-variant-numeric: tabular-nums;
}

.lesson__hour {
    font-size: 1.05rem;
    font-weight: 700;
    line-height: 1.25;
}

.lesson__time {
    font-size: .74rem;
    color: var(--text-muted);
    line-height: 1.35;
}

.lesson__time--end { color: var(--text-faint); }

.lesson__main { min-width: 0; }

.lesson__subject,
.lesson__teacher,
.lesson__room {
    margin: 0;
    overflow-wrap: anywhere;
}

.lesson__subject {
    font-weight: 650;
    font-size: 1rem;
    line-height: 1.3;
}

.lesson__dot {
    display: inline-block;
    width: 7px;
    height: 7px;
    margin-right: 6px;
    border-radius: 50%;
    background: var(--fach, transparent);
    /* Rein dekorativ: Der Punkt trägt keine Information, die nicht schon
       im Fachnamen daneben steht. */
    vertical-align: 1px;
}

.lesson__code {
    font-weight: 400;
    font-size: .78em;
    color: var(--text-faint);
}

.lesson__teacher {
    font-size: .86rem;
    color: var(--text-muted);
    line-height: 1.35;
}

.lesson__room {
    font-size: .86rem;
    color: var(--text-muted);
    line-height: 1.35;
}

/* Die zweite Raumbezeichnung. An der Tür steht die H-Nummer, hier steht
   daneben die Buchstabenform — sie ist der Anschluss an den Lageplan. Klein
   und blass: Sie soll da sein, wenn man sie sucht, und sonst nicht mitreden. */
.lesson__room-alt {
    font-size: .78em;
    color: var(--text-faint);
    font-variant-numeric: tabular-nums;
}

/* Bei einem Raumwechsel ist die ganze Zeile in Warnfarbe — die Zweitangabe
   erbt sie, sonst sähe sie wie ein Fehler aus. */
.lesson__room--away .lesson__room-alt { color: inherit; opacity: .7; }

/* Kleiner Zusatz "statt KÜRZEL" bei einer Vertretung. */
.lesson__label {
    font-size: .76rem;
    color: var(--text-faint);
    white-space: nowrap;
}

/* Raumwechsel: dezent, aber nicht nur über die Farbe — der Pfeil steht davor. */
.lesson__room--away { color: var(--raum); font-weight: 600; }

.lesson__status {
    flex: none;
    padding-top: 2px;
    /* Marke und Heft untereinander, rechtsbündig: Eine Stunde kann beides
       haben — Vertretung und offene Hausaufgabe. */
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 5px;
}

/* Das Heft sitzt am Rand der Karte und sagt: Hier wurde etwas aufgegeben.
   In der Akzentfarbe, damit es zwischen den Fachfarben nicht untergeht —
   aber ohne Fläche, denn es ist ein Hinweis und kein Knopf. Die ganze
   Karte ist ohnehin antippbar und zeigt dann den Wortlaut. */
.lesson__heft {
    position: relative;
    display: inline-flex;
    color: var(--accent);
}

.lesson__heft svg { width: 19px; height: 19px; }

/* Mehr als eine Aufgabe in derselben Stunde kommt vor. Die Zahl klebt
   am Heft, statt daneben Platz zu brauchen. */
.lesson__heft-zahl {
    position: absolute;
    right: -5px;
    bottom: -3px;
    min-width: 13px;
    padding: 0 3px;
    border-radius: 999px;
    background: var(--accent);
    color: var(--accent-text);
    font-size: .6rem;
    font-weight: 700;
    line-height: 13px;
    text-align: center;
}

/* Bei Ausfall gibt es keine Hausaufgabe zu zeigen — vorsichtshalber auch
   hier gedämpft, falls doch einmal eine durchkommt. */
.lesson--entfall .lesson__heft { opacity: .4; }

/* Ausgefallene Stunden treten zurück. Kein Durchstreichen: Die rote Kante
   und das "fällt aus" sagen es schon. */
.lesson--entfall .lesson__subject { color: var(--text-muted); font-weight: 550; }
.lesson--entfall .lesson__teacher,
.lesson--entfall .lesson__room { color: var(--text-faint); }
.lesson--entfall .lesson__dot { opacity: .55; }

.tag {
    display: inline-block;
    font-size: .68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    padding: 3px 8px;
    border-radius: 999px;
    background: var(--surface-alt);
    color: var(--text-muted);
    white-space: nowrap;
    /* Kontur aus der eigenen Textfarbe: trägt über alle Themen, ohne je
       Thema eigene Randfarben zu brauchen. */
    box-shadow: inset 0 0 0 1px color-mix(in srgb, currentColor 22%, transparent);
}

.tag--entfall { background: color-mix(in srgb, var(--entfall) 16%, transparent); color: var(--entfall); }
.tag--vertretung { background: color-mix(in srgb, var(--vertretung) 16%, transparent); color: var(--vertretung); }
/* Der eine Satz, der auf der Seite "Zweites Gerät" hängenbleiben muss:
   Das App-Passwort gehört nicht in den Link. */
.settings__hint--warnung {
    border-left: 3px solid var(--entfall);
    padding-left: 10px;
    color: var(--text);
}

/* Die Arbeit trägt die Farbe des Entfalls — nicht, weil sie etwas
   Schlechtes wäre, sondern weil das der Ton ist, den die App für "hier
   musst du hinsehen" benutzt. Kräftiger als die anderen Marken: Sie soll
   auf einer Karte voller Angaben zuerst auffallen. */
.tag--arbeit {
    background: var(--entfall);
    color: var(--surface);
    font-weight: 800;
}

/* Die Lernkontrolle verhält sich zur Arbeit wie "gleich" zu "jetzt": Es
   ist dieselbe Auskunft, nur eine Nummer kleiner. Deshalb dieselbe Farbe,
   aber als Pille statt als gefüllte Fläche — wer beides auf einem
   Bildschirm sieht, soll die Rangfolge sehen, ohne sie zu lernen. */
.tag--lernkontrolle {
    background: color-mix(in srgb, var(--entfall) 18%, transparent);
    color: var(--entfall);
    font-weight: 700;
}

/* Überfällig trägt dieselbe Farbe wie der Entfall — der Ton, den die App
   für "hier musst du hinsehen" benutzt. "Bald" eine Stufe darunter.

   Diese Regeln stehen bewusst HINTER der Grundregel .tag: Beide haben
   dieselbe Spezifität, also entscheidet die Reihenfolge. Weiter oben
   notiert blieben sie wirkungslos — die Marken sahen dann alle gleich aus,
   und im Bild fiel das nicht auf. */
.tag--frist-vorbei {
    background: var(--entfall);
    color: var(--surface);
    font-weight: 800;
}

.tag--frist-heute {
    background: color-mix(in srgb, var(--entfall) 18%, transparent);
    color: var(--entfall);
    font-weight: 700;
}

.tag--frist-bald {
    background: color-mix(in srgb, var(--raum) 18%, transparent);
    color: var(--raum);
    font-weight: 700;
}

.tag--raumaenderung,
.tag--eva { background: color-mix(in srgb, var(--raum) 18%, transparent); color: var(--raum); }

/* ---------- Infoblöcke ---------- */

.info {
    background: var(--surface-alt);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 12px 14px;
    margin-top: 12px;
    font-size: .88rem;
}

.info__label {
    font-weight: 650;
    font-size: .76rem;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--text-muted);
    margin: 0 0 4px;
}

.info__value { margin: 0; white-space: pre-line; }

/* ---------- Karten (Termine, Kurse, Nachrichten) ---------- */

.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-left: 4px solid var(--hinweis);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 12px 14px;
    margin-bottom: 10px;
}

.card--accent { border-left-color: var(--raum); }
.card--quiet { border-left-color: var(--border-strong); box-shadow: none; }

/* Eine Kursmappe trägt ihre Fachfarbe an der Kante — dieselbe wie die Stunde
   im Tagesplan. Vorher war die Liste farblos (card--quiet), und damit war
   sie das Einzige in der App, das man Zeile für Zeile lesen musste, statt
   am Fleck zu erkennen. */
.card--mappe { border-left-color: var(--fach, var(--border-strong)); }

/* Die Hausaufgabe an der Kursmappe. Eigene Fläche mit dem Heft davor —
   dasselbe Zeichen wie an der Stunde im Tagesplan, damit man den Bezug
   nicht lernen muss. */
.card__hausaufgabe {
    display: flex;
    align-items: flex-start;
    gap: 7px;
    margin: 8px 0 0;
    padding: 9px 11px;
    border-left: 3px solid var(--accent);
    border-radius: 4px 10px 10px 4px;
    background: color-mix(in srgb, var(--accent) 10%, var(--surface-alt));
    white-space: pre-line;
}

.card__hausaufgabe svg {
    width: 15px;
    height: 15px;
    flex: none;
    margin-top: 2px;
    color: var(--accent);
}

.card__top {
    display: flex;
    align-items: baseline;
    gap: 10px;
    margin-bottom: 4px;
}

.card__subject { font-weight: 600; }

/* Der Fachname als Weg in die Chronik. Er soll aussehen wie zuvor —
   nur der Pfeil sagt, dass dahinter etwas liegt. Ein Knopf mit
   Knopfaussehen an dieser Stelle machte die Karte unruhig. */
.card__subject--griff {
    display: inline-flex;
    align-items: baseline;
    gap: 4px;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    font-weight: 600;
    text-align: left;
    cursor: pointer;
}

.card__subject__pfeil {
    color: var(--text-muted);
    font-size: .9em;
}

.card__subject--griff:hover .card__subject__pfeil { color: inherit; }

/* ---------- Rückmeldungen lesen (Betreiber) ---------- */

#rml-zahl { color: var(--text-muted); font-weight: 400; }

.rml {
    border-left: 3px solid var(--border-strong);
    border-radius: var(--radius);
    background: var(--surface);
    padding: 10px 12px;
    margin-bottom: 8px;
}

.rml__kopf { font-size: .78rem; color: var(--text-muted); }

/* Absätze bleiben stehen — wer drei Sätze schreibt, hat sie gegliedert. */
.rml__text { margin: 4px 0 0; font-size: .92rem; white-space: pre-line; }

.rml__antwort { margin: 6px 0 0; font-size: .84rem; }
.rml__umstaende { margin: 4px 0 0; font-size: .76rem; color: var(--text-faint); }

/* Erledigtes tritt zurück, verschwindet aber nicht: Es liegt hinter dem
   Griff, und wer es aufklappt, soll sehen, dass es erledigt ist. */
.rml--erledigt { opacity: .62; }
.rml .haken { margin-top: 8px; }

/* ---------- Rückmeldung ---------- */

/* 16 px, nicht kleiner: Darunter zoomt iOS beim Antippen heran, und dann
   steht die halbe Maske ausserhalb des Bildschirms. Der Prüflauf hat genau
   das an diesen zwei Feldern gefangen. */
#rm-text, #rm-mail {
    width: 100%;
    font: inherit;
    font-size: 16px;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text);
}
#rm-text { min-height: 120px; resize: vertical; }

.rm-umstaende { margin: 12px 0 4px; }

.rm-umstaende summary {
    font-size: .86rem;
    color: var(--text-muted);
    cursor: pointer;
}

.rm-senden { width: 100%; margin-top: 14px; }

#rm-fehler { color: var(--entfall); }

/* ---------- Stundenplan drucken ---------- */

.druckwahl { display: flex; gap: 8px; margin: 10px 0 8px; }
.druckwahl--drei .druckwahl__knopf { padding: 10px 4px; font-size: .82rem; }
.druckwahl__knopf small {
    display: block;
    margin-top: 2px;
    font-size: .74rem;
    font-weight: 400;
    opacity: .75;
}

.druckwahl__knopf {
    flex: 1;
    padding: 12px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text-muted);
    font: inherit;
    font-size: .9rem;
    cursor: pointer;
}

.druckwahl__knopf.is-aktiv {
    border-color: var(--accent);
    color: var(--text);
    font-weight: 600;
}

.druckwahl__los { width: 100%; margin: 16px 0 10px; }

/* Auf dem Bildschirm gibt es das Druckbild nicht.
   display:none und nicht bloss versteckt: Ein Raster mit 39 Zellen im
   Dokument, das niemand sieht, kostet sonst bei jedem Zeichnen Platz und
   Rechenzeit — und Vorleseprogramme lesen es vor. */
.druckplan { display: none; }

@media print {
    /* Beim Drucken umgekehrt: die App weg, das Blatt da. */
    body > *:not(.druckplan) { display: none !important; }

    .druckplan { display: block !important; }

    html, body {
        margin: 0;
        background: #fff !important;
        background-image: none !important;
        color: #000 !important;
        font-size: 10pt;
    }

    /* Hochformat und ein Rand, der auf jedem Drucker vorhanden ist.
       Die Kopf- und Fusszeile von iOS (Adresse, Datum) lässt sich von der
       Seite aus nicht abschalten — dafür ist der eigene Fuss knapp. */
    @page { size: A4 portrait; margin: 12mm; }

    .druckplan__kopf { margin-bottom: 5mm; }

    .druckplan__kopf h1 {
        margin: 0;
        font-size: 14pt;
        letter-spacing: .01em;
    }

    /* Name und Klasse in dieselbe Zeile wie die Überschrift: Auf A5 ist
       jede Zeile Platz, den die Tabelle besser gebrauchen kann. */
    .druckplan__wer { font-size: 11pt; font-weight: 600; }
    .druckplan__wer::before { content: " — "; font-weight: 400; }

    .druckplan__schule { margin: 1mm 0 0; font-size: 9.5pt; }
    .druckplan__meta { margin: 1mm 0 0; font-size: 8.5pt; color: #333; }

    /*
     * A5 quer ist genau die obere Hälfte eines A4-Blattes im Hochformat:
     * 210 × 148,5 mm. Bei 12 mm Seitenrand bleiben davon 136,5 mm für den
     * Satz — zweimal untereinander ergibt 273 mm, also genau die
     * bedruckbare Höhe.
     *
     * Feste Höhe und NICHT overflow:hidden: Ein Plan, der still
     * abgeschnitten wird, sieht auf dem Bildschirm heil aus und ist auf
     * Papier unbrauchbar. Passt etwas nicht, soll es überstehen und
     * auffallen.
     */
    .druckplan__blatt--halb,
    .druckplan__blatt--doppelt {
        height: 136.5mm;
        box-sizing: border-box;
        overflow: visible;
    }

    /* --dicht kommt aus dem Renderer und folgt dem Gewicht des Plans.
       Alles Knappe rechnet damit, damit eine Stauchung nicht an einer
       vergessenen Stelle vorbeigeht. */
    .druckplan__blatt--halb,
    .druckplan__blatt--doppelt { --dicht: 1; }

    .druckplan__blatt--halb .druckplan__kopf,
    .druckplan__blatt--doppelt .druckplan__kopf { margin-bottom: calc(3mm * var(--dicht)); }

    .druckplan__blatt--halb .druckplan__kopf h1,
    .druckplan__blatt--doppelt .druckplan__kopf h1 { font-size: calc(11.5pt * var(--dicht)); }

    .druckplan__blatt--halb .druckplan__wer,
    .druckplan__blatt--doppelt .druckplan__wer { font-size: calc(9.5pt * var(--dicht)); }

    .druckplan__blatt--halb .druckplan__schule,
    .druckplan__blatt--doppelt .druckplan__schule { font-size: calc(8pt * var(--dicht)); }

    .druckplan__blatt--halb .druckplan__meta,
    .druckplan__blatt--doppelt .druckplan__meta { font-size: calc(7pt * var(--dicht)); }

    .druckplan__blatt--halb .druckplan__tabelle th,
    .druckplan__blatt--halb .druckplan__tabelle td,
    .druckplan__blatt--doppelt .druckplan__tabelle th,
    .druckplan__blatt--doppelt .druckplan__tabelle td { padding: calc(.9mm * var(--dicht)) 1mm; }

    .druckplan__blatt--halb .druckplan__fach,
    .druckplan__blatt--doppelt .druckplan__fach { font-size: calc(7.5pt * var(--dicht)); }

    .druckplan__blatt--halb .druckplan__raum,
    .druckplan__blatt--halb .druckplan__lehrer,
    .druckplan__blatt--doppelt .druckplan__raum,
    .druckplan__blatt--doppelt .druckplan__lehrer { font-size: calc(6pt * var(--dicht)); }

    .druckplan__blatt--halb .druckplan__nr,
    .druckplan__blatt--doppelt .druckplan__nr { font-size: calc(8pt * var(--dicht)); }

    .druckplan__blatt--halb .druckplan__zeit,
    .druckplan__blatt--doppelt .druckplan__zeit { font-size: calc(6pt * var(--dicht)); }

    .druckplan__blatt--halb .druckplan__woche,
    .druckplan__blatt--doppelt .druckplan__woche { font-size: 6pt; margin-top: .4mm; }

    .druckplan__blatt--halb .druckplan__ecke,
    .druckplan__blatt--halb .druckplan__stunde,
    .druckplan__blatt--doppelt .druckplan__ecke,
    .druckplan__blatt--doppelt .druckplan__stunde { width: 13mm; }

    .druckplan__blatt--halb .druckplan__tabelle thead th,
    .druckplan__blatt--doppelt .druckplan__tabelle thead th { font-size: calc(8pt * var(--dicht)); }

    /* Die Schnittlinie sitzt genau auf der Faltkante. Sie liegt IN der
       Höhe des Satzes, nicht darunter — sonst schöbe sie die zweite
       Hälfte um ihre eigene Höhe nach unten und der Schnitt läge falsch. */
    .druckplan__schnitt {
        position: relative;
        height: 0;
        border-top: .4pt dashed #999;
        text-align: right;
    }

    .druckplan__schnitt span {
        position: absolute;
        right: 0;
        top: -3.4mm;
        background: #fff;
        padding-left: 2mm;
        font-size: 6.5pt;
        color: #777;
    }

    .druckplan__blatt--doppelt + .druckplan__schnitt + .druckplan__blatt--doppelt {
        /* Nichts weiter: Die feste Höhe beider Hälften setzt den Schnitt
           von selbst auf 148,5 mm ab Papierkante. */
    }

    .druckplan__tabelle {
        width: 100%;
        border-collapse: collapse;
        table-layout: fixed;
    }

    .druckplan__tabelle th,
    .druckplan__tabelle td {
        border: .4pt solid #000;
        padding: 1.6mm 1.4mm;
        vertical-align: top;
        text-align: left;
    }

    .druckplan__tabelle thead th {
        font-size: 9.5pt;
        /* Kein grauer Grund: Auf einem schwachen Laserdrucker wird daraus
           ein Fleck, in dem die Schrift verschwindet. Eine dicke Linie
           trennt genauso deutlich und kostet keine Farbe. */
        border-bottom-width: 1.2pt;
    }

    .druckplan__ecke { width: 16mm; }

    .druckplan__stunde { width: 16mm; font-weight: 400; }
    .druckplan__nr { display: block; font-size: 10pt; font-weight: 700; }
    .druckplan__zeit { display: block; font-size: 7.5pt; color: #333; }

    .druckplan__stunde-block { padding-left: 0; }
    .druckplan__stunde-block + .druckplan__stunde-block {
        margin-top: 1.4mm;
        padding-top: 1.4mm;
        border-top: .4pt dotted #666;
    }

    .druckplan__fach { display: block; font-size: 9.5pt; font-weight: 700; }
    .druckplan__raum { display: block; font-size: 8pt; }
    .druckplan__lehrer { display: block; font-size: 8pt; color: #333; }

    /* Der A/B-Vermerk muss auffallen, sonst hängt der halbe Plan falsch
       am Kühlschrank. */
    .druckplan__woche {
        display: inline-block;
        margin-top: .8mm;
        padding: .2mm 1mm;
        border: .4pt solid #000;
        font-size: 7.5pt;
        font-weight: 700;
    }

    .druckplan__fuss {
        margin-top: 5mm;
        font-size: 7.5pt;
        color: #444;
    }

    /* Farbig: ein Streifen am Rand, keine gefüllte Fläche. Gefüllte
       Kästchen fressen Toner und machen den Text schlechter lesbar; ein
       Streifen von 1,5 mm trennt die Fächer genauso. */
    .druckplan__blatt--farbig .druckplan__stunde-block {
        border-left: 1.5mm solid var(--fach, #000);
        padding-left: 1.6mm;
    }

    .druckplan__blatt--farbig .druckplan__stunde-block + .druckplan__stunde-block {
        margin-top: 1.4mm;
    }

    /* Damit die Farbstreifen überhaupt gedruckt werden — Browser lassen
       Hintergründe im Druck sonst weg. */
    .druckplan__blatt--farbig .druckplan__stunde-block {
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
    }
}

/* ---------- Die Chronik ---------- */

/* Die Fächerleiste. Waagerecht scrollend statt umbrechend: Bei dreizehn
   Kursen wären es sonst vier Zeilen, bevor der erste Eintrag kommt. */
.chronik__faecher {
    display: flex;
    gap: 6px;
    overflow-x: auto;
    padding-bottom: 8px;
    margin-bottom: 4px;
    scrollbar-width: none;
}

.chronik__faecher::-webkit-scrollbar { display: none; }

.chronik__fach {
    flex: 0 0 auto;
    padding: 6px 12px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface);
    color: var(--text-muted);
    font: inherit;
    font-size: .84rem;
    white-space: nowrap;
    cursor: pointer;
}

.chronik__fach small {
    opacity: .7;
    margin-left: 2px;
}

.chronik__fach.is-aktiv {
    border-color: var(--border-strong);
    background: var(--surface-strong, var(--surface));
    color: var(--text);
    font-weight: 600;
}

.chronik__woche {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    margin: 18px 0 8px;
    font-size: .82rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--text-muted);
}

.chronik__woche span {
    font-weight: 400;
    letter-spacing: 0;
    text-transform: none;
}

/*
 * Die Hausaufgaben-Liste unter "Nachschlagen" — alles, was aufgegeben
 * wurde, neueste zuerst.
 *
 * Gebaut wie ein Chronik-Eintrag: dieselbe Fachfarbe am Rand, dieselbe
 * Kopfzeile. Sie stehen im selben Menü untereinander und sollen nicht
 * aussehen wie aus zwei Häusern.
 */
.ha-zeile {
    border-left: 3px solid var(--fach, var(--border-strong));
    border-radius: var(--radius);
    background: var(--surface);
    padding: 10px 12px;
    margin-bottom: 6px;
}

/* Erledigtes tritt zurück, verschwindet aber nicht: Die Frage "was war
   letzte Woche auf?" gilt gerade dem, was schon erledigt ist. */
.ha-zeile--fertig { opacity: .62; }

.ha-zeile__kopf {
    display: flex;
    align-items: baseline;
    gap: 10px;
    font-size: .8rem;
    color: var(--text-muted);
}

.ha-zeile__fach { font-weight: 600; color: var(--fach, var(--text)); }

/* Der Stand — offen oder erledigt. Er steht im Kopf, weil dort
   hingesehen wird; der Knopf darunter ist die Handlung, nicht die
   Auskunft. Offen trägt die Warnfarbe, erledigt bleibt still. */
.ha-zeile__stand {
    padding: 1px 7px;
    border-radius: 6px;
    background: color-mix(in srgb, var(--entfall) 16%, transparent);
    color: var(--entfall);
    font-size: .74rem;
    font-weight: 600;
    letter-spacing: .02em;
    text-transform: uppercase;
}

.ha-zeile__stand--fertig {
    background: var(--surface-alt);
    color: var(--text-faint);
}

.ha-zeile__kopf .tag { margin-left: auto; white-space: nowrap; }

.ha-zeile__text {
    margin: 6px 0 8px;
    color: var(--text);
    overflow-wrap: anywhere;
}

.chronik__eintrag {
    border-left: 3px solid var(--fach, var(--border-strong));
    border-radius: var(--radius);
    background: var(--surface);
    padding: 10px 12px;
    margin-bottom: 6px;
}

.chronik__kopf {
    display: flex;
    align-items: baseline;
    gap: 10px;
    font-size: .8rem;
    color: var(--text-muted);
}

.chronik__datum { margin-left: auto; white-space: nowrap; }
.chronik__fachname { font-weight: 600; color: var(--text); }
/* Die Lehrkraft am Chronik-Eintrag — leiser als das Thema, das die
   eigentliche Auskunft ist. */
.chronik__lehrkraft {
    margin: 2px 0 0;
    color: var(--text-muted);
    font-size: .82rem;
}

.chronik__thema { margin: 4px 0 0; font-size: .92rem; }
.chronik__stunde { margin: 2px 0 0; font-size: .78rem; color: var(--text-muted); }

/* Der Anwesenheitsvermerk der Stunde, rechts in derselben Zeile wie die
   Stundenangabe. "anwesend" ist die Bestätigung und bleibt blass; was
   davon abweicht, ist der Grund, aus dem jemand hier nachsieht. */
.chronik__anwesend { float: right; color: var(--text-faint); }
.chronik__anwesend--fehlt { color: var(--entfall); font-weight: 600; }
.card__top .tag { margin-left: auto; }

/* Eine Karte, die auf die Schulwebsite führt: sieht aus wie jede Karte,
   ist aber ein Verweis. Die Textfarben erben, sonst färbte der Browser
   den ganzen Beitrag verweisblau. */
a.card--extern {
    display: block;
    color: inherit;
    text-decoration: none;
}
a.card--extern .card__mehr { color: var(--hinweis); }

.card__detail { font-size: .86rem; color: var(--text-muted); margin: 0; }
.card__detail + .card__detail { margin-top: 2px; }
.card__body { font-size: .9rem; margin: 6px 0 0; white-space: pre-line; }

.unread { position: relative; }

.unread::after {
    content: "";
    position: absolute;
    top: 14px;
    right: 14px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--entfall);
}

/* ---------- Wochenplan ---------- */

.week {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}

.week__table {
    width: 100%;
    min-width: 320px;
    border-collapse: collapse;
    table-layout: fixed;
    font-size: .8rem;
}

.week__table th,
.week__table td {
    border: 1px solid var(--border);
    padding: 4px 3px;
    text-align: center;
    vertical-align: top;
}

.week__table thead th {
    background: var(--surface-alt);
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .03em;
    color: var(--text-muted);
    padding: 6px 3px;
}

.week__table thead th.is-today {
    color: var(--text);
    background: color-mix(in srgb, var(--hinweis) 16%, var(--surface-alt));
    /* Zweites Merkmal neben der Farbe — bei grellem Licht und für
       Farbenblinde ist die Tönung allein zu schwach. */
    font-weight: 800;
    box-shadow: inset 0 -2px 0 var(--hinweis);
}

.week__hour {
    width: 46px;
    background: var(--surface-alt);
    font-weight: 700;
    font-size: .75rem;
    color: var(--text-muted);
}

.week__time {
    display: block;
    font-weight: 400;
    font-size: .65rem;
    font-variant-numeric: tabular-nums;
    line-height: 1.3;
}

.week__cell.is-today { background: color-mix(in srgb, var(--hinweis) 7%, transparent); }

.week__lesson {
    /* Damit die Wochenmarke in der Ecke sitzen kann, ohne Platz im
       Textfluss zu belegen. */
    position: relative;
    display: block;
    width: 100%;
    background: none;
    border: 0;
    padding: 1px 0;
    font: inherit;
    color: inherit;
    text-align: center;
    cursor: pointer;
    min-height: 34px;
    border-radius: 6px;
}

/* Tönung je Stunde, nicht je Zelle: Eine geteilte Stunde hat zwei Fächer.
   Nur 12 % — die Schrift behält ihren Kontrast gegen die Kartenfläche. */
/* Die Fachfarbe: getönte Fläche plus ein Streifen an der Kante. Zwölf
   Prozent Tönung allein waren auf dunklem Grund kaum zu sehen — der Streifen
   trägt die Erkennbarkeit, die Fläche macht den Block ruhig. */
.week__lesson {
    background: color-mix(in srgb, var(--fach, transparent) 20%, transparent);
    border-left: 3px solid var(--fach, transparent);
    padding-left: 2px;
}

.week__lesson:active { background: color-mix(in srgb, var(--hinweis) 24%, transparent); }

.week__lesson + .week__lesson {
    margin-top: 2px;
    border-top: 1px dotted var(--border);
    padding-top: 3px;
}

/* Die Marke einer Stunde, die nur jede zweite Woche stattfindet.
   Vorher ein hochgestellter Buchstabe am Fachkürzel — in einer Zelle von
   55 Punkten eher ein Fußnotenzeichen als eine Auskunft. Jetzt eine
   gefüllte Marke in der Ecke, ausserhalb des Textflusses: Sie kann nicht
   mit dem Fachnamen um Platz streiten, weil sie keinen belegt. */
/* Die Zeile, die die Marke erklärt. Sie steht über dem üblichen Hinweis
   und trägt eine Aussage, nicht nur eine Bedienungsanleitung — deshalb
   etwas mehr Gewicht. */
.hint--wochen {
    padding: 8px 10px;
    border-radius: 8px;
    border-left: 3px solid var(--accent);
    background: color-mix(in srgb, var(--accent) 8%, var(--surface-alt));
}

.week__marke {
    position: absolute;
    top: 1px;
    right: 1px;
    min-width: 12px;
    height: 12px;
    padding: 0 2px;
    border-radius: 4px;
    background: var(--accent);
    color: var(--accent-text);
    font-size: .58rem;
    font-weight: 800;
    line-height: 12px;
    text-align: center;
    letter-spacing: 0;
}

/* Findet die Stunde diese Woche statt, ist die Marke eine Randnotiz —
   findet sie NICHT statt, ist sie die Erklärung für die Dämpfung. Deshalb
   dort umgekehrt: heller Rahmen, keine Füllung. */
.week__marke--andere {
    background: none;
    border: 1px solid currentColor;
    color: var(--text-muted);
    line-height: 10px;
}

/* Die Stunde der anderen Woche. Nicht ausgeblendet — der Plan gilt ja für
   beide Wochen, und wer nächste Woche vorausschaut, will sie sehen. Nur
   deutlich zurückgenommen, damit die laufende Woche vorn steht. */
.week__lesson--andere {
    opacity: .38;
    background: none;
}

.week__subject {
    display: block;
    font-weight: 650;
    line-height: 1.2;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.week__room {
    display: block;
    font-size: .68rem;
    color: var(--text-muted);
    line-height: 1.3;
    margin-bottom: 3px;
    /* Nie umbrechen: Eine Zelle über zwei Zeilen macht die ganze Zeile des
       Rasters höher, und "H1-" über "228" liest sich wie ein Fehler. Reicht
       es doch nicht, wird abgeschnitten — dann steht immerhin der Anfang da,
       und das Blatt zur Stunde zeigt beides. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.week__room--away { color: var(--raum); font-weight: 600; }

/* ---------- Sonstiges ---------- */

.empty {
    text-align: center;
    color: var(--text-muted);
    padding: 28px 12px;
    font-size: .95rem;
}

.empty strong { display: block; font-size: 1.05rem; color: var(--text); margin-bottom: 4px; }

.toggle {
    display: block;
    width: 100%;
    margin: 12px 0 0;
    padding: 12px;
    background: var(--surface);
    border: 1px dashed var(--border-strong);
    border-radius: var(--radius);
    color: var(--text-muted);
    font: inherit;
    font-size: .86rem;
    cursor: pointer;
}

/* Klapp-Knöpfe zeigen ihre Richtung: ▾ heisst "es kommt etwas dazu",
   ▴ heisst "hier klappt es wieder zu". Nur echte Klappstellen
   ([data-toggle]) — die Knöpfe, die woandershin führen (data-goto),
   bekommen keinen Pfeil, sie klappen nichts. Der Pfeil hängt an
   aria-expanded, derselben Angabe, die Vorlesehilfen benutzen: Ein
   Zustand, eine Quelle. */
.toggle[data-toggle]::after { content: "\00a0▾"; }
.toggle[data-toggle][aria-expanded="true"]::after { content: "\00a0▴"; }

.error-box {
    border: 1px solid color-mix(in srgb, var(--entfall) 35%, var(--border));
    background: color-mix(in srgb, var(--entfall) 8%, var(--surface));
    border-radius: var(--radius);
    padding: 12px 14px;
    font-size: .88rem;
    margin-bottom: 12px;
}

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

/* Seit der Stand oben in der Titelleiste steht, ist "Abmelden" der einzige
   Inhalt — mittig gesetzt sieht es gewollt aus, links wie ein Rest. */
.footer {
    max-width: 720px;
    margin: 0 auto;
    padding: 8px 16px calc(var(--safe-bottom) + 20px);
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: .78rem;
    color: var(--text-muted);
}

.footer__logout {
    background: none;
    border: 0;
    color: var(--text-muted);
    font: inherit;
    font-size: .78rem;
    text-decoration: underline;
    cursor: pointer;
    padding: 4px;
}

/* ---------- Detailansicht (von unten eingeschoben) ---------- */

.sheet {
    position: fixed;
    inset: 0;
    z-index: 50;
    display: flex;
    align-items: flex-end;
    justify-content: center;
}

/*
 * Die Einstellungen sind das UNTERSTE Blatt.
 *
 * Aus ihnen heraus öffnen sich andere: Impressum, Datenschutz, der
 * Lageplan, die Kurse, der Speiseplan, das Drucken. Alle Blätter tragen
 * dieselbe Stapelhöhe (50), und bei Gleichstand gewinnt das, was später
 * im Dokument steht — die Einstellungen stehen bei Zeile 978, die
 * anderen davor. Also gingen sie hinter den Einstellungen auf: sichtbar
 * war weiter die Einstellungsliste, das geöffnete Blatt lag dahinter.
 *
 * Am 05.09.2026 für Impressum und Datenschutz gemeldet, aber es betraf
 * jedes dieser Blätter. Beim Video war es schon einmal aufgefallen und
 * dort einzeln behoben (#video-blatt trägt 55) — die Ursache blieb.
 *
 * Eine Zeile statt sieben: Nicht jedes andere Blatt höher setzen,
 * sondern dieses eine tiefer. 45 liegt über der Liste und dem
 * schwebenden Knopf (40) und unter allen Blättern (50).
 */
#settings {
    z-index: 45;
}

.sheet__backdrop { position: absolute; inset: 0; background: rgba(8, 14, 24, .5); }

.sheet__panel {
    position: relative;
    width: 100%;
    max-width: 720px;
    background: var(--surface);
    border-top-left-radius: 18px;
    border-top-right-radius: 18px;
    /* Oben keine Polsterung: Die feststehende Kopfzeile bringt sie mit.
       Läge sie hier, müsste die Kopfzeile mit einem negativen Rand darüber
       hinausgreifen — und ein negativer Rand verträgt sich nicht mit
       position: sticky, das Element rutscht dann über den Text darunter. */
    padding: 0 20px calc(var(--safe-bottom) + 20px);
    box-shadow: 0 -8px 32px rgba(8, 14, 24, .25);
    animation: sheet-in .18s ease-out;
}

@keyframes sheet-in {
    from { transform: translateY(12px); opacity: .6; }
    to { transform: translateY(0); opacity: 1; }
}

/* Ein schmales Band in der Fachfarbe an der Oberkante — dieselbe Farbe wie
   die Karte, auf die man getippt hat. Als Fläche statt als Schrift, damit
   kein Kontrastproblem entsteht: Die Fachfarben sind für Text zu blass. */
.sheet__panel--fach::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 4px;
    background: var(--fach);
    border-top-left-radius: 18px;
    border-top-right-radius: 18px;
}

.sheet__title {
    display: flex;
    align-items: center;
    gap: 9px;
    margin: 0 0 14px;
    font-size: 1.15rem;
}

.sheet__punkt {
    flex: none;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--fach);
}

.sheet__list {
    margin: 0;
    display: grid;
    grid-template-columns: 96px 1fr;
    gap: 6px 12px;
    font-size: .92rem;
}

.sheet__list dt { color: var(--text-muted); font-size: .82rem; padding-top: 1px; }
.sheet__list dd { margin: 0; }

/* Die Hausaufgabe. Sie stand als gewöhnliche Zeile zwischen Uhrzeit,
   Lehrkraft und Raum — und ging darin unter, obwohl das Heft an der Karte
   gerade auf sie hingewiesen hat. Also über die ganze Breite, mit demselben
   Heft und einer eigenen Fläche: Wer dem Zeichen gefolgt ist, soll das Ziel
   auf den ersten Blick finden. */
.sheet__list dt.ist-heft {
    grid-column: 1 / -1;
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 6px;
    color: var(--accent);
    font-size: .76rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
}

.sheet__list dt.ist-heft svg { width: 15px; height: 15px; flex: none; }

.sheet__list dd.ist-heft {
    grid-column: 1 / -1;
    margin-bottom: 6px;
    padding: 10px 12px;
    border-left: 3px solid var(--accent);
    border-radius: 4px 10px 10px 4px;
    background: color-mix(in srgb, var(--accent) 10%, var(--surface-alt));
    /* Mehrere Aufgaben in einer Stunde sind mit Leerzeilen getrennt. Ohne
       das liefen sie in HTML zu einem Absatz zusammen. */
    white-space: pre-line;
}

/* Der Volltext einer Nachricht. Über die ganze Breite und mit erhaltenen
   Zeilenumbrüchen: Ein Elternbrief hat Absätze, und ohne pre-line liefe er
   in HTML zu einem Block zusammen. */
.sheet__list dd.ist-text {
    grid-column: 1 / -1;
    margin-top: 4px;
    white-space: pre-line;
    line-height: 1.5;
}

.sheet__list dt.ist-text {
    grid-column: 1 / -1;
    margin-top: 8px;
    font-size: .76rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--text-muted);
}

/* Eine Handlung, die zum Blatt gehört — steht über "Schließen" und tritt
   dagegen zurück: Sie ist die Ausnahme, nicht der Regelweg hinaus. */
.sheet__aktion { margin-top: 16px; }

.sheet__knopf {
    width: 100%;
    min-height: 40px;
    padding: 10px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: none;
    color: var(--hinweis);
    font: inherit;
    font-size: .88rem;
    cursor: pointer;
}

/* Der Verweis auf die ganze Nachricht. Er steht nur an Karten, die mehr
   haben als die Vorschau zeigt. */
.card__mehr {
    margin: 8px 0 0;
    color: var(--accent);
    font-size: .85rem;
    font-weight: 600;
}

.sheet__close {
    display: block;
    width: 100%;
    margin-top: 20px;
    padding: 12px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--surface-alt);
    color: var(--text);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

/* ---------- Fachfarben ---------- */

.fachfarbe {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: center;
    gap: 10px;
    padding: 7px 0;
    border-bottom: 1px solid var(--border);
}

/* Die aktuelle Farbe als Knopf. Rund und groß genug für den Daumen — 34
   Punkte plus Rand, das ist die kleinste Fläche, die sich zuverlässig
   treffen lässt, ohne dass die Liste zur Bildschirmlänge wird. */
.fachfarbe__marke {
    width: 34px;
    height: 34px;
    border: 2px solid var(--border-strong);
    border-radius: 50%;
    cursor: pointer;
    padding: 0;
}

/* Eine selbst gewählte Farbe bekommt einen Ring: So sieht man, welche Fächer
   von der Vorgabe abweichen, ohne sie zu vergleichen. */
.fachfarbe__marke.is-eigen {
    border-color: var(--accent);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 35%, transparent);
}

.fachfarbe__name {
    font-size: .94rem;
    font-weight: 600;
}

.fachfarbe__code {
    margin-left: 7px;
    font-size: .78rem;
    font-weight: 500;
    color: var(--text-faint);
}

/* Die Palette klappt unter der Zeile auf, über beide Spalten. */
.fachfarbe__palette {
    grid-column: 1 / -1;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 10px 0 4px;
}

.fachfarbe__wahl {
    width: 32px;
    height: 32px;
    border: 2px solid transparent;
    border-radius: 9px;
    cursor: pointer;
    padding: 0;
}

.fachfarbe__wahl.is-aktiv {
    border-color: var(--text);
    box-shadow: 0 0 0 2px var(--surface) inset;
}

.fachfarbe__zurueck {
    min-height: 32px;
    padding: 0 12px;
    border: 1px solid var(--border);
    border-radius: 9px;
    background: none;
    color: var(--hinweis);
    font: inherit;
    font-size: .84rem;
    cursor: pointer;
}

.settings__zuruecksetzen {
    display: block;
    width: 100%;
    min-height: 40px;
    margin-top: 14px;
    padding: 10px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: none;
    color: var(--hinweis);
    font: inherit;
    font-size: .88rem;
    cursor: pointer;
}

/* ---------- Ungeklärte Stunden ---------- */

/* Die einzige Stelle in den Einstellungen, an der etwas zu entscheiden ist —
   deshalb hervorgehoben statt eingereiht. */
.offen {
    margin: 12px 0 18px;
    padding: 14px;
    background: color-mix(in srgb, var(--raum) 12%, var(--surface));
    border-left: 3px solid var(--raum);
    border-radius: 0 var(--radius) var(--radius) 0;
}

.offen__wann {
    margin: 0;
    font-size: .74rem;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.offen__frage { margin: 4px 0 12px; font-size: .92rem; line-height: 1.35; }

.offen__wahlen { display: flex; gap: 8px; }

.offen__wahl {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 10px 12px;
    text-align: left;
    background: var(--surface);
    border: 1px solid var(--border);
    /* Die Fachfarbe als Kante — dieselbe Sprache wie im Stundenplan. */
    border-left: 3px solid var(--fach, var(--border-strong));
    border-radius: var(--radius);
    color: var(--text);
    font: inherit;
    cursor: pointer;
}

.offen__fach { font-weight: 600; }
.offen__wer { font-size: .78rem; color: var(--text-muted); }

#kurse-offen.is-busy { opacity: .5; pointer-events: none; }

/* ---------- Tutorial ---------- */

/* Als einziges Blatt wird dieses aus einem anderen heraus geöffnet — aus den
   Einstellungen. Alle Blätter liegen auf derselben Ebene (50), dann
   entscheidet die Reihenfolge im HTML, und die Einstellungen stehen weiter
   unten: Sie lägen darüber und fingen jeden Klick ab. Eine Stufe höher, aber
   unter dem Dateibetrachter (60), löst das an der Wurzel statt über die
   Reihenfolge der Zeilen. */
#video-blatt { z-index: 55; }

/*
 * Als einziges Blatt geht dieses über den ganzen Bildschirm.
 *
 * Das Video ist ein abgefilmtes Telefon, also hochkant im Verhältnis 440:956.
 * In einem Blatt, das unten nur zwei Drittel der Höhe bekommt, bliebe davon
 * eine Briefmarke mit grauen Balken links und rechts. Über die volle Höhe
 * passt es fast genau — Bildschirm und Aufnahme haben dieselbe Form.
 */
#video-blatt .sheet__panel {
    width: 100%;
    max-width: 520px;
    height: 100dvh;
    max-height: 100dvh;
    border-radius: 0;
    display: flex;
    flex-direction: column;
    padding-bottom: calc(var(--safe-bottom) + 12px);
}

.tutorial {
    flex: 1;
    /* Ohne das wächst ein Flex-Element über seinen Inhalt hinaus statt zu
       schrumpfen — das Video schöbe den Fertig-Knopf aus dem Bild. */
    min-height: 0;
    width: 100%;
    margin: 4px 0 10px;
    object-fit: contain;
    background: #021014;
    border-radius: var(--radius);
    border: 1px solid var(--border);
}

/* ---------- Einstellungen ---------- */

.sheet__panel--tall {
    max-height: 88dvh;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}

.settings__group {
    margin: 22px 0 10px;
    font-size: .78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--text-muted);
}

.settings__group:first-of-type { margin-top: 6px; }

.settings__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    padding: 12px 0;
    border-top: 1px solid var(--border);
    font-size: .92rem;
    cursor: pointer;
}

.settings__row small {
    display: block;
    color: var(--text-muted);
    font-size: .78rem;
    margin-top: 2px;
}

.settings__row input {
    flex: none;
    width: 22px;
    height: 22px;
    accent-color: var(--hinweis);
}

/* Themen als antippbare Karten mit Farbvorschau. */
.themes {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 8px;
}

.theme {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--surface-alt);
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.theme.is-active {
    border-color: var(--hinweis);
    box-shadow: inset 0 0 0 1px var(--hinweis);
}

.theme__preview {
    flex: none;
    width: 34px;
    height: 34px;
    border-radius: 9px;
    overflow: hidden;
    display: grid;
    grid-template-rows: 12px 1fr;
    border: 1px solid var(--border-strong);
}

.theme__bar { width: 100%; }

.theme__body {
    display: flex;
    align-items: flex-end;
    gap: 2px;
    padding: 3px;
    /* Damit eine Textur im kleinen Abbild auch zu sehen ist — sonst sähe
       "taher.de" im Wähler wie ein schlichtes Grau aus. */
    background-repeat: repeat;
}

.theme__dot { width: 5px; height: 5px; border-radius: 50%; }

.theme__name {
    display: block;
    font-size: .86rem;
    font-weight: 600;
    line-height: 1.2;
}

.theme__note {
    display: block;
    font-size: .72rem;
    color: var(--text-muted);
    line-height: 1.25;
}

/* ---------- Ladeanzeige ---------- */

.splash {
    position: fixed;
    inset: 0;
    display: grid;
    place-content: center;
    justify-items: center;
    gap: 14px;
    background: var(--bg);
    z-index: 100;
}

.splash__spinner {
    width: 30px;
    height: 30px;
    border: 3px solid var(--border);
    border-top-color: var(--hinweis);
    border-radius: 50%;
    animation: spin .8s linear infinite;
}

.splash__text { margin: 0; color: var(--text-muted); font-size: .9rem; }

/* ---------- Schmale Geräte ---------- */

/* ---------- Tablet ----------

   Ab 840 Punkten. Ein Standard-iPad ist hochkant 810 breit, quer 1080 —
   der Bruchpunkt trennt also Hochformat (bleibt wie auf dem Telefon) von
   Querformat und größeren Geräten.

   Grundhaltung: Die Lesespalte bleibt bei 720 Punkten. Text über die ganze
   Breite eines iPads zu ziehen macht ihn nicht besser lesbar, sondern
   schlechter — das Auge verliert die Zeile. Genutzt wird die Breite nur
   dort, wo sie etwas trägt: Kopfzeile, Reiter, und die Listen, deren Karten
   nebeneinander stehen dürfen. */
@media (min-width: 840px) {
    /* In der Stundenkarte Lehrkraft und Raum nebeneinander: Die Karte ist
       688 Punkte breit für drei kurze Angaben, also zwei Zeilen statt
       drei. Alle Karten bleiben gleich hoch, sie werden nur flacher. */
    .lesson__main {
        display: grid;
        grid-template-columns: 1fr auto;
        column-gap: 16px;
        align-items: baseline;
    }

    .lesson__subject { grid-column: 1 / -1; }

    .lesson__room { text-align: right; }

    /*
     * Nachrichten in zwei Spalten. Sie sind unabhängige Karten, die man nach
     * einem Betreff durchsieht — nicht eine Folge, die man von oben nach
     * unten abliest.
     *
     * Drei Listen bleiben bewusst einspaltig, und das ist derselbe Grund:
     *
     *   Der Tagesplan, weil die Reihenfolge dort die Uhrzeit ist.
     *
     *   Die Termine. Zuerst waren sie zweispaltig — und im Bild sah man den
     *   Fehler: Die Karten liegen in einem umrandeten Behälter mit
     *   Trennlinien je Zelle und lesen sich damit wie zwei untereinander
     *   stehende Listen. Wer die linke Spalte hinunterschaut, sieht den 23.,
     *   25., 27. und überspringt jeden zweiten Termin.
     *
     *   Der Reiter Unterricht, weil dort Wochenraster, Hinweise,
     *   Hausaufgaben und Menüpunkte Geschwister sind — ein Raster darüber
     *   ordnete Dinge nebeneinander, die nichts miteinander zu tun haben.
     */
    #panel-nachrichten {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 0 14px;
        align-items: start;
    }
}

@media (max-width: 380px) {
    :root { --when-width: 50px; }
    .lesson { gap: 10px; padding: 10px 11px; }
    .tabs__tab { font-size: .8rem; }
}

/* ---------- Ferien ---------- */

.holiday {
    background: color-mix(in srgb, var(--vertretung) 12%, var(--surface));
    border: 1px solid color-mix(in srgb, var(--vertretung) 35%, var(--border));
    border-radius: var(--radius);
    padding: 22px 16px;
    text-align: center;
}

.holiday__title { margin: 0; font-size: 1.2rem; font-weight: 700; }
.holiday__span { margin: 4px 0 0; font-size: .9rem; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.holiday__note { margin: 10px 0 0; font-size: .88rem; color: var(--text-muted); }

.card--ferien { border-left-color: var(--vertretung); }

/* ---------- Eigene Termine ---------- */

/* Eigene Termine haben keine Stundennummer — dafür sitzt die Uhrzeit in der
   Spalte, in der sonst die Stunde steht. Damit bleibt die Spaltenordnung
   erhalten, auch wenn der Inhalt ein anderer ist. */
.lesson--eigen {
    border-left-color: var(--accent);
    border-style: dashed;
    border-left-style: solid;
}

.lesson__time--own {
    font-size: .95rem;
    font-weight: 700;
    color: var(--text);
}

/* ---------- Planer in den Einstellungen ---------- */

.settings__hint {
    margin: -4px 0 12px;
    font-size: .8rem;
    color: var(--text-muted);
}

/* Konto löschen — bewusst zurückhaltend, aber unmissverständlich. */
.settings__danger {
    width: 100%;
    margin-top: 14px;
    padding: 12px;
    background: none;
    border: 1px solid var(--entfall);
    border-radius: 10px;
    color: var(--entfall);
    font-size: .9rem;
    cursor: pointer;
}

.planner__empty {
    margin: 0 0 12px;
    font-size: .88rem;
    color: var(--text-muted);
}

.planner__item {
    display: flex;
    align-items: stretch;
    gap: 8px;
    margin-bottom: 8px;
}

.planner__edit {
    flex: 1;
    min-width: 0;
    text-align: left;
    background: var(--surface-alt);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 9px 12px;
    font: inherit;
    color: inherit;
    cursor: pointer;
}

.planner__name { display: block; font-weight: 600; font-size: .92rem; }

.planner__meta {
    display: block;
    font-size: .78rem;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.planner__delete {
    flex: none;
    width: 42px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--surface-alt);
    color: var(--text-muted);
    font-size: 1.3rem;
    line-height: 1;
    cursor: pointer;
}

.planner-form {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--border);
}

.planner-form__row {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 10px;
    font-size: .88rem;
}

.planner-form__row > span:not(.pw) {
    flex: none;
    /* 72 px reichen für "Name", "Datum", "Von", "Bis" — die Felder des
       Terminplaners. Wo längere Beschriftungen stehen, setzt der Block
       die Breite selbst: siehe [data-page="konto"] weiter unten.

       Am 07.09.2026 gemeldet: "Benutzername" stand dort abgeschnitten
       als "Benutzernam". Gemessen braucht es 94 px, "Portal-Passwort"
       sogar 104. Die mit Bindestrich brachen um, das eine ohne wurde
       beschnitten — ohne Umbruchpunkt hilft kein Umbruch. */
    width: var(--label-breite, 72px);
    color: var(--text-muted);
}

/* Überall dort, wo Zugangsdaten eingetragen werden: "Portal-Passwort"
   ist das längste Wort der App in einer Beschriftungsspalte. Kürzen
   wäre riskant — "Portal" und "App" allein sagen bei zwei Passwörtern
   nicht genug, und verwechseln darf man sie nicht.

   Der Terminplaner bleibt bei 72: Dort heissen die Felder "Von" und
   "Bis", und eine Spalte von 118 Pixeln stünde grösstenteils leer. */
[data-page="konto"] .planner-form__row > span:not(.pw),
[data-page="kinder"] .planner-form__row > span:not(.pw) {
    /* 118 px: "Portal-Passwort" ist das längste Wort der App in einer
       Beschriftungsspalte und braucht gemessen 116. Bei 375 px
       Bildschirmbreite bleiben dem Feld daneben noch gut 200. */
    --label-breite: 118px;
}

/* Der Wrapper des Passwortfeldes tritt an die Stelle des Feldes und darf
   nicht als Beschriftungsspalte behandelt werden. */
/* Eine Zeile, deren Feld eine Vorschlagsliste führt, stellt die
   Beschriftung darüber statt daneben.

   Sonst beginnt das Feld 84px weiter rechts als die Liste darunter, und
   die Namen stehen neben dem Feld, zu dem sie gehören — beim Tippen auf
   dem Telefon besonders auffällig, weil der Blick der Einfügemarke folgt. */
.planner-form__row--breit {
    display: block;
}

.planner-form__row--breit > span {
    display: block;
    width: auto;
    margin-bottom: 5px;
}

/* Ohne Flexbox greift das flex:1 der Felder nicht mehr — sie fielen auf
   ihre Vorgabebreite zurück und standen als schmaler Kasten in einer
   breiten Zeile. */
.planner-form__row--breit > input,
.planner-form__row--breit > textarea,
.planner-form__row--breit > select {
    display: block;
    width: 100%;
}

.planner-form__row > .pw {
    flex: 1;
    min-width: 0;
    width: auto;
}

/* Die Abo-Adresse ist lang — sie soll scrollen, nicht das Layout sprengen.
   16px bleibt sie trotzdem: Auch ein Feld, das man nur zum Kopieren
   antippt, löst sonst den Zoom aus. Stattdessen kleinere Buchstabenabstände
   und Umbruch. */
#feed-url {
    font-size: 1rem;
    letter-spacing: -.02em;
}

/* search und textarea gehören dazu: Ohne sie standen die Felder im
   Schreibblatt weiß auf dunklem Grund — die Vorgabe des Browsers, weil die
   Liste sie nicht kannte. Im Bildschirmfoto fiel es sofort auf, in keiner
   Prüfung. */
.planner-form__row input[type="text"],
.planner-form__row input[type="password"],
.planner-form__row input[type="date"],
.planner-form__row input[type="time"],
.planner-form__row input[type="search"],
.planner-form__row textarea,
.planner-form__row select {
    flex: 1;
    min-width: 0;
    padding: 9px 10px;
    border: 1px solid var(--border);
    border-radius: 9px;
    background: var(--surface-alt);
    color: var(--text);
    font: inherit;
    /* 16px, nicht kleiner. Safari auf dem iPhone zoomt beim Hineintippen in
       jedes Feld unter 16px — und dann steht die halbe Maske ausserhalb des
       Bildschirms. Anmeldung und Suchfelder lagen längst bei 1rem, die
       Formularfelder nicht; aufgefallen ist es erst, als mit dem
       Schreibblatt ein Feld dazukam, in das man wirklich tippt. */
    font-size: 1rem;
}

/* Das Textfeld wächst nach unten statt in die Zeile. */
.planner-form__row textarea {
    resize: vertical;
    line-height: 1.45;
}

.planner-form__inline {
    flex: 1;
    display: flex;
    gap: 8px;
    min-width: 0;
}

.weekdays { flex: 1; display: flex; gap: 4px; }

.weekday {
    flex: 1;
    min-width: 0;
    padding: 8px 0;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--surface-alt);
    color: var(--text-muted);
    font: inherit;
    font-size: .78rem;
    font-weight: 600;
    cursor: pointer;
}

.weekday[aria-pressed="true"] {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--accent-text);
}

.planner-form__error { margin: 4px 0 8px; font-size: .84rem; color: var(--entfall); }

.planner-form__actions { display: flex; gap: 8px; margin-top: 12px; }

.planner-form__save,
.planner-form__cancel {
    flex: 1;
    padding: 11px;
    border-radius: 10px;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

.planner-form__save {
    background: var(--accent);
    color: var(--accent-text);
    border: 1px solid var(--accent);
}

.planner-form__cancel {
    flex: 0 0 40%;
    background: var(--surface-alt);
    color: var(--text-muted);
    border: 1px solid var(--border);
}

.planner__note {
    margin: 8px 0 0;
    padding: 9px 11px;
    border-radius: 9px;
    background: color-mix(in srgb, var(--vertretung) 14%, var(--surface));
    border: 1px solid color-mix(in srgb, var(--vertretung) 35%, var(--border));
    font-size: .84rem;
}

.card--eigen { border-left-color: var(--accent); border-style: dashed; border-left-style: solid; }

.login__logo {
    display: block;
    height: 52px;
    width: auto;
    margin: 0 auto 16px;
}

/* Angekündigtes früheres Unterrichtsende */
.notice--short {
    background: color-mix(in srgb, var(--raum) 14%, var(--surface));
    border-color: color-mix(in srgb, var(--raum) 40%, var(--border));
    font-weight: 600;
}

.notice__why {
    display: block;
    font-weight: 400;
    font-size: .82rem;
    color: var(--text-muted);
    margin-top: 2px;
}

/* ---------- Mensa ---------- */

/* ---------- Alter der Daten (in der Titelleiste) ---------- */

/* Steht in derselben Zeile wie die Klasse und erbt deren Schrift. */
/* Auch hier eine Fingerkuppe: Der Knopf ist nur so hoch wie seine
   Zeile (20 Pixel), und er ist der Weg, den Stand neu zu holen. */
.header__stand { position: relative; }

.header__stand::after {
    content: '';
    position: absolute;
    inset: -12px -6px;
}

.header__stand {
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    color: inherit;
    cursor: pointer;
}

/* Der trennende Punkt hängt an der Klasse, nicht am Stand. Zwei Dinge
   fallen damit von selbst weg: Ohne Klasse gibt es keinen Punkt (:empty),
   und bricht die Zeile auf einem schmalen Telefon um, wandert er als
   "06bG ·" mit nach oben statt allein am Zeilenanfang zu stehen. */
#klasse:not(:empty)::after { content: " ·"; }

/* Ab zwei Stunden ist es keine Fußnote mehr, sondern eine Warnung. Die
   Kopfleiste ist in jedem Theme dunkel — deshalb hier ein festes warmes
   Gelb statt einer Themenfarbe, die auf Schwarz verschwinden könnte. */
.header__stand--alt {
    display: inline-block;
    margin-left: 7px;
    padding: 2px 9px;
    border-radius: 999px;
    background: rgba(255, 201, 74, .18);
    color: #ffc94a;
    font-weight: 600;
    /* Nie in sich umbrechen: Wird es eng, rutscht die ganze Pille in die
       nächste Zeile — das liest sich, ein zerrissenes Datum nicht. */
    white-space: nowrap;
}

/* Vor der Warnpille stünde der Punkt wie ein Fussel — die Pille bringt
   ihren eigenen Abstand mit. Kennt ein Browser :has() nicht, bleibt der
   Punkt stehen; das ist unschön, aber nichts geht kaputt. */
.header__subtitle:has(.header__stand--alt) #klasse::after { content: none; }

/* Der Ladeknopf warnt mit: So führt der Blick von der Meldung direkt zu
   dem, was hilft — ohne dass "Jetzt laden" noch einmal danebensteht. */
#refresh.is-alt {
    background: rgba(255, 201, 74, .18);
    color: #ffc94a;
}

/* ---------- Einstellungen: Übersicht und Unterseiten ---------- */

/* Bleibt beim Blättern oben stehen. Der Schließen-Knopf am Fuß eines
   Blatts mit 95 Lehrkräften ist unerreichbar — man müsste erst ans Ende
   scrollen, nur um wieder herauszukommen. */
.sheet__kopf {
    position: sticky;
    top: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    gap: 6px;
    /* Seitlich über die Polsterung hinaus, damit beim Scrollen nichts
       daran vorbeiläuft — oben aber bündig, siehe .sheet__panel. */
    margin: 0 -20px 14px;
    padding: 20px 20px 12px;
    background: var(--surface);
}

.sheet__kopf .sheet__title { margin: 0; flex: 1; min-width: 0; }

/* Die Hinweiszeilen ziehen sich mit einem negativen Abstand an ihre
   Überschrift heran. Steht keine davor — weil die Kopfzeile den Titel trägt
   oder die Überschrift der Unterseite ausgeblendet ist — schöben sie sich
   sonst unter die feststehende Kopfzeile. */
.sheet__kopf + .settings__hint,
.settings-page > .settings__group:first-child + .settings__hint {
    margin-top: 0;
}

.sheet__x {
    flex: none;
    width: 34px;
    height: 34px;
    margin-right: -6px;
    padding: 0;
    background: var(--surface-alt);
    border: 1px solid var(--border);
    border-radius: 50%;
    color: var(--text-muted);
    font-size: 1.3rem;
    line-height: 1;
    cursor: pointer;
}

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

/*
 * Die Trefferfläche der beiden Kopfknöpfe: 44 × 44.
 *
 * Sichtbar bleiben sie 34 Pixel gross — ein grösserer Kreis nähme dem
 * Kopf die Ruhe. Antippbar sind sie über ein unsichtbares Feld
 * darüber. Am 07.09.2026 gemessen: 34 × 34 in allen achtzehn Blättern,
 * und das ist die Fläche, die man auf einem Telefon am häufigsten
 * trifft — jedes Blatt wird darüber geschlossen.
 *
 * 44 ist die Zahl, die Apple seit dem ersten iPhone nennt, und sie
 * entspricht ungefähr einer Fingerkuppe.
 */
.sheet__x,
.sheet__zurueck {
    position: relative;
}

.sheet__x::after,
.sheet__zurueck::after {
    content: '';
    position: absolute;
    /* -6, nicht -5: Nachgemessen trug -5 nur 42 Pixel, weil die
       Trefferprüfung am äussersten Rand nicht mehr anschlägt. */
    inset: -6px;
}

.sheet__zurueck {
    flex: none;
    width: 34px;
    height: 34px;
    margin-left: -8px;
    padding: 0;
    background: none;
    border: 0;
    color: var(--text);
    font-size: 1.6rem;
    line-height: 1;
    cursor: pointer;
}

/* Ein Eintrag zum Nachschlagen: Was dahinter liegt, steht als Zeile
   darunter — damit man nicht raten muss, was sich hinter "Anzeige"
   verbirgt. Wird in den Einstellungen und im Reiter Unterricht benutzt. */
.menu {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    margin-bottom: 8px;
    padding: 13px 14px;
    background: var(--surface-alt);
    border: 1px solid var(--border);
    border-radius: 12px;
    color: var(--text);
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.menu__text { flex: 1; min-width: 0; }
.menu__titel { display: block; font-size: .95rem; font-weight: 600; }

/*
 * Die Zwischenüberschrift unter "Nachschlagen".
 *
 * Deutlich leiser als die Abschnittsüberschrift darüber: Sie ordnet nur,
 * sie kündigt nichts an. Wäre sie so laut wie "Nachschlagen", zerfiele
 * der Reiter optisch in vier Abschnitte statt einen.
 *
 * Erscheint bedingt — siehe nachschlagenGruppiert(): erst ab zwei
 * Einträgen in der Gruppe, und nur wenn mindestens zwei Gruppen sie
 * verdienen.
 */
.nachschlagen__gruppe {
    /* Knapp gehalten: Mit 14/6 stand der Block bei 702 px und damit
       einen Pixel über dem, was ein iPhone SE unter der Kopfzeile
       hergibt (701 px). Drei Überschriften kosten sonst 50 px allein an
       Rändern. */
    margin: 10px 0 4px;
    color: var(--text-faint);
    font-size: .74rem;
    letter-spacing: .04em;
}

/* Die erste braucht den Abstand nach oben nicht: Darüber steht schon
   die Überschrift des Abschnitts. */
.section-title + .nachschlagen__gruppe { margin-top: 4px; }

.menu__hinweis {
    display: block;
    margin-top: 2px;
    font-size: .8rem;
    color: var(--text-muted);
}

/* Was offen ist, fällt auf.
 *
 * Muss NACH .menu__hinweis stehen: Beide Regeln haben dieselbe
 * Spezifität, und dann gewinnt die spätere. Am 07.09.2026 im Browser
 * gemessen — weiter oben eingesetzt blieb der Hinweis gedämpft, obwohl
 * die Klasse am Element hing.
 *
 * Ist alles entschuldigt, bleibt es beim ruhigen Ton: Die Entwarnung
 * steht im Wortlaut ("alle entschuldigt") und braucht keine Farbe. */
.menu__hinweis--achtung {
    color: var(--entfall);
}

.menu__pfeil { flex: none; color: var(--text-faint); font-size: 1.3rem; line-height: 1; }

/* Der Assistent zur Einrichtung ---------------------------------------- */

.assistent__zaehler {
    margin: 0 0 6px;
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--text-faint);
}

.assistent__navi {
    display: flex;
    gap: 10px;
    margin-top: 18px;
}

/* width: 100% aus .login__button muss hier weg — sonst schiebt der erste
   Knopf den zweiten aus dem Bild. */
.assistent__navi .login__button { margin-top: 0; width: auto; flex: 1 1 0; min-width: 0; }

/* "Zurück" ist die leisere der beiden Möglichkeiten — es soll da sein, aber
   nicht mit "Weiter" um den Daumen streiten. Deshalb nur so breit wie sein
   Wort, und ohne Füllung. */
.login__button--still {
    flex: 0 0 auto;
    padding-inline: 22px;
    background: transparent;
    border: 1px solid var(--border-strong);
    color: var(--text);
    font-weight: 500;
}

.login__hint--klein { font-size: .78rem; }

/* ---------- Pausenhof (das versteckte Spiel) ---------- */

/* Das Feld füllt die Blattbreite. Die Höhe setzt das Spiel selbst — es
   kennt das Seitenverhältnis des Labyrinths, das CSS nicht. */
.spiel__feld {
    display: block;
    width: 100%;
    height: auto;
    margin: 4px 0 10px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--surface);
    touch-action: none;
    cursor: pointer;
}

/* Die Wahl zwischen den beiden Spielen. Zwei Reiter, klein — sie sind
   Wegweiser, nicht die Hauptsache. */
/* Fünf Reiter passen auf einem Telefon nicht in eine Zeile — also umbrechen
   statt seitlich schieben. Ein Reiter, den man erst wegwischen muss, findet
   niemand, und die Wahl ist ohnehin kein Dauerzustand. */
.spiel__wahl {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 2px 0 10px;
}

.spiel__reiter {
    flex: 1 1 30%;
    padding: 7px 10px;
    background: transparent;
    border: 1px solid var(--border);
    border-radius: 9px;
    color: var(--text-muted);
    font: inherit;
    font-size: .85rem;
    font-weight: 600;
    cursor: pointer;
}

.spiel__reiter.is-aktiv {
    background: color-mix(in srgb, var(--accent) 16%, transparent);
    border-color: var(--accent);
    color: var(--text);
}

.spiel__stand {
    margin: 0;
    font-variant-numeric: tabular-nums;
    font-size: .92rem;
    font-weight: 600;
    color: var(--text);
}

/* Ist eine Runde zu Ende, wird aus dem Hinweis eine Einladung — und die
   soll man sehen, ohne sie zu suchen. */
.spiel__hinweis--ende {
    color: var(--accent);
    font-weight: 600;
}

/* Der Satz, der sagt, was verloren geht. Nicht rot wie ein Fehler — es ist
   kein Fehler, sondern eine Folge. Aber auch nicht wie der Rest, sonst
   überliest man ihn und wundert sich hinterher. */
.login__hint--warnung {
    padding: 10px 12px;
    background: color-mix(in srgb, var(--entfall) 10%, transparent);
    border-left: 3px solid var(--entfall);
    border-radius: 0 8px 8px 0;
}

/* Eine wartende Bitte sieht anders aus als eine Zeile in einer Liste. */
.planner__item--wartet { border-color: var(--hinweis); }

.anfrage__ja {
    flex: none;
    align-self: center;
    padding: 7px 12px;
    background: var(--accent);
    border: 1px solid var(--accent);
    border-radius: 9px;
    color: var(--accent-text);
    font: inherit;
    font-size: .82rem;
    font-weight: 600;
    cursor: pointer;
}

/* Der frische Einladungslink. Er wird einmal angezeigt und muss vollständig
   lesbar sein — deshalb Umbruch mitten im Wort statt Auslassungspunkte. */
.einladung__frisch {
    margin-top: 14px;
    padding: 12px 14px;
    background: var(--surface-alt);
    border: 1px solid var(--accent);
    border-radius: 12px;
}

.einladung__frisch-titel {
    margin: 0 0 6px;
    font-size: .8rem;
    font-weight: 600;
    color: var(--text-muted);
}

.einladung__knoepfe {
    display: flex;
    gap: 8px;
}

.einladung__knoepfe .settings__zuruecksetzen { flex: 1; margin-top: 0; }

/* Der QR-Code steht auf Weiß, immer — auch im dunkelsten Thema. Ein Leser
   erwartet dunkel auf hell, und ein Code in Themenfarben wird von manchen
   Kameras gar nicht erkannt. Deshalb bekommt er eine eigene weiße Fläche
   statt der Fläche der App. */
.einladung__qr {
    margin-top: 12px;
    text-align: center;
}

.einladung__qr-bild {
    display: block;
    width: 100%;
    max-width: 320px;
    height: auto;
    margin: 0 auto 8px;
    border-radius: 8px;
    background: #ffffff;
}

.einladung__link {
    margin: 0 0 10px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: .82rem;
    line-height: 1.45;
    color: var(--text);
    overflow-wrap: anywhere;
    user-select: all;
}

/* Gruppenüberschrift in der Menü-Übersicht. Klein und gedämpft: Sie ordnet
   die Einträge, konkurriert aber nicht mit ihnen — die Einträge sind das,
   was man antippt. Der Abstand über der Überschrift ist der eigentliche
   Trenner; eine Linie käme neben den umrandeten Kacheln als dritte Kante
   dazu. */
.menu-gruppe + .menu-gruppe { margin-top: 22px; }

.menu-gruppe__titel {
    margin: 0 0 8px 4px;
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--text-faint);
}

/* Die erste Überschrift einer Unterseite ist die Seite selbst — der Titel
   steht schon oben im Kopf.

   Die beiden Hüllen sind namentlich genannt, und das ist der Punkt: Vorher
   stand hier "> div >", also JEDE Hülle. Am 22.08.2026 bekam die Seite "Wer
   nutzt die App" einen zweiten Abschnitt in einem eigenen div — und dessen
   Überschrift verschwand lautlos, weil sie in ihrer Hülle die erste war.
   Wer hier eine dritte Hülle einträgt, hat sich das überlegt. */
.settings-page > .settings__group:first-child,
#biometric-group > .settings__group:first-child,
#account-group > .settings__group:first-child { display: none; }

/* ---------- Lageplan ---------- */

.lageplan {
    display: block;
    width: 100%;
    height: auto;
    margin: 4px 0 14px;
    background: var(--surface-alt);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

/* Vier Ebenen, jede mit eigener Sprache — Freifläche, Straße, Gebäude,
   Nebenbau. Man soll am Aussehen erkennen, was etwas ist, ohne nachzulesen. */

/* 1. Die Freifläche: schraffiert und gestrichelt umrandet. Kein Haus. */
.lp__gelaende {
    fill: color-mix(in srgb, var(--border) 45%, var(--surface-alt));
    stroke: var(--border-strong);
    stroke-width: 1.2;
    stroke-dasharray: 6 4;
}

.lp__hof { stroke: none; }
.lp__schraffurlinie { stroke: var(--border-strong); stroke-width: .9; opacity: .55; }

/* 2. Die Straße: durchgehendes Band, keine Kontur. */
.lp__strasse { fill: var(--border); stroke: none; }

/* 3. Die Hauptgebäude. Die Leitfarben stammen aus dem Plan der Schule:
      A orange, B petrol, C dunkelrot. Als Tönung über der Blattfarbe, damit
      sie in hellen wie in dunklen Themes tragen und die Schrift lesbar
      bleibt. Die Fläche deckt — sie liegt auf der Schraffur. */
.lp__haus { stroke-width: 1.5; }

/* Der Orangeanteil ist höher als bei den anderen beiden — nicht aus Laune:
   Über einem petrolfarbenen Untergrund frisst der Blauanteil das Orange auf,
   bei 32 % kommt Oliv heraus statt Orange. Rot und Petrol tragen dort von
   selbst. */
.lp__haus--a { fill: color-mix(in srgb, #f39200 52%, var(--surface)); stroke: #f39200; }
.lp__haus--b { fill: color-mix(in srgb, #00969b 32%, var(--surface)); stroke: #00969b; }
.lp__haus--c { fill: color-mix(in srgb, #94132f 30%, var(--surface)); stroke: #94132f; }

/* 4. Nebenbauten und benannte Orte: neutral, aber deckend. */
.lp__bau {
    fill: var(--surface);
    stroke: var(--border-strong);
    stroke-width: 1.5;
}

.lp__raum {
    fill: var(--surface);
    stroke: var(--border-strong);
    stroke-width: 1;
}

.lageplan text {
    fill: var(--text);
    font-family: inherit;
    text-anchor: middle;
    dominant-baseline: middle;
}

/* Schriftstufen: Gebäudebuchstabe, Gebäudename, Nebenbau, Ort, Hinweis. */
.lp__brief { font-size: 30px; font-weight: 700; }
.lp__name { font-size: 11px; }

/* Die H-Nummer im Plan. Klein und blass: Sie ist der Anschluss aus dem
   Stundenplan, nicht die Hauptbeschriftung — im Plan der Schule steht sie
   überhaupt nicht.

   NICHT .lp__haus nennen: So heissen die Gebäuderechtecke. Der erste
   Versuch tat es doch und legte damit opacity: .62 über alle drei Häuser. */
.lp__hausnr { font-size: 9px; opacity: .62; letter-spacing: .04em; }

/* Und in der Legende, wo Platz für Text ist: als Marke vor der Beschreibung. */
.lp__haus-nr {
    font-variant-numeric: tabular-nums;
    letter-spacing: .02em;
}
.lp__bauschrift { font-size: 11px; fill: var(--text-muted); }
.lp__raumschrift { font-size: 10px; fill: var(--text-muted); }
.lp__hinweis { font-size: 11px; fill: var(--text-muted); }

/* Flächen und Straße bekommen gesperrte Schrift ohne Kasten — das
   unterscheidet sie auf den ersten Blick von allem Gebauten. */
.lp__hofschrift,
.lp__strassenschrift {
    font-size: 12px;
    fill: var(--text-muted);
    letter-spacing: .16em;
}

.lp__pfeil path,
.lp__nord path {
    stroke: var(--text-muted);
    stroke-width: 1.5;
    fill: none;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.lp__nordschrift { font-size: 11px; font-weight: 700; fill: var(--text-muted); }

/* Der Text am Eingangspfeil setzt links an, nicht mittig — sonst läge er
   auf dem Pfeil. Als Attribut im SVG reicht das nicht: Die Regel oben für
   alle Texte gewinnt gegen das Attribut. */
.lp__pfeil text { text-anchor: start; }

/* Legende: welches Gebäude was beherbergt. */
.lp__zeile {
    display: flex;
    gap: 10px;
    align-items: flex-start;
    margin-bottom: 8px;
    font-size: .84rem;
    line-height: 1.4;
}

.lp__marke {
    flex: none;
    /* Mindestens quadratisch, aber breiter, wenn die Marke es braucht:
       Die Carl-von-Weinberg-Schule nennt ihre Hallen "TH-A" und "TH-B",
       und in 26 Pixeln brach das zu "TH-" und "A" um. */
    min-width: 26px;
    padding: 0 5px;
    white-space: nowrap;
    font-size: .82rem;
    height: 26px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 7px;
    font-weight: 700;
    color: var(--text);
}

.lp__zeile--a .lp__marke { background: color-mix(in srgb, #f39200 50%, var(--surface)); }
.lp__zeile--b .lp__marke { background: color-mix(in srgb, #00969b 30%, var(--surface)); }
.lp__zeile--c .lp__marke { background: color-mix(in srgb, #94132f 28%, var(--surface)); }

/* Dieselbe Schraffur wie im Plan — dieselben 45 Grad, derselbe Abstand. */
.lp__marke--hof {
    background:
        repeating-linear-gradient(45deg,
            var(--border-strong) 0 1px,
            transparent 1px 6px),
        color-mix(in srgb, var(--border) 45%, var(--surface-alt));
    border: 1px dashed var(--border-strong);
}

.lp__text { color: var(--text-muted); }
.lp__legende { margin-bottom: 14px; }

/* ---------- Kontakte ---------- */

.suche {
    width: 100%;
    margin-bottom: 12px;
    padding: 11px 13px;
    background: var(--surface-alt);
    border: 1px solid var(--border);
    border-radius: 10px;
    color: var(--text);
    font: inherit;
    font-size: 1rem;
}

.suche:focus { outline: 2px solid var(--hinweis); outline-offset: 1px; }

.kontakt {
    display: block;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-left: 3px solid var(--border-strong);
    border-radius: 10px;
    background: var(--surface-alt);
    margin-bottom: 6px;
    color: inherit;
    text-decoration: none;
}

/* Die drei, die man wirklich braucht, sind hervorgehoben. */
.kontakt--wichtig { border-left-color: var(--hinweis); background: var(--surface); }

.kontakt__rolle {
    display: block;
    font-size: .72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--text-faint);
}

.kontakt__name { display: block; font-size: .95rem; font-weight: 600; margin-top: 1px; }

.kontakt__meta {
    display: block;
    margin-top: 2px;
    font-size: .8rem;
    color: var(--text-muted);
}

.kontakt__wege {
    display: flex;
    /* Umbruch als Rückfalllinie, nicht als Reparatur: Bei 440 Pixern
       passen die drei Wege nebeneinander, nachgemessen. Auf einem
       schmaleren Gerät oder bei einer längeren Nummer rutscht der
       letzte eine Zeile tiefer, statt hinauszuragen. Das eigentliche
       Problem löst flex unten. */
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 8px;
}

.kontakt__weg {
    /* Wachsen ja, schrumpfen nein.
     *
     * Hier stand "flex: 1" — alle Wege gleich breit, egal was drinsteht.
     * Seit der Portal-Knopf dazukam, sind es drei: Am 06.09.2026
     * gemessen, brauchte die Telefonnummer 113 Pixel und bekam 97. Sie
     * stand abgeschnitten da.
     *
     * Jetzt ist die Basis, was der Text braucht; verteilt wird nur, was
     * übrig bleibt. */
    flex: 1 1 auto;
    min-width: max-content;
    padding: 7px 10px;
    background: var(--surface-alt);
    border: 1px solid var(--border);
    border-radius: 8px;
    color: var(--hinweis);
    font-size: .82rem;
    text-align: center;
    text-decoration: none;
}

/*
 * Zeichen und Wort in einem Knopf.
 *
 * Das Zeichen steht davor, nicht statt des Wortes: Ein Umschlag allein
 * sagt nicht, ob eine Mail hinausgeht oder ein Postfach aufgeht.
 * Vorgelesen wird nur das Wort — das Zeichen ist aria-hidden.
 */
.kontakt__weg,
.kurs__mail {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
}

.weg__zeichen {
    flex: none;
    width: 15px;
    height: 15px;
    /* Zurückhaltender als das Wort: Es soll den Knopf einordnen, nicht
       ihn übernehmen. */
    opacity: .75;
}

.weg__zeichen svg { width: 100%; height: 100%; display: block; }

.weg__wort { min-width: 0; }

/* Anrufen bekommt eine eigene Zeile — siehe renderKontakt(). Mit
   Zeichen passen drei Wege nicht mehr nebeneinander (bei 440 Pixern
   nachgemessen), und dann soll die Reihe nach dem gegliedert sein, was
   man vorhat: oben anrufen, darunter die beiden Schreibwege. */
.kontakt__weg--tel { flex-basis: 100%; }

/*
 * Der zweite Weg: eine Nachricht im Schulportal.
 *
 * Er ist ein <button>, der Mail-Weg ein <a>. Damit beide gleich
 * aussehen, werden hier ALLE Knopf-Vorgaben zurückgesetzt — Schrift,
 * Zeilenhöhe, Rand. Genau daran ist am 06.09.2026 die antippbare
 * Terminzeile gescheitert: Sie stand als weisser Kasten zwischen
 * dunklen Zeilen, weil nur border und font gesetzt waren.
 *
 * font: inherit reicht nicht — es lässt line-height aus dem
 * Browser-Vorgabewert stehen, und der Knopf wäre ein Pixel höher als
 * der Verweis daneben.
 */
.kontakt__weg--portal,
.kurs__mail--portal {
    font-family: inherit;
    font-weight: inherit;
    line-height: inherit;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
}

.kurs__mail--portal { margin-left: 6px; }

/* Trennt die drei wichtigen Kontakte oben vom Verzeichnis darunter. */
.kontakt__gruppe {
    margin: 16px 0 8px;
    font-size: .72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--text-faint);
}

.kontakt__leer {
    margin: 10px 0;
    font-size: .88rem;
    color: var(--text-muted);
}

/* ---------- Terminliste ---------- */

.termine {
    margin-bottom: 14px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
}

.termin {
    display: flex;
    align-items: baseline;
    gap: 12px;
    padding: 9px 12px;
}

.termin + .termin { border-top: 1px solid var(--border); }

/*
 * Die anstehende Arbeit ist ein <button>, keine <div> — sie lässt sich
 * antippen.
 *
 * Ein Knopf bringt eigene Vorgaben des Browsers mit: hellgrauer
 * Hintergrund, eigene Textfarbe, eigener Rahmen, eigene Schrift. Beim
 * ersten Versuch am 06.09.2026 standen die vier Prüfungen deshalb als
 * weisse Kästen mit blauer Schrift zwischen den dunklen Terminzeilen —
 * das sah nach einem Bruch aus, und genau so wurde es gemeldet.
 *
 * Zurückgesetzt wird deshalb ALLES, was ein Knopf mitbringt, nicht nur
 * Rahmen und Schrift: Hintergrund und Farbe gehören dazu. Die Zeile
 * soll aussehen wie jede andere — der Pfeil rechts ist der einzige
 * Unterschied.
 *
 * Und die Regel steht hier, bei den anderen Termin-Regeln. Vorher lag
 * sie dreitausend Zeilen entfernt; wer .termin liest, sieht sonst nicht,
 * dass es diese Fassung überhaupt gibt.
 */
.termin--lernbar {
    width: 100%;
    text-align: left;
    font: inherit;
    color: inherit;
    background: none;
    border: 0;
    cursor: pointer;
}

/* Nur bei der antippbaren Zeile: Der Pfeil sagt, dass da mehr ist. */
.termin__pfeil {
    margin-left: auto;
    padding-left: 8px;
    color: var(--text-faint);
    font-size: 1.1rem;
}

/* Der heutige Termin, wie die laufende Stunde im Tagesplan.
   Dieselbe Akzentfarbe wie .tag--jetzt — wer sie einmal am Tagesplan
   gelernt hat, muss sie hier nicht neu lernen. */
.termin.is-heute { background: color-mix(in srgb, var(--accent) 8%, transparent); }

.termin.is-heute .termin__tag b {
    display: inline-block;
    padding: 1px 6px;
    border-radius: 6px;
    background: var(--accent);
    color: var(--accent-text);
    font-weight: 800;
}

.termin.is-heute .termin__titel { font-weight: 600; }

/* Feste Spalte, damit die Daten untereinander stehen und das Auge
   die Liste in einem Zug abfahren kann. */
.termin__tag {
    flex: none;
    width: 62px;
    font-size: .74rem;
    color: var(--text-faint);
    text-transform: uppercase;
    letter-spacing: .03em;
}

.termin__tag b {
    display: block;
    font-size: .88rem;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: none;
    letter-spacing: 0;
}

.termin__text { min-width: 0; }

.termin__titel {
    display: block;
    font-size: .92rem;
    line-height: 1.35;
}

.termin__meta {
    display: block;
    margin-top: 1px;
    font-size: .78rem;
    color: var(--text-muted);
}

/* Der Streifen links sagt, woher der Termin stammt. In der gemischten
   Liste der nächsten Tage ist das die einzige Unterscheidung, die es
   braucht — Symbole wären bei dieser Zeilenhöhe nur Unruhe. */
.termin--arbeit { border-left: 3px solid var(--entfall); }
.termin--arbeit .termin__titel { font-weight: 600; }

/* Blau statt Akzentfarbe: Die Akzentfarbe liegt in mehreren Themes dicht
   am Rot der Klassenarbeiten (im Tiefsee-Thema #ff7a59 gegen #ff8577) —
   nebeneinander wären die Streifen nicht auseinanderzuhalten. */
.termin--eigen { border-left: 3px solid var(--hinweis); }
/* In der Terminliste derselbe Streifen, aber blasser und ohne fetten
   Titel — die Arbeit soll beim Überfliegen zuerst auffallen. */
.termin--lernkontrolle {
    border-left: 3px solid color-mix(in srgb, var(--entfall) 45%, transparent);
}

.termin--ferien { border-left: 3px solid var(--vertretung); }
.termin--schule { border-left: 3px solid var(--border-strong); }

/*
 * "Diese Woche" / "Nächste Woche" über den nächsten vierzehn Tagen.
 *
 * Derselbe leise Ton wie die Gruppen unter "Nachschlagen": Sie ordnen,
 * sie kündigen nichts an. Die Monatsüberschrift darunter darf lauter
 * sein — sie trennt größere Abstände.
 */
.termine__woche {
    margin: 10px 0 4px;
    color: var(--text-faint);
    font-size: .74rem;
    letter-spacing: .04em;
}

.section-title + .termine__woche { margin-top: 4px; }

.termine__monat {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    margin: 14px 0 6px;
    font-size: .8rem;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: .04em;
}

.termine__monat span {
    font-weight: 400;
    color: var(--text-faint);
    text-transform: none;
}

/* ---------- Kursauswahl ---------- */

.kurs {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    margin-bottom: 6px;
    padding: 9px 10px;
    background: var(--surface-alt);
    border: 1px solid var(--border);
    border-left: 4px solid var(--fach, var(--border-strong));
    border-radius: 10px;
    color: var(--text);
    font: inherit;
    text-align: left;
    cursor: pointer;
}

/* Zum Nachschlagen: dieselbe Zeile, aber ohne Häkchen und ohne Anfassen. */
.kurs--nur-lesen { cursor: default; }

.kurs__mail {
    flex: none;
    padding: 6px 11px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
    color: var(--hinweis);
    font-size: .8rem;
    text-decoration: none;
}

/* Abgewählt: sichtbar bleiben, aber deutlich zurücktreten. */
.kurs[data-aktiv="0"] { opacity: .5; }
.kurs[data-aktiv="0"] .kurs__name { text-decoration: line-through; }

.kurs__box {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    flex: none;
    border: 1.5px solid var(--border-strong);
    border-radius: 6px;
    color: var(--vertretung);
    font-size: .9rem;
    line-height: 1;
}

.kurs[data-aktiv="1"] .kurs__box { border-color: var(--vertretung); }

.kurs__text { flex: 1; min-width: 0; }
.kurs__name { display: block; font-size: .9rem; font-weight: 600; }

.kurs__meta {
    display: block;
    font-size: .78rem;
    color: var(--text-muted);
}

.kurs__marke {
    flex: none;
    padding: 2px 7px;
    border-radius: 999px;
    font-size: .7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .03em;
}

.kurs__marke--belegt { background: color-mix(in srgb, var(--vertretung) 20%, transparent); color: var(--vertretung); }
.kurs__marke--neu { background: color-mix(in srgb, var(--raum) 22%, transparent); color: var(--raum); }

.kurse__neu {
    margin: 0 0 12px;
    padding: 9px 11px;
    border-left: 3px solid var(--raum);
    background: color-mix(in srgb, var(--raum) 10%, transparent);
    border-radius: 0 8px 8px 0;
    font-size: .82rem;
    color: var(--text);
}

/* Während gespeichert wird, soll niemand zweimal tippen. */
#kurse-liste.is-busy { opacity: .5; pointer-events: none; }

/* ---------- Hausaufgaben abhaken ---------- */

.haken {
    display: flex;
    align-items: center;
    gap: 9px;
    margin-top: 10px;
    padding: 8px 10px;
    width: 100%;
    background: var(--surface-alt);
    border: 1px solid var(--border);
    border-radius: 10px;
    color: var(--text-muted);
    font: inherit;
    font-size: .85rem;
    cursor: pointer;
}

.haken__box {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    flex: none;
    border: 1.5px solid var(--border-strong);
    border-radius: 6px;
    color: var(--vertretung);
    font-size: .9rem;
    line-height: 1;
}

.haken[data-done="1"] { color: var(--vertretung); }
.haken[data-done="1"] .haken__box { border-color: var(--vertretung); }
.haken:disabled { opacity: .5; }

/* Erledigtes bleibt lesbar, tritt aber zurück — nicht durchgestrichen. */
.card--erledigt .card__body,
.card--erledigt .card__subject { opacity: .55; }

/* ---------- Neuigkeiten ---------- */

/* Ein Block je Fassung. Die Datumszeile trägt sie, nicht eine Überschrift —
   eine Familie sucht nach "seit wann", nicht nach einer Nummer. */
.neuigkeit {
    margin: 0 0 18px;
    padding-bottom: 18px;
    border-bottom: 1px solid var(--border);
}

.neuigkeit:last-child {
    margin-bottom: 0;
    padding-bottom: 0;
    border-bottom: 0;
}

.neuigkeit__kopf {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 6px;
}

.neuigkeit__datum {
    font-size: .76rem;
    color: var(--text-faint);
}

/* Nur am obersten Eintrag. Sie beantwortet die Frage, die "Über die App" mit
   zwei Zahlen beantwortet — hier aber in Worten, für den, der die Zahlen
   nicht lesen will. */
.neuigkeit__jetzt {
    padding: 1px 7px;
    border-radius: 9px;
    background: var(--accent);
    color: var(--accent-text);
    font-size: .7rem;
    font-weight: 600;
}

.neuigkeit__titel {
    margin: 0 0 8px;
    font-size: .98rem;
    font-weight: 600;
    color: var(--text);
}

.neuigkeit__punkte {
    margin: 0;
    padding-left: 18px;
    font-size: .84rem;
    line-height: 1.5;
    color: var(--text-muted);
}

.neuigkeit__punkte li { margin-bottom: 6px; }
.neuigkeit__punkte li:last-child { margin-bottom: 0; }

/* ---------- Über die App ---------- */

.ueber {
    margin-bottom: 6px;
    font-size: .82rem;
    line-height: 1.5;
    color: var(--text-muted);
}

.ueber__zeile { margin: 0 0 10px; }
.ueber__zeile strong { color: var(--text); font-weight: 600; }

/* Der Hinweis, dass die App nicht von der Schule kommt, darf nicht untergehen. */
.ueber__zeile--warnung {
    padding-left: 10px;
    border-left: 3px solid var(--raum);
}

.ueber__version {
    display: inline-block;
    margin-left: 4px;
    color: var(--text-faint);
    /*
     * Kein Doppeltipp-Zoom auf dieser Zeile.
     *
     * Auf dem iPhone versteht Safari zwei schnelle Berührungen als
     * „heranzoomen" — auf einer Zeile, die man mehrfach antippt, springt
     * die Seite sonst. Das versteckte Spiel liegt inzwischen am Zeichen
     * oben links (dort greift dieselbe Regel über den Stern weiter oben),
     * aber auch diese Zeile wird angetippt und soll dabei ruhig bleiben.
     *
     * touch-action: manipulation schaltet genau das ab und lässt alles
     * andere in Ruhe: Wischen geht weiter, und die Lupe mit zwei Fingern
     * bleibt erhalten. Deshalb steht hier auch nicht user-scalable=no im
     * Kopf der Seite — wer schlecht sieht, soll vergrößern können.
     */
    touch-action: manipulation;
    -webkit-user-select: none;
    user-select: none;
}

/*
 * "Seit deinem letzten Blick" — die Zeile über dem Schulschluss.
 *
 * Sie muss auffallen, ohne zu erschrecken: Es ist eine Nachricht, kein
 * Fehler. Deshalb die Hinweisfarbe wie beim neuen Stundenplan und keine
 * Warnfarbe — dass die erste Stunde ausfällt, ist meistens eine gute
 * Nachricht.
 */
.schluss__neu {
    margin: 0 0 8px;
    padding: 6px 10px;
    border-left: 3px solid var(--hinweis);
    background: color-mix(in srgb, var(--hinweis) 10%, var(--surface));
    border-radius: 0 8px 8px 0;
    color: var(--text);
    font-size: .88rem;
}

/* Ein neuer Stundenplan ist eine Nachricht, kein Fehler — deshalb in der
   Hinweisfarbe und antippbar, um ihn zur Kenntnis zu nehmen. */
.notice--neu {
    display: block;
    width: 100%;
    text-align: left;
    border-color: var(--hinweis);
    color: var(--text);
    cursor: pointer;
    font: inherit;
    font-size: .88rem;
}

/* Das Essen des Tages, direkt lesbar — die PDF steht darunter als Quelle. */
.mensa-tag {
    background: var(--surface);
    border: 1px solid var(--border);
    border-left: 4px solid var(--raum);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 4px 14px;
    margin-bottom: 10px;
}

/* Im Speiseplan-Blatt trägt jeder Tag eine Überschrift — sonst sind zehn
   Tage eine Wand aus Text. */
.mensa-tag__kopf {
    margin: 8px 0 6px;
    font-size: .82rem;
    font-weight: 650;
    color: var(--text-muted);
}

/* Der heutige Tag wird hervorgehoben und beim Öffnen angescrollt: Bei zwei
   Wochen sucht man ihn sonst. */
.mensa-tag--heute {
    border-left-color: var(--accent);
    background: color-mix(in srgb, var(--accent) 6%, var(--surface));
}

.mensa-tag--heute .mensa-tag__kopf { color: var(--accent); }

.mensa-tag__marke {
    margin-left: 6px;
    padding: 1px 7px;
    border-radius: 999px;
    background: var(--accent);
    color: var(--accent-text);
    font-size: .68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
}

/* Der Weg zur Quelle. Bewusst ein Verweis und kein Knopf: Er führt aus der
   App heraus, und auf dem iPhone öffnet iOS die PDF dann in seinem eigenen
   Betrachter — dem einzigen, der sie zuverlässig darstellt. */
.mensa-blatt__quelle {
    display: block;
    margin-top: 16px;
    padding: 10px;
    border: 1px solid var(--border);
    border-radius: 10px;
    color: var(--hinweis);
    font-size: .88rem;
    font-weight: 600;
    text-align: center;
    text-decoration: none;
}

.mensa-tag__zeile {
    display: grid;
    grid-template-columns: 74px 1fr auto;
    gap: 4px 10px;
    align-items: baseline;
    padding: 9px 0;
    border-top: 1px solid var(--border);
}

.mensa-tag__zeile:first-child { border-top: 0; }

.mensa-tag__was {
    font-size: .78rem;
    font-weight: 600;
    color: var(--text-muted);
}

.mensa-tag__essen { font-size: .92rem; }

.mensa-tag__preis {
    font-size: .8rem;
    color: var(--text-faint);
    white-space: nowrap;
}

.mensa {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-left: 4px solid var(--raum);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    color: inherit;
    text-decoration: none;
}

.mensa:active { background: var(--surface-alt); }

.mensa__icon { flex: none; font-size: 1.4rem; line-height: 1; }
.mensa__text { flex: 1; min-width: 0; }
.mensa__title { display: block; font-weight: 600; font-size: .95rem; }

.mensa__meta {
    display: block;
    font-size: .82rem;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.mensa__arrow { flex: none; color: var(--text-faint); font-size: 1.3rem; line-height: 1; }

/*
 * Die Zeile "3 Hausaufgaben offen" oben im Tagesplan.
 *
 * Gebaut wie der Mensa-Knopf, damit sie nicht als Fremdkörper wirkt —
 * aber mit dem Akzentstreifen links statt der Raumfarbe: Sie ist das
 * Einzige auf dieser Seite, das eine Handlung verlangt.
 *
 * Alle Knopf-Vorgaben zurückgesetzt, nicht nur der Rahmen. Hintergrund
 * und Textfarbe kommen sonst vom Browser; genau daran ist am 06.09.2026
 * die antippbare Terminzeile gescheitert.
 */
.hausaufgaben-zeile {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    margin: 0 0 10px;
    padding: 12px 14px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-left: 4px solid var(--accent);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.hausaufgaben-zeile:active { background: var(--surface-alt); }

.hausaufgaben-zeile__icon {
    flex: none;
    width: 22px;
    height: 22px;
    color: var(--text-muted);
}

.hausaufgaben-zeile__icon svg { width: 100%; height: 100%; display: block; }

/* Die Hofdienst-Zeile: dieselbe Form, anderer Streifen.

   Steht NACH dem Grundstil, nicht davor: Dort setzt border-left die
   Kurzform, und die überschriebe eine Farbe, die weiter oben steht —
   gleiche Spezifität, und dann gewinnt die letzte Regel. */
.hausaufgaben-zeile--dienst { border-left-color: var(--raum); }
.hausaufgaben-zeile--dienst .hausaufgaben-zeile__icon { color: var(--raum); }

.hausaufgaben-zeile__text { flex: 1; min-width: 0; }
.hausaufgaben-zeile__text b { display: block; font-weight: 600; font-size: .95rem; }

/* "1 von heute" — der Teil, der sich täglich ändert und die Zeile davor
   bewahrt, zur Tapete zu werden. */
.hausaufgaben-zeile__neu {
    display: block;
    font-size: .82rem;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.hausaufgaben-zeile__arrow {
    flex: none;
    color: var(--text-faint);
    font-size: 1.3rem;
    line-height: 1;
}

/* ---------- Betrachter für Dateien ---------- */

/* Vollbild innerhalb der App. Eine Vollbild-App hat keine Browserleiste;
   ohne eigenen Zurück-Knopf wäre eine geöffnete Datei eine Einbahnstraße. */
.viewer {
    position: fixed;
    inset: 0;
    z-index: 60;
    display: flex;
    flex-direction: column;
    background: var(--bg);
}

.viewer__bar {
    flex: none;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: calc(var(--safe-top) + 10px) 12px 10px;
    background: var(--header-bg);
    color: var(--header-text);
    border-bottom: 1px solid rgba(255, 255, 255, .08);
}

.viewer__close {
    flex: none;
    display: flex;
    align-items: center;
    gap: 4px;
    min-height: 40px;
    padding: 0 12px 0 8px;
    background: var(--header-fill);
    border: 0;
    border-radius: 10px;
    color: inherit;
    font: inherit;
    font-size: .92rem;
    font-weight: 600;
    cursor: pointer;
}

.viewer__close span { font-size: 1.3rem; line-height: 1; }

.viewer__title {
    flex: 1;
    min-width: 0;
    font-size: .88rem;
    opacity: .8;
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.viewer__extern {
    flex: none;
    width: 40px;
    height: 40px;
    display: grid;
    place-items: center;
    background: var(--header-fill);
    border-radius: 10px;
    color: inherit;
    text-decoration: none;
    font-size: 1.1rem;
}

.viewer__body {
    flex: 1;
    position: relative;
    min-height: 0;
}

.viewer__frame {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
    background: var(--surface);
}

/* Die selbst gezeichneten Seiten. Untereinander, in voller Breite und
   scrollbar — so liest man ein Dokument am Telefon. */
.viewer__zoom {
    flex: none;
    width: 34px;
    height: 34px;
    border-radius: 9px;
    border: 1px solid rgba(255, 255, 255, .22);
    background: rgba(255, 255, 255, .08);
    color: var(--header-text);
    font: inherit;
    font-size: 1.15rem;
    line-height: 1;
    cursor: pointer;
}

.viewer__zoom:disabled { opacity: .35; }

.viewer__seiten {
    position: absolute;
    inset: 0;
    overflow: auto;
    -webkit-overflow-scrolling: touch;
    background: var(--surface-alt);
    padding: 10px;
}

.pdfseite {
    display: block;
    width: 100%;
    height: auto;
    /* Weiss unter der Seite: Eine PDF hat einen weissen Grund, und ein
       dunkler Rahmen darum lässt sie als Blatt erkennen. */
    background: #fff;
    border-radius: 4px;
    box-shadow: 0 2px 10px rgba(0, 0, 0, .35);
}

.pdfseite + .pdfseite { margin-top: 10px; }

/* Während gezeichnet wird. Er verschwindet, sobald die letzte Seite steht. */
.viewer__stand {
    padding: 28px 12px;
    text-align: center;
    color: var(--text-muted);
    font-size: .9rem;
}

/* Wo der Rahmen nichts zeigen kann, steht das hier — und sagt es auch. */
.viewer__ersatz {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 24px;
    background: var(--surface);
    text-align: center;
}

.viewer__ersatz-typ {
    padding: 6px 14px;
    border-radius: 8px;
    background: var(--surface-alt);
    border: 1px solid var(--border);
    font-size: .78rem;
    font-weight: 800;
    letter-spacing: .06em;
    color: var(--text-muted);
}

.viewer__ersatz-name {
    font-size: 1.02rem;
    font-weight: 650;
    line-height: 1.35;
    word-break: break-word;
}

.viewer__ersatz-text { color: var(--text-muted); font-size: .88rem; max-width: 30ch; }

.viewer__ersatz-knopf {
    margin-top: 6px;
    padding: 13px 28px;
    border: 0;
    border-radius: 12px;
    background: var(--accent);
    color: var(--accent-text);
    font: inherit;
    font-size: 1rem;
    font-weight: 700;
    cursor: pointer;
}

.viewer__ersatz-knopf:disabled { opacity: .6; }

.viewer__ersatz-fuss { color: var(--text-faint); font-size: .8rem; }

/* Schmaler Streifen unter dem Rahmen — immer sichtbar. */
.viewer__hint {
    flex: none;
    margin: 0;
    padding: 10px 16px calc(var(--safe-bottom) + 10px);
    background: var(--surface-alt);
    border-top: 1px solid var(--border);
    font-size: .8rem;
    color: var(--text-muted);
    text-align: center;
}

.viewer__hint a { color: var(--hinweis); font-weight: 600; }

/* Der Knopf sieht aus wie der Verweis daneben — beide tun dasselbe, nur
   auf verschiedenen Wegen. */
#viewer-teilen {
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    font-weight: 700;
    color: var(--hinweis);
    text-decoration: underline;
    cursor: pointer;
}

/* Hintergrund nicht mitscrollen, solange der Betrachter offen ist. */
body.is-locked { overflow: hidden; }

/* Die Mensa-Karte ist ein Knopf — sie soll aber wie eine Karte aussehen. */
button.mensa {
    width: 100%;
    font: inherit;
    text-align: left;
    cursor: pointer;
}
