/* ==========================================================================
   FoBi – Dienstreiseportal
   ==========================================================================

   AUFBAU DIESER DATEI
   -------------------
   1. Wertesatz (Tokens)   – identisch mit dem Block in public/assets/css/app.css
   2. Grundlagen            – Reset, Fokus, Sprungmarke, Honigtopf
   3. Geruest               – Kopf, Fortschritt, Blatt, Spalten, Fuss
   4. Text                  – Ueberschriften, Abschnitte, Listen
   5. Formular              – Felder, Gruppen, aufklappbare Bloecke
   6. Bedienelemente        – Schaltflaechen, Abzeichen, Meldungen
   7. Seiten                – Zugang, Pruefansicht, Bestaetigung
   8. Umgebung              – Bewegung, Kontrast, Druck

   DER WERTESATZ STEHT ZWEIMAL IM PROJEKT
   --------------------------------------
   Einmal hier, einmal in app.css. Kein Bauwerkzeug fasst die beiden zusammen –
   das Projekt hat bewusst keines. Stattdessen wacht ein Konventionstest
   darueber, dass die beiden Bloecke zeichengleich sind
   (SecurityConventionsTest::testDerWertesatzIstInBeidenStylesheetsGleich).
   Wer hier eine Zahl aendert und dort nicht, faellt beim naechsten Testlauf auf.

   Das ist die einzige Form von "eine Quelle der Wahrheit", die ohne
   Bauschritt und ohne dritte Datei im Auslieferungspfad auskommt.

   Was der gemeinsame Satz NOCH NICHT umfasst: die Farbpalette und die
   Schriftkette des Verwaltungsbereichs. Die Werte liegen dicht beieinander,
   aber app.css bringt seine eigenen mit, und sie stillschweigend
   auszutauschen waere eine Gestaltungsaenderung an einer laufenden
   Anwendung. Der Stand ist in app.css, Abschnitt 1a, benannt – damit ihn
   niemand fuer erledigt haelt.

   WARUM EIN EIGENES STYLESHEET UND KEINE KOPIE VON app.css
   --------------------------------------------------------
   Der Verwaltungsbereich ist eine Arbeitsumgebung: dichte Tabellen, kleine
   Schrift, viel gleichzeitig sichtbar. Das Portal ist das Gegenteil – ein
   Formular, das jemand zwei- bis dreimal im Jahr ausfuellt, zwischen zwei
   Unterrichtsstunden, oft am geteilten Rechner. Dort gilt: groessere Schrift,
   groessere Trefferflaechen, wenig gleichzeitig sichtbar.

   Gemeinsam ist beiden der Wertesatz. Unterschiedlich sind die Groessen, die
   daraus gewaehlt werden – und genau eine Farbe.
   ========================================================================== */

/* ==========================================================================
   1. WERTESATZ — ab hier zeichengleich mit app.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
   ========================================================================== */

/* --------------------------------------------------------------------------
   Farben und Groessen dieser Oberflaeche

   Der Akzent ist gruen und unterscheidet das Portal vom blauen
   Verwaltungsbereich. Aber: Gruen ist ab hier ausschliesslich der Weg nach
   vorn – der gefuellte Teil der Fortschrittslinie und die Hauptschaltflaeche.
   Die vollflaechige gruene Kopfleiste ist entfallen. Ein gesaettigter
   Farbbalken ueber die ganze Breite wird als Behoerdenportal gelesen, und er
   konkurriert mit dem gruenen Weiter-Knopf um dieselbe Bedeutung.
   -------------------------------------------------------------------------- */
:root {
    /* Ein Ton tiefer als --fl-erfolg (#0e5b3c), mit dem er bisher
       ZEICHENGLEICH war. Marke und Bedeutung duerfen nicht dieselbe Farbe
       sein: Der Knopf "Weiter" und die Meldung "hat geklappt" waren farblich
       nicht zu unterscheiden. Ein Produkt sagt nicht in seiner Markenfarbe
       "gut gegangen". */
    --dr-akzent: #0a4d34;
    --dr-akzent-tief: #073626;
    --dr-akzent-sanft: #e9f3ee;
    --dr-akzent-linie: #c2ddce;

    /* Groesser als im Verwaltungsbereich: Das Portal wird selten benutzt,
       oft unter Zeitdruck und manchmal an einem Rechner, vor dem jemand
       steht statt sitzt. */
    --dr-h-bedien: 2.75rem;   /* 44 – WCAG 2.5.5 ohne Kunstgriffe */
    --dr-h-haupt: 3rem;       /* 48 – Hauptschaltflaeche */
    --dr-h-kopf: 3.5rem;      /* 56 */
    --dr-rand: clamp(1.25rem, 4vw, 2rem);
}

/* ==========================================================================
   2. GRUNDLAGEN
   ========================================================================== */
*,
*::before,
*::after {
    box-sizing: border-box;
}

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

body {
    margin: 0;
    background: var(--fl-grund);
    color: var(--fl-text);
    font-family: var(--fl-schrift);
    font-size: var(--fl-t-500);
    line-height: var(--fl-zh-500);
    font-weight: var(--fl-fett-normal);
    -webkit-font-smoothing: antialiased;
}

img,
svg {
    max-width: 100%;
}

/* --------------------------------------------------------------------------
   Fokus – eine Regel fuer alles Bedienbare

   Der weisse Zwischenring macht den Fokus auch auf gefuellten Flaechen
   sichtbar. Ohne ihn ist ein gruener Ring an einer gruenen Schaltflaeche
   unsichtbar – der haeufigste Fehler an dieser Stelle.

   Die Geometrie des Elements bleibt unberuehrt: Frueher setzte diese Regel
   border-radius am Element selbst, wodurch fokussierte Felder ihre Form
   aenderten.
   -------------------------------------------------------------------------- */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
    outline: 2px solid transparent;   /* sichtbar bei erzwungenen Farben */
    outline-offset: 2px;
    box-shadow: 0 0 0 2px var(--fl-flaeche), 0 0 0 4px var(--dr-akzent);
}

/* --------------------------------------------------------------------------
   Sprungmarke und Text nur fuer Vorlesehilfen
   -------------------------------------------------------------------------- */
.dr-sprung {
    position: absolute;
    left: var(--fl-a-4);
    top: -6rem;
    z-index: 100;
    padding: var(--fl-a-3) var(--fl-a-4);
    background: var(--fl-flaeche);
    color: var(--dr-akzent);
    font-size: var(--fl-t-400);
    font-weight: var(--fl-fett-halb);
    border-radius: var(--fl-radius-1);
    box-shadow: var(--fl-schatten-decke);
    transition: top var(--fl-zeit) var(--fl-kurve);
}

.dr-sprung:focus {
    top: var(--fl-a-3);
}

