/* ==========================================================================
   FoBi – Fortbildungsverwaltung Gymnasium Landsberg
   Oberflaeche

   Grundsaetze
   -----------
   * Keine externen Ressourcen. Keine Web-Fonts von fremden Servern, keine
     CDN-Bibliotheken. Alles liegt auf dem eigenen Webspace – das ist
     datenschutzrechtlich sauber und funktioniert auch ohne Internetzugang
     des Browsers zu Dritten.
   * Systemschriften. Sie sind sofort da, sehen auf jeder Plattform stimmig
     aus und erzeugen keine Verbindung nach aussen.
   * Ruhige, dichte Verwaltungsoberflaeche: viel Information, wenig Farbe.
     Farbe wird ausschliesslich zur Bedeutungsunterscheidung eingesetzt.
   * Bedienbar ohne Maus. Jeder fokussierbare Bereich hat einen sichtbaren
     Fokusrahmen.
   ========================================================================== */

/* ==========================================================================
   1. WERTESATZ — ab hier zeichengleich mit portal.css
   ========================================================================== */
:root {
    /* --- Schrift ---------------------------------------------------------
       "Segoe UI Variable Text" ausdruecklich benannt: Auf den Windows-11-
       Arbeitsplaetzen der Schule ist das die moderne Fassung, sie liegt
       lokal vor und ist deutlich ruhiger als Segoe UI. Fehlt sie, greift die
       alte Kette unveraendert. Keine Fremdschrift, kein Nachladen. */
    --fl-schrift: ui-sans-serif, system-ui, -apple-system, "Segoe UI Variable Text",
                  "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif;
    --fl-schrift-fest: ui-monospace, "Cascadia Mono", SFMono-Regular, Consolas,
                       "Liberation Mono", Menlo, monospace;

    /* --- Schriftgrade ----------------------------------------------------
       Neun Grade fuer beide Oberflaechen. Vorher waren es neunzehn, darunter
       halbe Pixel – das ist keine Feinabstimmung, sondern eine fehlende
       Entscheidung. Die Sperrung haengt am Grad, nicht global an h1–h4. */
    --fl-t-900: 2.125rem;   /* 34 */
    --fl-t-800: 1.75rem;    /* 28 */
    --fl-t-700: 1.375rem;   /* 22 */
    --fl-t-600: 1.125rem;   /* 18 */
    --fl-t-500: 1rem;       /* 16 */
    --fl-t-400: 0.9375rem;  /* 15 */
    --fl-t-300: 0.875rem;   /* 14 */
    --fl-t-200: 0.8125rem;  /* 13 */
    --fl-t-100: 0.75rem;    /* 12 – nur Overline */

    --fl-zh-900: 2.5rem;
    --fl-zh-800: 2.25rem;
    --fl-zh-700: 1.875rem;
    --fl-zh-600: 1.625rem;
    --fl-zh-500: 1.5rem;
    --fl-zh-400: 1.4375rem;
    --fl-zh-300: 1.3125rem;
    --fl-zh-200: 1.1875rem;
    --fl-zh-100: 1.0625rem;

    /* Nur 400, 600, 700. 500/550/650/800 gibt es in den Systemschriften nicht
       verlaesslich; der Browser rundet dann je nach Plattform verschieden,
       und die Hierarchie ist auf keinem zweiten Rechner dieselbe. */
    --fl-fett-normal: 400;
    --fl-fett-halb: 600;
    --fl-fett-voll: 700;

    /* --- Neutrale Leiter (kuehl, Ton ~215°) ------------------------------
       Zwoelf Tokens statt neunzehn. Jedes hat genau eine Bedeutung; die
       Kontrastwerte sind gerechnet, nicht geschaetzt. */
    --fl-flaeche: #ffffff;
    /* Der Grund traegt die Flaechen. Er lag bei #f7f8fa und damit nur drei
       Prozent unter Weiss – auf dem Bildschirm eines Schullaptops nicht zu
       sehen. Ohne sichtbaren Grund gibt es keine Ebenen, und ohne Ebenen
       bleiben als Gestaltungsmittel nur Haarlinien und Fettung. */
    --fl-grund: #f4f6fa;
    --fl-versenkt: #eff1f5;
    --fl-linie: #e3e6ec;
    --fl-linie-kraeftig: #cdd3dc;
    --fl-rahmen: #7c8798;          /* 3,64:1 auf Weiss – WCAG 1.4.11 */
    --fl-text-leise: #5b6675;      /* 5,83:1 auf Weiss */
    --fl-text: #1b2230;            /* 15,93:1 auf Weiss */
    --fl-tinte: #12181f;
    --fl-text-invers: #ffffff;
    --fl-text-invers-leise: #c7ceda;
    --fl-fokus-hell: #7fb0f0;

    /* --- Bedeutungsfarben, in beiden Oberflaechen gleich ------------------ */
    --fl-erfolg: #0e5b3c;
    --fl-erfolg-sanft: #e6f1eb;
    --fl-warnung: #7a4e00;
    --fl-warnung-sanft: #fcf2e2;
    --fl-fehler: #9b1c1c;
    --fl-fehler-sanft: #fbeaea;

    /* --- Abstaende, 4-px-Raster, neun Stufen mit Zustaendigkeit ----------- */
    --fl-a-1: 0.25rem;   /*  4 – innerhalb eines Bedienelements */
    --fl-a-2: 0.5rem;    /*  8 – Beschriftung zu Feld */
    --fl-a-3: 0.75rem;   /* 12 – Kaestchen zu Beschriftung, Schaltflaechen */
    --fl-a-4: 1rem;      /* 16 – Zellen, Meldungen */
    --fl-a-5: 1.5rem;    /* 24 – Feld zu Feld, Panel innen */
    --fl-a-6: 2rem;      /* 32 – Abschnitt zu Abschnitt */
    --fl-a-7: 3rem;      /* 48 – Block zu Block, Spaltenabstand */
    --fl-a-8: 4rem;      /* 64 – ueber der Aktionszeile */
    --fl-a-9: 6rem;      /* 96 – Fussluft */

    /* --- Radien: drei, jeder mit Zustaendigkeit ---------------------------
       6 px an einem 44 px hohen Feld liest sich als Vorgabe eines Baukastens,
       nicht als Entscheidung. Der Radius muss zur Hoehe passen. */
    --fl-radius-1: 8px;    /* Feld, Schaltflaeche, Abzeichen, Fokusring */
    --fl-radius-2: 12px;   /* Panel, Dialog, Kurzmeldung */
    --fl-radius-voll: 999px;

    /* --- Erhebung: Kante und Schatten aus EINER Quelle ---------------------
       "Rahmen UND Schatten am selben Kasten ist die Signatur einer
       Admin-Vorlage" – das stimmt, und die Folgerung daraus war bisher "gar
       keine Erhebung". Das ist die andere Uebertreibung: Eine Flaeche, die
       nichts von ihrer Umgebung abhebt, kann auch nichts tragen.

       Der Schattenrahmen loest beides. Sein erster Anteil ist eine Kante von
       einem Pixel, sein zweiter ein sehr flacher Schatten. Er zaehlt nicht in
       die Geometrie, laesst sich nicht versehentlich neben einen border
       stellen und ist genau EIN Wert – wo er steht, gilt dieselbe Erhebung. */
    --fl-schatten-blatt: 0 0 0 1px rgba(16, 22, 34, .055), 0 1px 2px rgba(16, 22, 34, .04);
    --fl-schatten-ebene: 0 1px 2px rgba(16, 22, 34, .04), 0 6px 16px rgba(16, 22, 34, .07);
    --fl-schatten-decke: 0 2px 6px rgba(16, 22, 34, .08), 0 16px 40px rgba(16, 22, 34, .16);

    /* --- Bewegung -------------------------------------------------------- */
    --fl-zeit: 120ms;
    --fl-kurve: cubic-bezier(.2, 0, .2, 1);

    /* --- Inhaltsbreiten --------------------------------------------------- */
    --fl-breite-lesen: 68ch;
    --fl-breite-formular: 40rem;
    --fl-breite-inhalt: 80rem;
    /* Der Assistent ist genau so breit wie seine beiden Spalten: 40 rem
       Formular + 3 rem Abstand + 21,25 rem Kontext + zweimal Rand. Bei den
       vorherigen 85 rem standen dazwischen ueber 300 Pixel tote Flaeche –
       die Formularsaeule klebte links, der Kontext rechts am Fensterrand. */
    --fl-breite-assistent: 68rem;
    --fl-breite-liste: 100rem;
}
/* ==========================================================================
   ENDE WERTESATZ
   ========================================================================== */

/* --------------------------------------------------------------------------
   1a. Werte dieser Oberflaeche

   Der Verwaltungsbereich hat historisch eigene Namen. Wo der Wert derselbe
   ist, steht hier nur noch ein Verweis auf den gemeinsamen Wertesatz – dann
   gibt es die Zahl im Projekt genau einmal. Nachgerechnet, nicht geschaetzt:

       --fl-space-1..4   4/8/12/16 px  =  --fl-a-1..4
       --fl-space-6      24 px         =  --fl-a-5
       --fl-space-8      32 px         =  --fl-a-6
       --fl-space-12     48 px         =  --fl-a-7
       --fl-radius-sm     6 px         =  --fl-radius-1
       --fl-radius       10 px         =  --fl-radius-2
       --fl-radius-pill 999 px         =  --fl-radius-voll

   Zwei Stufen bleiben eigenstaendig: 20 px und 40 px haben im gemeinsamen
   Satz keine Entsprechung. Die dichte Verwaltungsoberflaeche braucht sie
   zwischen 16 und 24 beziehungsweise 32 und 48 – sie einfach auf die
   naechste Stufe zu ziehen, wuerde jede Karte lockerer machen, und das ist
   eine Gestaltungsentscheidung, die man ansehen muss, statt sie beim
   Aufraeumen mitzunehmen.

   NICHT vereinheitlicht sind Farben und Schriftkette. Die Werte liegen dicht
   beieinander (--fl-text #16202e gegen #1b2230), aber "dicht beieinander"
   ist kein Grund, die Palette einer laufenden Anwendung stillschweigend
   auszutauschen. Das gehoert vor einen Bildschirm, nicht in einen Commit.
   -------------------------------------------------------------------------- */

:root {
    /* Flaechen */
    --fl-bg:            #f4f6f9;
    --fl-surface:       #ffffff;
    --fl-surface-muted: #f8fafc;
    --fl-surface-sunken: #eef2f7;

    /* Linien
       Unterschieden wird zwischen rein dekorativen Trennlinien und den
       Raendern von Bedienelementen. Nur letztere muessen nach WCAG 1.4.11
       mindestens 3:1 gegen den Hintergrund erreichen – ein Eingabefeld ist
       sonst nicht als solches erkennbar. */
    --fl-border:         #dfe5ed;  /* Trennlinien, dekorativ */
    --fl-border-strong:  #c6d0dc;  /* betonte Trennlinien, dekorativ */
    --fl-border-control: #767f8c;  /* Bedienelemente: 4,08:1 auf Weiss */

    /* Text
       Die Werte sind auf Weiss und auf --fl-bg geprueft. --fl-text-subtle
       traegt echte Information ("keine Angabe", "nicht hinterlegt") und
       erfuellt deshalb ebenfalls 4,5:1. */
    --fl-text:          #16202e;   /* 15,3:1 */
    --fl-text-muted:    #5a6b80;   /* 5,46:1 */
    --fl-text-subtle:   #626f84;   /* 5,09:1 auf Weiss, 4,70:1 auf --fl-bg */
    --fl-text-invert:   #ffffff;

    /* Rein dekorative Symbole ohne eigene Aussage (Suchlupe, Leerzustand,
       Auslassungspunkte). Sie stehen immer neben beschriftetem Text und
       fallen nicht unter die Kontrastanforderung. */
    --fl-icon-subtle:   #9aa6b6;

    /* Markenfarbe: gedecktes Blau, schultauglich und kontraststark */
    --fl-primary:        #1f4f8f;
    --fl-primary-hover:  #1a4278;
    --fl-primary-soft:   #e8effa;
    --fl-primary-border: #bcd0ec;

    /* Bedeutungsfarben */
    --fl-success:        #1d6b45;
    --fl-success-soft:   #e3f3ea;
    --fl-success-border: #b8ddc8;

    --fl-warning:        #8a5a05;
    --fl-warning-soft:   #fdf1dc;
    --fl-warning-border: #edd6a8;

    --fl-danger:         #a72a2a;
    --fl-danger-soft:    #fbe9e9;
    --fl-danger-border:  #eec4c4;

    --fl-neutral:        #4a5769;
    --fl-neutral-soft:   #eef1f5;
    --fl-neutral-border: #d5dce5;

    /* Typografie – aus dem gemeinsamen Wertesatz.

       Hier stand eine eigene Kette, die mit -apple-system begann und "Segoe
       UI" nannte; der gemeinsame Satz beginnt mit ui-sans-serif/system-ui und
       nennt "Segoe UI Variable Text". Auf DEMSELBEN Windows-11-Rechner
       rendern die beiden Subdomains damit in zwei verschiedenen Schnitten –
       die Verwaltung haerter und schmaler, das Portal weicher. Das ist kein
       Entwurf, sondern ein Erbe, und es ist der Unterschied, den man ohne
       Messgeraet sieht.

       Eine Kette. Die alten Namen bleiben, damit die 2000 Zeilen darunter
       unveraendert weiterlaufen. */
    --fl-font: var(--fl-schrift);
    --fl-font-mono: var(--fl-schrift-fest);

    /* Abstaende – konsequent auf einem 4px-Raster.
       Sieben von neun Stufen kommen aus dem gemeinsamen Wertesatz; die
       Begruendung fuer die beiden eigenen steht in Abschnitt 1a. */
    --fl-space-1: var(--fl-a-1);   /*  4 */
    --fl-space-2: var(--fl-a-2);   /*  8 */
    --fl-space-3: var(--fl-a-3);   /* 12 */
    --fl-space-4: var(--fl-a-4);   /* 16 */
    --fl-space-5: 20px;            /* eigene Stufe */
    --fl-space-6: var(--fl-a-5);   /* 24 */
    --fl-space-8: var(--fl-a-6);   /* 32 */
    --fl-space-10: 40px;           /* eigene Stufe */
    --fl-space-12: var(--fl-a-7);  /* 48 */

    /* Rundungen */
    --fl-radius-sm: var(--fl-radius-1);
    --fl-radius:    var(--fl-radius-2);
    --fl-radius-lg: 14px;
    --fl-radius-pill: var(--fl-radius-voll);

    /* Schatten – sehr zurueckhaltend */
    --fl-shadow-sm: 0 1px 2px rgba(16, 30, 48, .06);
    --fl-shadow:    0 1px 3px rgba(16, 30, 48, .08), 0 1px 2px rgba(16, 30, 48, .04);
    --fl-shadow-md: 0 4px 12px rgba(16, 30, 48, .10);
    --fl-shadow-lg: 0 12px 32px rgba(16, 30, 48, .16);

    --fl-sidebar-width: 248px;
    --fl-header-height: 60px;
}