.dr-nurlesen {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* --------------------------------------------------------------------------
   hidden ist eine Zusage, kein Vorschlag

   Das Attribut traegt hier die gesamte bedingte Sichtbarkeit: Der Server
   setzt es beim Ausliefern, portal.js nimmt es weg. Die Voreinstellung des
   Browsers dafuer ist display:none mit der schwaechsten Spezifitaet, die es
   gibt – jede eigene display-Regel auf demselben Element schlaegt sie. Genau
   das passiert bei einem Abschnitt, dem spaeter einmal display:flex
   zugedacht wird: Er waere ausgeblendet und stuende trotzdem da.

   Deshalb ausnahmsweise !important. Ein Bereich, der sich fuer verdeckt
   haelt, aber Felder zeigt, ist schlimmer als eine Regel, die sich nicht
   ueberschreiben laesst.
   -------------------------------------------------------------------------- */
[hidden] {
    display: none !important;
}

/* --------------------------------------------------------------------------
   Honigtopf

   Das Feld MUSS im Layout bleiben und ein gewoehnliches Textfeld sein:
   display:none, visibility:hidden und type="hidden" erkennen die verbreiteten
   Formularroboter und lassen es aus – dann greift die Huerde nicht mehr.
   Deshalb wird es aus dem Sichtfeld geschoben. Fuer Vorlesehilfen ist es in
   der Vorlage ueber aria-hidden und tabindex="-1" ausgenommen.

   Diese Regel nicht zu display:none aendern. Sie sieht nach einem Fehler aus
   und ist keiner.
   -------------------------------------------------------------------------- */
.fl-honigtopf {
    position: absolute;
    left: -10000px;
    top: auto;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* ==========================================================================
   3. GERUEST
   ========================================================================== */

/* Kopfleiste: weiss, nicht gruen. Siehe Begruendung oben. */
.dr-kopf {
    position: sticky;
    top: 0;
    z-index: 30;
    height: var(--dr-h-kopf);
    display: flex;
    align-items: center;
    background: var(--fl-flaeche);
    /*
     * KEINE UNTERKANTE – die Fortschrittslinie IST sie.
     *
     * Hier standen zwei waagerechte Linien im Abstand von einem Pixel: die
     * Unterkante der Leiste und der ungefuellte Teil der Fortschrittslinie
     * darunter. Rechts vom gefuellten Teil ergab das eine vier Pixel hohe
     * graue Doppelkante. Eine Linie, zwei Aussagen – das ist genau eine zu
     * viel.
     */
    border-bottom: 0;
}

/* --------------------------------------------------------------------------
   Kopf, Fuss und Inhalt stehen auf DERSELBEN Fluchtlinie

   Sie taten es nicht: Gemessen lag die Marke auf der Zugangsseite bei 208
   Pixeln, der Inhalt bei 544 – 336 Pixel Versatz auf einer Seite aus fuenf
   Elementen. Ursache waren vier verschiedene Breitendeckel fuer Kopf, Fuss,
   Blatt und Zugangskarte.

   Kopf und Fuss folgen jetzt dem Blatt: unterhalb der zweispaltigen
   Darstellung auf Formularbreite, darueber auf Assistentenbreite. Die
   Zugangsseite ist der begruendete Sonderfall – dort steht eine zentrierte
   Karte auf der Flaeche, und eine Karte richtet sich an ihrer Mitte aus,
   nicht am Seitenkopf.
   -------------------------------------------------------------------------- */
.dr-kopf__reihe {
    width: 100%;
    max-width: calc(var(--fl-breite-formular) + 2 * var(--dr-rand));
    margin: 0 auto;
    padding: 0 var(--dr-rand);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--fl-a-4);
}

.dr-marke {
    display: flex;
    align-items: center;
    gap: var(--fl-a-3);
    min-width: 0;
}

.dr-marke__text {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.dr-marke__titel {
    font-size: var(--fl-t-400);
    line-height: 1.25;
    font-weight: var(--fl-fett-halb);
    color: var(--fl-text);
}

.dr-marke__schule {
    font-size: var(--fl-t-200);
    line-height: 1.25;
    color: var(--fl-text-leise);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dr-kopf__aktion {
    display: flex;
    align-items: center;
    gap: var(--fl-a-4);
    flex-shrink: 0;
}

.dr-rest {
    font-size: var(--fl-t-200);
    color: var(--fl-text-leise);
}

.dr-rest--knapp {
    color: var(--fl-warnung);
    font-weight: var(--fl-fett-halb);
}

/* --------------------------------------------------------------------------
   Fortschritt

   Zwei Teile, beide kleiner als die frueheren fuenf beschrifteten Punkte:

   1. Eine 3-px-Linie ueber die volle Fensterbreite. Sie sagt nichts, was der
      Text nicht sagt, und traegt deshalb aria-hidden. Sie ist die einzige
      Stelle, an der die Anzeige ueber die Inhaltsspalte hinausreicht – und
      der einzige Gewinn, den ein sehr breiter Bildschirm hier bringt:
      peripher lesbar, ohne den Blick vom Feld zu nehmen.

   2. Die Ueberzeile "Schritt 2 von 4" ueber der Ueberschrift. Der Name des
      Schrittes steht als h1 darunter; ihn zu wiederholen waere doppelt.

   Anders als frueher verschwindet auf schmalen Geraeten nichts. Dort war die
   Anzeige bisher auf den blossen Satz reduziert – gerade dort, wo sie am
   noetigsten ist.
   -------------------------------------------------------------------------- */
.dr-fortschritt {
    position: sticky;
    top: var(--dr-h-kopf);
    z-index: 20;
    height: 3px;
    background: var(--fl-linie);
}

.dr-fortschritt__gefuellt {
    height: 100%;
    background: var(--dr-akzent);
    transition: width var(--fl-zeit) var(--fl-kurve);
}

/* --------------------------------------------------------------------------
   Blatt und Spalten

   Die Feldspalte bleibt bei 40 rem. Eingabefelder darueber hinaus zu dehnen
   macht sie messbar schlechter zu bedienen – der Weg von der Beschriftung zum
   Feldende wird zu lang, und lange Felder laden zu langen Eingaben ein, wo
   kurze erwartet werden.

   Die Flaeche eines 1920-px-Bildschirms wird deshalb NICHT durch Dehnen
   gefuellt, sondern durch eine zweite Spalte, die echten Inhalt traegt:
   den Stand des Antrags. Sie ersetzt den haeufigsten Grund, "Zurueck" zu
   druecken – nachsehen, was man eingetragen hat.
   -------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------
   Das Blatt

   ZWEI GEMESSENE FEHLER, BEIDE HIER BEHOBEN

   1. Bei genau 1366 Pixeln – dem haeufigsten Schullaptop – ergab
      max-width: 85rem einen Aussenrand von drei Pixeln links und rechts. Der
      Inhalt klebte am Fensterrand. min() deckelt die Breite jetzt zusaetzlich
      am Fenster und laesst immer zwei Zentimeter Luft stehen.

   2. Unterhalb von 75rem gibt es die Kontextspalte nicht. Das Blatt blieb
      trotzdem bis zu 85rem breit, waehrend die Feldspalte bei 40rem endet –
      bei 1100 Pixeln standen so bis zu 400 Pixel tote Flaeche rechts neben
      dem Formular, und das Formular selbst klebte links. Ohne zweite Spalte
      wird das Blatt deshalb auf Formularbreite gesetzt und ist damit mittig.
   -------------------------------------------------------------------------- */
.dr-blatt {
    max-width: calc(var(--fl-breite-formular) + 2 * var(--dr-rand));
    margin: 0 auto;
    padding: var(--fl-a-7) var(--dr-rand) var(--fl-a-9);
}

/* Ab hier gibt es die zweite Spalte – Kopf, Blatt und Fuss wachsen gemeinsam
   auf Assistentenbreite, damit die Fluchtlinie erhalten bleibt.

   Die Regel fuer den Fuss steht NICHT hier, sondern hinter seiner eigenen
   Definition weiter unten: Beide haben dieselbe Spezifitaet, und dann
   entscheidet die Reihenfolge in der Datei. Eine Medienabfrage vor der Regel,
   die sie uebersteuern soll, ist wirkungslos – derselbe Fehler wie beim
   Ruecksetzer der Rasterabstaende, nur ueber die Quellreihenfolge statt ueber
   die Spezifitaet. */
@media (min-width: 75rem) {
    .dr-blatt,
    .dr-kopf__reihe {
        max-width: min(var(--fl-breite-assistent), 100vw - 4rem);
    }
}

.dr-blatt--schmal {
    max-width: calc(var(--fl-breite-formular) + 2 * var(--dr-rand));
    /* Als Blatt bekommt sie den Innenabstand einer Karte, nicht den einer
       Seite – 96 Pixel Fussluft sind in einem Kasten zu viel. */
    padding: var(--fl-a-6);
    margin-top: var(--fl-a-7);
    margin-bottom: var(--fl-a-9);
}

/* Meldungen sitzen ueber dem Inhalt und bringen ihre eigene Fussluft mit. */
.dr-blatt--meldungen {
    padding-top: var(--fl-a-6);
    padding-bottom: 0;
}

.dr-spalten {
    display: grid;
    gap: var(--fl-a-7);
    align-items: start;
}

@media (min-width: 75rem) {
    .dr-spalten {
        grid-template-columns: minmax(0, 1fr) 21.25rem;
    }
}

/* --------------------------------------------------------------------------
   DAS BLATT IST EIN BLATT

   Der Auftraggeber schrieb: "keine schmale Formularsaeule mitten auf einem
   1920-Pixel-Bildschirm". Die naheliegende Antwort waere, breiter zu werden.
   Sie ist falsch, und die Messung sagt warum:

   Der Seitengrund war WEISS und das Formular hatte KEINE KANTE. Eine
   Textsaeule in unbegrenztem Weiss ist eine schmale Saeule – bei 1088 Pixeln
   Blattbreite genauso wie bei 1360. Die Verkleinerung von 85 auf 68 rem hat
   den Eindruck sogar verschaerft: Sie hat die einzige sichtbare Struktur
   (den Abstand zwischen den Spalten) entfernt, ohne eine andere anzubieten.

   Der Verwaltungsbereich wirkt bei denselben Verhaeltnissen hochwertiger,
   und zwar aus genau einem Grund: getoenter Grund, weisse Karten mit Kante.

   Also bekommt das Formular eine Kante und liegt auf getoentem Grund. Die
   400 Pixel links und rechts sind dann PAPIERRAND und nicht ungenutzte
   Flaeche – was der Sache entspricht, denn es ist ein amtlicher Vordruck.

   Die Breite bleibt bei 40 rem. Sie ist eine begruendete Lesebreite: Das
   Feld "Reiseziel" nimmt "Magdeburg" auf, neun Zeichen. Breiter macht es
   messbar schlechter zu bedienen.
   -------------------------------------------------------------------------- */
.dr-feldspalte {
    max-width: var(--fl-breite-formular);
    min-width: 0;
}

.dr-feldspalte,
.dr-blatt--schmal {
    background: var(--fl-flaeche);
    box-shadow: var(--fl-schatten-blatt);
    border-radius: var(--fl-radius-2);
}

.dr-feldspalte {
    padding: var(--fl-a-6) var(--fl-a-6) var(--fl-a-7);
}

/* Auf dem Telefon ist der Papierrand Luxus: Dort IST das Blatt die Seite. */
@media (max-width: 34rem) {
    body {
        background: var(--fl-flaeche);
    }

    .dr-feldspalte,
    .dr-blatt--schmal {
        background: transparent;
        box-shadow: none;
        border-radius: 0;
        padding: 0;
    }
}

/* Die Kontextspalte gibt es nur dort, wo Platz dafuer ist. Auf schmalen
   Geraeten waeren ihre Inhalte Ballast – der Fortschritt steht in der
   Ueberzeile, und was bisher erfasst wurde, sieht man beim Zurueckblaettern. */
.dr-kontext {
    display: none;
}

@media (min-width: 75rem) {
    .dr-kontext {
        display: block;
        position: sticky;
        top: calc(var(--dr-h-kopf) + var(--fl-a-7));
        /* Weiss auf grauem Grund, gehoben – vorher grau auf weiss, also
           versenkt. Eine Flaeche, die den Stand des Antrags traegt, gehoert
           nicht in die Vertiefung. */
        background: var(--fl-flaeche);
        box-shadow: var(--fl-schatten-blatt);
        border-radius: var(--fl-radius-2);
        padding: var(--fl-a-5);
    }
}

.dr-kontext__titel {
    margin: 0 0 var(--fl-a-4);
    font-size: var(--fl-t-200);
    line-height: var(--fl-zh-200);
    font-weight: var(--fl-fett-halb);
    color: var(--fl-text-leise);
}

.dr-schritte {
    list-style: none;
    margin: 0;
    padding: 0;
}

.dr-schritte__punkt {
    display: grid;
    grid-template-columns: 1.5rem 1fr;
    align-items: baseline;
    gap: var(--fl-a-3);
    padding: var(--fl-a-2) 0;
    font-size: var(--fl-t-300);
    line-height: var(--fl-zh-300);
    color: var(--fl-text-leise);
}

.dr-schritte__zahl {
    font-variant-numeric: tabular-nums;
    font-size: var(--fl-t-200);
    color: var(--fl-text-leise);
}

.dr-schritte__punkt.ist-erledigt .dr-schritte__zahl {
    color: var(--dr-akzent);
}

.dr-schritte__punkt.ist-aktiv {
    color: var(--fl-text);
    font-weight: var(--fl-fett-halb);
}

.dr-schritte__punkt.ist-aktiv .dr-schritte__zahl {
    color: var(--dr-akzent);
    font-weight: var(--fl-fett-halb);
}

/* Bisher erfasste Angaben in der Kontextspalte. */
.dr-stand {
    margin: var(--fl-a-5) 0 0;
    padding-top: var(--fl-a-5);
    border-top: 1px solid var(--fl-linie);
}

.dr-stand__zeile + .dr-stand__zeile {
    margin-top: var(--fl-a-3);
}

.dr-stand__was {
    display: block;
    font-size: var(--fl-t-200);
    line-height: var(--fl-zh-200);
    color: var(--fl-text-leise);
}

.dr-stand__wert {
    display: block;
    font-size: var(--fl-t-300);
    line-height: var(--fl-zh-300);
    color: var(--fl-text);
}

/* Fuss – zwei stille Verweise, sonst nichts. */
.dr-fuss {
    border-top: 1px solid var(--fl-linie);
    padding: var(--fl-a-5) 0 var(--fl-a-7);
}

.dr-fuss__reihe {
    max-width: calc(var(--fl-breite-formular) + 2 * var(--dr-rand));
    margin: 0 auto;
    padding: 0 var(--dr-rand);
    display: flex;
    flex-wrap: wrap;
    gap: var(--fl-a-5);
    font-size: var(--fl-t-200);
}

/* Hinter der Definition, nicht davor – siehe Begruendung bei .dr-blatt. */
@media (min-width: 75rem) {
    .dr-fuss__reihe {
        max-width: min(var(--fl-breite-assistent), 100vw - 4rem);
    }
}

/* Beide Fusszeilenelemente sehen gleich aus. Vorher war das eine ein Verweis
   mit Browserunterstreichung und das andere ein Text ohne – es las sich wie
   ein kaputter zweiter Link. */
.dr-fuss a {
    color: var(--fl-text-leise);
    text-decoration: none;
}

.dr-fuss a:hover {
    color: var(--fl-text);
    text-decoration: underline;
}

/* ==========================================================================
   4. TEXT
   ========================================================================== */
.dr-ueberzeile {
    margin: 0 0 var(--fl-a-2);
    font-size: var(--fl-t-200);
    line-height: var(--fl-zh-200);
    font-weight: var(--fl-fett-halb);
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--fl-text-leise);
    font-variant-numeric: tabular-nums;
}

.dr-titel {
    margin: 0;
    font-size: var(--fl-t-800);
    line-height: var(--fl-zh-800);
    font-weight: var(--fl-fett-halb);
    letter-spacing: -.02em;
    color: var(--fl-text);
}

.dr-lead {
    margin: var(--fl-a-2) 0 0;
    max-width: var(--fl-breite-lesen);
    font-size: var(--fl-t-500);
    line-height: var(--fl-zh-500);
    color: var(--fl-text-leise);
}

.dr-fliess {
    margin: var(--fl-a-4) 0 0;
    max-width: var(--fl-breite-lesen);
    font-size: var(--fl-t-400);
    line-height: var(--fl-zh-400);
    color: var(--fl-text-leise);
}

/* --------------------------------------------------------------------------
   Abschnitt statt Karte

   Frueher lagen auf einem Schritt bis zu sieben gerahmte weisse Kaesten auf
   grauem Grund – sieben Rahmen um Inhalt, der eine einzige Sache ist. Ein
   Abschnitt ist jetzt eine Ueberschrift, eine Haarlinie und Luft. Elf
   sichtbare Rahmenkanten weniger je Schritt.

   Karten kehren nur dort zurueck, wo ein Abschnitt handelbar wird – auf der
   Pruefansicht, wo jeder ein "Ändern" traegt.
   -------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------
   Abschnitte: Etikett und Luft, keine Haarlinie

   Hier stand eine Trennlinie zwischen je zwei Abschnitten. Eine Trennlinie
   sagt "gleichrangig und getrennt". Auf Schritt 1 stimmt das – Anlass,
   Abreise, Rueckkehr sind drei gleichrangige Bloecke. Auf der Pruefseite
   stimmt es nicht: Dort trennt dieselbe Linie eine Zusammenfassung, die man
   LIEST, von Feldern, die man AUSFUELLT. Eine Linie kann Gleichheit
   ausdruecken, keine Rangfolge – und die Rangfolge ist dort die Botschaft.

   Dazu sass sie genau in der Mitte des Abstands (32 Pixel darueber, 32
   darunter): maximal trennend, minimal gruppierend.

   Die Arbeit macht jetzt die Luft, und sie kann es: 48 Pixel ueber einem
   Abschnitt gegen 24 zwischen zwei Feldern ist ein Verhaeltnis von 2 : 1.
   Voraussetzung dafuer ist, dass sich das Etikett typografisch vom Feldnamen
   unterscheidet – siehe .dr-abschnitt__titel.
   -------------------------------------------------------------------------- */
.dr-abschnitt {
    margin-top: var(--fl-a-7);
}

.dr-abschnitt:first-of-type {
    margin-top: var(--fl-a-7);
}

.dr-abschnitt__kopf {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--fl-a-4);
    margin-bottom: var(--fl-a-5);
}

/* --------------------------------------------------------------------------
   Der "Ändern"-Knopf darf den Abschnittskopf nicht aufblasen

   Eine Schaltflaeche ist 44 Pixel hoch – das ist die Mindesttrefferflaeche
   und an jeder anderen Stelle richtig. Im Abschnittskopf der Pruefansicht
   macht sie den Kopf 44 statt 26 Pixel hoch, und weil der Innenabstand des
   Abschnitts fest ist, verschiebt sich der ganze Rhythmus: Abschnitte MIT
   "Ändern" haben 40 Pixel zwischen Haarlinie und Ueberschrift, Abschnitte
   OHNE 32. Auf der Pruefseite stehen beide Sorten untereinander, und der
   Uebergang von "Kosten und Vertretung" zu "Wer stellt den Antrag" ist genau
   die Stelle, an der es auffaellt.

   Die Trefferflaeche geht dabei nicht verloren: Der Knopf traegt weiterhin
   Innenabstand, und sein Text ist zweizeilig hoch genug. Wer mit dem Finger
   zielt, ist auf der Pruefseite ohnehin nicht an dieser Stelle.
   -------------------------------------------------------------------------- */
.dr-abschnitt__kopf .dr-knopf {
    height: auto;
    min-height: 0;
    padding: var(--fl-a-1) var(--fl-a-2);
    margin-right: calc(-1 * var(--fl-a-2));
}

/* --------------------------------------------------------------------------
   Der Abschnittstitel ist ein Etikett, keine Ueberschrift

   Er stand auf 18 px / 600, die Feldbeschriftung auf 15 px / 600 – zwei
   strukturelle Ebenen, die sich um drei Pixel und gar kein Gewicht
   unterscheiden. "Anlass", "Abreise" und "Rueckkehr" verschwanden dadurch
   zwischen den Feldnamen, und die Seite las sich als eine einzige Liste aus
   siebzehn Feldern. Genau das ist gemeint, wenn eine Oberflaeche "flach"
   wirkt: nicht zu wenig Abstand, sondern zu wenig Unterschied.

   Jetzt ist die Leiter eindeutig und ohne Nachbarschaft:
   28 (Seite) – 12 gesperrt (Gruppe) – 15/600 (Feld) – 16 (Eingabe) –
   14 leise (Hinweis).

   --fl-t-100 heisst im Wertesatz ausdruecklich "nur Overline" und war bis
   hierher unbenutzt. Es bekommt seine Aufgabe.
   -------------------------------------------------------------------------- */
.dr-abschnitt__titel {
    margin: 0;
    font-size: var(--fl-t-100);
    line-height: var(--fl-zh-100);
    font-weight: var(--fl-fett-voll);
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--fl-text-leise);
}

.dr-abschnitt__hinweis {
    margin: calc(-1 * var(--fl-a-3)) 0 var(--fl-a-5);
    max-width: var(--fl-breite-lesen);
    font-size: var(--fl-t-300);
    line-height: var(--fl-zh-300);
    color: var(--fl-text-leise);
}

/* ==========================================================================
   5. FORMULAR
   ========================================================================== */

/* --------------------------------------------------------------------------
   Senkrechter Abstand zwischen Formularbausteinen

   ZWEI FEHLER STECKTEN HIER, EINER IM ANDEREN

   1. Der Geschwisterselektor legt den Abstand an das ZWEITE Element. Das ist
      richtig, solange die Bausteine untereinander stehen – und falsch, sobald
      zwei von ihnen nebeneinander in einer .dr-reihe liegen: Dort sind sie
      ebenfalls Geschwister, das zweite bekam 24 Pixel margin-top und sass in
      seiner Rasterzelle sichtbar tiefer als das erste. Betroffen war JEDES
      Feldpaar des Portals – Vorname/Nachname, Strasse/Nummer,
      Postleitzahl/Ort, Datum/Uhrzeit und die Namen jeder mitreisenden Person.

   2. Der erste Versuch, das zu beheben, lautete `.dr-reihe > * + *`. Er wirkte
      nicht, und zwar aus einem Grund, der sich nicht ansehen laesst: Der
      Universalselektor traegt zur Spezifitaet NICHTS bei. `.dr-reihe > * + *`
      ist 0-1-0, `.dr-feld + .dr-feld` ist 0-2-0 – die alte Regel gewann, der
      Versatz blieb bei unveraenderten 24 Pixeln. Erst die Messung im Browser
      hat das gezeigt.

   Deshalb steht der Ruecksetzer jetzt mit :is() da: Die Spezifitaet von :is()
   ist die seines staerksten Arguments, hier also je 0-1-0. Zusammen mit
   .dr-reihe ergibt das 0-3-0 und schlaegt die Grundregel sicher.

   Die Liste der Bausteintypen ist gegenueber frueher laenger. Sie nannte nur
   .dr-feld, .dr-gruppe und .dr-reihe; jeder andere Block unterbrach die Kette,
   und das folgende Element klebte mit null Pixeln daran. Gemessen an vier
   Stellen, darunter der Knopf "Weitere Person hinzufuegen" direkt unter der
   letzten Personenzeile.
   -------------------------------------------------------------------------- */