/* --------------------------------------------------------------------------
   2. Grundlagen
   -------------------------------------------------------------------------- */

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

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

body {
    margin: 0;
    background: var(--fl-bg);
    color: var(--fl-text);
    font-family: var(--fl-font);
    font-size: 15px;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { margin: 0; font-weight: 600; line-height: 1.3; letter-spacing: -.01em; }
h1 { font-size: 22px; }
h2 { font-size: 18px; }
h3 { font-size: 16px; }
h4 { font-size: 14px; }

p { margin: 0 0 var(--fl-space-3); }
p:last-child { margin-bottom: 0; }

a { color: var(--fl-primary); text-decoration: none; }
a:hover { text-decoration: underline; }

hr {
    border: 0;
    border-top: 1px solid var(--fl-border);
    margin: var(--fl-space-6) 0;
}

code, kbd, samp { font-family: var(--fl-font-mono); font-size: .92em; }

/* Sichtbarer Fokus – Grundlage der Tastaturbedienung. Wird nirgends
   entfernt, sondern nur bei reinen Mausklicks unterdrueckt. */
:focus-visible {
    outline: 2px solid var(--fl-primary);
    outline-offset: 2px;
    border-radius: var(--fl-radius-sm);
}

/* Nur fuer Bildschirmleser sichtbar */
/*
 * Honigtopf des oeffentlichen Formulars (FormGuard::HONEYPOT_CLASS).
 *
 * Ein normales Textfeld, das aus dem Sichtfeld geschoben wird. Bewusst KEIN
 * type="hidden": Ausfuellwerkzeuge lassen versteckte Felder haeufig aus,
 * sichtbare dagegen nicht – genau darauf beruht die Huerde.
 *
 * OHNE DIESE REGEL IST DAS FELD SICHTBAR und jeder eingereichte Antrag wird
 * abgewiesen, weil ein Mensch es ausfuellt. Die Regel gehoert damit zur
 * Funktion, nicht zur Gestaltung.
 *
 * Nicht display:none oder visibility:hidden – manche Werkzeuge erkennen beides
 * und ueberspringen das Feld dann ebenfalls.
 */
.fl-honigtopf {
    position: absolute;
    left: -9999px;
    top: auto;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

.fl-sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Sprungmarke zum Inhalt */
.fl-skip {
    position: absolute;
    left: var(--fl-space-4);
    top: -100px;
    z-index: 200;
    padding: var(--fl-space-2) var(--fl-space-4);
    background: var(--fl-primary);
    color: var(--fl-text-invert);
    border-radius: var(--fl-radius-sm);
    transition: top .15s ease;
}
.fl-skip:focus { top: var(--fl-space-4); text-decoration: none; }

/* --------------------------------------------------------------------------
   3. Grundgeruest
   -------------------------------------------------------------------------- */

.fl-app {
    display: grid;
    grid-template-columns: var(--fl-sidebar-width) 1fr;
    min-height: 100vh;
}

/* Seitenleiste */
.fl-sidebar {
    background: #12233c;
    color: #cdd8e6;
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
}

.fl-brand {
    display: flex;
    align-items: center;
    gap: var(--fl-space-3);
    padding: var(--fl-space-5) var(--fl-space-5) var(--fl-space-4);
    border-bottom: 1px solid rgba(255, 255, 255, .09);
}

.fl-brand__mark {
    width: 34px; height: 34px;
    flex: 0 0 34px;
    border-radius: 9px;
    background: linear-gradient(140deg, #3f7fd4, #1f4f8f);
    color: #fff;
    display: grid;
    place-items: center;
    font-weight: 700;
    font-size: 14px;
    letter-spacing: .02em;
}

.fl-brand__text { min-width: 0; }
.fl-brand__title {
    color: #fff;
    font-weight: 600;
    font-size: 15px;
    line-height: 1.2;
}
.fl-brand__subtitle {
    font-size: 12px;
    color: #8ea3bd;
    line-height: 1.3;
    margin-top: 1px;
}

.fl-nav { padding: var(--fl-space-4) var(--fl-space-3); flex: 1; }

.fl-nav__group + .fl-nav__group { margin-top: var(--fl-space-5); }

.fl-nav__label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .07em;
    color: #7b90ab;
    padding: 0 var(--fl-space-3) var(--fl-space-2);
    font-weight: 600;
}

.fl-nav__link {
    display: flex;
    align-items: center;
    gap: var(--fl-space-3);
    padding: 9px var(--fl-space-3);
    border-radius: var(--fl-radius-sm);
    color: #cdd8e6;
    font-size: 14px;
    font-weight: 500;
    margin-bottom: 2px;
    transition: background .12s ease, color .12s ease;
}
.fl-nav__link:hover { background: rgba(255, 255, 255, .07); color: #fff; text-decoration: none; }
.fl-nav__link[aria-current="page"] { background: rgba(63, 127, 212, .22); color: #fff; }
.fl-nav__link:focus-visible { outline-color: #7fb0f0; }

.fl-nav__icon { flex: 0 0 18px; width: 18px; height: 18px; opacity: .85; }
.fl-nav__link[aria-current="page"] .fl-nav__icon { opacity: 1; }

.fl-nav__badge {
    margin-left: auto;
    background: #c8892c;
    color: #1a1206;
    border-radius: var(--fl-radius-pill);
    font-size: 11px;
    font-weight: 700;
    padding: 1px 7px;
    min-width: 20px;
    text-align: center;
}

.fl-sidebar__footer {
    padding: var(--fl-space-4) var(--fl-space-5);
    border-top: 1px solid rgba(255, 255, 255, .09);
    font-size: 11px;
    /* Aufgehellt: gegen #12233c erreicht der vorherige Wert nur 4,37:1. */
    color: #8ba0b8;
}

/* Kopfzeile */
.fl-main { min-width: 0; display: flex; flex-direction: column; }

.fl-header {
    height: var(--fl-header-height);
    background: var(--fl-surface);
    border-bottom: 1px solid var(--fl-border);
    display: flex;
    align-items: center;
    gap: var(--fl-space-4);
    padding: 0 var(--fl-space-6);
    position: sticky;
    top: 0;
    z-index: 30;
}

.fl-header__title { flex: 1; min-width: 0; }
.fl-header__title h1 {
    font-size: 17px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.fl-header__subtitle {
    font-size: 12.5px;
    color: var(--fl-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* min-width: 0 laesst die Gruppe schrumpfen. Ohne sie stand die rechte Kante
   der Kopfleiste auf einem 390 Pixel breiten Telefon bei 442 Pixeln: "Erfassen"
   und das Benutzermenue lagen ausserhalb des Bildes. */
.fl-header__actions { display: flex; align-items: center; gap: var(--fl-space-2); min-width: 0; }

.fl-menu-toggle { display: none; }

/* Benutzermenue */
.fl-usermenu { position: relative; }

.fl-usermenu__button {
    display: flex;
    align-items: center;
    gap: var(--fl-space-2);
    background: none;
    border: 1px solid transparent;
    border-radius: var(--fl-radius-sm);
    padding: 5px 8px 5px 5px;
    cursor: pointer;
    font: inherit;
    color: var(--fl-text);
}
.fl-usermenu__button:hover { background: var(--fl-surface-muted); border-color: var(--fl-border); }

.fl-avatar {
    width: 30px; height: 30px;
    flex: 0 0 30px;
    border-radius: 50%;
    background: var(--fl-primary-soft);
    color: var(--fl-primary);
    display: grid;
    place-items: center;
    font-size: 12px;
    font-weight: 700;
}

.fl-usermenu__name { font-size: 13.5px; font-weight: 500; }

/*
 * Das Menue waechst mit seinem Inhalt.
 *
 * Feste 232 px waren zu schmal fuer eine dienstliche E-Mail-Adresse; sie brach
 * mitten im Wort um ("…bildung-ls" / "a.de"), was wie ein Darstellungsfehler
 * aussieht. width: max-content laesst das Feld so breit werden, wie die
 * laengste Zeile es braucht, die Obergrenze verhindert ein Herauslaufen aus
 * dem Fenster.
 */
.fl-usermenu__panel {
    position: absolute;
    right: 0;
    top: calc(100% + 6px);
    min-width: 232px;
    width: max-content;
    max-width: min(360px, calc(100vw - 2rem));
    background: var(--fl-surface);
    border: 1px solid var(--fl-border);
    border-radius: var(--fl-radius);
    box-shadow: var(--fl-shadow-lg);
    padding: var(--fl-space-2);
    z-index: 40;
}
.fl-usermenu__panel[hidden] { display: none; }

.fl-usermenu__head {
    padding: var(--fl-space-2) var(--fl-space-3) var(--fl-space-3);
    border-bottom: 1px solid var(--fl-border);
    margin-bottom: var(--fl-space-2);
}
.fl-usermenu__head strong {
    display: block;
    font-size: 13.5px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/*
 * Die Adresse bleibt einzeilig. Ist sie ausnahmsweise laenger als die
 * Obergrenze des Menues, wird sie am Ende gekuerzt – nicht mitten im Wort
 * umgebrochen. Der vollstaendige Wert steht im title-Attribut.
 */
.fl-usermenu__mail {
    display: block;
    font-size: 12px;
    color: var(--fl-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.fl-usermenu__item {
    display: block;
    width: 100%;
    text-align: left;
    padding: 7px var(--fl-space-3);
    border: 0;
    background: none;
    border-radius: var(--fl-radius-sm);
    color: var(--fl-text);
    font: inherit;
    font-size: 13.5px;
    cursor: pointer;
}
.fl-usermenu__item:hover { background: var(--fl-surface-muted); text-decoration: none; }

/* Inhaltsbereich

   margin-inline: auto fehlte. Auf einem 1920er Schirm blieben dadurch 112
   Pixel einseitig rechts liegen, auf einem 2560er 752 – der Inhalt sass
   sichtbar aus der Mitte geruecht, ohne dass ein Grund dafuer erkennbar war. */
.fl-content {
    padding: var(--fl-space-6);
    flex: 1;
    max-width: 1560px;
    width: 100%;
    margin-inline: auto;
}

.fl-page-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--fl-space-2);
    align-items: center;
}

/* --------------------------------------------------------------------------
   4. Karten
   -------------------------------------------------------------------------- */

/*
 * Die Karte ist eine Spalte aus Kopf, Rumpf und Fuss.
 *
 * Der Rumpf waechst (flex: 1), der Fuss sitzt dadurch immer unten. Stehen
 * zwei Karten nebeneinander und sind gleich hoch, liegen ihre Fusszeilen auf
 * einer Linie – vorher endeten sie unterschiedlich, was unaufgeraeumt wirkte.
 *
 * min-width: 0 ist noetig, damit breite Inhalte (Tabellen mit eigenem
 * Seitwaertsscrollen) die Karte nicht auseinanderdruecken. Flex-Elemente
 * schrumpfen sonst nicht unter ihre Inhaltsbreite.
 */
.fl-card {
    background: var(--fl-surface);
    border: 1px solid var(--fl-border);
    border-radius: var(--fl-radius);
    box-shadow: var(--fl-shadow-sm);
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.fl-card + .fl-card { margin-top: var(--fl-space-5); }

.fl-card__header {
    display: flex;
    align-items: center;
    gap: var(--fl-space-3);
    padding: var(--fl-space-4) var(--fl-space-5);
    border-bottom: 1px solid var(--fl-border);
}
.fl-card__header h2, .fl-card__header h3 { flex: 1; min-width: 0; }
.fl-card__hint { font-size: 12.5px; color: var(--fl-text-muted); font-weight: 400; margin-top: 2px; }

/*
 * Manche Karten umschliessen Kopf, Rumpf und Fuss mit einem <form>. Dann ist
 * das Formular das einzige Flex-Element der Karte und muss die Spalte
 * fortsetzen – sonst bliebe der Fuss in der Mitte haengen.
 */
.fl-card > form { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; }

.fl-card__body { padding: var(--fl-space-5); flex: 1 1 auto; min-width: 0; }
.fl-card__body--tight { padding: var(--fl-space-4); }
.fl-card__body--flush { padding: 0; }

.fl-card__footer {
    padding: var(--fl-space-4) var(--fl-space-5);
    border-top: 1px solid var(--fl-border);
    background: var(--fl-surface-muted);
    border-radius: 0 0 var(--fl-radius) var(--fl-radius);
    display: flex;
    gap: var(--fl-space-2);
    align-items: center;
    flex-wrap: wrap;
}

/* --------------------------------------------------------------------------
   5. Kennzahlen
   -------------------------------------------------------------------------- */

/*
 * 11rem statt 190px als Mindestbreite.
 *
 * Sechs Karten passten bei 190px erst ab etwa 1600 Pixeln in eine Reihe;
 * zwischen 1280 und 1600 standen fuenf oben und eine allein darunter. Eine
 * Waise ist kein Umbruch, sie sieht nach einem Fehler aus – und das Band war
 * dadurch 232 statt 108 Pixel hoch, auf jeder Listenseite.
 */
.fl-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    gap: var(--fl-space-4);
    margin-bottom: var(--fl-space-5);
}

.fl-stat {
    background: var(--fl-surface);
    border: 1px solid var(--fl-border);
    border-radius: var(--fl-radius);
    padding: var(--fl-space-4) var(--fl-space-5);
    box-shadow: var(--fl-shadow-sm);
    display: block;
    color: inherit;
    position: relative;
    transition: border-color .12s ease, box-shadow .12s ease, transform .12s ease;
}

a.fl-stat:hover {
    text-decoration: none;
    border-color: var(--fl-border-strong);
    box-shadow: var(--fl-shadow);
    transform: translateY(-1px);
}

.fl-stat__label {
    font-size: 12.5px;
    color: var(--fl-text-muted);
    font-weight: 500;
    display: flex;
    align-items: center;
    gap: 6px;
}

.fl-stat__value {
    font-size: 28px;
    font-weight: 650;
    line-height: 1.15;
    margin-top: 2px;
    font-variant-numeric: tabular-nums;
}

.fl-stat__meta { font-size: 12px; color: var(--fl-text-subtle); margin-top: 2px; }

.fl-stat--review .fl-stat__value { color: var(--fl-warning); }
.fl-stat--approved .fl-stat__value { color: var(--fl-success); }
.fl-stat--rejected .fl-stat__value { color: var(--fl-danger); }
.fl-stat--open .fl-stat__value { color: var(--fl-primary); }

.fl-stat__dot {
    width: 7px; height: 7px;
    border-radius: 50%;
    flex: 0 0 7px;
}
.fl-stat--open .fl-stat__dot { background: var(--fl-primary); }
.fl-stat--review .fl-stat__dot { background: var(--fl-warning); }
.fl-stat--approved .fl-stat__dot { background: var(--fl-success); }
.fl-stat--rejected .fl-stat__dot { background: var(--fl-danger); }

/* --------------------------------------------------------------------------
   6. Tabellen
   -------------------------------------------------------------------------- */

/* Breite Tabellen scrollen waagerecht in ihrem eigenen Bereich.
   Das Skript setzt tabindex="0", sobald der Inhalt tatsaechlich breiter ist
   als der Bereich – erst dann laesst sich der Ausschnitt auch ohne Maus mit
   den Pfeiltasten verschieben. Der Fokusrahmen macht sichtbar, dass der
   Bereich aktiv ist. */
/*
 * position: relative ist hier kein Gestaltungsmittel, sondern die Behebung
 * eines gemessenen Fehlers.
 *
 * In der Aktionsspalte steht eine Ueberschrift als .fl-sr-only, also
 * position: absolute. Ohne positionierten Vorfahren ist ihr Bezugsrahmen das
 * Wurzelelement – sie entkommt dem Scrollbereich und macht die GESAMTE Seite
 * waagerecht scrollbar. Gemessen auf /antraege bei 1366 Pixeln: 1622 Pixel
 * Dokumentbreite, 256 Pixel echter Seitenversatz. Betroffen war jedes Fenster
 * unter etwa 1650 Pixeln, also praktisch jeder Schullaptop.
 *
 * overflow-x: clip hilft dagegen nicht; nur der Bezugsrahmen tut es.
 */
.fl-table-wrap {
    position: relative;
    overflow-x: auto;
    scrollbar-width: thin;
}

.fl-table-wrap[tabindex]:focus-visible {
    outline: 2px solid var(--fl-primary);
    outline-offset: -2px;
    border-radius: var(--fl-radius-sm);
}

.fl-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13.5px;
}

.fl-table th, .fl-table td {
    padding: 10px var(--fl-space-4);
    text-align: left;
    border-bottom: 1px solid var(--fl-border);
    vertical-align: top;
}

.fl-table thead th {
    background: var(--fl-surface-muted);
    color: var(--fl-text-muted);
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .035em;
    white-space: nowrap;
    border-bottom: 1px solid var(--fl-border-strong);
}

/*
 * Bewusst KEINE klebende Kopfzeile.
 *
 * "position: sticky" bezieht sich immer auf den naechstgelegenen
 * Scrollbehaelter. Das ist hier .fl-table-wrap, denn "overflow-x: auto" macht
 * den Bereich zum Scrollbehaelter – und zwar in beiden Richtungen, weil ein
 * einzeln gesetztes overflow-x den anderen Wert von "visible" auf "auto"
 * anhebt. Dieser Behaelter ist genauso hoch wie sein Inhalt, also gibt es in
 * ihm nichts zu scrollen: Die Kopfzeile wuerde mit der Tabelle nach oben aus
 * dem Bild wandern, obwohl die Regel so aussieht, als bliebe sie stehen.
 *
 * Der Bereich muss waagerecht scrollen koennen, sonst laufen breite Tabellen
 * auf schmalen Geraeten aus der Seite. Damit schliessen sich beide Wuensche
 * aus, und das waagerechte Scrollen wiegt schwerer. Die Listen sind ohnehin
 * auf 25 Zeilen je Seite begrenzt, unter 720 px werden Tabellen zu Karten
 * umgebrochen und tragen ihre Spaltenbezeichnung an jeder Zelle.
 */

.fl-table tbody tr:last-child td { border-bottom: 0; }
.fl-table tbody tr:hover { background: var(--fl-surface-muted); }

/*
 * Ganze Zeile anklickbar (siehe app.js).
 *
 * Der Zeiger zeigt das an. Die Klasse wird erst vom Skript gesetzt – ohne
 * JavaScript verspricht der Zeiger also nichts, was nicht auch eintritt.
 * Die echten Verweise in der Zeile bleiben unabhaengig davon bestehen.
 */
.fl-table tbody tr.is-klickbar { cursor: pointer; }

.fl-table td.fl-num, .fl-table th.fl-num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.fl-table td.fl-nowrap, .fl-table th.fl-nowrap { white-space: nowrap; }

.fl-table__actions { text-align: right; white-space: nowrap; }

/* Sortierbare Spaltenkoepfe */
.fl-sort {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: inherit;
    text-transform: inherit;
    letter-spacing: inherit;
    font-weight: inherit;
}
.fl-sort:hover { color: var(--fl-primary); text-decoration: none; }
.fl-sort__icon { opacity: .35; width: 12px; height: 12px; flex: 0 0 12px; }
/*
 * Die aktive Sortierspalte wird ueber eine eigene Klasse hervorgehoben, nicht
 * ueber [aria-sort]. Grund: aria-sort ist laut ARIA nur an Spalten- und
 * Zeilenkoepfen zulaessig; an einem <a> ist es ungueltig und wird von
 * Bildschirmlesern zusaetzlich vorgelesen. Das Attribut steht deshalb
 * ausschliesslich am <th>, die Optik haengt an .fl-sort--active.
 */
.fl-sort--active { color: var(--fl-primary); }
.fl-sort--active .fl-sort__icon { opacity: 1; }

/* Hervorhebung von Suchtreffern */
mark {
    background: #fdf0c3;
    color: inherit;
    border-radius: 2px;
    padding: 0 1px;
}

.fl-cell-title {
    font-weight: 550;
    display: block;
    max-width: 340px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.fl-cell-sub { font-size: 12px; color: var(--fl-text-muted); }

.fl-teacher-cell { display: flex; align-items: center; gap: var(--fl-space-2); }
.fl-teacher-cell .fl-avatar { width: 26px; height: 26px; flex-basis: 26px; font-size: 10.5px; }

/* --------------------------------------------------------------------------
   7. Abzeichen
   -------------------------------------------------------------------------- */

.fl-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 9px;
    border-radius: var(--fl-radius-pill);
    font-size: 12px;
    font-weight: 600;
    line-height: 1.6;
    border: 1px solid transparent;
    white-space: nowrap;
}

/* Jeder Status traegt zusaetzlich ein Symbol – die Bedeutung darf nie
   allein an der Farbe haengen (Barrierefreiheit). */
.fl-badge::before { font-size: 11px; line-height: 1; }

.fl-badge--open      { background: var(--fl-primary-soft); color: var(--fl-primary); border-color: var(--fl-primary-border); }
.fl-badge--open::before { content: "●"; }

.fl-badge--review    { background: var(--fl-warning-soft); color: var(--fl-warning); border-color: var(--fl-warning-border); }
.fl-badge--review::before { content: "!"; font-weight: 800; }

.fl-badge--approved  { background: var(--fl-success-soft); color: var(--fl-success); border-color: var(--fl-success-border); }
.fl-badge--approved::before { content: "✓"; }

.fl-badge--rejected  { background: var(--fl-danger-soft); color: var(--fl-danger); border-color: var(--fl-danger-border); }
.fl-badge--rejected::before { content: "✕"; }

.fl-badge--cancelled { background: var(--fl-neutral-soft); color: var(--fl-neutral); border-color: var(--fl-neutral-border); }
.fl-badge--cancelled::before { content: "–"; }

/*
 * "Erledigt" – der Doppelhaken sagt: erst genehmigt, dann abgeschlossen.
 * Der einfache Haken bleibt der Genehmigung vorbehalten.
 */
.fl-badge--done { background: var(--fl-neutral-soft); color: var(--fl-neutral); border-color: var(--fl-neutral-border); }
.fl-badge--done::before { content: "✓✓"; letter-spacing: -1px; }

/*
 * Dritter Unterscheidungskanal neben Wort und Symbol: Abgeschlossene
 * Zustaende sind nur umrandet, laufende flaechig gefuellt. Das ist auch ohne
 * Farbwahrnehmung und ohne Symbolerkennung aus einigen Metern sichtbar.
 */
.fl-badge--outline { background: transparent; }

/* Bewusst --fl-neutral statt --fl-text-subtle: Auf der hellen Abzeichenfarbe
   erreicht letzteres nur 3,02:1. */
.fl-badge--archived  { background: var(--fl-neutral-soft); color: var(--fl-neutral); border-color: var(--fl-neutral-border); }
.fl-badge--archived::before { content: "⌂"; }

.fl-badge--plain { background: var(--fl-neutral-soft); color: var(--fl-neutral); border-color: var(--fl-neutral-border); }
.fl-badge--plain::before { content: none; }

.fl-badge--count {
    background: var(--fl-surface-sunken);
    color: var(--fl-text-muted);
    border-color: var(--fl-border);
    font-variant-numeric: tabular-nums;
    min-width: 26px;
    justify-content: center;
}
.fl-badge--count::before { content: none; }

.fl-badge--sm { font-size: 11px; padding: 1px 7px; }

/* --------------------------------------------------------------------------
   8. Schaltflaechen
   -------------------------------------------------------------------------- */

.fl-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--fl-space-2);
    padding: 8px 15px;
    border-radius: var(--fl-radius-sm);
    border: 1px solid var(--fl-border-control);
    background: var(--fl-surface);
    color: var(--fl-text);
    font: inherit;
    font-size: 13.5px;
    font-weight: 550;
    cursor: pointer;
    text-decoration: none;
    white-space: nowrap;
    transition: background .12s ease, border-color .12s ease, color .12s ease;
    position: relative;
}

.fl-btn:hover { background: var(--fl-surface-muted); border-color: var(--fl-text-subtle); text-decoration: none; }
.fl-btn:active { transform: translateY(1px); }

.fl-btn:disabled, .fl-btn[aria-disabled="true"] {
    opacity: .55;
    cursor: not-allowed;
    transform: none;
}

.fl-btn--primary {
    background: var(--fl-primary);
    border-color: var(--fl-primary);
    color: var(--fl-text-invert);
}
.fl-btn--primary:hover { background: var(--fl-primary-hover); border-color: var(--fl-primary-hover); color: #fff; }

.fl-btn--success {
    background: var(--fl-success);
    border-color: var(--fl-success);
    color: var(--fl-text-invert);
}
.fl-btn--success:hover { background: #175737; border-color: #175737; color: #fff; }

.fl-btn--danger {
    background: var(--fl-surface);
    border-color: var(--fl-danger-border);
    color: var(--fl-danger);
}
.fl-btn--danger:hover { background: var(--fl-danger-soft); border-color: var(--fl-danger); }

.fl-btn--ghost { border-color: transparent; background: transparent; }
.fl-btn--ghost:hover { background: var(--fl-surface-muted); border-color: var(--fl-border); }

.fl-btn--sm { padding: 5px 11px; font-size: 12.5px; }
.fl-btn--lg { padding: 11px 20px; font-size: 15px; }
.fl-btn--block { width: 100%; }

.fl-btn__icon { width: 16px; height: 16px; flex: 0 0 16px; }

/* Ladezustand: verhindert Doppelklicks und zeigt Fortschritt */
.fl-btn.is-loading { color: transparent !important; pointer-events: none; }
.fl-btn.is-loading .fl-btn__icon { visibility: hidden; }
.fl-btn.is-loading::after {
    content: "";
    position: absolute;
    width: 15px; height: 15px;
    border: 2px solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    animation: fl-spin .6s linear infinite;
    color: var(--fl-text-invert);
}
.fl-btn--ghost.is-loading::after,
.fl-btn.is-loading:not(.fl-btn--primary):not(.fl-btn--success)::after { color: var(--fl-text); }

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

@media (prefers-reduced-motion: reduce) {
    .fl-btn.is-loading::after { animation-duration: 2s; }
    * { transition-duration: .01ms !important; }
}

.fl-btn-group { display: inline-flex; gap: var(--fl-space-2); flex-wrap: wrap; }

/* --------------------------------------------------------------------------
   9. Formulare
   -------------------------------------------------------------------------- */

.fl-form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: var(--fl-space-4) var(--fl-space-5);
}

.fl-field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.fl-field--wide { grid-column: 1 / -1; }

.fl-label {
    font-size: 13px;
    font-weight: 600;
    color: var(--fl-text);
    display: flex;
    align-items: center;
    gap: 5px;
}

.fl-label__required { color: var(--fl-danger); font-weight: 700; }

.fl-input, .fl-select, .fl-textarea {
    width: 100%;
    padding: 8px 11px;
    border: 1px solid var(--fl-border-control);
    border-radius: var(--fl-radius-sm);
    background: var(--fl-surface);
    color: var(--fl-text);
    font: inherit;
    font-size: 14px;
    transition: border-color .12s ease, box-shadow .12s ease;
}

.fl-input:focus, .fl-select:focus, .fl-textarea:focus {
    outline: none;
    border-color: var(--fl-primary);
    box-shadow: 0 0 0 3px rgba(31, 79, 143, .13);
}

.fl-input:disabled, .fl-select:disabled, .fl-textarea:disabled {
    background: var(--fl-surface-sunken);
    color: var(--fl-text-muted);
    cursor: not-allowed;
}

.fl-input[aria-invalid="true"], .fl-select[aria-invalid="true"], .fl-textarea[aria-invalid="true"] {
    border-color: var(--fl-danger);
}
.fl-input[aria-invalid="true"]:focus { box-shadow: 0 0 0 3px rgba(167, 42, 42, .13); }

.fl-textarea { resize: vertical; min-height: 96px; line-height: 1.6; }
.fl-textarea--mail { min-height: 260px; font-family: var(--fl-font); }

.fl-select {
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%235a6b80' d='M1.4 0 6 4.6 10.6 0 12 1.4 6 7.4 0 1.4z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 11px center;
    padding-right: 32px;
}

.fl-hint { font-size: 12px; color: var(--fl-text-muted); }

/* Fehlermeldung: nie nur ueber Farbe – immer mit Symbol und Text */
.fl-error {
    font-size: 12.5px;
    color: var(--fl-danger);
    font-weight: 550;
    display: flex;
    align-items: flex-start;
    gap: 5px;
}
.fl-error::before { content: "⚠"; flex: 0 0 auto; }

.fl-check {
    display: flex;
    align-items: flex-start;
    gap: var(--fl-space-2);
    font-size: 14px;
    cursor: pointer;
}
.fl-check input {
    width: 16px; height: 16px;
    margin: 3px 0 0;
    flex: 0 0 16px;
    accent-color: var(--fl-primary);
    cursor: pointer;
}
.fl-check__text { min-width: 0; }
.fl-check__hint { font-size: 12px; color: var(--fl-text-muted); display: block; }

.fl-fieldset {
    border: 1px solid var(--fl-border);
    border-radius: var(--fl-radius);
    padding: var(--fl-space-4) var(--fl-space-5) var(--fl-space-5);
    margin: 0 0 var(--fl-space-5);
}
.fl-fieldset legend {
    font-size: 13px;
    font-weight: 650;
    padding: 0 var(--fl-space-2);
    color: var(--fl-text);
}

/* --------------------------------------------------------------------------
   10. Filterleiste
   -------------------------------------------------------------------------- */

.fl-filters { display: flex; flex-direction: column; gap: var(--fl-space-3); }

.fl-filters__row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--fl-space-3);
    align-items: flex-end;
}

.fl-filters__field { min-width: 150px; flex: 0 1 auto; }
/* Der Deckel ist Absicht: Ohne ihn war das Suchfeld auf einem 1920er Schirm
   990 Pixel breit – dreimal so lang wie jede Sucheingabe, die je darin steht,
   und der gewonnene Platz fehlte den uebrigen Filtern. */
.fl-filters__field--search { flex: 1 1 20rem; min-width: 200px; max-width: 32rem; }

/*
 * Selten gebrauchte Filter, zugeklappt.
 *
 * <details> statt eines Skripts: Der Bereich laesst sich auch ohne
 * JavaScript oeffnen, und die Tastaturbedienung bringt der Browser mit.
 */
.fl-filters__more { width: 100%; margin-top: var(--fl-space-3); }
.fl-filters__more > summary {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    cursor: pointer;
    font-size: 13px;
    font-weight: 600;
    color: var(--fl-primary);
    padding: 4px 2px;
    border-radius: var(--fl-radius-sm);
    width: fit-content;
    list-style: none;
}
.fl-filters__more > summary::-webkit-details-marker { display: none; }
.fl-filters__more > summary::before {
    content: "";
    width: 0; height: 0;
    border-left: 5px solid currentColor;
    border-top: 4px solid transparent;
    border-bottom: 4px solid transparent;
    transition: transform .15s ease;
}
.fl-filters__more[open] > summary::before { transform: rotate(90deg); }
.fl-filters__more > summary:focus-visible {
    outline: 2px solid var(--fl-primary);
    outline-offset: 2px;
}
.fl-filters__more > .fl-filters__row { margin-top: var(--fl-space-3); }
/* Fuer Inhalte, die ihre eigene Breite mitbringen – etwa einen Filterchip. */
.fl-filters__field--auto { min-width: 0; flex: 0 0 auto; display: flex; align-items: flex-end; }

.fl-search {
    position: relative;
    display: block;
}
.fl-search .fl-input { padding-left: 34px; }
.fl-search__icon {
    position: absolute;
    left: 10px;
    top: 50%;
    transform: translateY(-50%);
    width: 15px; height: 15px;
    color: var(--fl-icon-subtle);
    pointer-events: none;
}

/* Aktive Filter als entfernbare Chips */
.fl-chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--fl-space-2);
    align-items: center;
    padding-top: var(--fl-space-1);
}

.fl-chips__label { font-size: 12.5px; color: var(--fl-text-muted); font-weight: 550; }

.fl-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--fl-primary-soft);
    border: 1px solid var(--fl-primary-border);
    color: var(--fl-primary);
    border-radius: var(--fl-radius-pill);
    padding: 2px 5px 2px 11px;
    font-size: 12.5px;
    font-weight: 550;
}
.fl-chip strong { font-weight: 700; }
.fl-chip__remove {
    display: grid;
    place-items: center;
    position: relative;
    width: 18px; height: 18px;
    border-radius: 50%;
    color: inherit;
    font-size: 13px;
    line-height: 1;
    text-decoration: none;
}
/*
 * Das sichtbare Kreuz misst 18 px, damit der Filterchip kompakt bleibt. Fuer
 * die Bedienung mit dem Finger waere das zu klein (WCAG 2.2, 2.5.8 verlangt
 * mindestens 24 x 24 px). Die Trefferflaeche wird deshalb ueber ein
 * unsichtbares Pseudoelement vergroessert – das aendert nichts am Aussehen
 * und verschiebt auch nichts im Umbruch, weil das Element absolut liegt.
 */
.fl-chip__remove::after {
    content: '';
    position: absolute;
    top: 50%; left: 50%;
    width: 24px; height: 24px;
    transform: translate(-50%, -50%);
}
.fl-chip__remove:hover { background: rgba(31, 79, 143, .16); text-decoration: none; }

/* --------------------------------------------------------------------------
   11. Seitennummerierung
   -------------------------------------------------------------------------- */

.fl-pagination {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--fl-space-4);
    padding: var(--fl-space-3) var(--fl-space-5);
    border-top: 1px solid var(--fl-border);
    background: var(--fl-surface-muted);
    border-radius: 0 0 var(--fl-radius) var(--fl-radius);
    flex-wrap: wrap;
}