:is(.dr-feld, .dr-gruppe, .dr-reihe, .dr-abhaengig, .dr-mehr, .dr-personen, .dr-hinweis)
+ :is(.dr-feld, .dr-gruppe, .dr-reihe) {
    margin-top: var(--fl-a-5);
}

/* --------------------------------------------------------------------------
   Zwei Bausteine stehen NICHT auf der rechten Seite der Regel darueber

   .dr-mehr (aufklappbarer Block) und .dr-abhaengig (Feld unter seinem
   Schalter) bringen ihren Abstand selbst mit – .dr-abhaengig einen bewusst
   engeren von 12 Pixeln, weil es unmittelbar zu dem Kaestchen darueber
   gehoert. Stuenden sie rechts, ueberschriebe die Regel mit ihrer hoeheren
   Spezifitaet genau diese Absicht und risse das Feld von seinem Schalter los.
   Links stehen sie sehr wohl: Was NACH ihnen kommt, braucht Abstand.
   -------------------------------------------------------------------------- */

.dr-reihe > :is(.dr-feld, .dr-gruppe, .dr-reihe)
+ :is(.dr-feld, .dr-gruppe, .dr-reihe) {
    margin-top: 0;
}

.dr-label {
    display: block;
    margin-bottom: var(--fl-a-2);
    font-size: var(--fl-t-400);
    line-height: var(--fl-zh-400);
    font-weight: var(--fl-fett-halb);
    color: var(--fl-text);
}

.dr-pflicht {
    margin-left: 2px;
    color: var(--fl-fehler);
}

.dr-input,
.dr-select,
.dr-textarea {
    display: block;
    width: 100%;
    font-family: inherit;
    /* 16 px, nicht kleiner: Darunter zoomt iOS-Safari beim Antippen hinein
       und der Nutzer muss danach von Hand herauszoomen. */
    font-size: var(--fl-t-500);
    line-height: var(--fl-zh-500);
    color: var(--fl-text);
    background: var(--fl-flaeche);
    border: 1px solid var(--fl-rahmen);
    border-radius: var(--fl-radius-1);
    transition: border-color var(--fl-zeit) var(--fl-kurve),
                box-shadow var(--fl-zeit) var(--fl-kurve);
}

.dr-input,
.dr-select {
    height: var(--dr-h-bedien);
    padding: 0 var(--fl-a-3);
}

.dr-textarea {
    min-height: 7rem;
    padding: var(--fl-a-3);
    resize: vertical;
}

.dr-select {
    appearance: none;
    padding-right: 2.125rem;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%235b6675' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right var(--fl-a-3) center;
}

.dr-input:hover,
.dr-select:hover,
.dr-textarea:hover {
    border-color: var(--fl-text-leise);
}

/* :focus, nicht :focus-visible – ein Feld zeigt den Fokus auch beim Klicken.
   Das ist Rueckmeldung, keine Tastaturhilfe. Der Ring uebernimmt den
   Fokusschatten, deshalb hier kein outline. */
.dr-input:focus,
.dr-select:focus,
.dr-textarea:focus {
    outline: none;
    border-color: var(--dr-akzent);
    box-shadow: 0 0 0 3px rgba(14, 91, 60, .14);
}

.dr-input[aria-invalid="true"],
.dr-select[aria-invalid="true"],
.dr-textarea[aria-invalid="true"] {
    border-color: var(--fl-fehler);
}

/* --------------------------------------------------------------------------
   Der Fokus muss auch auf einem fehlerhaften Feld zu sehen sein

   Hier stand ein Schatten von 14 Prozent Deckung. Nachgerechnet ergibt das
   ueber Weiss #f1dfdf – ein Kontrast von 1,19:1, und da der Rahmen in beiden
   Zustaenden rot bleibt, war das der EINZIGE Unterschied zwischen
   "fehlerhaft" und "fehlerhaft und fokussiert". Wer nach einem Fehlversuch
   mit der Tastatur durch vier markierte Felder geht, sieht nicht, wo er
   steht (WCAG 2.4.7).

   Im Regelfall traegt der Fokus, weil dort zusaetzlich die Rahmenfarbe
   wechselt; im Fehlerfall kann sie das nicht.

   Deshalb derselbe zweifarbige Ring wie ueberall sonst, nur in Fehlerrot:
   ein weisser Zwischenring, damit er auf jedem Untergrund traegt, und
   darueber die Farbe. Nicht lauter als die rote Kante daneben, aber
   sichtbar.
   -------------------------------------------------------------------------- */
.dr-input[aria-invalid="true"]:focus,
.dr-select[aria-invalid="true"]:focus,
.dr-textarea[aria-invalid="true"]:focus {
    box-shadow: 0 0 0 2px var(--fl-flaeche), 0 0 0 4px var(--fl-fehler);
}

/* Der Hauptknopf waehrend des Absendens. Kein disabled – siehe portal.js. */
.dr-knopf.ist-beschaeftigt {
    opacity: .75;
    cursor: progress;
}

/* --------------------------------------------------------------------------
   Fehlerkennzeichnung

   Die Regel hiess einmal "ohne Sprung" und sprang trotzdem – nur seitwaerts
   statt senkrecht. Der negative linke Rand zog die Zelle 12 Pixel aus ihrer
   Rasterspalte heraus; gemessen an einem fehlerhaften Datumsfeld: x = -12 bei
   einer Spalte, die bei 0 beginnt, und 12 Pixel mehr Breite als die Spalte
   hat. Standen zwei fehlerhafte Felder untereinander, wanderte die linke
   Kante des gesamten Blattes mit. Genau in dem Augenblick, in dem jemand
   ohnehin schon einen Fehler vor sich hat.

   Jetzt liegt die Marke INNEN. Das Feld ruecken 12 Pixel nach rechts, die
   Zelle bleibt stehen, die Fluchtlinie des Formulars haelt.

   Die Auswahlgruppe steht seit jeher mit derselben Klasse da (radios.php gibt
   "dr-gruppe ist-fehlerhaft" aus), hatte aber nie eine Regel dazu: Jedes
   Textfeld bekam im Fehlerfall eine rote Kante, jede Pflichtauswahl – und das
   sind Hinfahrt, Rueckfahrt, Rolle am Steuer und die Kostenwahl – nur den
   roten Text darunter. Zwei Fehlerdarstellungen in einem Formular.
   -------------------------------------------------------------------------- */
.dr-feld.ist-fehlerhaft,
.dr-gruppe.ist-fehlerhaft {
    box-shadow: inset 3px 0 0 var(--fl-fehler);
    padding-left: var(--fl-a-3);
}

.dr-hinweis {
    margin: var(--fl-a-2) 0 0;
    font-size: var(--fl-t-300);
    line-height: var(--fl-zh-300);
    color: var(--fl-text-leise);
}

/* Derselbe Text, aber EINLEITEND statt nachgestellt: Luft nach unten, keine
   nach oben. Mit .dr-hinweis klebte der erklaerende Satz eines Aufklappers
   mit null Pixeln an der ersten Beschriftung darunter. */
.dr-vorspann {
    margin: 0 0 var(--fl-a-5);
    max-width: var(--fl-breite-lesen);
    font-size: var(--fl-t-300);
    line-height: var(--fl-zh-300);
    color: var(--fl-text-leise);
}

/* --------------------------------------------------------------------------
   Kurze Felder

   Ein Eingabefeld sagt durch seine Breite, was hineingehoert. Ein Feld von
   640 Pixeln fuer eine Telefonnummer, den Schulnamen oder die einstellige
   Antwort auf eine Rechenaufgabe sagt etwas Falsches – und es sagt es umso
   lauter, je knapper der Inhalt ist.

   Die Breite steht am Feld, nicht an der Reihe: Diese drei stehen einzeln,
   nicht paarweise.
   -------------------------------------------------------------------------- */
.dr-feld--kurz .dr-input,
.dr-feld--kurz .dr-select {
    max-width: 8rem;
}

.dr-feld--mittel .dr-input,
.dr-feld--mittel .dr-select {
    max-width: 20rem;
}

.dr-fehlertext {
    margin: var(--fl-a-2) 0 0;
    font-size: var(--fl-t-300);
    line-height: var(--fl-zh-300);
    font-weight: var(--fl-fett-halb);
    color: var(--fl-fehler);
}

/* --------------------------------------------------------------------------
   Feldreihe

   Zusammengehoerige Felder auf einer Zeile – Vorname | Nachname,
   PLZ | Ort, Datum | Uhrzeit. Ueber ein Raster mit benannten Anteilen, nicht
   ueber flex-wrap mit Basisbreiten: Ein Umbruch, der sich aus Restbreiten
   ergibt, ist kein Entwurf, sondern ein Zufall.

   Datum und Uhrzeit bleiben AUCH auf 390 px nebeneinander. Sie sind ein
   Gedanke, und 11 + 7 rem passen.
   -------------------------------------------------------------------------- */
.dr-reihe {
    display: grid;
    gap: var(--fl-a-4);
    grid-template-columns: 1fr;
}