.fl-pagination__info { font-size: 12.5px; color: var(--fl-text-muted); font-variant-numeric: tabular-nums; }
.fl-pagination__pages { display: flex; gap: 4px; align-items: center; }

.fl-page-link {
    min-width: 32px;
    height: 32px;
    padding: 0 9px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--fl-border-control);
    border-radius: var(--fl-radius-sm);
    background: var(--fl-surface);
    color: var(--fl-text);
    font-size: 13px;
    font-variant-numeric: tabular-nums;
}
.fl-page-link:hover { background: var(--fl-surface-sunken); text-decoration: none; }
.fl-page-link[aria-current="page"] {
    background: var(--fl-primary);
    border-color: var(--fl-primary);
    color: #fff;
    font-weight: 650;
}
.fl-page-link--disabled { opacity: .4; pointer-events: none; }
.fl-page-ellipsis { padding: 0 4px; color: var(--fl-text-subtle); }

/* --------------------------------------------------------------------------
   12. Hinweise und Meldungen
   -------------------------------------------------------------------------- */

.fl-note {
    display: flex;
    gap: var(--fl-space-3);
    padding: var(--fl-space-3) var(--fl-space-4);
    border-radius: var(--fl-radius-sm);
    border: 1px solid var(--fl-border);
    background: var(--fl-surface-muted);
    font-size: 13.5px;
    align-items: flex-start;
}
.fl-note + .fl-note { margin-top: var(--fl-space-3); }
.fl-note__icon { flex: 0 0 18px; width: 18px; height: 18px; margin-top: 1px; }
.fl-note__body { min-width: 0; flex: 1; }
.fl-note__body strong { display: block; margin-bottom: 2px; }