/* --------------------------------------------------------------------------
   Zwei Paare bleiben IMMER nebeneinander, auch auf dem Telefon

   Datum/Uhrzeit und Postleitzahl/Ort gehoeren sichtbar zusammen; keines der
   vier Felder braucht die volle Breite. Eine Postleitzahl hat fuenf Zeichen –
   ein Eingabefeld von 350 Pixeln dafuer sieht aus, als werde dort etwas
   anderes erwartet, und schiebt den Ort eine Zeile tiefer.

   Die uebrigen Paare (Vor-/Nachname, Strasse/Nummer) brechen dagegen bewusst
   um: Dort ist der Inhalt lang genug, dass zwei halbe Spalten auf 390 Pixeln
   beide zu eng waeren.
   -------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------
   Ein Feld ist so breit wie sein Inhalt, nicht wie die Spalte

   Hier standen Anteile (1.6fr / 1fr). Anteile DEHNEN sich: Aus den 11 + 7 rem,
   die der Kommentar oben beschreibt, wurden in der 40-rem-Feldspalte
   gemessene 384 + 240 Pixel – ein Datumsfeld, mehr als doppelt so breit wie
   das laengste Datum, das je darin steht, und daneben eine Uhrzeit von 240
   Pixeln fuer fuenf Zeichen. Die Absicht stand im Kommentar, in der Regel
   stand sie nicht.

   minmax(0, X) deckelt nach oben und laesst nach unten schrumpfen. Bei 390 px
   Fensterbreite bleiben 11 + 7 rem plus Abstand unter der verfuegbaren
   Breite – die beiden bleiben also nebeneinander, wie es der Kommentar oben
   zusagt.
   -------------------------------------------------------------------------- */
.dr-reihe--zeit {
    grid-template-columns: minmax(0, 11rem) minmax(0, 7rem);
}

/* Die Postleitzahl wird gedeckelt, der Ort nimmt den Rest: Dann endet das
   Paar auf derselben Linie wie Strasse/Hausnummer darueber. */
.dr-reihe--plz {
    grid-template-columns: minmax(0, 8rem) minmax(0, 1fr);
}

@media (min-width: 34rem) {
    .dr-reihe--halb {
        grid-template-columns: 1fr 1fr;
    }

    .dr-reihe--strasse {
        grid-template-columns: 3fr 1fr;
    }
}

/* --------------------------------------------------------------------------
   Auswahlgruppen und Kaestchen
   -------------------------------------------------------------------------- */
.dr-gruppe {
    border: 0;
    margin: 0;
    padding: 0;
    min-width: 0;
}

.dr-gruppe__frage {
    display: block;
    margin-bottom: var(--fl-a-3);
    padding: 0;
    font-size: var(--fl-t-400);
    line-height: var(--fl-zh-400);
    font-weight: var(--fl-fett-halb);
    color: var(--fl-text);
}

.dr-wahl,
.dr-kasten {
    display: flex;
    align-items: flex-start;
    gap: var(--fl-a-3);
    min-height: var(--dr-h-bedien);
    padding: var(--fl-a-2) 0;
    cursor: pointer;
}

.dr-wahl input,
.dr-kasten input {
    flex-shrink: 0;
    width: 1.25rem;
    height: 1.25rem;
    margin: 2px 0 0;
    accent-color: var(--dr-akzent);
    cursor: pointer;
}

.dr-wahl__text,
.dr-kasten__text {
    font-size: var(--fl-t-400);
    line-height: var(--fl-zh-400);
    color: var(--fl-text);
}

.dr-wahl__hinweis,
.dr-kasten__hinweis {
    display: block;
    margin-top: 2px;
    font-size: var(--fl-t-300);
    line-height: var(--fl-zh-300);
    font-weight: var(--fl-fett-normal);
    color: var(--fl-text-leise);
}

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

   Der Weg, auf dem vierzig Felder aus dem Regelfall verschwinden, ohne
   unerreichbar zu werden. <details> braucht kein JavaScript – und der Server
   rendert den Block aufgeklappt, sobald eines seiner Felder gefuellt ist oder
   einen Fehler traegt. Ein befuellter, aber zugeklappter Block waere derselbe
   Fehler wie ein wirksamer Filter, der sich versteckt.
   -------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------
   Der Aufklapper ist VERSENKT, nicht erhoben

   Er war weiss, gerahmt und gerundet – und damit das optisch schwerste
   Element auf Schritt 1. "Zeiten der Veranstaltung" wog mehr als "Zweck der
   Dienstreise", das Pflichtfeld daneben. Umgekehrte Hierarchie: Was
   ausdruecklich der Sonderfall ist, trat am staerksten hervor.

   Versenkt heisst "hier ist weniger". Gerahmt hiesse "hier ist mehr".
   -------------------------------------------------------------------------- */
.dr-mehr {
    margin-top: var(--fl-a-5);
    border: 0;
    border-radius: var(--fl-radius-2);
    background: var(--fl-versenkt);
}

.dr-mehr__frage {
    display: flex;
    align-items: center;
    gap: var(--fl-a-3);
    min-height: var(--dr-h-bedien);
    padding: var(--fl-a-3) var(--fl-a-4);
    cursor: pointer;
    list-style: none;
    border-radius: var(--fl-radius-2);
}

.dr-mehr__frage::-webkit-details-marker {
    display: none;
}

.dr-mehr__frage:hover {
    background: var(--fl-grund);
}

.dr-mehr__winkel {
    flex-shrink: 0;
    color: var(--fl-text-leise);
    transition: transform var(--fl-zeit) var(--fl-kurve);
}

.dr-mehr[open] > .dr-mehr__frage {
    border-bottom: 1px solid var(--fl-linie);
    border-radius: var(--fl-radius-2) var(--fl-radius-2) 0 0;
}

.dr-mehr[open] > .dr-mehr__frage .dr-mehr__winkel {
    transform: rotate(90deg);
}

.dr-mehr__text {
    min-width: 0;
}

.dr-mehr__titel {
    display: block;
    font-size: var(--fl-t-400);
    line-height: var(--fl-zh-400);
    font-weight: var(--fl-fett-halb);
    color: var(--fl-text);
}

.dr-mehr__was {
    display: block;
    font-size: var(--fl-t-300);
    line-height: var(--fl-zh-300);
    color: var(--fl-text-leise);
}

/* --------------------------------------------------------------------------
   Genau EINE Einrueckungsebene

   Der Einzug bleibt – ein Inhalt, der am Rahmen des Aufklappers klebt, sieht
   nach einem Fehler aus. Was nicht bleibt, ist die zweite Ebene: Gemessen
   standen in Schritt 3 vier verschiedene Fluchtlinien untereinander (640 –
   606 – 572 Pixel), weil die Anschrift einer mitreisenden Person in einem
   Aufklapper innerhalb eines Aufklappers lag. Sie sass damit 68 Pixel
   schmaler als die Felder daneben, bei drei Personen eine Treppe ueber die
   halbe Seite.

   Behoben ist das dort, wo es entsteht: Die Anschriften stehen jetzt offen
   unter dem Namen, ohne zweite Klappe. Verschachtelte .dr-mehr gibt es im
   Formular nicht mehr, und es sollen auch keine wieder entstehen.
   -------------------------------------------------------------------------- */
.dr-mehr__inhalt {
    padding: var(--fl-a-5) var(--fl-a-4);
}

/* Abhaengiges Einzelfeld unmittelbar unter seinem Schalter. */
.dr-abhaengig {
    margin-top: var(--fl-a-3);
    margin-left: var(--fl-a-4);
    padding-left: var(--fl-a-4);
    border-left: 2px solid var(--fl-linie);
}

/* ==========================================================================
   6. BEDIENELEMENTE
   ========================================================================== */
.dr-knopf {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--fl-a-2);
    height: var(--dr-h-bedien);
    padding: 0 var(--fl-a-4);
    font-family: inherit;
    font-size: var(--fl-t-400);
    line-height: 1;
    font-weight: var(--fl-fett-halb);
    text-decoration: none;
    white-space: nowrap;
    border: 1px solid transparent;
    border-radius: var(--fl-radius-1);
    cursor: pointer;
    transition: background-color var(--fl-zeit) var(--fl-kurve),
                border-color var(--fl-zeit) var(--fl-kurve),
                color var(--fl-zeit) var(--fl-kurve);
}

.dr-knopf--haupt {
    height: var(--dr-h-haupt);
    background: var(--dr-akzent);
    border-color: var(--dr-akzent);
    color: var(--fl-text-invers);
}

.dr-knopf--haupt:hover {
    background: var(--dr-akzent-tief);
    border-color: var(--dr-akzent-tief);
}

.dr-knopf--zweit {
    background: var(--fl-flaeche);
    border-color: var(--fl-rahmen);
    color: var(--fl-text);
}

.dr-knopf--zweit:hover {
    background: var(--fl-grund);
    border-color: var(--fl-text-leise);
}

.dr-knopf--still {
    background: transparent;
    color: var(--fl-text-leise);
}

.dr-knopf--still:hover {
    background: var(--fl-grund);
    color: var(--fl-text);
}

.dr-knopf--breit {
    width: 100%;
}

.dr-knopf:disabled {
    background: var(--fl-linie);
    border-color: var(--fl-linie);
    color: var(--fl-text-leise);
    cursor: not-allowed;
}

/* --------------------------------------------------------------------------
   Aktionszeile

   Auf Breitbild: Zurueck links, Weiter rechts.
   Auf dem Telefon: eine klebende Fussleiste, "Weiter" traegt die Breite.
   Ungleiche Breiten mit Absicht – die vorwaertsfuehrende Handlung ist die
   haeufigere und gehoert unter den Daumen.
   -------------------------------------------------------------------------- */
.dr-aktionen {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--fl-a-3);
    margin-top: var(--fl-a-8);
    padding-top: var(--fl-a-5);
    border-top: 1px solid var(--fl-linie);
}

@media (max-width: 47.99rem) {
    .dr-aktionen--klebend {
        position: sticky;
        bottom: 0;
        z-index: 20;
        margin-top: var(--fl-a-7);
        padding: var(--fl-a-3) 0 calc(var(--fl-a-3) + env(safe-area-inset-bottom));
        background: var(--fl-flaeche);
        border-top: 1px solid var(--fl-linie);
    }

    .dr-aktionen--klebend .dr-knopf--haupt {
        flex: 1;
    }

    .dr-aktionen--klebend .dr-knopf--still {
        flex: 0 0 auto;
    }
}

/* --------------------------------------------------------------------------
   Meldungen – kein Kasten, eine farbige Kante

   Ausnahme: die Fehleruebersicht nach einem gescheiterten Absenden bekommt
   eine getoente Flaeche. Sie muss quer ueber die Seite gefunden werden.
   -------------------------------------------------------------------------- */
.dr-meldung {
    margin: 0 0 var(--fl-a-5);
    padding: 2px 0 2px var(--fl-a-4);
    border-left: 3px solid var(--fl-linie-kraeftig);
}

.dr-meldung--erfolg { border-left-color: var(--fl-erfolg); }
.dr-meldung--warnung { border-left-color: var(--fl-warnung); }
.dr-meldung--fehler { border-left-color: var(--fl-fehler); }
.dr-meldung--info { border-left-color: var(--dr-akzent); }

.dr-meldung__titel {
    margin: 0;
    font-size: var(--fl-t-400);
    line-height: var(--fl-zh-400);
    font-weight: var(--fl-fett-halb);
    color: var(--fl-text);
}

.dr-meldung p {
    margin: var(--fl-a-1) 0 0;
    font-size: var(--fl-t-400);
    line-height: var(--fl-zh-400);
    color: var(--fl-text-leise);
}

.dr-fehlerkasten {
    margin: 0 0 var(--fl-a-6);
    padding: var(--fl-a-4) var(--fl-a-5);
    background: var(--fl-fehler-sanft);
    border-radius: var(--fl-radius-2);
}

.dr-fehlerkasten__titel {
    margin: 0 0 var(--fl-a-3);
    font-size: var(--fl-t-400);
    line-height: var(--fl-zh-400);
    font-weight: var(--fl-fett-halb);
    color: var(--fl-fehler);
}

.dr-fehlerkasten ul {
    margin: 0;
    padding-left: var(--fl-a-5);
}

.dr-fehlerkasten li + li {
    margin-top: var(--fl-a-2);
}

.dr-fehlerkasten a,
.dr-fehlerkasten button {
    color: var(--fl-fehler);
    font-size: var(--fl-t-400);
}

.dr-sprungknopf {
    padding: 0;
    background: none;
    border: 0;
    font-family: inherit;
    font-size: var(--fl-t-400);
    font-weight: var(--fl-fett-halb);
    color: var(--fl-fehler);
    text-decoration: underline;
    cursor: pointer;
}

/* ==========================================================================
   7. SEITEN
   ========================================================================== */

/* --------------------------------------------------------------------------
   Zugangsseite

   Eine Spalte, linksbuendig, ruhig. Kein zweites Feld, kein Erklaerkasten,
   keine Sicherheitsbelehrung – die Vorgabe des Auftraggebers lautet "nicht
   mehr". Auf Breitbild ist die Leere die Aussage: Es wird nichts verlangt
   ausser diesem einen Wort.
   -------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------
   Die Zugangsseite ist eine Karte, und das ist hier richtig

   Sonst gilt in diesem Stylesheet: keine Kaesten um alles. Hier steht genau
   EIN Element auf der Seite und konkurriert mit nichts – dann ist die Karte
   die klarere Form als eine Textsaeule in leerem Weiss.

   Der gemessene Versatz zwischen Marke (208 px) und Inhalt (544 px) faellt
   damit nicht als Bruch auf: Eine Karte richtet sich an ihrer Mitte aus,
   nicht am Seitenkopf. Genau deshalb ist sie hier die Ausnahme und nicht die
   Regel.
   -------------------------------------------------------------------------- */
.dr-zugang {
    max-width: 26rem;
    margin: clamp(2rem, 9vh, 5rem) auto var(--fl-a-9);
    padding: var(--fl-a-7) var(--fl-a-6);
    background: var(--fl-flaeche);
    box-shadow: var(--fl-schatten-blatt);
    border-radius: var(--fl-radius-2);
}

@media (max-width: 34rem) {
    .dr-zugang {
        margin-top: var(--fl-a-6);
        padding: var(--fl-a-5) var(--dr-rand);
        background: transparent;
        box-shadow: none;
        border-radius: 0;
    }
}

.dr-zugang__schule {
    margin: var(--fl-a-2) 0 0;
    font-size: var(--fl-t-200);
    line-height: var(--fl-zh-200);
    font-weight: var(--fl-fett-halb);
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--fl-text-leise);
}

.dr-zugang__titel {
    margin: 0;
    font-size: var(--fl-t-900);
    line-height: var(--fl-zh-900);
    font-weight: var(--fl-fett-halb);
    letter-spacing: -.022em;
}

@media (max-width: 34rem) {
    .dr-zugang__titel {
        font-size: var(--fl-t-800);
        line-height: var(--fl-zh-800);
    }
}

.dr-zugang__lead {
    margin: var(--fl-a-3) 0 0;
    font-size: var(--fl-t-500);
    line-height: var(--fl-zh-500);
    color: var(--fl-text-leise);
}

/* Was bereitzuhalten ist – ein Satz auf getoenter Flaeche.

   Vorher drei Aufzaehlungszeilen zwischen zwei Haarlinien. Das las sich als
   eingeschobener Kasten, obwohl es der Kern der Seite ist; die Linien
   trennten ihn von genau dem Feld, zu dem er gehoert. */
.dr-briefing {
    margin: var(--fl-a-6) 0 0;
    padding: var(--fl-a-4);
    background: var(--fl-grund);
    border-radius: var(--fl-radius-1);
    font-size: var(--fl-t-300);
    line-height: var(--fl-zh-300);
    color: var(--fl-text-leise);
}

.dr-zugang__form {
    margin-top: var(--fl-a-6);
}