/* Aufzaehlung der fehlerhaften Felder in der Zusammenfassung eines Formulars. */
.fl-error-list { margin: 6px 0 0; padding-left: 1.15em; }
.fl-error-list li { margin-top: 2px; }
.fl-error-list a { color: inherit; font-weight: 600; }

.fl-note--info    { background: var(--fl-primary-soft); border-color: var(--fl-primary-border); color: #163a68; }
.fl-note--success { background: var(--fl-success-soft); border-color: var(--fl-success-border); color: #124d31; }
.fl-note--warning { background: var(--fl-warning-soft); border-color: var(--fl-warning-border); color: #6b4604; }
.fl-note--danger  { background: var(--fl-danger-soft);  border-color: var(--fl-danger-border);  color: #7d1f1f; }

/* Kurzmeldungen */
.fl-toasts {
    position: fixed;
    right: var(--fl-space-5);
    bottom: var(--fl-space-5);
    z-index: 120;
    display: flex;
    flex-direction: column;
    gap: var(--fl-space-2);
    max-width: min(400px, calc(100vw - 32px));
}

.fl-toast {
    display: flex;
    align-items: flex-start;
    gap: var(--fl-space-3);
    background: var(--fl-surface);
    border: 1px solid var(--fl-border);
    border-left: 3px solid var(--fl-neutral);
    border-radius: var(--fl-radius-sm);
    box-shadow: var(--fl-shadow-lg);
    padding: var(--fl-space-3) var(--fl-space-4);
    font-size: 13.5px;
    animation: fl-toast-in .18s ease-out;
}

.fl-toast--success { border-left-color: var(--fl-success); }
.fl-toast--error   { border-left-color: var(--fl-danger); }
.fl-toast--warning { border-left-color: var(--fl-warning); }
.fl-toast--info    { border-left-color: var(--fl-primary); }

.fl-toast__body { flex: 1; min-width: 0; }
.fl-toast__close {
    border: 0;
    background: none;
    cursor: pointer;
    color: var(--fl-text-subtle);
    font-size: 17px;
    line-height: 1;
    /* Mindestens 24 x 24 px Trefferflaeche (WCAG 2.2, 2.5.8). */
    display: grid;
    place-items: center;
    width: 26px; height: 26px;
    padding: 0;
    flex: 0 0 auto;
    border-radius: var(--fl-radius-sm);
}
.fl-toast__close:hover { color: var(--fl-text); }

.fl-toast.is-leaving { animation: fl-toast-out .18s ease-in forwards; }

@keyframes fl-toast-in  { from { opacity: 0; transform: translateY(10px); } }
@keyframes fl-toast-out { to   { opacity: 0; transform: translateY(6px); } }

/* --------------------------------------------------------------------------
   13. Leere Zustaende
   -------------------------------------------------------------------------- */

.fl-empty {
    text-align: center;
    padding: var(--fl-space-12) var(--fl-space-6);
    color: var(--fl-text-muted);
}

.fl-empty__icon {
    width: 46px; height: 46px;
    margin: 0 auto var(--fl-space-4);
    color: var(--fl-icon-subtle);
}
.fl-empty__title { font-size: 15.5px; font-weight: 600; color: var(--fl-text); margin-bottom: var(--fl-space-2); }
.fl-empty__text { font-size: 13.5px; max-width: 460px; margin: 0 auto var(--fl-space-4); }

/* --------------------------------------------------------------------------
   14. Beschreibungslisten
   -------------------------------------------------------------------------- */

.fl-dl {
    display: grid;
    grid-template-columns: minmax(140px, 190px) 1fr;
    gap: var(--fl-space-3) var(--fl-space-4);
    margin: 0;
    font-size: 14px;
}
.fl-dl dt { color: var(--fl-text-muted); font-size: 13px; font-weight: 550; }
.fl-dl dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
.fl-dl dd.fl-muted { color: var(--fl-text-subtle); }

.fl-dl--stacked { grid-template-columns: 1fr; gap: var(--fl-space-1); }
.fl-dl--stacked dt { margin-top: var(--fl-space-3); }
.fl-dl--stacked dt:first-child { margin-top: 0; }

/* --------------------------------------------------------------------------
   15. Zeitleiste
   -------------------------------------------------------------------------- */

.fl-timeline { list-style: none; margin: 0; padding: 0; position: relative; }

.fl-timeline::before {
    content: "";
    position: absolute;
    left: 7px;
    top: 8px;
    bottom: 8px;
    width: 1px;
    background: var(--fl-border);
}

.fl-timeline__item {
    position: relative;
    padding: 0 0 var(--fl-space-4) var(--fl-space-6);
}
.fl-timeline__item:last-child { padding-bottom: 0; }

.fl-timeline__dot {
    position: absolute;
    left: 3px;
    top: 6px;
    width: 9px; height: 9px;
    border-radius: 50%;
    background: var(--fl-surface);
    border: 2px solid var(--fl-border-strong);
}
.fl-timeline__item--success .fl-timeline__dot { border-color: var(--fl-success); }
.fl-timeline__item--danger  .fl-timeline__dot { border-color: var(--fl-danger); }
.fl-timeline__item--warning .fl-timeline__dot { border-color: var(--fl-warning); }
.fl-timeline__item--primary .fl-timeline__dot { border-color: var(--fl-primary); }

.fl-timeline__title { font-size: 13.5px; font-weight: 550; }
.fl-timeline__meta { font-size: 12px; color: var(--fl-text-muted); }
.fl-timeline__text { font-size: 13px; color: var(--fl-text-muted); margin-top: 2px; }

/* --------------------------------------------------------------------------
   16. Dialoge
   -------------------------------------------------------------------------- */

.fl-modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(12, 22, 36, .5);
    z-index: 100;
    display: grid;
    place-items: center;
    padding: var(--fl-space-4);
    animation: fl-fade-in .12s ease-out;
}
.fl-modal-backdrop[hidden] { display: none; }

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

.fl-modal {
    background: var(--fl-surface);
    border-radius: var(--fl-radius-lg);
    box-shadow: var(--fl-shadow-lg);
    width: min(520px, 100%);
    max-height: calc(100vh - 32px);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.fl-modal--wide { width: min(860px, 100%); }

.fl-modal__header {
    padding: var(--fl-space-5) var(--fl-space-5) var(--fl-space-3);
    display: flex;
    align-items: flex-start;
    gap: var(--fl-space-3);
}
.fl-modal__header h2 { flex: 1; font-size: 16.5px; }
.fl-modal__close {
    border: 0; background: none; cursor: pointer;
    font-size: 20px; line-height: 1;
    color: var(--fl-text-subtle);
    /* Mindestens 24 x 24 px Trefferflaeche (WCAG 2.2, 2.5.8). */
    display: grid;
    place-items: center;
    width: 28px; height: 28px;
    padding: 0;
    border-radius: var(--fl-radius-sm);
}
.fl-modal__close:hover { color: var(--fl-text); }

.fl-modal__body { padding: 0 var(--fl-space-5) var(--fl-space-5); overflow-y: auto; font-size: 14px; }

.fl-modal__footer {
    padding: var(--fl-space-4) var(--fl-space-5);
    border-top: 1px solid var(--fl-border);
    background: var(--fl-surface-muted);
    display: flex;
    justify-content: flex-end;
    gap: var(--fl-space-2);
    flex-wrap: wrap;
}

/* --------------------------------------------------------------------------
   17. Anmeldung
   -------------------------------------------------------------------------- */

.fl-auth {
    min-height: 100vh;
    display: grid;
    place-items: center;
    padding: var(--fl-space-6);
    background:
        radial-gradient(1100px 520px at 50% -12%, #e6edf7 0%, transparent 62%),
        var(--fl-bg);
}

.fl-auth__box { width: min(420px, 100%); }

.fl-auth__brand {
    text-align: center;
    margin-bottom: var(--fl-space-6);
}
.fl-auth__mark {
    width: 46px; height: 46px;
    border-radius: 12px;
    background: linear-gradient(140deg, #3f7fd4, #1f4f8f);
    color: #fff;
    display: grid;
    place-items: center;
    font-weight: 700;
    font-size: 17px;
    margin: 0 auto var(--fl-space-3);
    box-shadow: var(--fl-shadow-md);
}
.fl-auth__title { font-size: 19px; font-weight: 650; }
.fl-auth__subtitle { font-size: 13.5px; color: var(--fl-text-muted); }

.fl-auth__card {
    background: var(--fl-surface);
    border: 1px solid var(--fl-border);
    border-radius: var(--fl-radius-lg);
    box-shadow: var(--fl-shadow-md);
    padding: var(--fl-space-6);
}

.fl-auth__fields { display: flex; flex-direction: column; gap: var(--fl-space-4); }

.fl-auth__footer {
    text-align: center;
    margin-top: var(--fl-space-5);
    font-size: 12.5px;
    color: var(--fl-text-subtle);
}

/* --------------------------------------------------------------------------
   18. Diverses
   -------------------------------------------------------------------------- */

.fl-muted { color: var(--fl-text-muted); }
.fl-subtle { color: var(--fl-text-subtle); }
.fl-small { font-size: 12.5px; }
.fl-mono { font-family: var(--fl-font-mono); font-size: 12.5px; }
.fl-strong { font-weight: 650; }
.fl-nowrap { white-space: nowrap; }
.fl-break { overflow-wrap: anywhere; }
.fl-center { text-align: center; }
.fl-right { text-align: right; }

.fl-stack > * + * { margin-top: var(--fl-space-4); }
.fl-stack--sm > * + * { margin-top: var(--fl-space-2); }
.fl-stack--lg > * + * { margin-top: var(--fl-space-6); }

.fl-row { display: flex; gap: var(--fl-space-3); align-items: center; flex-wrap: wrap; }
.fl-row--between { justify-content: space-between; }
.fl-row--end { justify-content: flex-end; }
.fl-spacer { flex: 1; }

/* --------------------------------------------------------------------------
   Abstaende – ein geschlossener Satz, kein Baukasten

   In den Ansichten standen 139 Abstaende als style-Attribut am Element:
   margin-top:var(--fl-space-4), margin-bottom:var(--fl-space-5) und so fort.
   Jeder einzelne war richtig; zusammen waren sie das Gegenteil eines
   Wertesatzes. Wer den Abstand zwischen Meldung und Inhalt aendern wollte,
   musste ihn an vierunddreissig Stellen suchen.

   Die Ziffern sind mit Absicht dieselben wie in --fl-space-N. Eine zweite
   Skala mit eigenen Namen ("eng", "weit", "knapp") waere eine Uebersetzung,
   die man nachschlagen muss – und beim naechsten Wert schon nicht mehr
   aufgeht.

   Was hier NICHT steht: Abstaende nach links und rechts, Innenabstaende,
   Zwischenraeume. Der Satz ist bewusst geschlossen. Ein senkrechter Abstand
   zwischen zwei Bloecken ist ein Layoutbedarf, den jede Seite hat; alles
   Weitere gehoert an die Klasse des Bauteils. Wo mehrere Bloecke
   untereinander stehen, ist ohnehin .fl-stack das richtige Mittel.
   -------------------------------------------------------------------------- */
.fl-luft-oben-2 { margin-top: var(--fl-space-2); }
.fl-luft-oben-3 { margin-top: var(--fl-space-3); }
.fl-luft-oben-4 { margin-top: var(--fl-space-4); }
.fl-luft-oben-5 { margin-top: var(--fl-space-5); }

.fl-luft-unten-2 { margin-bottom: var(--fl-space-2); }
.fl-luft-unten-3 { margin-bottom: var(--fl-space-3); }
.fl-luft-unten-4 { margin-bottom: var(--fl-space-4); }
.fl-luft-unten-5 { margin-bottom: var(--fl-space-5); }

/*
 * Der Titelblock einer Kartenueberschrift.
 *
 * .fl-card__header ist eine Flexzeile; der Titelblock muss den freien Platz
 * nehmen und schrumpfen duerfen, sonst draengt eine lange Ueberschrift die
 * Schaltflaechen rechts aus der Karte. Das stand neunundzwanzigmal als
 * style="flex:1;min-width:0" am Element – die haeufigste Wiederholung im
 * ganzen Vorlagenbestand.
 */
.fl-card__headline { flex: 1; min-width: 0; }

/*
 * Nebeneinanderstehende Karten sind gleich hoch (align-items: stretch, die
 * Vorgabe bei Grid). Vorher stand hier "start"; die Karten endeten dann auf
 * unterschiedlicher Hoehe, und die Zeile wirkte ausgefranst. Da die Karte
 * selbst eine Flex-Spalte ist, waechst dabei ihr Rumpf – der Fuss bleibt
 * unten und liegt mit dem der Nachbarkarte auf einer Linie.
 */
.fl-grid-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: var(--fl-space-5); }
.fl-grid-detail { display: grid; grid-template-columns: minmax(0, 1fr) minmax(300px, 360px); gap: var(--fl-space-5); align-items: start; }

/*
 * Ein Raster bringt seinen Abstand selbst mit (gap). Ein Geschwisterabstand
 * an einem Kind wirkt dort nicht zwischen Zeilen, sondern INNERHALB der
 * Rasterzelle: Er schiebt das Element nach unten.
 *
 * Genau das tat `.fl-card + .fl-card { margin-top: 20px }` in jedem
 * `.fl-grid-2`. Die zweite Karte sass zwanzig Pixel tiefer als die erste,
 * ihre Oberkanten lagen nicht auf einer Linie, und die Zusage der Regel
 * darueber – nebeneinanderstehende Karten sind gleich hoch – war damit
 * gerade nicht eingeloest. Betroffen waren Konto, Allgemein, E-Mail-Versand,
 * Dienstreiseportal, Import und Statistik.
 *
 * Derselbe Fehler steckte im Portal-Stylesheet in `.dr-reihe`; dort standen
 * Vorname und Nachname deshalb auf verschiedenen Hoehen.
 */
.fl-grid-2 > * + *,
.fl-grid-detail > * + * {
    margin-top: 0;
}

.fl-pre {
    background: var(--fl-surface-sunken);
    border: 1px solid var(--fl-border);
    border-radius: var(--fl-radius-sm);
    padding: var(--fl-space-3) var(--fl-space-4);
    font-family: var(--fl-font-mono);
    font-size: 12.5px;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    margin: 0;
    max-height: 420px;
    overflow-y: auto;
}

.fl-mail-preview {
    background: var(--fl-surface-muted);
    border: 1px solid var(--fl-border);
    border-radius: var(--fl-radius-sm);
    padding: var(--fl-space-4);
    white-space: pre-wrap;
    font-size: 14px;
    line-height: 1.65;
    overflow-wrap: anywhere;
}

/* Fortschrittsbalken fuer Statistiken */
.fl-bar {
    height: 7px;
    background: var(--fl-surface-sunken);
    border-radius: var(--fl-radius-pill);
    overflow: hidden;
    min-width: 60px;
}
.fl-bar__fill { height: 100%; background: var(--fl-primary); border-radius: inherit; }
.fl-bar__fill--success { background: var(--fl-success); }
.fl-bar__fill--warning { background: var(--fl-warning); }
.fl-bar__fill--danger  { background: var(--fl-danger); }

/* Statuspunkt fuer die Systemdiagnose */
.fl-status-dot {
    width: 9px; height: 9px;
    border-radius: 50%;
    display: inline-block;
    flex: 0 0 9px;
    margin-right: 7px;
}
.fl-status-dot--ok    { background: var(--fl-success); }
.fl-status-dot--warn  { background: var(--fl-warning); }
.fl-status-dot--error { background: var(--fl-danger); }
.fl-status-dot--off   { background: var(--fl-text-subtle); }

/* --------------------------------------------------------------------------
   19. Fortschrittsanzeige des Assistenten
   --------------------------------------------------------------------------
   Erwarteter Aufbau:

     <nav class="fl-steps" aria-label="Fortschritt">
       <p class="fl-steps__status">Schritt 3 von 5 · <strong>Reisezeit</strong></p>
       <ol class="fl-steps__list">
         <li class="fl-steps__item fl-steps__item--done">
           <a class="fl-steps__link" href="…">
             <span class="fl-steps__marker" aria-hidden="true">1</span>
             <span class="fl-steps__label">Reise</span>
           </a>
         </li>
         <li class="fl-steps__item fl-steps__item--current" aria-current="step">
           <span class="fl-steps__link">…</span>
         </li>
       </ol>
     </nav>

   Erledigte Schritte tragen ein <a>, offene ein <span>. Ein Schritt, den man
   noch nicht ausgefuellt hat, ist kein Ziel – ein Verweis dorthin waere eine
   Schaltflaeche ohne Wirkung. Deshalb haengt der Zeiger am Elementtyp, nicht
   an einer Klasse.

   Die schmale Fassung ist der Grundzustand, die waagerechte kommt erst ab
   900 px dazu (min-width statt der sonst ueblichen max-width). Grund: In der
   schmalen Fassung sind Nummer und Beschriftung mit der Klammertechnik aus
   .fl-sr-only weggeblendet – sie bleiben damit fuer Bildschirmleser lesbar,
   und die erledigten Schritte behalten einen erreichbaren Verweis. Waere die
   Reihenfolge umgekehrt, muesste jede dieser Eigenschaften zweimal
   zurueckgenommen werden.
   -------------------------------------------------------------------------- */

.fl-steps {
    /* Klebt unter der Kopfzeile: Auf dem Telefon ist der Schrittzaehler die
       einzige Ortsangabe im Assistenten und darf nicht wegscrollen. */
    position: sticky;
    top: var(--fl-header-height);
    z-index: 20;
    background: var(--fl-surface);
    border-bottom: 1px solid var(--fl-border);
    padding: var(--fl-space-3) var(--fl-space-4);
}

.fl-steps__status {
    font-size: 13px;
    font-weight: 550;
    color: var(--fl-text-muted);
    margin: 0 0 var(--fl-space-2);
}
.fl-steps__status strong { color: var(--fl-text); font-weight: 650; }

.fl-steps__list {
    display: flex;
    gap: var(--fl-space-1);
    list-style: none;
    margin: 0;
    padding: 0;
}

.fl-steps__item { flex: 1 1 0; min-width: 0; position: relative; }

/*
 * Fuenf getrennte Segmente, kein durchgehender Balken. Ein Balken mit
 * Fuellstand liest sich als Prozentangabe ("60 % fertig"), und das waere
 * geraten: Wie viel Arbeit ein Schritt macht, weiss die Anwendung nicht.
 * Getrennte Segmente sagen nur, was sie wissen – wie viele Schritte hinter
 * einem liegen.
 */
.fl-steps__link {
    display: block;
    position: relative;
    height: 6px;
    border-radius: var(--fl-radius-pill);
    background: var(--fl-surface-sunken);
}

a.fl-steps__link { text-decoration: none; }
a.fl-steps__link:focus-visible { outline-offset: 4px; }

/*
 * Ein 6 px hohes Segment ist als Verweis nicht zu treffen. Die Trefferflaeche
 * wird deshalb wie beim Filterchip ueber ein unsichtbares Pseudoelement auf
 * 24 px gebracht (WCAG 2.2, 2.5.8) – das aendert nichts am Aussehen und
 * verschiebt nichts im Umbruch.
 */
a.fl-steps__link::after {
    content: "";
    position: absolute;
    left: 0; right: 0;
    top: 50%;
    height: 24px;
    transform: translateY(-50%);
}

/* Nummer und Beschriftung bleiben vorhanden, nur unsichtbar: Ohne sie haette
   der Verweis eines erledigten Schrittes keinen zugaenglichen Namen. */
.fl-steps__marker, .fl-steps__label {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
}

.fl-steps__item--done .fl-steps__link,
.fl-steps__item--current .fl-steps__link { background: var(--fl-primary); }
.fl-steps__item--error .fl-steps__link { background: var(--fl-danger); }

/* 901 px und nicht 900: Die Anwendung zaehlt 900 px zu den schmalen Geraeten
   (siehe Abschnitt 28), dort schaltet auch die Navigation um. */
@media (min-width: 901px) {
    .fl-steps:not(.fl-steps--kompakt) {
        position: static;
        background: none;
        border-bottom: 0;
        padding: 0 0 var(--fl-space-2);
    }

    /* Die Angabe steckt hier in den sichtbaren Beschriftungen und in
       aria-current="step" am laufenden Schritt. */
    .fl-steps:not(.fl-steps--kompakt) .fl-steps__status { display: none; }

    .fl-steps:not(.fl-steps--kompakt) .fl-steps__list { gap: 0; }

    .fl-steps:not(.fl-steps--kompakt) .fl-steps__link {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 6px;
        height: auto;
        padding: var(--fl-space-2) var(--fl-space-1);
        background: none;
        border-radius: var(--fl-radius-sm);
        text-align: center;
    }
    .fl-steps:not(.fl-steps--kompakt) a.fl-steps__link::after { content: none; }

    .fl-steps:not(.fl-steps--kompakt) .fl-steps__marker,
    .fl-steps:not(.fl-steps--kompakt) .fl-steps__label {
        position: static;
        width: auto; height: auto;
        margin: 0;
        overflow: visible;
        clip: auto;
        white-space: normal;
    }

    /* --todo braucht keine eigene Regel: Es ist der Grundzustand. Im Markup
       steht die Klasse trotzdem, damit jeder Schritt seinen Zustand nennt. */
    .fl-steps:not(.fl-steps--kompakt) .fl-steps__marker {
        width: 30px; height: 30px;
        flex: 0 0 30px;
        border-radius: 50%;
        display: grid;
        place-items: center;
        border: 2px solid var(--fl-border-control);
        background: var(--fl-surface);
        color: var(--fl-text-muted);
        font-size: 13px;
        font-weight: 650;
        font-variant-numeric: tabular-nums;
    }

    .fl-steps:not(.fl-steps--kompakt) .fl-steps__label {
        font-size: 12.5px;
        line-height: 1.3;
        color: var(--fl-text-muted);
    }

    /*
     * Verbindungslinie zwischen zwei Kreisen. Sie liegt am Element rechts
     * davon und reicht von der Mitte des Vorgaengers bis kurz vor den eigenen
     * Kreis: -50 % ist die halbe Breite des gleich breiten Nachbarn, 19 px
     * sind Kreisradius plus Rand plus etwas Luft.
     */
    .fl-steps:not(.fl-steps--kompakt) .fl-steps__item + .fl-steps__item::before {
        content: "";
        position: absolute;
        top: 22px;
        left: calc(-50% + 19px);
        right: calc(50% + 19px);
        height: 2px;
        background: var(--fl-border-strong);
    }
    .fl-steps:not(.fl-steps--kompakt) .fl-steps__item--done::before,
    .fl-steps:not(.fl-steps--kompakt) .fl-steps__item--current::before {
        background: var(--fl-primary-border);
    }

    .fl-steps:not(.fl-steps--kompakt) .fl-steps__item--done .fl-steps__marker {
        background: var(--fl-primary-soft);
        border-color: var(--fl-primary-border);
        color: var(--fl-primary);
    }
    .fl-steps:not(.fl-steps--kompakt) .fl-steps__item--done .fl-steps__label { color: var(--fl-text); }

    .fl-steps:not(.fl-steps--kompakt) .fl-steps__item--current .fl-steps__marker {
        background: var(--fl-primary);
        border-color: var(--fl-primary);
        color: var(--fl-text-invert);
    }
    .fl-steps:not(.fl-steps--kompakt) .fl-steps__item--current .fl-steps__label {
        color: var(--fl-text);
        font-weight: 650;
    }

    .fl-steps:not(.fl-steps--kompakt) .fl-steps__item--error .fl-steps__marker {
        background: var(--fl-danger-soft);
        border-color: var(--fl-danger);
        color: var(--fl-danger);
    }
    .fl-steps:not(.fl-steps--kompakt) .fl-steps__item--error .fl-steps__label { color: var(--fl-danger); }

    .fl-steps:not(.fl-steps--kompakt) a.fl-steps__link:hover { text-decoration: none; }
    .fl-steps:not(.fl-steps--kompakt) a.fl-steps__link:hover .fl-steps__label { text-decoration: underline; }
}

/*
 * Dritter Unterscheidungskanal neben Farbe und Stellung. Der zweite Teil des
 * content-Wertes ist der Ersatztext fuer Bildschirmleser – leer, weil die
 * Zustaende schon ueber aria-current und den Schrittzaehler angesagt werden.
 */
.fl-steps__item--done .fl-steps__label::after  { content: " ✓" / ""; }
.fl-steps__item--error .fl-steps__label::after { content: " ⚠" / ""; }

/* --------------------------------------------------------------------------
   20. Auswahlkacheln
   --------------------------------------------------------------------------
   Fuer die wenigen Hauptentscheidungen eines Antrags (Befoerderungsmittel,
   ein- oder mehrtaegig, Beginn an der Wohnung oder an der Dienststelle).
   Aufbau – das <input> steht VOR dem <label>, sonst greift der
   Geschwisterselektor nicht:

     <div class="fl-choice">
       <input type="radio" id="m-bahn" name="mittel" value="bahn">
       <label class="fl-choice__label" for="m-bahn">
         <span class="fl-choice__title">Bahn</span>
         <span class="fl-choice__hint">2. Klasse</span>
       </label>
     </div>
   -------------------------------------------------------------------------- */

.fl-choice-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: var(--fl-space-3);
}

.fl-choice { position: relative; display: flex; }

/*
 * Das Bedienelement wird weggeblendet, nicht ausgeblendet. display: none und
 * visibility: hidden nehmen es aus der Tabulatorreihenfolge – die Kacheln
 * waeren dann nur noch mit der Maus zu bedienen.
 */
.fl-choice input {
    position: absolute;
    width: 1px; height: 1px;
    margin: 0;
    opacity: 0;
    pointer-events: none;
}

.fl-choice__label {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 2px;
    position: relative;
    /* Fingerbreite Trefferflaeche auf dem Telefon. */
    min-height: 44px;
    /* Rechts bleibt Platz fuer das Haekchen des gewaehlten Zustands. Der Platz
       steht immer bereit, sonst spraenge der Text beim Auswaehlen um. */
    padding: 10px 34px 10px 14px;
    border: 1px solid var(--fl-border-control);
    border-radius: var(--fl-radius-sm);
    background: var(--fl-surface);
    cursor: pointer;
    font-size: 14px;
}

.fl-choice__label:hover { background: var(--fl-surface-muted); }

.fl-choice__title { font-weight: 600; }
.fl-choice__hint { font-size: 12.5px; color: var(--fl-text-muted); }

.fl-choice input:checked + .fl-choice__label {
    background: var(--fl-primary-soft);
    border-color: var(--fl-primary);
    /* Zweiter Rahmen nach innen: Der Unterschied ist so auch ohne
       Farbwahrnehmung als staerkere Linie sichtbar. */
    box-shadow: inset 0 0 0 1px var(--fl-primary);
}
.fl-choice input:checked + .fl-choice__label .fl-choice__title { color: var(--fl-primary); }

/* Dritter Kanal: ein Haekchen. Die Kachel darf sich nicht allein durch ihre
   Farbe von den uebrigen unterscheiden. */
.fl-choice input:checked + .fl-choice__label::after {
    content: "✓";
    position: absolute;
    top: 8px;
    right: 11px;
    color: var(--fl-primary);
    font-weight: 700;
    line-height: 1;
}

/*
 * Der Fokus liegt am unsichtbaren Bedienelement und muss an die Kachel
 * weitergereicht werden. Ohne diese Regel gaebe es beim Bedienen mit der
 * Tastatur keine sichtbare Marke – man waehlte blind.
 */
.fl-choice input:focus-visible + .fl-choice__label {
    outline: 2px solid var(--fl-primary);
    outline-offset: 2px;
}

.fl-choice input:disabled + .fl-choice__label {
    background: var(--fl-surface-sunken);
    color: var(--fl-text-muted);
    cursor: not-allowed;
}

/* --------------------------------------------------------------------------
   21. Bedingt eingeblendete Bereiche
   --------------------------------------------------------------------------
   <div class="fl-reveal" data-reveal-when="mittel=pkw">…</div>

   Der Server rendert diese Bereiche IMMER sichtbar. Erst app.js setzt das
   hidden-Attribut. Faellt das Skript aus, steht das ganze Formular offen da
   und laesst sich vollstaendig ausfuellen – der Server prueft ohnehin, welche
   Angaben zur gewaehlten Antwort gehoeren.
   -------------------------------------------------------------------------- */

.fl-reveal {
    /* Der Rand links stellt die Zugehoerigkeit zur Auswahl darueber her.
       Ohne ihn wirkt der eingeblendete Bereich wie ein neuer Abschnitt. */
    border-left: 3px solid var(--fl-primary-border);
    padding-left: var(--fl-space-4);
    margin-top: var(--fl-space-4);
}

/* Ausdruecklich, weil eine spaetere display-Regel die Vorgabe des Browsers
   fuer [hidden] sonst ueberstimmen wuerde. */
.fl-reveal[hidden] { display: none; }

/* --------------------------------------------------------------------------
   22. Wiederholfeldgruppen
   --------------------------------------------------------------------------
   Mitreisende Personen. Der Server rendert die vorhandenen Eintraege plus
   einen leeren Block; damit ist die Gruppe auch ohne Skript benutzbar. app.js
   klont nur zusaetzliche Bloecke.

   Deshalb sind "Hinzufuegen" und "Entfernen" bis zum Setzen von .is-klonbar
   unsichtbar: Eine Schaltflaeche, die ohne JavaScript nichts tut, waere eine
   Scheinfunktion.
   -------------------------------------------------------------------------- */

.fl-repeat { display: flex; flex-direction: column; gap: var(--fl-space-3); }

.fl-repeat__item {
    border: 1px solid var(--fl-border);
    border-radius: var(--fl-radius);
    background: var(--fl-surface-muted);
    padding: var(--fl-space-4);
}

.fl-repeat__head {
    display: flex;
    align-items: center;
    gap: var(--fl-space-2);
    margin-bottom: var(--fl-space-3);
    font-size: 13px;
    font-weight: 650;
}
.fl-repeat__head > :first-child { flex: 1; min-width: 0; }

.fl-repeat__add, .fl-repeat__remove { display: none; }
.fl-repeat.is-klonbar .fl-repeat__add { display: inline-flex; align-self: flex-start; }
.fl-repeat.is-klonbar .fl-repeat__remove { display: inline-flex; }
.fl-repeat.is-klonbar .fl-repeat__add[hidden],
.fl-repeat.is-klonbar .fl-repeat__remove[hidden] { display: none; }

.fl-repeat__remove {
    align-items: center;
    justify-content: center;
    gap: 5px;
    /* Mindestens 24 x 24 px Trefferflaeche (WCAG 2.2, 2.5.8). */
    min-height: 24px;
    padding: 2px 8px;
    border: 1px solid transparent;
    border-radius: var(--fl-radius-sm);
    background: none;
    color: var(--fl-danger);
    font: inherit;
    font-size: 12.5px;
    font-weight: 550;
    cursor: pointer;
}
.fl-repeat__remove:hover { background: var(--fl-danger-soft); border-color: var(--fl-danger-border); }

/* --------------------------------------------------------------------------
   23. Eingabegruppen und Geldbetraege
   -------------------------------------------------------------------------- */

.fl-input-group { display: flex; align-items: stretch; min-width: 0; }
.fl-input-group .fl-input {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
    min-width: 0;
}
/* Der Fokusring des Feldes liegt sonst hinter dem Anhang. */
.fl-input-group .fl-input:focus { position: relative; z-index: 1; }

/*
 * Das Waehrungszeichen steht als Anhang neben dem Feld, nicht im Platzhalter.
 * Ein Platzhalter verschwindet beim Tippen – genau dann, wenn die Einheit
 * gebraucht wird – und Bildschirmleser lesen ihn nicht verlaesslich vor.
 */
.fl-input-affix {
    display: flex;
    align-items: center;
    padding: 0 11px;
    border: 1px solid var(--fl-border-control);
    border-left: 0;
    border-radius: 0 var(--fl-radius-sm) var(--fl-radius-sm) 0;
    background: var(--fl-surface-sunken);
    color: var(--fl-text-muted);
    font-size: 14px;
    white-space: nowrap;
}
.fl-input-group:focus-within .fl-input-affix { border-color: var(--fl-primary); }

/* Betraege werden untereinander gelesen und verglichen: rechtsbuendig und mit
   gleich breiten Ziffern. */
.fl-input--money {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   24. Datum und Uhrzeit
   -------------------------------------------------------------------------- */

/*
 * Datum und Uhrzeit sind EINE Angabe ("Abfahrt am 12.05. um 07:30") und
 * bleiben deshalb bis hinunter zu 360 px nebeneinander. Moeglich wird das
 * ueber min-width: 0 an den Feldern – Flex-Elemente schrumpfen sonst nicht
 * unter ihre Inhaltsbreite und brechen um.
 */
.fl-datetime {
    display: flex;
    flex-wrap: wrap;
    gap: var(--fl-space-2);
    align-items: center;
}
.fl-datetime > .fl-input { min-width: 0; }
.fl-datetime > input[type="date"] { flex: 3 1 0; }
.fl-datetime > input[type="time"] { flex: 2 1 0; }

/* Das "ca."-Haekchen ist eine Ergaenzung, keine dritte Spalte: Es rutscht in
   die naechste Zeile und laesst das Paar zusammen. */
.fl-datetime__approx {
    flex: 0 0 100%;
    font-size: 12.5px;
}

@media (max-width: 360px) {
    /* Statt umzubrechen wird der Innenabstand knapper. */
    .fl-datetime > .fl-input { padding-left: 6px; padding-right: 6px; }
    .fl-datetime { gap: var(--fl-space-1); }
}

/* --------------------------------------------------------------------------
   25. Oeffentlicher Bereich
   --------------------------------------------------------------------------
   Huelle fuer die Seiten ohne Anmeldung: keine Seitenleiste, kein
   Benutzermenue, eine Spalte.
   -------------------------------------------------------------------------- */

.fl-public {
    /* Eigene Kopfzeilenhoehe – hier steht nur der Name der Schule. Der Wert
       ist zugleich der Halt fuer die klebende Fortschrittsanzeige. */
    --fl-header-height: 56px;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    background: var(--fl-bg);
}

/*
 * Der Innenabstand zentriert den Inhalt auf 760 px, ohne dass ein zweites
 * Element noetig waere. Der untere Rand laeuft dabei ueber die volle Breite –
 * mit einem max-width am Element selbst haette er in der Mitte geendet.
 */
.fl-public__header {
    display: flex;
    align-items: center;
    gap: var(--fl-space-3);
    min-height: var(--fl-header-height);
    padding: var(--fl-space-2) max(var(--fl-space-4), calc((100% - 760px) / 2));
    background: var(--fl-surface);
    border-bottom: 1px solid var(--fl-border);
    position: sticky;
    top: 0;
    z-index: 30;
}

.fl-public__main {
    flex: 1;
    width: 100%;
    max-width: 760px;
    margin: 0 auto;
    padding: var(--fl-space-6) var(--fl-space-4);
}

.fl-public__footer {
    width: 100%;
    max-width: 760px;
    margin: 0 auto;
    padding: var(--fl-space-5) var(--fl-space-4) var(--fl-space-8);
    font-size: 12.5px;
    color: var(--fl-text-subtle);
}

/* Steht die Fortschrittsanzeige ausserhalb des Inhaltsbereichs, traegt sie
   dessen Zentrierung selbst. */
.fl-public > .fl-steps {
    padding-left: max(var(--fl-space-4), calc((100% - 760px) / 2));
    padding-right: max(var(--fl-space-4), calc((100% - 760px) / 2));
}

@media (max-width: 720px) {
    .fl-public__main { padding: var(--fl-space-4); }
}

/* --------------------------------------------------------------------------
   26. Schrittfuss des Assistenten
   -------------------------------------------------------------------------- */

/*
 * "Zurueck" links (ghost), "Weiter" rechts (primary), beide gleich breit.
 * Gleiche Breite, weil auf dem Telefon der Daumen und nicht das Auge trifft;
 * die Unterscheidung leisten Beschriftung und Farbe.
 */
.fl-form-actions {
    display: flex;
    align-items: center;
    gap: var(--fl-space-3);
    margin-top: var(--fl-space-6);
}
.fl-form-actions > .fl-btn { flex: 1 1 0; }

@media (max-width: 900px) {
    /*
     * Der Fuss klebt am unteren Rand, damit "Weiter" auf einem langen Schritt
     * nicht erst gesucht werden muss. Bewusst OHNE negative Aussenabstaende:
     * Die wuerden von der Polsterung des umgebenden Behaelters abhaengen und
     * je nach Einbau daneben liegen.
     */
    .fl-form-actions--sticky {
        position: sticky;
        bottom: 0;
        z-index: 20;
        background: var(--fl-surface);
        border-top: 1px solid var(--fl-border);
        margin-top: var(--fl-space-5);
        padding: var(--fl-space-3) 0;
        /* Auf Geraeten mit Gestensteuerung liegt der untere Bildschirmrand
           unter der Systemleiste. */
        padding-bottom: calc(var(--fl-space-3) + env(safe-area-inset-bottom, 0px));
    }
}

/* --------------------------------------------------------------------------
   27. Pruefseite
   -------------------------------------------------------------------------- */

/* "Bearbeiten" im Kartenkopf: fuehrt zurueck in den Schritt, aus dem die
   Angaben stammen. */
.fl-review__edit {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    /* Mindestens 24 x 24 px Trefferflaeche (WCAG 2.2, 2.5.8). */
    min-height: 24px;
    padding: 2px 4px;
    border-radius: var(--fl-radius-sm);
    font-size: 13px;
    font-weight: 600;
    white-space: nowrap;
}

/* Abgeschlossene Vorgaenge werden nicht mehr bearbeitet und treten deshalb
   zurueck – wie beim gleichnamigen Abzeichen. */
.fl-stat--done .fl-stat__value,
.fl-stat--cancelled .fl-stat__value { color: var(--fl-neutral); }
.fl-stat--done .fl-stat__dot,
.fl-stat--cancelled .fl-stat__dot { background: var(--fl-neutral); }

/* --------------------------------------------------------------------------
   28. Reaktionsfaehiges Verhalten
   -------------------------------------------------------------------------- */

/*
 * Die zweite Spalte faellt erst unter 62rem weg, nicht schon unter 1100px.
 *
 * Gemessener toter Winkel: Zwischen 901 und 1100 Pixeln stand die feste
 * 248-px-Leiste UND das einspaltige Raster. Die Inhaltsspalte war damit
 * 776 bis 852 Pixel breit – bei 900 Pixeln Fensterbreite klappte die Leiste
 * weg und die Spalte sprang auf 900. Ein breiteres Fenster ergab also die
 * schmalere Spalte und die laengere Seite: /dienstreisen/{id} war bei 1024
 * Pixeln hoeher als bei 900.
 *
 * 62rem (992px) ist die Grenze, unterhalb derer 300 Pixel Seitenspalte plus
 * Inhalt tatsaechlich nicht mehr nebeneinander passen.
 */
@media (max-width: 61.99rem) {
    .fl-grid-detail { grid-template-columns: 1fr; }
}

/* Zwischen 60 und 80 rem ist die volle Seitenleiste zu teuer: Sie nimmt der
   Inhaltsspalte ein Viertel der Breite, ohne selbst mehr zu zeigen. */
@media (min-width: 60rem) and (max-width: 80rem) {
    :root { --fl-sidebar-width: 13rem; }
}

@media (max-width: 900px) {
    .fl-app { grid-template-columns: 1fr; }

    /* Eingeklappte Seitenleiste.
       Neben dem Verschieben wird sie mit visibility ausgeblendet. Ohne das
       blieben ihre Verweise fokussierbar: Der Tabulator wanderte in acht
       unsichtbare Links ausserhalb des Bildschirms, und wer ohne Maus
       arbeitet, verlor die Orientierung vollstaendig. */
    .fl-sidebar {
        position: fixed;
        inset: 0 auto 0 0;
        width: var(--fl-sidebar-width);
        transform: translateX(-100%);
        visibility: hidden;
        transition: transform .18s ease, visibility 0s linear .18s;
        z-index: 90;
        box-shadow: var(--fl-shadow-lg);
    }
    .fl-sidebar.is-open {
        transform: none;
        visibility: visible;
        transition: transform .18s ease, visibility 0s;
    }

    .fl-menu-toggle {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 36px; height: 36px;
        border: 1px solid var(--fl-border-control);
        border-radius: var(--fl-radius-sm);
        background: var(--fl-surface);
        cursor: pointer;
        color: var(--fl-text);
    }

    .fl-scrim {
        position: fixed;
        inset: 0;
        background: rgba(12, 22, 36, .4);
        z-index: 80;
    }
    .fl-scrim[hidden] { display: none; }

    .fl-content { padding: var(--fl-space-4); }
    .fl-header { padding: 0 var(--fl-space-4); }

    /*
     * Tabellen werden zu Karten umgebrochen; die Spaltenbezeichnung kommt aus
     * dem data-label-Attribut.
     *
     * Die Grenze liegt bewusst bei 900 px und nicht bei 720 px: Ein iPad
     * hochkant hat 768 px, ein kleineres Tablet 800 px. Bei 720 px blieben
     * die neunspaltige Antragsliste und die Lehrkraeftliste dort Tabellen,
     * die man seitlich schieben muesste – die Spalten "ELTIS", "FB im
     * Schuljahr" und die Schaltflaeche "Oeffnen" lagen ausserhalb des
     * Sichtbereichs. 900 px ist zugleich die Grenze, an der die Navigation
     * ohnehin umschaltet.
     */
    .fl-table--stack thead { display: none; }
    .fl-table--stack tbody tr {
        display: block;
        border-bottom: 1px solid var(--fl-border);
        padding: var(--fl-space-3) var(--fl-space-4);
    }
    .fl-table--stack tbody tr:hover { background: none; }
    .fl-table--stack tbody td {
        display: flex;
        gap: var(--fl-space-3);
        border: 0;
        padding: 3px 0;
        align-items: baseline;
    }
    .fl-table--stack tbody td[data-label]::before {
        content: attr(data-label);
        flex: 0 0 108px;
        font-size: 12px;
        color: var(--fl-text-muted);
        font-weight: 550;
    }
    /* Zellen ohne Bezeichnung (Aktionsspalte) brauchen keinen Einzug – sonst
       stuende dort eine leere Flaeche von 108 px. */
    .fl-table--stack tbody td:not([data-label]) { padding-left: 0; }
    .fl-table--stack tbody td:empty { display: none; }
    .fl-table--stack .fl-cell-title { max-width: none; white-space: normal; }
    .fl-table--stack .fl-table__actions { text-align: left; padding-top: var(--fl-space-2); }

    /* ----------------------------------------------------------------------
       Listenkarte

       --stack stellt jede Zelle als "Bezeichnung: Wert" untereinander. Bei
       neun Spalten wurde eine einzige Zeile damit 473 Pixel hoch; fuenfund-
       zwanzig Eintraege ergaben ein Dokument von 11 800 Pixeln. Man las
       neunmal dieselbe Bezeichnung und einmal den Namen.

       --liste ordnet stattdessen an, was ohnehin zusammengehoert: Name und
       Status in einer Zeile, darunter Zeitraum, darunter der Inhalt. Die
       gezeichneten Bezeichnungen entfallen – "Wollmann, Anke" braucht kein
       "Antragsteller" davor.

       ACHTUNG, hier stand einmal das Gegenteil: "Fuer Vorlesehilfen bleiben
       sie ueber das data-label der Zelle erhalten." Das ist falsch – KEIN
       Screenreader liest data-*-Attribute. Zusammen mit display:none am
       thead und den aufgeloesten Tabellenrollen (grid/block) blieben fuenf
       unbeschriftete Textbloecke uebrig; vorgelesen wurde "Wollmann, Anke –
       DR-26/27-0001 – 14.10.2026 – Magdeburg – Fachtagung – Genehmigt",
       ohne dass das letzte Wort als Status erkennbar war.

       Die Zuordnung liefert jetzt sichtbarer Text, der nur nicht gezeichnet
       wird: .fl-sr-only in der Zelle, dort wo der Bezug ohne ihn fehlt.
       Optisch aendert das nichts.

       Die Schaltflaeche "Oeffnen" faellt weg: Die ganze Karte ist Ziel, und
       der Name bleibt ein echter Verweis fuer den Fall ohne JavaScript.
       ---------------------------------------------------------------------- */
    .fl-table--liste thead { display: none; }
    .fl-table--liste tbody tr {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto;
        gap: 2px var(--fl-space-3);
        align-items: baseline;
        padding: var(--fl-space-4);
        border-bottom: 1px solid var(--fl-border);
    }
    .fl-table--liste tbody td {
        display: block;
        border: 0;
        padding: 0;
        min-width: 0;
    }
    .fl-table--liste tbody td[data-label]::before { content: none; }

    .fl-table--liste .fl-zelle--haupt   { grid-column: 1; grid-row: 1; }
    .fl-table--liste .fl-zelle--status  { grid-column: 2; grid-row: 1; justify-self: end; }
    .fl-table--liste .fl-zelle--zeit    { grid-column: 1 / -1; grid-row: 2; }
    .fl-table--liste .fl-zelle--inhalt  { grid-column: 1 / -1; grid-row: 3; }

    .fl-table--liste .fl-table__actions { display: none; }
    /*
     * Der feste Deckel von 340 px faellt weg – in einer Karte von 350 px
     * Breite schnitte er frueher ab als die Zelle. .fl-cell-title behaelt
     * dabei nowrap und Auslassungspunkte: eine Zeile, sauber abgeschnitten,
     * statt drei Zeilen Umbruch in einer kompakten Karte. Der Prozentwert
     * bindet die Breite an die Rasterzelle, die min-width: 0 traegt.
     */
    .fl-table--liste .fl-cell-title { max-width: 100%; }
    .fl-table--liste .fl-avatar { display: none; }
}

/* Die Reise steht bevor und der Antrag ist unentschieden – die einzige Stelle
   in einer Liste, an der eine Farbe eine Aufgabe benennt statt eines Zustands.
   Deshalb warnfarben und halbfett, und deshalb nur hier. */
.fl-dringend { color: var(--fl-warning); font-weight: 600; }

/* --------------------------------------------------------------------------
   Aufklappbarer Block

   Dasselbe Mittel wie im Portal und aus demselben Grund: <details> braucht
   kein JavaScript, der Browser bringt Tastaturbedienung und Vorlesetext mit,
   und moderne Browser klappen von sich auf, wenn die Seitensuche etwas darin
   findet. Ein Bereich, den nur ein Skript oeffnet, waere ohne Skript
   entweder dauerhaft zu oder dauerhaft offen.
   -------------------------------------------------------------------------- */
.fl-details { margin-top: var(--fl-space-5); }

.fl-details__frage {
    display: flex;
    align-items: center;
    gap: var(--fl-space-2);
    padding: var(--fl-space-3) var(--fl-space-4);
    background: var(--fl-surface);
    border: 1px solid var(--fl-border);
    border-radius: var(--fl-radius);
    cursor: pointer;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--fl-text-muted);
    list-style: none;
}
.fl-details__frage::-webkit-details-marker { display: none; }

.fl-details__frage::before {
    content: "";
    width: 7px;
    height: 7px;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    transform: rotate(-45deg);
    transition: transform var(--fl-transition, .12s) ease;
}
.fl-details[open] > .fl-details__frage::before { transform: rotate(45deg); }

.fl-details__frage:hover { color: var(--fl-text); border-color: var(--fl-border-strong); }
.fl-details__frage:focus-visible { outline: 2px solid var(--fl-primary); outline-offset: 2px; }

/* Die Karten im Inneren bringen ihren eigenen Abstand mit; hier fehlt nur die
   Luft zur Zusammenfassung darueber. */
.fl-details__inhalt { margin-top: var(--fl-space-4); }

@media (max-width: 720px) {
    body { font-size: 14.5px; }

    .fl-stats { grid-template-columns: repeat(2, 1fr); gap: var(--fl-space-3); }
    .fl-stat { padding: var(--fl-space-3) var(--fl-space-4); }
    .fl-stat__value { font-size: 23px; }

    /*
     * Auf dem Telefon drei nebeneinander statt zwei, und ohne die Zeile
     * "alle Schuljahre" darunter: Sechs Karten in drei Reihen waren 307 Pixel
     * hoch – fast ein halber Bildschirm, bevor der erste Eintrag kam. Die
     * Schuljahresangabe steht ohnehin im Filter direkt darunter.
     */
    @media (max-width: 34rem) {
        .fl-stats { grid-template-columns: repeat(3, 1fr); }
        .fl-stat { padding: var(--fl-space-2) var(--fl-space-3); }
        .fl-stat__value { font-size: 20px; }
        .fl-stat__meta { display: none; }
    }

    .fl-dl { grid-template-columns: 1fr; gap: var(--fl-space-1); }
    .fl-dl dt { margin-top: var(--fl-space-3); }
    .fl-dl dt:first-child { margin-top: 0; }

    .fl-card__body { padding: var(--fl-space-4); }
    .fl-card__header { padding: var(--fl-space-4); }

    .fl-filters__row { flex-direction: column; align-items: stretch; }
    .fl-filters__field { min-width: 0; width: 100%; }

    /*
     * In der Spaltenrichtung wirkt flex-basis als HOEHE, nicht als Breite.
     * Das Suchfeld trug flex: 1 1 260px und wuchs deshalb, sobald die Zeile
     * umbrach, auf 260 Pixel Hoehe: Gemessen bei 390 Pixeln Fensterbreite war
     * die erste Filterzeile 455 Pixel hoch, die Filterleiste zusammen bis zu
     * 878 – zwei Bildschirmhoehen, bevor der erste Eintrag kam.
     */
    .fl-filters__field--search { flex: 0 0 auto; }

    .fl-pagination { flex-direction: column; align-items: stretch; gap: var(--fl-space-3); }
    .fl-pagination__pages { justify-content: center; }

    .fl-toasts { right: var(--fl-space-3); left: var(--fl-space-3); bottom: var(--fl-space-3); max-width: none; }

    .fl-header__subtitle { display: none; }
    .fl-usermenu__name { display: none; }

    /* Bei sehr schmalen Bildschirmen steht die Spaltenbezeichnung ueber dem
       Wert statt daneben – 108 px Einzug waeren hier zu viel. */
    .fl-table--stack tbody td { flex-direction: column; gap: 0; align-items: stretch; }
    .fl-table--stack tbody td[data-label]::before { flex: none; }
}

/* --------------------------------------------------------------------------
   29. Druck
   -------------------------------------------------------------------------- */

@media print {
    .fl-sidebar, .fl-header, .fl-toasts, .fl-page-actions,
    .fl-pagination, .fl-filters, .fl-scrim,
    /* Bedienung des Assistenten: auf Papier ohne Wirkung. */
    .fl-steps, .fl-form-actions, .fl-repeat__add, .fl-repeat__remove,
    .fl-review__edit { display: none !important; }

    .fl-app { display: block; }
    .fl-content { padding: 0; max-width: none; }
    .fl-card { border: 0; box-shadow: none; }
    body { background: #fff; font-size: 11pt; }
    a { color: inherit; text-decoration: none; }
}