.dr-zugang__absenden {
    margin-top: var(--fl-a-5);
}

/* --------------------------------------------------------------------------
   Antragskopf – eine Komponente, mehrere Orte

   Sechs Zeilen ohne Feldbeschriftungen. Wohin, warum, wann, wie, Vertretung,
   wer. Die Bedeutung steht in der Form der Angabe, nicht in einem Etikett
   davor. Erscheint auf der Pruefansicht, auf der Bestaetigung und im Kopf der
   Verwaltungsansicht – wer den Vorgang irgendwo im System sieht, erkennt ihn
   wieder.
   -------------------------------------------------------------------------- */
/* Derselbe Abstand, den .dr-abschnitt:first-of-type in den Schritten 1 bis 3
   setzt. Vorher stand hier ein style-Attribut mit 2rem – Schritt 4 fing damit
   sichtbar enger an als die drei davor. */
.dr-kopfblock {
    margin-top: var(--fl-a-6);
    padding: var(--fl-a-5);
    /* Getoent, nicht weiss: Er liegt INNERHALB des weissen Blattes. Weiss auf
       weiss waere keine Flaeche, sondern nur ein Rahmen. */
    background: var(--fl-grund);
    border-radius: var(--fl-radius-2);
}

.dr-kopfblock__ziel {
    margin: 0;
    font-size: var(--fl-t-700);
    line-height: var(--fl-zh-700);
    font-weight: var(--fl-fett-halb);
    letter-spacing: -.016em;
    color: var(--fl-text);
}

.dr-kopfblock__zweck {
    margin: var(--fl-a-2) 0 0;
    font-size: var(--fl-t-500);
    line-height: var(--fl-zh-500);
    color: var(--fl-text);
}

.dr-kopfblock__zeile {
    margin: var(--fl-a-2) 0 0;
    font-size: var(--fl-t-400);
    line-height: var(--fl-zh-400);
    color: var(--fl-text);
    font-variant-numeric: tabular-nums;
}

.dr-kopfblock__leise {
    margin: var(--fl-a-2) 0 0;
    font-size: var(--fl-t-300);
    line-height: var(--fl-zh-300);
    color: var(--fl-text-leise);
}

/* --------------------------------------------------------------------------
   Ausnahmenliste – "Das ist an Ihrem Antrag besonders"

   Nur vorhanden, wenn es etwas gibt. Ist nichts besonders, fehlt der Block –
   nicht "keine Besonderheiten". Schweigen ist die Aussage.
   -------------------------------------------------------------------------- */
.dr-besonders {
    margin-top: var(--fl-a-6);
    padding: var(--fl-a-4) var(--fl-a-5);
    background: var(--dr-akzent-sanft);
    border-radius: var(--fl-radius-2);
}

.dr-besonders__titel {
    margin: 0 0 var(--fl-a-3);
    font-size: var(--fl-t-400);
    line-height: var(--fl-zh-400);
    font-weight: var(--fl-fett-halb);
    color: var(--dr-akzent);
}

.dr-besonders ul {
    margin: 0;
    padding-left: var(--fl-a-5);
}

.dr-besonders li {
    font-size: var(--fl-t-400);
    line-height: var(--fl-zh-400);
    color: var(--fl-text);
}

.dr-besonders li + li {
    margin-top: var(--fl-a-2);
}

/* --------------------------------------------------------------------------
   Wertepaare der Pruefansicht
   -------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------
   EIN Raster fuer die ganze Liste, nicht eines je Zeile

   Hier lag der auffaelligste Fehler der Pruefseite, und er war messbar: Die
   vierzehn Wertezeilen begannen an DREIZEHN verschiedenen linken Kanten
   (263, 270, 274, 276, 281, 282, 283, 284, 297, 310, 339, 344, 351 Pixel).
   "Magdeburg", "Landesinstitut fuer Schulqualitaet" und "Landsberg –
   Magdeburg – Landsberg" fingen jeweils woanders an.

   Ursache war, dass jede Zeile ein EIGENES Raster aufmachte. minmax(0,
   max-content) misst dann je Zeile neu – und die laengste Beschriftung einer
   Zeile ist eben nicht die laengste der Liste. Die Begruendung fuer
   max-content gegen feste 15 rem war richtig; sie greift nur, wenn alle
   Zeilen sich EIN Raster teilen.

   Die Zeile ist damit kein eigener Kasten mehr. Die Trennlinie sitzt an dt
   und dd, die Zuordnung besorgt das gemeinsame Raster.
   -------------------------------------------------------------------------- */
.dr-werte {
    margin: 0;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 34rem) {
    .dr-werte {
        grid-template-columns: minmax(0, max-content) minmax(0, 1fr);
        column-gap: var(--fl-a-5);
        align-items: baseline;
    }
}

.dr-werte dt,
.dr-werte dd {
    padding: var(--fl-a-3) 0;
    border-bottom: 1px solid var(--fl-linie);
}

/* Die letzte Zeile traegt keine Linie. Bei zwei Spalten sind das die beiden
   letzten Kinder, bei einer Spalte nur das letzte. */
.dr-werte > :last-child,
.dr-werte > :nth-last-child(2) {
    border-bottom: 0;
}

@media (max-width: 33.99rem) {
    .dr-werte > :nth-last-child(2) {
        border-bottom: 1px solid var(--fl-linie);
    }

    .dr-werte dt {
        padding-bottom: 0;
        border-bottom: 0;
    }
}

.dr-werte dt {
    font-size: var(--fl-t-300);
    line-height: var(--fl-zh-300);
    color: var(--fl-text-leise);
}

.dr-werte dd {
    margin: 0;
    font-size: var(--fl-t-400);
    line-height: var(--fl-zh-400);
    color: var(--fl-text);
    overflow-wrap: break-word;
}

/* "keine Angabe" – gedaempft, aber NICHT kursiv. Kursiv in einer Datenliste
   liest sich als Fehler. */
.dr-leer {
    color: var(--fl-text-leise);
}

/* Sammelzeile fuer nicht gesetzte Kreuze. Sie nennt jedes einzelne beim
   Namen – wer pruefen will, ob er eines vergessen hat, findet es dort. */
.dr-ungesetzt {
    margin: var(--fl-a-3) 0 0;
    font-size: var(--fl-t-300);
    line-height: var(--fl-zh-300);
    color: var(--fl-text-leise);
}

/* --------------------------------------------------------------------------
   Bestaetigung
   -------------------------------------------------------------------------- */
.dr-erfolg__haken {
    color: var(--dr-akzent);
}

.dr-vorgangsnummer {
    margin: var(--fl-a-5) 0 0;
}

.dr-vorgangsnummer__was {
    display: block;
    font-size: var(--fl-t-200);
    line-height: var(--fl-zh-200);
    color: var(--fl-text-leise);
}

.dr-vorgangsnummer__wert {
    display: block;
    font-size: var(--fl-t-700);
    line-height: var(--fl-zh-700);
    font-weight: var(--fl-fett-voll);
    font-variant-numeric: tabular-nums;
    color: var(--fl-text);
    user-select: all;
}

.dr-schritte-danach {
    margin: var(--fl-a-5) 0 0;
    padding-left: var(--fl-a-5);
}

.dr-schritte-danach li {
    font-size: var(--fl-t-400);
    line-height: var(--fl-zh-400);
}

.dr-schritte-danach li + li {
    margin-top: var(--fl-a-2);
}

/* ==========================================================================
   8. UMGEBUNG
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        transition-duration: 1ms !important;
        animation-duration: 1ms !important;
    }
}

@media (prefers-contrast: more) {
    :root {
        --fl-linie: #b4bcc8;
        --fl-rahmen: #56606f;
        --fl-text-leise: #414a58;
    }
}

@media print {
    .dr-kopf,
    .dr-fortschritt,
    .dr-fuss,
    .dr-aktionen,
    .dr-sprung {
        display: none !important;
    }

    body {
        font-size: 11pt;
    }

    .dr-blatt {
        max-width: none;
        padding: 0;
    }
}
