/* ==========================================================================
   ATF Liniensystem - Design "Linienverkehr"
   --------------------------------------------------------------------------
   Das EINE Stylesheet aller fuenf Oberflaechen (Partner-Portal, Zentrale
   Linien, Zentrale Clearing, Kundenportal, API-Oberflaeche). Es liegt in
   atf-common und wird von nginx unter /assets/atf.css ausgeliefert - es gibt
   bewusst KEINE Kopie je Portal und KEINE CSS-Bibliothek.

   Aufbau:
     1. Design-Tokens          Farben, Schriften, Abstaende
     2. Grundgeruest           Kopfleiste, Navigation, Inhalt, Fuss
     3. Bausteine              Karten, Kennzahlen, Chips, Status, Meldungen,
                                Filterzeile/Blaetterleiste, Zusammenfassungs-
                                karte, Zeitstrahl, Routenlauf, Options-Karten,
                                Auslastungsbalken, leerer Zustand
     4. Nackte Elemente        Tabellen, Formulare, Knoepfe, Ueberschriften
     5. Kleine Bildschirme

   Abschnitt 4 ist der wichtigste: die meisten Seiten bestehen aus schlichtem
   HTML (h1, table, form). Sie sehen allein durch diese Regeln richtig aus,
   ohne dass jede Seite eigene Klassen braucht. Abschnitt 3 baut die groesseren
   Muster aus den Referenz-Mockups (Dashboard, Sendung anlegen, Sendungs-
   Detail, Linienplan, Login) - jede Klasse dort ist bewusst so benannt, dass
   sie in mehreren Diensten wiederverwendbar ist.
   ========================================================================== */

/* ---------- 1. Design-Tokens --------------------------------------------- */

:root {
    /* Grundfarben - Navy traegt, Rot ist Signal und bleibt selten. */
    --atf-navy: #16325c;
    --atf-navy-dunkel: #0e2140;
    --atf-navy-hell: #2a4a7d;
    --atf-rot: #d5232a;
    --atf-rot-dunkel: #b31c22;
    /* RGB-Zerlegung derselben zwei Farben, einmal zentral - fuer rgba() an
       Stellen, die Transparenz brauchen (Fokusring, Overlay, Rahmen). Aendert
       sich --atf-navy oder --atf-rot, muss diese Zerlegung mitgepflegt werden. */
    --atf-navy-rgb: 22, 50, 92;
    --atf-rot-rgb: 213, 35, 42;

    /* Flaechen */
    --atf-flaeche: #f4f5f7;
    --atf-karte: #ffffff;
    --atf-rand: #dfe3e9;
    /* Zwei Grautoene fuer Trennlinien - das ist Absicht, kein Zufall: Mockups
       nutzen konsequent #e8ebef unter Karten-/Tabellenkoepfen und das etwas
       hellere #eef0f3 zwischen einzelnen Tabellenzeilen. */
    --atf-rand-kopf: #e8ebef;
    --atf-rand-leicht: #eef0f3;
    --atf-eingabe-rand: #c9cfd8;
    --atf-kopfzeile: #f8f9fa;
    --atf-chip-flaeche: #eef1f6;
    --atf-dekor: #b6bec8;   /* Pfeile, Trennzeichen, deaktivierte Icons */

    /* Schrift */
    --atf-text: #1c2430;
    --atf-text-kraeftig: #3c4654;
    --atf-nebentext: #66707e;
    --atf-gedaempft: #96a0ac;
    --atf-navy-nebentext: #8fa3c2;
    --atf-navy-menue: #aebdd4;

    /* Statusfarben - reserviert, nie dekorativ verwenden. */
    --atf-status-angemeldet: #aab3bd;
    --atf-status-abgeholt: #d9a10c;
    --atf-status-abgeholt-text: #8a6a14;
    --atf-status-unterwegs: #16325c;
    --atf-status-zugestellt: #1e7a3c;
    --atf-status-fehler: #b12a24;

    /* Auslastung/Warnung - KEINE Statusfarben, sondern eigene, bewusst
       gedaempfte Werte fuer Balken und Hinweiskarten (Linienplan-Mockup:
       Zusatzlinie in blaeulichem Grau, Fast-voll-Hinweis in Pfirsich). */
    --atf-balken-neutral: #7d93b5;
    --atf-linie-offen: #e3e7ec;
    --atf-gefahr-rand: #e3b6b4;
    --atf-warnung-flaeche: #fdf6ee;
    --atf-warnung-rand: #e7c9c7;
    --atf-warnung-rand-leicht: #f0e2cd;
    /* Gedaempfte Fehler-Flaeche fuer Tabellenzeilen (z. B. eine ueberladene
       Linie im Linienplan) - derselbe Farbwert, den .meldung.error und
       .atf-anmelde-fehler bereits als Hintergrund nutzen, hier als
       wiederverwendbarer Token statt erneut hart verdrahtet. */
    --atf-fehler-flaeche: #fdf0ef;

    /* Schriftfamilien mit System-Rueckfall, falls Google Fonts nicht laedt. */
    --atf-schrift: 'Barlow', 'Segoe UI', system-ui, -apple-system, sans-serif;
    --atf-schrift-titel: 'Zilla Slab', Georgia, 'Times New Roman', serif;
    --atf-schrift-zahl: 'IBM Plex Mono', 'Consolas', 'Courier New', monospace;

    --atf-radius: 4px;
    --atf-radius-klein: 3px;
}

/* ---------- 2. Grundgeruest ---------------------------------------------- */

* { box-sizing: border-box; }

body {
    margin: 0;
    background: var(--atf-flaeche);
    color: var(--atf-text);
    font-family: var(--atf-schrift);
    font-size: 14px;
    line-height: 1.45;
}

a { color: var(--atf-navy); }
a:hover { color: var(--atf-navy-dunkel); }

/* Sprunglink: unsichtbar, bis Tastatur-/Screenreader-Nutzer ihn fokussieren -
   dann faehrt er sichtbar oben links ein. */
.atf-sprunglink {
    position: absolute;
    left: -999px;
    top: 0;
    background: var(--atf-navy);
    color: #ffffff;
    padding: 10px 16px;
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
    border-radius: 0 0 var(--atf-radius) 0;
    z-index: 1000;
}
.atf-sprunglink:focus {
    left: 0;
    outline: 3px solid #ffffff;
    outline-offset: -3px;
}

/* Die zwei schraegen Flottenstreifen - das Signatur-Element. Nur im Kopf und
   klein im Fuss, sonst nirgends. */
.atf-streifen { display: flex; flex-direction: column; gap: 3px; flex: none; }
.atf-streifen span { display: block; width: 30px; height: 6px; transform: skewX(-20deg); }
.atf-streifen span:first-child { background: var(--atf-rot); }
.atf-streifen span:last-child { background: #ffffff; }

.atf-streifen--fuss { flex-direction: row; gap: 3px; }
.atf-streifen--fuss span { width: 16px; height: 4px; }
.atf-streifen--fuss span:last-child { background: var(--atf-navy); }

/* Kopfleiste */
.atf-kopf { background: var(--atf-navy); color: #ffffff; }
.atf-kopf-innen {
    display: flex;
    align-items: center;
    gap: 28px;
    padding: 0 24px;
    min-height: 64px;
    flex-wrap: wrap;
}

.atf-marke { display: flex; align-items: center; gap: 13px; flex: none; }
.atf-marke-text { display: flex; flex-direction: column; line-height: 1.1; }
.atf-marke-name { font-family: var(--atf-schrift-titel); font-weight: 700; font-size: 19px; }
.atf-marke-untertitel {
    font-size: 10px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--atf-navy-nebentext);
}
.atf-marke a { color: inherit; text-decoration: none; }
/* Partner-Logo, wenn ein eigenes Branding hinterlegt ist (statt der
   Flottenstreifen) - im Kopf wie auf der Anmeldeseite gleich hoch. */
.atf-marke-logo { height: 32px; }

/* Hauptnavigation - die aktive Seite bekommt die rote Unterkante.
   Marcel (30.08.): Clearing hat 12 Menuepunkte mit insgesamt mehr Zeichen als
   Linien (ebenfalls 12) und brach deshalb in eine zweite Zeile um, waehrend
   Linien "gerade noch" einzeilig blieb - beide teilen sich dieselbe Klasse.
   Entschieden: Variante A, alles bleibt einzeilig - Beschriftungen bleiben
   unveraendert (keine kryptischen Abkuerzungen), stattdessen Abstand und
   Schrift je Menuepunkt enger gefasst. flex-wrap bleibt bewusst erhalten:
   auf einem wirklich schmalen Fenster (siehe Abschnitt 5, Kleine Bildschirme)
   darf die Navigation weiterhin in mehrere Zeilen umbrechen statt aus dem
   Bild zu laufen. */
.atf-menue { display: flex; flex-wrap: wrap; align-items: stretch; gap: 1px; }
/* Design-Entscheidung (design-agent, 30.08., nach Chrome-Nachmessung):
   Der Referenz-Mockup zeigt den Kopf einzeilig und 64px hoch - Logo,
   Navigation und Benutzerblock in EINER Zeile. Gemessen (echtes Chrome,
   beide Bereiche): bei 1920px und 1680px ist das bei Clearing UND Linien
   bereits von selbst so (64px, einzeilig) - der kompakte Mockup-Kopf passt
   dort auch mit dem laengeren Clearing-Menue bequem neben Benutzerblock und
   Logo. Bei 1536px passt er nicht mehr (Clearing bricht dort als erstes,
   weil es insgesamt mehr Zeichen traegt als Linien) - genau DAS war der
   urspruengliche Fehler: beide Koepfe sahen bei gleicher Fensterbreite
   unterschiedlich aus, obwohl es dieselbe Leiste ist.
   Deshalb: der kompakte einzeilige Kopf aus dem Mockup bleibt auf breiten
   Bildschirmen erhalten (kein verschenkter Platz), und unterhalb der Grenze
   bekommt die Navigation ihre eigene volle Zeile - bewusst EINHEITLICH fuer
   alle Portale, unabhaengig von der jeweiligen Beschriftungslaenge. Das ist
   exakt der Aufbau, den Marcel am Linien-Kopf bereits als "super" bestaetigt
   hat, jetzt verlaesslich in jedem Portal gleich statt vom Zufall abhaengig.
   DIE GRENZE SELBST wurde mit echtem Chrome nachgemessen und liegt bei
   1679px: Bei einer Innenbreite von 1602px trug das laengere Clearing-Menue
   noch NICHT neben dem Logo (eigene Zeile, 100px), waehrend Linien dort noch
   einzeilig blieb (64px) - genau die Ungleichheit, die wir loswerden wollten.
   Ab 1682px sind beide Bereiche gemessen wieder einzeilig bei 64px. 1679px
   ist damit der letzte Wert, bei dem beide Bereiche unter allen gemessenen
   Breiten (1024, 1152, 1280, 1366, 1440, 1536, 1580, 1600, 1620, 1700, 1920,
   2560) gleich aussehen. Wer hier etwas aendert, misst bitte nach - schaetzen
   reicht dafuer nicht, das hat dieser Durchgang gezeigt. */
@media (max-width: 1679px) {
    .atf-menue { flex-basis: 100%; }
}
.atf-menue a {
    display: flex;
    align-items: center;
    padding: 8px 9px;
    min-height: 40px;
    font-size: 13px;
    font-weight: 500;
    color: var(--atf-navy-menue);
    text-decoration: none;
    white-space: nowrap;
}
.atf-menue a:hover { color: #ffffff; background: rgba(255, 255, 255, 0.06); }
.atf-menue a.aktiv { color: #ffffff; font-weight: 600; box-shadow: inset 0 -3px 0 var(--atf-rot); }

/* Rechter Block: Hauptaktion, Bereichswechsel, Benutzer */
.atf-kopf-rechts { display: flex; align-items: center; gap: 14px; margin-left: auto; flex-wrap: wrap; }

.atf-benutzer {
    display: flex;
    align-items: center;
    gap: 10px;
    padding-left: 16px;
    border-left: 1px solid var(--atf-navy-hell);
}
.atf-benutzer-kuerzel {
    width: 32px; height: 32px; border-radius: 50%;
    background: var(--atf-navy-hell);
    display: flex; align-items: center; justify-content: center;
    font-size: 12px; font-weight: 700; color: #cdd9ea;
    flex: none;
}
.atf-benutzer-text { display: flex; flex-direction: column; line-height: 1.2; }
.atf-benutzer-name { font-size: 13px; font-weight: 600; }
.atf-benutzer-rolle { font-size: 11px; color: var(--atf-navy-nebentext); }
.atf-benutzer a { color: var(--atf-navy-menue); font-size: 12px; text-decoration: none; }
.atf-benutzer a:hover { color: #ffffff; text-decoration: underline; }

/* Bereichswechsel: die Verknuepfung der Oberflaechen untereinander. Steht
   bewusst in einer eigenen, ruhigen Leiste unter der Kopfleiste - sie ist ein
   Wechsel des Arbeitsbereichs, kein Menuepunkt. */
.atf-bereiche {
    background: var(--atf-navy-dunkel);
    color: var(--atf-navy-menue);
    padding: 7px 24px;
    font-size: 12px;
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}
.atf-bereiche-titel { text-transform: uppercase; letter-spacing: 0.08em; color: var(--atf-navy-nebentext); margin-right: 6px; }
.atf-bereiche a {
    color: #ffffff;
    text-decoration: none;
    padding: 3px 10px;
    border: 1px solid var(--atf-navy-hell);
    border-radius: var(--atf-radius-klein);
}
.atf-bereiche a:hover { background: var(--atf-navy-hell); }
.atf-bereiche a.aktiv { background: var(--atf-navy-hell); border-color: #4a6ba3; font-weight: 600; }

/* Inhaltsflaeche */
.atf-inhalt { padding: 24px; max-width: 1400px; margin: 0 auto; }

/* Fussbereich */
.atf-fuss {
    max-width: 1400px;
    margin: 0 auto;
    padding: 10px 24px 26px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    font-size: 12px;
    color: var(--atf-gedaempft);
    flex-wrap: wrap;
}
.atf-fuss-marke { display: flex; align-items: center; gap: 10px; }

/* ---------- 3. Bausteine -------------------------------------------------- */

/* Karte - der Grundbaustein. 4px Radius, 1px Rand, kein starker Schatten. */
.atf-karte {
    background: var(--atf-karte);
    border: 1px solid var(--atf-rand);
    border-radius: var(--atf-radius);
    padding: 16px 20px;
    margin-bottom: 16px;
}
/* Groessere Polsterung fuer Karten mit viel Luft, z. B. den Routenlauf einer
   Sendung (siehe sendung-detail.html). */
.atf-karte--gross { padding: 20px 24px; }
/* Achtung-Variante: rosastichiger Rand statt des neutralen Kartenrands -
   signalisiert "beobachten", ohne die reservierte Statusfarbe Rot zu
   verbrauchen (siehe Linienplan-Mockup "Fast voll"). */
.atf-karte--warnung { border-color: var(--atf-warnung-rand); }

.atf-karte-kopf {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; flex-wrap: wrap;
    padding-bottom: 12px; margin-bottom: 14px;
    border-bottom: 1px solid var(--atf-rand-kopf);
}
.atf-karte-kopf h2 { margin: 0; }

/* Abschnitts-Karte: ein Kopfstreifen mit eigener Polsterung, ein Koerper mit
   eigener Polsterung - anders als .atf-karte hat die Huelle selbst KEINE
   Polsterung, damit Kopf und Koerper randlos an den Kartenrand reichen. Das
   ist das Muster hinter den Formular-Abschnitten (Abholung/Zustellung/
   Packstuecke in sendung-anlegen.html), den Sendungsdetail-Karten
   (Packstuecke/Verlauf) und den Linienplan-Zeilen. Fuer Tabellen mit
   Filterzeile (siehe unten) ist es ebenfalls die Basis. */
.atf-abschnitt {
    background: var(--atf-karte);
    border: 1px solid var(--atf-rand);
    border-radius: var(--atf-radius);
    overflow: hidden;
    margin-bottom: 16px;
}
.atf-abschnitt--warnung { border-color: var(--atf-warnung-rand); }
/* Pflicht-Markierung eines Abschnitts, wenn eine vorherige Eingabe ihn
   verbindlich macht (siehe "Zoll" in sendung/new.html.twig: erst ab einem
   Land ausserhalb der Zollunion, data-zoll-abschnitt/atf-abschnitt--pflicht
   per Skript umgeschaltet). Dieselbe gedaempfte Warnfarbe wie
   .atf-abschnitt--warnung/.atf-hinweisleiste - "jetzt zwingend" ist naeher
   an einer Warnung als an einem Fehler, Rot bleibt der einen Hauptaktion der
   Seite vorbehalten. */
.atf-abschnitt--pflicht { border-color: var(--atf-warnung-rand); }
.atf-abschnitt--pflicht > .atf-abschnitt-kopf {
    background: var(--atf-warnung-flaeche);
    border-bottom-color: var(--atf-warnung-rand-leicht);
}
.atf-abschnitt-kopf {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; flex-wrap: wrap;
    padding: 13px 20px;
    border-bottom: 1px solid var(--atf-rand-kopf);
    font-family: var(--atf-schrift-titel);
    font-weight: 700;
    font-size: 16px;
}
/* Eine Aktion im Kopf (z. B. "+ Packstueck hinzufuegen", "Aus Adressbuch
   uebernehmen") ist Fliesstext-Groesse, nicht Titel-Groesse. */
.atf-abschnitt-kopf-aktion { font-family: var(--atf-schrift); font-size: 13px; font-weight: 600; }
/* Kurze Marke im Abschnitts-Kopf neben dem Titel, z. B. "Pflicht fuer diese
   Strecke" (data-zoll-marke) - erscheint zusammen mit .atf-abschnitt--pflicht,
   dieselbe gedaempfte Warnfarbe wie deren Kopf-Flaeche. */
.atf-abschnitt-kopf-hinweis {
    font-family: var(--atf-schrift);
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--atf-status-abgeholt-text);
    background: var(--atf-warnung-flaeche);
    border: 1px solid var(--atf-warnung-rand-leicht);
    border-radius: 999px;
    padding: 3px 10px;
}
/* Ein zweiter Abschnitts-Kopf INNERHALB desselben Abschnitts, wenn eine Karte
   zwei Arbeitsschritte nacheinander zeigt (z. B. Zahlung: "Abgleich" gefolgt
   von "Von Hand zuordnen" in derselben Karte). */
.atf-abschnitt-kopf--getrennt { border-top: 1px solid var(--atf-rand-kopf); }
.atf-abschnitt-koerper { padding: 16px 20px; }
/* Gestapelter Inhalt innerhalb eines Abschnitts-Koerpers (mehrere Formulare
   oder Absaetze untereinander) im einheitlichen 16px-Rhythmus. */
.atf-abschnitt-koerper--gestapelt { display: flex; flex-direction: column; gap: 16px; }
/* "Ohne Abstand": universeller Ausgleich fuer das letzte sichtbare Element in
   einer Karte/Zeile/einem Stapel - EIN Klassenname fuer zwei Faelle. Am
   gewoehnlichen Element (Absatz, Formularfeld) wird der Aussenabstand
   genullt; direkt an einem .atf-abschnitt-koerper (der seinen Abstand ueber
   Innenabstand setzt) wird stattdessen dessen unterer Innenabstand genullt -
   z. B. ein kurzer erklaerender Satz, dem in derselben Karte unmittelbar eine
   Tabelle oder ein Leerzustand folgt (Scans in sendung/show.html.twig,
   Bedingungen in kundenzuschlag/show.html.twig, Stationen in
   linie/show.html.twig, PLZ-Bereiche in partner/show.html.twig, Hinweis vor
   der Positionstabelle im Linien-Clearing). */
.atf-ohne-abstand { margin-bottom: 0; }
.atf-abschnitt-koerper.atf-ohne-abstand { padding-bottom: 0; }
/* Unter-Abschnitt: trennt ein weiteres Element in derselben Karte von dem,
   was darueber steht, durch eine obere Trennlinie - Regelfall ein weiterer,
   bereits gepolsterter .atf-abschnitt-koerper (z. B. "Stufe hinzufuegen"
   unter der Stufen-Tabelle eines Kundentarifs, "Bedingung eintragen" unter
   den Zuschlags-Bedingungen, "Foto oder Dokument anhaengen" unter den
   Reklamations-Anhaengen), Sonderfall ein "nacktes" Element ohne eigene
   Polsterung wie ein Formular (z. B. der Linien-Clearing-Lauf unterhalb der
   Filterzeile) - das bekommt zusaetzlich eigenen Abstand. */
.atf-unterabschnitt { border-top: 1px solid var(--atf-rand-kopf); }
.atf-unterabschnitt:not(.atf-abschnitt-koerper) { margin-top: 16px; padding-top: 16px; }
.atf-abschnitt-fuss {
    display: flex; justify-content: flex-end; align-items: baseline; gap: 22px;
    padding: 12px 20px;
    background: var(--atf-kopfzeile);
    border-top: 1px solid var(--atf-rand-kopf);
    font-size: 13px;
    color: var(--atf-nebentext);
}
/* Linksbuendige Variante fuer einen Fuss, der nur ein-zwei Aktions-Formulare
   traegt statt einer rechtsbuendigen Summenzeile (z. B. Sperren/Aktivieren +
   Loeschen bei einem API-Schluessel, ein erklaerender Satz statt eines
   Summenwerts bei einer Abrechnungs-Vorschau). */
.atf-abschnitt-fuss--links { justify-content: flex-start; }
/* Der grosse Gesamtwert im Fuss einer Abschnitts-Karte - Zilla Slab statt
   Mono, genau wie im sendung-detail.html-Mockup ("Gesamt frachtpflichtig"
   21px). Steht z. B. bei "Gesamt frachtpflichtig" (sendung/show.html.twig)
   und "Gesamt-Betrag" (kundenabrechnung/beleg.html.twig). */
.atf-abschnitt-fuss-wert {
    font-family: var(--atf-schrift-titel);
    font-weight: 700;
    font-size: 21px;
    color: var(--atf-text);
}
/* Eine table innerhalb einer Abschnitts-Karte bekommt nicht noch einmal einen
   eigenen Rand/Radius/Aussenabstand - die Huelle uebernimmt das schon. */
.atf-abschnitt table { border: 0; border-radius: 0; margin-bottom: 0; }

/* Kennzahl-Karte: immer mit einordnender Unterzeile. */
.atf-kennzahlen {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 16px;
    margin-bottom: 20px;
}
.atf-kennzahl {
    background: var(--atf-karte);
    border: 1px solid var(--atf-rand);
    border-radius: var(--atf-radius);
    padding: 16px 20px 14px;
}
.atf-kennzahl-titel { font-size: 12px; color: var(--atf-nebentext); font-weight: 600; }
/* Navy ist laut Design-Vorgabe die Farbe der grossen Zahlen-Akzente. Sie steht
   deshalb HIER als Regel - eine Statusfarbe (gruen, rot) ist die begruendete
   Ausnahme und wird an der einzelnen Kennzahl gesetzt, nicht umgekehrt. */
.atf-kennzahl-wert {
    font-family: var(--atf-schrift-titel);
    font-weight: 700;
    font-size: 36px;
    line-height: 1.15;
    color: var(--atf-navy);
}
.atf-kennzahl-zusatz { font-size: 12px; color: var(--atf-gedaempft); }
/* Statusfarbige Kennzahl - die begruendete Ausnahme zum Navy oben (siehe
   Kommentar dort). Pendant zu .atf-mini-kennzahl-wert.positiv/.negativ. */
.atf-kennzahl-wert--erfolg { color: var(--atf-status-zugestellt); }
.atf-kennzahl-wert--warnung { color: var(--atf-status-abgeholt-text); }
.atf-kennzahl-wert--fehler { color: var(--atf-status-fehler); }
/* Geldbetrag als Kennzahl: Mono/tabellarische Ziffern wie .atf-zahl, aber
   OHNE Rechtsbuendigkeit - die Kennzahl steht als eigene, grosse Zahl fuer
   sich (Clearing-Ergebnis: Erloes, Verguetung, Marge), nicht in einer
   Tabellenspalte. Kombinierbar mit .atf-kennzahl-wert--erfolg. */
.atf-kennzahl-wert--betrag { font-family: var(--atf-schrift-zahl); font-variant-numeric: tabular-nums; }

/* Mini-Kennzahl: kompakte, waagerechte Variante fuer eine einzelne Zahl neben
   dem Seitenkopf (siehe Dashboard-Mockup "Kontokorrent"). */
.atf-mini-kennzahl {
    display: inline-flex;
    align-items: center;
    gap: 14px;
    background: var(--atf-karte);
    border: 1px solid var(--atf-rand);
    border-radius: var(--atf-radius);
    padding: 12px 18px;
}
.atf-mini-kennzahl-text { display: flex; flex-direction: column; line-height: 1.25; }
.atf-mini-kennzahl-titel { font-size: 11px; color: var(--atf-nebentext); font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; }
.atf-mini-kennzahl-zusatz { font-size: 12px; color: var(--atf-gedaempft); }
.atf-mini-kennzahl-wert { font-family: var(--atf-schrift-titel); font-weight: 700; font-size: 24px; color: var(--atf-navy); }
.atf-mini-kennzahl-wert.positiv { color: var(--atf-status-zugestellt); }
.atf-mini-kennzahl-wert.negativ { color: var(--atf-status-fehler); }
/* Steht die Mini-Kennzahl (anders als im Seitenkopf) als eigener Block ueber
   einer Tabellenkarte, braucht sie denselben Abstand nach unten wie eine
   .atf-kennzahlen-Reihe. */
.atf-mini-kennzahl--block { margin-bottom: 20px; }

/* Seitenkopf: Titel links, Nebeninformation/Aktionen rechts. */
.atf-seitenkopf {
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: 16px; flex-wrap: wrap; margin-bottom: 20px;
}
.atf-seitenkopf-unterzeile { font-size: 13px; color: var(--atf-nebentext); }
.atf-seitenkopf-titelblock { display: flex; flex-direction: column; gap: 3px; }
.atf-seitenkopf-titelzeile { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.atf-seitenkopf-titelzeile h1 { margin: 0; }

/* Brotkrumen oberhalb eines Seitentitels, z. B. "Sendungen / S2026-000214". */
.atf-brotkrumen { font-size: 12px; color: var(--atf-gedaempft); margin: 0; }
.atf-brotkrumen a { color: inherit; text-decoration: none; }
.atf-brotkrumen a:hover { color: var(--atf-navy); text-decoration: underline; }

/* Hub-Route als Chips: FRA -> KLS */
.atf-chip {
    display: inline-block;
    background: var(--atf-chip-flaeche);
    border-radius: var(--atf-radius-klein);
    padding: 2px 8px;
    font-weight: 600;
    font-size: 12px;
    color: var(--atf-navy);
}
.atf-pfeil { color: var(--atf-dekor); padding: 0 2px; }

/* Status immer als farbiger Punkt PLUS Text - nie als reine Farbflaeche. */
.atf-status { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; font-weight: 600; }
.atf-status::before { content: ''; width: 8px; height: 8px; border-radius: 50%; background: var(--atf-status-angemeldet); flex: none; }
.atf-status--angemeldet { color: var(--atf-nebentext); }
.atf-status--abgeholt { color: var(--atf-status-abgeholt-text); }
.atf-status--abgeholt::before { background: var(--atf-status-abgeholt); }
.atf-status--unterwegs { color: var(--atf-status-unterwegs); }
.atf-status--unterwegs::before { background: var(--atf-status-unterwegs); }
.atf-status--zugestellt { color: var(--atf-status-zugestellt); }
.atf-status--zugestellt::before { background: var(--atf-status-zugestellt); }
.atf-status--fehler { color: var(--atf-status-fehler); }
.atf-status--fehler::before { background: var(--atf-status-fehler); }
/* Groessere Chip-Variante fuer den Seitenkopf einer Sendung (siehe
   sendung-detail.html): heller Hintergrund, mehr Innenabstand, runde Form. */
.atf-status--pille {
    background: var(--atf-chip-flaeche);
    border-radius: 999px;
    padding: 5px 14px;
    font-size: 14px;
}
/* Textbetonung in Fliesstext/Tabellenzellen fuer eine Frist- oder
   Grenzueberschreitung, ohne dafuer einen vollen Status-Punkt zu setzen (das
   waere fuer eine eingebettete Randbemerkung zu viel Gewicht) - siehe
   Reklamationen: "ueberfaellig", "Haftungsgrenze bewusst ueberschritten",
   "bereits abgerechnet", "nach Ablauf der Einreichfrist". Nutzt dieselben
   reservierten Statusfarben wie .atf-status, nur ohne Punkt und Pille. */
.atf-text-fehler { color: var(--atf-status-fehler); font-weight: 600; }
.atf-text-warnung { color: var(--atf-status-abgeholt-text); font-weight: 600; }

/* Bauart-Kennzeichnung einer Gewichtsstaffel-Stufe (Preisliste, Clearing):
   "Aufbauend" (Stufen addieren sich) vs. "Gesamtklasse" (das GESAMTgewicht
   waehlt EINE Stufe, die dann allein den Preis bestimmt - Auslandstarife wie
   Ost-Schweiz/Liechtenstein). Genau diese Verwechslung nennt der
   Klassenkommentar von Atf\Common\Entity\PreisStaffelArt "der teuerste
   Irrtum dieser Liste", deshalb bekommt sie eine eigene, auf einen Blick
   erkennbare Marke statt nur eines Wortes in der Art-Spalte. Aufbauend
   bleibt neutral (derselbe Chip-Ton wie eine Hub-Route), Gesamtklasse nutzt
   bewusst denselben gedaempften Warnton wie "Fast voll" im Linienplan -
   keine neue Farbe, nur die vorhandene "genauer hinsehen"-Sprache des
   Systems. */
.atf-bauart {
    display: inline-flex;
    align-items: center;
    padding: 2px 9px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    background: var(--atf-chip-flaeche);
    color: var(--atf-navy);
    white-space: nowrap;
}
.atf-bauart--gesamtklasse {
    background: var(--atf-warnung-flaeche);
    color: var(--atf-status-abgeholt-text);
    border: 1px solid var(--atf-warnung-rand-leicht);
}

/* Auslastungsbalken mit kg-Angabe (Linienplan-Mockup). */
.atf-balken { background: var(--atf-rand-leicht); border-radius: var(--atf-radius-klein); height: 14px; overflow: hidden; }
.atf-balken span { display: block; height: 100%; background: var(--atf-navy); }
.atf-balken--warnung span { background: var(--atf-status-abgeholt); }
.atf-balken--neutral span { background: var(--atf-balken-neutral); }
.atf-balken--voll span { background: var(--atf-status-fehler); }

/* Die vollstaendige Auslastungszeile: Balken + Zusatzangaben links/rechts +
   grosse Prozentzahl - genau das Muster der drei Linien im Linienplan. */
.atf-auslastung { display: flex; align-items: center; gap: 22px; padding: 16px 20px; }
.atf-auslastung-balken-block { flex-grow: 1; display: flex; flex-direction: column; gap: 7px; }
.atf-auslastung-zeile { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 6px; font-size: 12px; color: var(--atf-nebentext); }
.atf-auslastung-prozent {
    font-family: var(--atf-schrift-titel); font-weight: 700; font-size: 26px;
    color: var(--atf-navy); width: 76px; text-align: right; flex: none;
}
.atf-auslastung-prozent--warnung { color: var(--atf-status-abgeholt-text); }
.atf-auslastung-prozent--neutral { color: var(--atf-nebentext); }
/* Ueberladen - derselbe Farbwert, den .atf-balken--voll fuer den Fuellstand
   schon nutzt (siehe unten), hier fuer die Prozentzahl daneben. */
.atf-auslastung-prozent--kritisch { color: var(--atf-status-fehler); }

/* Kompakte Variante fuer die Auslastung INNERHALB einer Tabellenzelle (siehe
   Linienplan-Tabelle: dort steht Soll- und Ist-Auslastung je Linie in einer
   eigenen Spalte, ohne die grosszuegige Kartenpolsterung der Vollansicht). */
.atf-auslastung--kompakt { padding: 0; gap: 12px; }
.atf-auslastung--kompakt .atf-auslastung-balken-block { gap: 3px; }
.atf-auslastung--kompakt .atf-auslastung-prozent { font-size: 18px; width: 62px; }
.atf-auslastung--kompakt .atf-auslastung-zeile { font-size: 11px; }

/* Hinweisleiste am Fuss einer Karte, z. B. Prognose + Zusatzlinie-Vorschlag
   unterhalb einer fast vollen Linie. */
.atf-hinweisleiste {
    display: flex; align-items: center; justify-content: space-between;
    gap: 14px; flex-wrap: wrap;
    padding: 11px 20px;
    background: var(--atf-warnung-flaeche);
    border-top: 1px solid var(--atf-warnung-rand-leicht);
    font-size: 13px;
    color: var(--atf-status-abgeholt-text);
}
/* Eigenstaendige Hinweisleiste: dieselbe gedaempfte Warnfarbe, aber als
   vollstaendige, freistehende Karte mit eigenem Rand und Radius statt nur als
   Fuss EINER Karte - z. B. der Vorlagen-Hinweis oberhalb eines
   Zuschlag-Formulars, das selbst keine umschliessende Abschnitts-Karte hat. */
.atf-hinweisleiste--eigenstaendig {
    border: 1px solid var(--atf-warnung-rand);
    border-radius: var(--atf-radius);
}
/* Neutrales Ergebnisfeld (ausdruecklich KEIN Warnhinweis) fuer ein
   Rechenergebnis, z. B. die Preislisten-Proberechnung - dieselbe Form wie
   .atf-hinweisleiste, aber in der neutralen Kartenkopf-Flaeche statt
   Pfirsich, weil ein Rechenergebnis keine Warnung ist. */
.atf-ergebnisleiste {
    margin-top: 14px;
    background: var(--atf-kopfzeile);
    border-radius: var(--atf-radius);
    padding: 11px 20px;
    font-size: 13px;
    color: var(--atf-text);
}

/* Key-Value-Liste: fuer "Details"-Karten (hell) genauso wie fuer die dunkle
   Zusammenfassungskarte (siehe unten) - EIN Baustein, zwei Farbkontexte. */
.atf-kv-liste { display: flex; flex-direction: column; gap: 10px; font-size: 13px; margin: 0; }
.atf-kv { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; margin: 0; }
.atf-kv dt { color: var(--atf-nebentext); font-weight: 400; }
.atf-kv dd { margin: 0; font-weight: 600; text-align: right; }

/* Dunkle Navy-Zusammenfassungskarte fuer Formulare - zeigt live den
   frachtpflichtigen Wert (Gewicht, Preis o. ae.), siehe sendung-anlegen.html.
   Steht als rechte Spalte neben dem Formular, siehe .atf-formular-layout. */
.atf-zusammenfassung {
    background: var(--atf-navy);
    color: #ffffff;
    border-radius: var(--atf-radius);
    padding: 18px 20px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.atf-zusammenfassung-titel { font-family: var(--atf-schrift-titel); font-weight: 700; font-size: 16px; }
.atf-zusammenfassung .atf-kv-liste { gap: 7px; }
.atf-zusammenfassung .atf-kv dt { color: var(--atf-navy-menue); }
.atf-zusammenfassung .atf-kv dd { font-family: var(--atf-schrift-zahl); font-weight: 400; color: #ffffff; }
.atf-zusammenfassung-summe {
    border-top: 1px solid var(--atf-navy-hell);
    padding-top: 12px;
    display: flex;
    justify-content: space-between;
    align-items: baseline;
}
.atf-zusammenfassung-summe-label { font-size: 13px; color: var(--atf-navy-menue); }
.atf-zusammenfassung-summe-wert { font-family: var(--atf-schrift-titel); font-weight: 700; font-size: 26px; }
/* Der Hauptknopf sitzt direkt in der Zusammenfassung und darf hier die volle
   Breite einnehmen - es ist die EINE rote Hauptaktion der Seite. */
.atf-zusammenfassung .knopf--haupt { width: 100%; text-align: center; font-size: 15px; padding: 12px 0; }
.atf-zusammenfassung-abbrechen {
    display: block;
    text-align: center;
    font-size: 13px;
    color: var(--atf-navy-nebentext);
    text-decoration: none;
    background: none;
    border: 0;
    cursor: pointer;
    font-family: inherit;
}
.atf-zusammenfassung-abbrechen:hover { color: #ffffff; text-decoration: underline; }

/* Preisbox: Live-Vorschau des Sendungspreises (Aufgabe 386, sendung/new.html.
   twig). Steht als eigene Karte direkt unter der dunklen Zusammenfassung in
   der Formular-Seitenspalte - bewusst HELL statt navy, sonst stuenden zwei
   dunkle Bloecke uebereinander und die Seite haette zwei "laute" Stellen
   statt einer. Der Aufbau echot die Zusammenfassung trotzdem bewusst (Titel,
   dann Zeilen, dann eine herausgehobene Summe), damit beide Karten als
   zusammengehoerig erkennbar bleiben. Die einzige bewusst betonte Stelle in
   dieser Karte ist die Brutto-Zeile: das ist die Zahl, auf die der Partner
   tatsaechlich schaut, alles andere bleibt zurueckhaltend. Die Klassen-
   und data-Attribut-Namen sind mit dem Skript im selben Template fest
   verdrahtet und duerfen hier nicht abweichen. */
.atf-preisbox {
    background: var(--atf-karte);
    border: 1px solid var(--atf-rand);
    border-radius: var(--atf-radius);
    padding: 16px 20px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.atf-preisbox-titel {
    font-family: var(--atf-schrift-titel);
    font-weight: 700;
    font-size: 16px;
    color: var(--atf-text);
}
.atf-preisbox-status {
    margin: 0;
    font-size: 13px;
    color: var(--atf-nebentext);
}
/* Sobald ein Preis feststeht, wird die Statuszeile zur navyfarbenen
   Kurzauskunft ("Frachtpflichtig 24,54 kg") - erkannt am sichtbaren Zustand
   der Positionsliste per :has(), ganz ohne eigenes JS-Flag (dasselbe Muster
   nutzt .atf-optionskarte weiter unten schon). */
.atf-preisbox:has([data-preis-liste]:not([hidden])) .atf-preisbox-status {
    color: var(--atf-navy);
    font-weight: 600;
}

.atf-preisbox-liste {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
/* Die Karte steht in einem <form> - hebt die globale Formularfehler-Marke
   "form ul li::before" (rotes Ausrufezeichen, siehe Abschnitt 4) fuer die
   Preiszeilen wieder auf, das ist hier kein Fehler. */
.atf-preisbox-liste > li::before { content: none; }
.atf-preisbox-zeile {
    display: block;
    margin: 0;
    padding: 0;
    font-size: 13px;
    font-weight: 400;
    color: var(--atf-text);
}
.atf-preisbox-zeile + .atf-preisbox-zeile {
    border-top: 1px solid var(--atf-rand-leicht);
    padding-top: 10px;
}
.atf-preisbox-zeile-kopf {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
}
/* Lange Bezeichnungen (Zuschlagsnamen, Zonentexte) duerfen umbrechen - die
   Karte steht in einer 330px-Spalte. */
.atf-preisbox-zeile-name {
    color: var(--atf-text-kraeftig);
    font-weight: 500;
    min-width: 0;
    overflow-wrap: break-word;
}
.atf-preisbox-zeile-betrag {
    flex: none;
    font-family: var(--atf-schrift-zahl);
    font-weight: 600;
    color: var(--atf-text);
    text-align: right;
    white-space: nowrap;
}

.atf-preisbox-rechenweg { margin-top: 6px; font-size: 12px; }
.atf-preisbox-rechenweg summary {
    cursor: pointer;
    color: var(--atf-navy);
    font-weight: 600;
}
.atf-preisbox-rechenweg summary:hover { color: var(--atf-navy-dunkel); }
.atf-preisbox-rechenweg[open] summary { margin-bottom: 6px; }
.atf-preisbox-rechenweg p {
    margin: 0;
    padding: 8px 10px;
    background: var(--atf-kopfzeile);
    border-radius: var(--atf-radius-klein);
    color: var(--atf-nebentext);
    font-family: var(--atf-schrift-zahl);
    font-size: 12px;
    line-height: 1.5;
}
.atf-preisbox-zeile-hinweis {
    margin: 4px 0 0;
    font-size: 12px;
    color: var(--atf-nebentext);
}

.atf-preisbox-summen {
    margin: 0;
    padding-top: 12px;
    border-top: 1px solid var(--atf-rand-kopf);
    display: flex;
    flex-direction: column;
    gap: 7px;
}
.atf-preisbox-summe {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin: 0;
}
.atf-preisbox-summe dt { font-weight: 400; font-size: 12px; color: var(--atf-nebentext); }
.atf-preisbox-summe dd {
    margin: 0;
    font-family: var(--atf-schrift-zahl);
    font-weight: 600;
    font-size: 13px;
    color: var(--atf-text);
    text-align: right;
}
/* Die Brutto-Zeile ist die eine bewusst betonte Stelle dieser Karte: eigenes
   navygetoentes Band, Zilla Slab statt Mono und deutlich groesser - dieselbe
   Rolle wie die grosse Zahl in der Zusammenfassungskarte darueber, nur hell
   statt dunkel und innerhalb der Karte statt kartenfuellend. */
.atf-preisbox-summe--brutto {
    margin-top: 4px;
    padding: 10px 12px;
    background: rgba(var(--atf-navy-rgb), 0.06);
    border-radius: var(--atf-radius-klein);
    align-items: center;
}
.atf-preisbox-summe--brutto dt {
    font-size: 13px;
    font-weight: 600;
    color: var(--atf-text-kraeftig);
}
.atf-preisbox-summe--brutto dd {
    font-family: var(--atf-schrift-titel);
    font-weight: 700;
    font-size: 24px;
    color: var(--atf-navy);
}

/* Warnhinweise (fehlende Zone, fehlender Tarif): dieselben gedaempften
   Warnton-Tokens wie .atf-hinweisleiste, und dasselbe Ausrufezeichen-Muster
   wie die Formularfehler oben - erkennbar als Hinweis, nicht schreierisch,
   und nie mit der reservierten Fehlerfarbe verwechselbar. */
.atf-preisbox-hinweise {
    list-style: none;
    margin: 0;
    padding: 10px 12px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    background: var(--atf-warnung-flaeche);
    border: 1px solid var(--atf-warnung-rand-leicht);
    border-radius: var(--atf-radius-klein);
}
.atf-preisbox-hinweise li {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    margin: 0;
    font-size: 12px;
    font-weight: 600;
    color: var(--atf-status-abgeholt-text);
}
.atf-preisbox-hinweise li::before { content: '!'; flex: none; }

.atf-preisbox-fuss {
    margin: 0;
    padding-top: 10px;
    border-top: 1px solid var(--atf-rand-kopf);
    font-size: 11px;
    line-height: 1.5;
    color: var(--atf-gedaempft);
}

/* Options-Karte: eine radiofoermige Auswahlkarte, z. B. die Produktwahl
   ND/OV in sendung-anlegen.html - der Kopfkommentar dieser Datei nennt sie
   schon lange als Baustein, sie fehlte aber bisher tatsaechlich. Markup je
   Karte: <label class="atf-optionskarte"><input type="radio" ...
   class="atf-optionskarte-eingabe"><span class="atf-optionskarte-text">
   <span class="atf-optionskarte-titel">...</span><span
   class="atf-optionskarte-untertitel">...</span></span><span
   class="atf-optionskarte-kugel" aria-hidden="true"></span></label>, mehrere
   davon in einem umschliessenden .atf-optionskarten. Das echte
   input[type=radio] bleibt fuer Maus, Tastatur, Formularabsendung und
   Screenreader vollstaendig erhalten (nur visuell durch die Kugel ersetzt,
   siehe .atf-optionskarte-eingabe) - der Feldname bleibt damit exakt der,
   den das jeweilige Formular vorgibt. Ausgewaehlt/Fokus wird rein per
   CSS (:has) erkannt, ohne dass eine Fachlogik zusaetzliche Klassen
   pflegen muesste. */
.atf-optionskarten { display: flex; flex-direction: column; gap: 10px; }
.atf-optionskarte {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    border: 1px solid var(--atf-rand);
    border-radius: var(--atf-radius);
    padding: 12px 14px;
    cursor: pointer;
}
.atf-optionskarte-eingabe {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}
.atf-optionskarte-text { display: flex; flex-direction: column; gap: 1px; }
.atf-optionskarte-titel { font-weight: 600; font-size: 14px; color: var(--atf-text-kraeftig); }
.atf-optionskarte-untertitel { font-size: 12px; color: var(--atf-gedaempft); }
.atf-optionskarte-kugel {
    width: 18px; height: 18px; flex: none;
    border-radius: 50%;
    border: 2px solid var(--atf-eingabe-rand);
}
.atf-optionskarte:has(.atf-optionskarte-eingabe:checked) {
    border: 2px solid var(--atf-navy);
    background: var(--atf-flaeche);
    /* 1px weniger Innenabstand gleicht den 1px dickeren Rand aus, damit die
       Karte beim Auswaehlen nicht "springt". */
    padding: 11px 13px;
}
.atf-optionskarte:has(.atf-optionskarte-eingabe:checked) .atf-optionskarte-titel { color: var(--atf-navy); }
.atf-optionskarte:has(.atf-optionskarte-eingabe:checked) .atf-optionskarte-kugel {
    border-width: 5px;
    border-color: var(--atf-navy);
}
.atf-optionskarte:has(.atf-optionskarte-eingabe:focus-visible) {
    outline: 3px solid rgba(var(--atf-navy-rgb), 0.5);
    outline-offset: 2px;
}

/* Aufklappbare Erklaerung mehrerer gleichartiger Auswahlmoeglichkeiten, z. B.
   der fuenf Staffel-Arten im Formular "Stufe hinzufuegen" (Preisliste,
   Clearing) - der Text je Eintrag kommt direkt aus
   Atf\Common\Entity\PreisStaffelArt::erklaerung() (siehe choice_attr in
   PreisStaffelType), damit die Erklaerung an GENAU EINER Stelle im Code
   steht statt zusaetzlich im Twig nachgebaut zu werden. Dieselbe navyfarbene
   Klick-Optik wie .atf-preisbox-rechenweg, aber als Liste statt eines
   einzelnen Absatzes - standardmaessig eingeklappt, damit das Formular ruhig
   bleibt, ohne die Erklaerung zu verstecken (siehe help-Text am Feld). Jeder
   Eintrag traegt zusaetzlich dieselbe .atf-bauart-Marke wie die Stufenliste
   oben, damit beide Ansichten dieselbe Sprache sprechen. */
.atf-arten-erklaerung { margin-top: 4px; }
.atf-arten-erklaerung summary { cursor: pointer; font-size: 13px; font-weight: 600; color: var(--atf-navy); }
.atf-arten-erklaerung summary:hover { color: var(--atf-navy-dunkel); }
.atf-arten-erklaerung[open] summary { margin-bottom: 10px; }
.atf-arten-erklaerung-liste { display: flex; flex-direction: column; gap: 8px; }
.atf-arten-eintrag {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 9px 12px;
    background: var(--atf-kopfzeile);
    border-radius: var(--atf-radius-klein);
}
.atf-arten-eintrag-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.atf-arten-eintrag-titel { font-size: 13px; color: var(--atf-text-kraeftig); }
.atf-arten-eintrag-erklaerung { margin: 0; font-size: 12px; color: var(--atf-nebentext); }

/* Live-Rueckmeldung zur Sendungsart-Auswahl: wie viele Sendungsarten auf der
   eingetragenen Strecke buchbar sind (data-sendungsart-status,
   sendung/new.html.twig) - ruhiger Hinweistext unterhalb der Produktwahl,
   dieselbe Sprache wie .atf-preisbox-status. */
.atf-sendungsart-status {
    margin: 10px 0 0;
    font-size: 12px;
    color: var(--atf-nebentext);
}

/* Zweispaltiges Formular-Layout: Formular-Abschnitte links, Zusammenfassung/
   Details rechts in fester Breite (siehe sendung-anlegen.html,
   sendung-detail.html). */
.atf-formular-layout { display: flex; gap: 20px; align-items: flex-start; }
.atf-formular-haupt { flex-grow: 1; min-width: 0; display: flex; flex-direction: column; gap: 16px; }
.atf-formular-seite { width: 330px; flex: none; display: flex; flex-direction: column; gap: 16px; }

/* Feld-Raster innerhalb eines Formular-Abschnitts: zwei Spalten, ein Feld
   kann mit .breit beide Spalten belegen (siehe "Firma / Name" im Mockup). */
.atf-feld-raster { display: grid; grid-template-columns: 1fr 1fr; gap: 14px 16px; }
.atf-feld-raster .breit, .atf-feld-raster .atf-feld--breit { grid-column: 1 / -1; }
/* PLZ (schmal) + Ort (breit) nebeneinander. */
.atf-feld-doppel { display: flex; gap: 12px; flex-wrap: wrap; }
.atf-feld-doppel > :first-child { width: 120px; flex: none; }
.atf-feld-doppel > :last-child { flex-grow: 1; min-width: 160px; }
/* Ein Formularfeld, das in einer Aktions-Zeile (siehe .atf-aktions-zeile
   weiter unten) den restlichen Platz einnimmt, z. B. die Begruendung neben
   "Ablehnen"/"Zuruecknehmen" bei Reklamationen. */
.atf-feld--wachsend { flex-grow: 1; min-width: 220px; }
/* Strasse (breit) + Hausnummer (schmal) nebeneinander - Gegenstueck zu
   .atf-feld-doppel--plz darunter, beide ueberschreiben die 120px/breit-
   Grundaufteilung von .atf-feld-doppel vollstaendig (siehe Absender/
   Empfaenger in sendung/new.html.twig). */
.atf-feld-doppel--strasse > :first-child { width: auto; flex-grow: 1; min-width: 200px; }
.atf-feld-doppel--strasse > :last-child { width: 100px; flex: none; min-width: 0; }
/* PLZ (schmal) + Ort (breit) - entspricht der Grundaufteilung von
   .atf-feld-doppel, hier als eigene, sprechende Klasse fuer die
   Sendungs-Adressbloecke, statt sich auf die unbenannte Voreinstellung zu
   verlassen. */
.atf-feld-doppel--plz > :first-child { width: 120px; flex: none; }
.atf-feld-doppel--plz > :last-child { flex-grow: 1; min-width: 160px; }
/* Zwei gleichrangige Felder nebeneinander (E-Mail/Telefon, Zeitfenster
   von/bis in sendung/new.html.twig) - anders als PLZ/Ort ist keins der
   beiden Felder von Natur aus kurz, deshalb wachsen beide zu gleichen
   Teilen statt das erste auf 120px zu zwingen. */
.atf-feld-doppel--gleich > :first-child,
.atf-feld-doppel--gleich > :last-child { width: auto; flex: 1 1 0; min-width: 140px; }

/* Kopfzeile einer dynamischen Zeilenliste (z. B. Packstuecke): kleine graue
   Spaltentitel ueber wiederholbaren Formularzeilen. Die Spaltenzahl ist je
   Seite unterschiedlich - dafuer gibt es je Anwendungsfall eine eigene
   Modifier-Klasse weiter unten (--packstueck, --zuordnung). NIEMALS inline
   setzen: Inline-Angaben gewinnen die Kaskade und haetten in der mobilen
   Ein-Spalten-Ansicht ein !important erzwungen. */
.atf-zeilen-kopf {
    display: grid;
    gap: 10px;
    padding: 10px 20px 4px;
    font-size: 11px;
    color: var(--atf-nebentext);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.atf-zeilen-raster {
    display: grid;
    gap: 10px;
    padding: 6px 20px;
    align-items: center;
}
.atf-zeilen-raster:last-of-type { padding-bottom: 16px; }
.atf-zeilen-raster input, .atf-zeilen-raster select { max-width: none; padding: 9px 12px; }
/* Sieben-Spalten-Variante fuer die Packstueck-Zeilenliste: # / Laenge /
   Breite / Hoehe / Realgewicht / Volumengewicht-Hinweis / Entfernen-Knopf. */
.atf-zeilen-kopf--packstueck,
.atf-zeilen-raster--packstueck {
    grid-template-columns: 34px repeat(4, 1fr) 120px 34px;
}
/* Zwei-Spalten-Variante fuer die CSV-Spaltenzuordnung: gefundene Spalte /
   zugeordnetes Sendungsfeld - Letzteres etwas breiter, weil dort ein
   Auswahlmenue mit langen Feldnamen samt "(Pflicht)"-Zusatz steht. */
.atf-zeilen-kopf--zuordnung,
.atf-zeilen-raster--zuordnung {
    grid-template-columns: 1fr 1.4fr;
}
/* Steht in einer Zeilenliste ein Formular-Label statt einer reinen Nummer
   (z. B. die Spaltennamen der CSV-Zuordnung), braucht es nicht den
   Abstand nach unten, den "form label" fuer gestapelte Formulare setzt -
   hier sitzt es in derselben Zeile wie sein Eingabefeld. */
.atf-zeilen-raster label { margin-bottom: 0; }
.atf-zeilen-nummer { font-family: var(--atf-schrift-zahl); font-size: 13px; color: var(--atf-nebentext); }
.atf-zeilen-hinweis { font-family: var(--atf-schrift-zahl); font-size: 13px; color: var(--atf-nebentext); }
.atf-zeilen-hinweis span { color: var(--atf-dekor); }
.atf-zeilen-entfernen {
    color: var(--atf-dekor);
    font-size: 16px;
    text-align: center;
    background: none;
    border: 0;
    cursor: pointer;
    padding: 6px;
    line-height: 1;
    border-radius: var(--atf-radius-klein);
}
.atf-zeilen-entfernen:hover { color: var(--atf-status-fehler); background: var(--atf-fehler-flaeche); }

/* Haken-Raster: viele Ankreuzfelder (die 17 Sendungs-Kennzeichen) in
   mehreren Spalten statt einer langen Liste - siehe "Kennzeichen und
   Zusatzleistungen" in sendung/new.html.twig. Symfony liefert je Checkbox
   ein eigenes <div> (form_row_render: erst das Label, dann die Eingabe,
   dann optional der Hilfetext) - jede dieser Zeilen bekommt zusaetzlich die
   Klasse .atf-haken per row_attr, an Feldname/ID oder Struktur aendert das
   nichts. Damit trotzdem "Kaestchen vor Text" zu sehen ist (die gewohnte
   Lesrichtung), wird NUR die Reihenfolge visuell per flex/order getauscht -
   im DOM bleibt es beim Symfony-Standard. Spaltenzahl richtet sich nach
   verfuegbarem Platz (auto-fill), auf schmalen Bildschirmen faellt es von
   selbst auf eine Spalte zusammen - keine eigene Media-Query noetig. */
.atf-haken-raster {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 2px 24px;
}
.atf-haken-raster > .atf-haken {
    margin-bottom: 0;
    padding: 8px 0;
    border-bottom: 1px solid var(--atf-rand-leicht);
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
}
.atf-haken-raster label {
    order: 2;
    display: inline;
    font-size: 13px;
    font-weight: 500;
    margin-bottom: 0;
    cursor: pointer;
}
.atf-haken-raster input[type="checkbox"] { order: 1; }
/* Der Hilfetext (help-text) bleibt bewusst kleiner und gedaempfter als
   sonst im Formular ueblich - er ist wichtig, soll aber neben 17 Zeilen
   nicht dominieren. Er steht auf eigener Zeile unter Kaestchen und Label
   (order 3 + volle Breite), mit demselben Einzug wie der Label-Text. */
.atf-haken-raster .help-text {
    order: 3;
    flex-basis: 100%;
    margin: 3px 0 0 24px;
    font-size: 11px;
    line-height: 1.4;
}

/* Bedingt eingeblendetes Feld: erscheint erst mit dem zugehoerigen Haken
   (z. B. Abstellort unter "Abstellgenehmigung", data-abstellort-block) - das
   Ein-/Ausblenden macht ausschliesslich das Skript im Template, hier nur die
   Optik: ein eingerueckter Kasten mit Navy-Akzentkante, damit erkennbar
   bleibt, dass das Feld zu einem Haken darueber gehoert statt ein eigener,
   gleichrangiger Formular-Abschnitt zu sein. */
.atf-bedingtes-feld {
    margin-top: 12px;
    padding: 14px 16px;
    background: var(--atf-flaeche);
    border-left: 3px solid var(--atf-navy);
    border-radius: 0 var(--atf-radius) var(--atf-radius) 0;
}

/* Zeitstrahl mit Punkten fuer Verlaeufe (siehe "Verlauf" in
   sendung-detail.html). Markup je Eintrag:
   .atf-zeitstrahl-eintrag > (.atf-zeitstrahl-spur > .atf-zeitstrahl-punkt +
   .atf-zeitstrahl-linie) + .atf-zeitstrahl-inhalt. Der juengste Eintrag steht
   oben; .atf-zeitstrahl-punkt--ursprung markiert den Startpunkt (z. B.
   "Sendung angelegt") in gedaempftem Grau statt Navy. */
.atf-zeitstrahl { display: flex; flex-direction: column; }
.atf-zeitstrahl-eintrag { display: flex; gap: 14px; }
.atf-zeitstrahl-spur { display: flex; flex-direction: column; align-items: center; flex: none; }
.atf-zeitstrahl-punkt { width: 12px; height: 12px; border-radius: 50%; background: var(--atf-navy); flex: none; }
.atf-zeitstrahl-punkt--ursprung { background: var(--atf-status-angemeldet); }
.atf-zeitstrahl-linie { width: 2px; flex-grow: 1; min-height: 12px; background: var(--atf-rand-leicht); }
.atf-zeitstrahl-eintrag:last-child .atf-zeitstrahl-linie { display: none; }
.atf-zeitstrahl-inhalt { display: flex; flex-direction: column; gap: 1px; padding-bottom: 16px; }
.atf-zeitstrahl-eintrag:last-child .atf-zeitstrahl-inhalt { padding-bottom: 0; }
.atf-zeitstrahl-titel { font-weight: 600; font-size: 14px; }
.atf-zeitstrahl-zeit { font-size: 12px; color: var(--atf-gedaempft); }

/* Routenlauf: waagerechter Fortschritt Abholung -> Hub(s) -> Zustellung
   (siehe sendung-detail.html, obere Karte). Markup: zwei
   .atf-routenlauf-endpunkt (links/rechts) umschliessen eine
   .atf-routenlauf-strecke mit abwechselnd .atf-routenlauf-linie und
   .atf-routenlauf-hub - je erreichtem Abschnitt mit dem Zusatz "--erledigt"
   bzw. "--erreicht"; der aktuelle Standort bekommt zusaetzlich einen
   .atf-routenlauf-marker in der laufenden Linie. */
.atf-routenlauf { display: flex; align-items: center; }
.atf-routenlauf-endpunkt { display: flex; flex-direction: column; gap: 3px; width: 220px; flex: none; }
.atf-routenlauf-endpunkt--rechts { align-items: flex-end; text-align: right; }
.atf-routenlauf-label { font-size: 11px; color: var(--atf-nebentext); font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; }
.atf-routenlauf-ort { font-weight: 600; font-size: 15px; }
.atf-routenlauf-zeit { font-size: 12px; color: var(--atf-gedaempft); }
.atf-routenlauf-strecke { flex-grow: 1; display: flex; align-items: center; }
.atf-routenlauf-linie { flex-grow: 1; height: 4px; background: var(--atf-linie-offen); position: relative; }
.atf-routenlauf-linie--erledigt { background: var(--atf-navy); }
.atf-routenlauf-marker {
    position: absolute; right: -2px; top: 50%; transform: translateY(-50%);
    width: 18px; height: 18px; border-radius: 50%;
    background: #ffffff; border: 4px solid var(--atf-navy);
}
.atf-routenlauf-hub {
    flex: none;
    border: 2px solid var(--atf-eingabe-rand);
    background: var(--atf-karte);
    color: var(--atf-nebentext);
    border-radius: var(--atf-radius);
    padding: 5px 14px;
    font-weight: 700;
    font-size: 13px;
}
.atf-routenlauf-hub--erreicht { border-color: var(--atf-navy); background: var(--atf-navy); color: #ffffff; }
.atf-routenlauf-hinweis { margin-top: 10px; font-size: 12px; color: var(--atf-gedaempft); text-align: center; }

/* Filterzeile fuer Tabellen: Suche, Status, Zeitraum - rein gestalterisch,
   ohne eigene Filter-Logik (die liefert der jeweilige Dienst). Sitzt
   typischerweise im .atf-abschnitt-kopf neben dem Kartentitel. */
.atf-filterzeile { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

input[type="search"].atf-suchfeld {
    width: 220px;
    max-width: 100%;
    padding: 7px 12px 7px 34px;
    font-size: 13px;
    color: var(--atf-text);
    border: 1px solid var(--atf-rand);
    border-radius: var(--atf-radius-klein);
    background-color: var(--atf-karte);
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2396a0ac' stroke-width='2.4' stroke-linecap='round'><circle cx='11' cy='11' r='7'/><path d='M20 20l-4-4'/></svg>");
    background-repeat: no-repeat;
    background-position: 10px center;
    background-size: 14px 14px;
}
input[type="search"].atf-suchfeld::placeholder { color: var(--atf-gedaempft); }

select.atf-filter {
    appearance: none;
    -webkit-appearance: none;
    width: auto;
    max-width: 220px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 30px 7px 12px;
    font-size: 13px;
    font-weight: 500;
    color: var(--atf-text-kraeftig);
    border: 1px solid var(--atf-rand);
    border-radius: var(--atf-radius-klein);
    background-color: var(--atf-karte);
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2366707e' stroke-width='2.4' stroke-linecap='round'><path d='M6 9l6 6 6-6'/></svg>");
    background-repeat: no-repeat;
    background-position: right 10px center;
    background-size: 12px 12px;
    cursor: pointer;
}

/* Fuss einer Tabellen-Karte: Trefferzahl links, Blaetterleiste rechts. */
.atf-tabellen-fuss {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    flex-wrap: wrap;
    padding: 11px 20px;
    background: var(--atf-kopfzeile);
}
.atf-trefferzahl { font-size: 12px; color: var(--atf-gedaempft); }

.atf-blaetterleiste { display: flex; align-items: center; gap: 4px; font-size: 13px; list-style: none; margin: 0; padding: 0; }
.atf-blaetterleiste a,
.atf-blaetterleiste span {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 30px;
    padding: 5px 11px;
    border: 1px solid var(--atf-rand);
    border-radius: var(--atf-radius-klein);
    color: var(--atf-text-kraeftig);
    text-decoration: none;
}
.atf-blaetterleiste a:hover { border-color: var(--atf-navy); color: var(--atf-navy); }
.atf-blaetterleiste a.aktuell,
.atf-blaetterleiste span.aktuell {
    background: var(--atf-navy);
    border-color: var(--atf-navy);
    color: #ffffff;
    font-weight: 600;
}
.atf-blaetterleiste span.deaktiviert { color: var(--atf-dekor); border-color: var(--atf-rand); cursor: default; }

/* Leerer Zustand: ruhiger Hinweis statt einer leeren Tabelle/Liste - erklaert,
   was hier erscheinen wird und was der naechste Schritt waere. */
.atf-leerzustand {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 48px 24px;
    text-align: center;
    color: var(--atf-nebentext);
}
.atf-leerzustand-symbol {
    width: 40px; height: 40px;
    border-radius: 50%;
    border: 2px dashed var(--atf-rand);
    display: flex; align-items: center; justify-content: center;
    color: var(--atf-gedaempft);
    font-size: 18px;
    margin-bottom: 4px;
}
.atf-leerzustand-titel { font-family: var(--atf-schrift-titel); font-weight: 700; font-size: 16px; color: var(--atf-text); }
.atf-leerzustand-text { font-size: 13px; color: var(--atf-nebentext); max-width: 360px; }
.atf-leerzustand .knopf, .atf-leerzustand .knopf--haupt { margin-top: 10px; }

/* Schritt-Anzeige fuer mehrstufige Ablaeufe (z. B. CSV-Import: Hochladen ->
   Zuordnen -> Ergebnis). Nummerierte Kreise, durch eine Linie verbunden -
   dieselbe Sprache aus Punkt-und-Linie wie beim Routenlauf einer Sendung,
   nur fuer einen Arbeitsablauf statt einer physischen Strecke. Drei
   Zustaende: erledigt (Navy, ausgefuellt), aktuell (Navy-Rand, betont),
   offen (gedaempft) - bewusst OHNE Rot, das bleibt der Hauptaktion der
   jeweiligen Seite vorbehalten. Markup: <ol class="atf-schritte"><li
   class="atf-schritt atf-schritt--erledigt|--aktuell|--offen"><span
   class="atf-schritt-marke">1</span><span class="atf-schritt-label">...
   </span></li>...</ol>, das aktuelle <li> traegt zusaetzlich
   aria-current="step". */
.atf-schritte { display: flex; align-items: center; list-style: none; margin: 0 0 20px; padding: 0; }
.atf-schritt { display: flex; align-items: center; flex: 1 1 0; min-width: 0; }
.atf-schritt:last-child { flex: 0 0 auto; }
.atf-schritt-marke {
    width: 26px; height: 26px; border-radius: 50%; flex: none;
    display: flex; align-items: center; justify-content: center;
    font-family: var(--atf-schrift-zahl); font-weight: 600; font-size: 12px;
    border: 2px solid var(--atf-rand); color: var(--atf-gedaempft); background: var(--atf-karte);
}
.atf-schritt-label { margin-left: 10px; font-size: 13px; font-weight: 600; color: var(--atf-gedaempft); white-space: nowrap; }
.atf-schritt:not(:last-child)::after { content: ''; flex-grow: 1; height: 2px; background: var(--atf-rand); margin: 0 14px; }
.atf-schritt--erledigt .atf-schritt-marke { background: var(--atf-navy); border-color: var(--atf-navy); color: #ffffff; }
.atf-schritt--erledigt .atf-schritt-label { color: var(--atf-text-kraeftig); }
.atf-schritt--erledigt:not(:last-child)::after { background: var(--atf-navy); }
.atf-schritt--aktuell .atf-schritt-marke { border-color: var(--atf-navy); color: var(--atf-navy); }
.atf-schritt--aktuell .atf-schritt-label { color: var(--atf-navy); }

/* Ergebniszeile: eine Kennzahl eingebettet in einen Fliesstext-Satz, z. B.
   nach einem Stapel-Vorgang ("<strong>3</strong> Sendung(en) angelegt").
   Bewusst KEIN Kennzahl-Karten-Baustein, weil der Zahlenwert Teil eines
   ganzen, testrelevanten Satzes bleiben muss - die Zahl wird nur groesser
   und in Navy hervorgehoben, der Satz drumherum bleibt normaler Fliesstext. */
.atf-ergebnis-zeile { font-size: 15px; }
.atf-ergebnis-zeile strong {
    font-family: var(--atf-schrift-titel);
    font-size: 22px;
    color: var(--atf-navy);
}

/* Anmelde-Buehne: dunkle, markenstarke Flaeche mit den Flottenstreifen am
   Rand, die die weisse Login-Karte zentriert traegt (siehe login.html-
   Mockup). Wiederverwendbar von jedem der fuenf Dienste. */
.atf-anmelde-buehne {
    background: var(--atf-navy);
    min-height: calc(100vh - 64px);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 40px 20px;
    position: relative;
    overflow: hidden;
}
.atf-anmelde-buehne::before {
    content: '';
    position: absolute;
    top: 0;
    left: -60px;
    width: 46px;
    height: 100%;
    background: rgba(var(--atf-rot-rgb), 0.85);
    transform: skewX(-14deg);
}
.atf-anmelde-buehne::after {
    content: '';
    position: absolute;
    top: 0;
    left: -6px;
    width: 18px;
    height: 100%;
    background: rgba(255, 255, 255, 0.12);
    transform: skewX(-14deg);
}
.atf-anmelde-karte {
    width: 100%;
    max-width: 420px;
    background: var(--atf-karte);
    border-radius: 6px;
    padding: 34px 36px 30px;
    display: flex;
    flex-direction: column;
    gap: 20px;
    position: relative;
    z-index: 1;
}
.atf-anmelde-marke { display: flex; flex-direction: column; gap: 10px; }
.atf-anmelde-marke .atf-streifen span { width: 34px; height: 7px; }
.atf-anmelde-titel { font-family: var(--atf-schrift-titel); font-weight: 700; font-size: 24px; color: var(--atf-text); }
.atf-anmelde-untertitel { font-size: 13px; color: var(--atf-nebentext); }
.atf-anmelde-fuss {
    border-top: 1px solid var(--atf-rand-kopf);
    padding-top: 14px;
    font-size: 12px;
    color: var(--atf-gedaempft);
    line-height: 1.5;
}
.atf-anmelde-karte form { display: flex; flex-direction: column; gap: 14px; }
.atf-anmelde-karte .knopf--haupt { width: 100%; text-align: center; padding: 12px 0; font-size: 15px; }
.atf-anmelde-fehler {
    border: 1px solid var(--atf-gefahr-rand);
    background: var(--atf-fehler-flaeche);
    color: var(--atf-status-fehler);
    border-radius: var(--atf-radius);
    padding: 10px 14px;
    font-size: 13px;
    font-weight: 600;
}
@media (max-width: 900px) {
    .atf-anmelde-buehne { min-height: 0; padding: 24px 14px; }
    .atf-anmelde-karte { padding: 26px 22px 24px; }
}

/* Meldungen. Die Klassennamen "meldung"/"flash" sind Bestand aus den
   vorhandenen Vorlagen - beide werden unterstuetzt, damit keine Seite
   angefasst werden muss. */
.meldung, .flash {
    padding: 11px 14px;
    border-radius: var(--atf-radius);
    margin-bottom: 14px;
    border: 1px solid var(--atf-rand);
    background: var(--atf-karte);
    border-left-width: 4px;
}
.meldung.success, .flash-success { border-left-color: var(--atf-status-zugestellt); background: #eef7f1; }
.meldung.error, .flash-error { border-left-color: var(--atf-status-fehler); background: var(--atf-fehler-flaeche); }
.meldung.warning, .flash-warning { border-left-color: var(--atf-status-abgeholt); background: #fdf7e8; }

.atf-nebentext, .nebentext { color: var(--atf-nebentext); font-size: 13px; }
/* .atf-leer ist ausschliesslich fuer echte Leere reserviert: es existiert
   gerade nichts (keine Bedingung, kein Verlaufseintrag, kein Hub gesetzt).
   Fuer real vorhandenen, aber bewusst zurueckhaltend gestalteten Inhalt -
   z. B. die stille Spaltenueberschrift "Aktion" ueber einer Spalte mit
   echten Knoepfen - gilt stattdessen .atf-nebentext; sonst behauptet die
   kursive "nichts vorhanden"-Optik etwas, das nicht stimmt. */
.atf-leer { color: var(--atf-gedaempft); font-style: italic; }
/* Abstand oberhalb eines kurzen Zusatzsatzes, wenn er auf eine kv-Liste oder
   ein Berechnungsergebnis folgt (z. B. Saldovortrag im Kontokorrent, Hinweis
   nach einer Reklamations-Entscheidung, Ergebnis einer Tarifstufen-Vorschau). */
.atf-abstand-oben { margin-top: 14px; }

/* ---------- 4. Nackte Elemente ------------------------------------------- */

h1, h2, h3, h4 { font-family: var(--atf-schrift-titel); font-weight: 700; color: var(--atf-text); margin: 0 0 10px; }
h1 { font-size: 26px; line-height: 1.15; }
h2 { font-size: 18px; margin-top: 26px; }
h3 { font-size: 15px; margin-top: 20px; }
/* Der erste Titel einer Seite braucht keinen Abstand nach oben - dasselbe
   gilt eine Ebene tiefer fuer den ersten Zwischentitel (h3) in einem
   Abschnitts-Koerper, z. B. "PLZ-Bereich hinzufuegen", "Station
   hinzufuegen", "Stufe hinzufuegen". */
.atf-inhalt > h1:first-child, .atf-inhalt > h2:first-child,
.atf-abschnitt-koerper > h3:first-child { margin-top: 0; }

p { margin: 0 0 12px; }
p:last-child { margin-bottom: 0; }

hr { border: 0; border-top: 1px solid var(--atf-rand); margin: 20px 0; }

/* Tabellen: sehen wie eine Karte aus. Die alten border="1"-Angaben aus den
   Vorlagen werden hier absichtlich ueberschrieben, damit keine Seite dafuer
   angefasst werden muss. */
table {
    border-collapse: collapse;
    width: 100%;
    background: var(--atf-karte);
    border: 1px solid var(--atf-rand);
    border-radius: var(--atf-radius);
    overflow: hidden;
    margin-bottom: 18px;
    font-size: 14px;
}
th, td {
    border: 0;
    border-bottom: 1px solid var(--atf-rand-leicht);
    padding: 10px 14px;
    text-align: left;
    vertical-align: top;
}
thead th, table > tr:first-child > th {
    background: var(--atf-kopfzeile);
    color: var(--atf-nebentext);
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    white-space: nowrap;
    /* Etwas kraeftiger als die Trennlinie zwischen einzelnen Zeilen - so
       steht es in allen fuenf Mockups. */
    border-bottom: 1px solid var(--atf-rand-kopf);
}
/* Steckbrief-Tabellen (th in der ersten Spalte statt im Kopf) */
tbody tr > th:first-child, table > tr > th:first-child {
    background: var(--atf-kopfzeile);
    width: 240px;
    color: var(--atf-nebentext);
    font-weight: 600;
    text-transform: none;
    letter-spacing: 0;
    font-size: 13px;
}
tbody tr:last-child > td, tbody tr:last-child > th { border-bottom: 0; }
tbody tr:hover > td { background: #fbfcfd; }

/* Zeilenhervorhebung, z. B. eine ueberladene Linie im Linienplan oder eine
   Zeile ohne Soll-Zuordnung - dieselben gedaempften Flaechen wie die
   Hinweisleiste/Meldungen, nur je Tabellenzeile statt je Karte. */
.atf-zeile--warnung > td { background: var(--atf-warnung-flaeche); }
.atf-zeile--warnung:hover > td { background: #fbecd6; }
.atf-zeile--kritisch > td { background: var(--atf-fehler-flaeche); }
.atf-zeile--kritisch:hover > td { background: #f9dedc; }
/* Eine Zeile, die noch DA ist, aber nicht mehr MITZAEHLT - heute ein aus der
   Sendung genommenes Packstueck. Bewusst weder Warnung noch Fehler: Es ist
   nichts schiefgegangen, die Zeile gehoert nur nicht mehr in die Summe. Nur
   gedaempft und nicht ausgeblendet, weil das Etikett dazu weiter existiert. */
.atf-zeile--gedaempft > td { color: var(--atf-nebentext); background: var(--atf-flaeche-leise, #fafbfc); }

/* Feste, schmale Spaltenbreite fuer eine kurze Kopfzeile (z. B. "Zeile" in
   der CSV-Import-Fehlerliste), damit die zweite, textreiche Spalte den Rest
   des Platzes bekommt statt sich mit einer zufaellig breiten ersten Spalte
   zu teilen. */
.atf-spalte--schmal { width: 130px; }

/* Zahlen, Sendungsnummern, PLZ und Betraege: Monospace und rechtsbuendig. */
.atf-zahl, td.zahl, th.zahl { font-family: var(--atf-schrift-zahl); text-align: right; font-variant-numeric: tabular-nums; }
/* Groessere Zahl/Betrag innerhalb von Fliesstext, z. B. das
   Vorschau-Ergebnis einer Tarifstufen-Berechnung oder einer
   Preislisten-Proberechnung. */
.atf-zahl--gross { font-size: 18px; }
.atf-nummer { font-family: var(--atf-schrift-zahl); font-size: 13px; font-weight: 500; color: var(--atf-navy); }
/* Groessere Darstellung eines einmalig prominent angezeigten Codes, z. B.
   der Klartext-API-Schluessel direkt nach dem Anlegen. */
.atf-nummer--gross { font-size: 15px; }
/* Eine Belegnummer, die groesser im Seitentitel steht statt in einer
   Tabellenzelle (Beleg-Detailseite: "Rechnung R2026-000042"). */
.atf-nummer--titel { font-size: 20px; }
/* Eine Summenzeilen-Beschriftung ("Netto", "Gesamt") in einer <th colspan>,
   die mit der rechtsbuendigen Betragsspalte danach fluchten soll - bewusst
   OHNE Mono-Schrift, das ist hier ein Wort, keine Ziffer (siehe Beleg-Detail,
   Fusszeile der Positionstabelle). */
.atf-tabelle-label-rechts { text-align: right; }

/* Ein Befehl oder eine Antwort zum Abtippen bzw. Kopieren - bisher nur in der
   Anleitung der Partner-Schnittstelle (/api/doku, Aufgabe 418). Bewusst mit
   Umbruch statt waagerechtem Schieben: Ein curl-Aufruf ueber mehrere Zeilen
   soll ganz zu sehen sein, sonst kopiert jemand die Haelfte. */
.atf-codeblock {
    font-family: var(--atf-schrift-zahl);
    font-size: 12.5px;
    line-height: 1.55;
    background: var(--atf-flaeche);
    border: 1px solid var(--atf-rand);
    border-radius: 6px;
    padding: 12px 14px;
    margin: 10px 0 14px;
    overflow-x: auto;
    white-space: pre-wrap;
    word-break: break-word;
}

/* Formulare: Symfony liefert je Feld ein div mit label und Eingabe. */
form { margin: 0; }
form > div, .atf-feld { margin-bottom: 14px; }
form label {
    display: block;
    font-size: 13px;
    font-weight: 600;
    color: var(--atf-text-kraeftig);
    margin-bottom: 5px;
}
input[type="text"], input[type="email"], input[type="password"], input[type="number"],
input[type="date"], input[type="time"], input[type="datetime-local"], input[type="search"],
input[type="tel"], input[type="url"], input[type="file"], select, textarea {
    width: 100%;
    max-width: 520px;
    border: 1px solid var(--atf-eingabe-rand);
    border-radius: var(--atf-radius);
    padding: 10px 13px;
    font-size: 14px;
    font-family: inherit;
    color: var(--atf-text);
    background: var(--atf-karte);
}
input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--atf-navy);
    box-shadow: 0 0 0 3px rgba(var(--atf-navy-rgb), 0.12);
}
textarea { min-height: 90px; }
/* Schmales Zahleneingabefeld, wenn ein einzelner Wert bewusst nicht die
   volle Formularbreite braucht, z. B. das Beispielgewicht in einer
   Tarif-Vorschau. */
input.atf-eingabe--schmal { width: 120px; max-width: 120px; }
/* Schmales, rechtsbuendiges Mono-Eingabefeld fuer einen Betrag, den ein
   Sachbearbeiter von Hand eintraegt (Zahlung von Hand zuordnen). */
input.atf-eingabe-betrag { max-width: 110px; text-align: right; font-family: var(--atf-schrift-zahl); }

/* Ankreuzfelder stehen neben ihrer Beschriftung, nicht darunter. */
input[type="checkbox"], input[type="radio"] { width: auto; margin-right: 8px; vertical-align: middle; }
input[type="checkbox"] + label, input[type="radio"] + label { display: inline; font-weight: 500; }

/* Hilfetexte */
.help-text, .form-help, small { display: block; font-size: 12px; color: var(--atf-gedaempft); margin-top: 4px; }

/* Scanplatz-Formular: eine Lager-Ansicht auf einem Tablet, kein
   Buero-Formular - Eingaben und der Hauptknopf brauchen deutlich groessere,
   leichter zu treffende Flaechen als der sonst uebliche Formularsatz. Wirkt
   nur innerhalb von .atf-scan-formular, aendert also nichts an
   Feldnamen/IDs oder am generischen Formular-Erscheinungsbild ueberall
   sonst. */
.atf-scan-formular label { font-size: 14px; }
.atf-scan-formular input[type="text"],
.atf-scan-formular input[type="number"],
.atf-scan-formular select {
    font-size: 18px;
    padding: 14px 16px;
    min-height: 52px;
}
.atf-scan-formular .knopf--haupt {
    width: 100%;
    font-size: 18px;
    padding: 16px 0;
    margin-top: 4px;
}

/* Formularfehler AM FELD: Symfonys form_row rendert form_errors zwischen
   Label und Eingabe (form_errors kommt vor form_widget) - genau diese
   Reihenfolge nutzen wir aus, um die Eingabe automatisch rot zu rahmen,
   ganz ohne Twig-Logik zu aendern. */
form ul {
    margin: 0 0 6px;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 3px;
}
form ul li {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    font-size: 12px;
    font-weight: 600;
    color: var(--atf-status-fehler);
    margin: 0;
}
form ul li::before { content: '!'; flex: none; }
form ul + input,
form ul + select,
form ul + textarea {
    border-color: var(--atf-status-fehler);
    background: var(--atf-fehler-flaeche);
}
form ul + input:focus,
form ul + select:focus,
form ul + textarea:focus {
    border-color: var(--atf-status-fehler);
    box-shadow: 0 0 0 3px rgba(177, 42, 36, 0.15);
}

/* Zustaende: deaktivierte Eingaben/Knoepfe sind erkennbar, aber nicht
   unleserlich, und geben Klick/Tastatur keine Reaktion mehr. */
button:disabled, .knopf[aria-disabled="true"], input:disabled, select:disabled, textarea:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}
.knopf[aria-disabled="true"] { pointer-events: none; }

/* Sichtbarer Fokusring fuer alle interaktiven Elemente - Pflicht fuer
   Tastaturbedienung. Elemente mit eigenem Fokusstil (Eingaben oben, Options-
   Karten) sind bewusst ausgenommen, damit sich die Ringe nicht doppeln. */
a:focus-visible, button:focus-visible, .knopf:focus-visible,
summary:focus-visible, [tabindex]:focus-visible {
    outline: 3px solid rgba(var(--atf-navy-rgb), 0.5);
    outline-offset: 2px;
}
/* Auf dunklem Grund (Kopfleiste, Bereichswechsel, Zusammenfassungskarte)
   muss der Ring hell sein, sonst verschwindet er vor der Navy-Flaeche. */
.atf-kopf :focus-visible, .atf-bereiche :focus-visible, .atf-zusammenfassung :focus-visible {
    outline-color: #ffffff;
}

/* Knoepfe. Genau EIN roter Hauptknopf je Seite - deshalb ist Rot an die
   ausdrueckliche Klasse gebunden und nicht der Standard.

   REGEL Kopf- vs. Seiten-Hauptaktion (Design-Feinschliff, Aufgabe 327):
   Traegt ein Dienst EINE einzige Handlung, die auf jeder seiner Seiten
   gleichermassen Sinn ergibt (Partner-Portal und Kundenportal: "+ Sendung
   anlegen"/"anmelden" - egal wo man gerade ist, das ist immer die naechste
   sinnvolle Handlung), sitzt GENAU DIESE rot im Kopf (grundgeruest.html.twig
   Block "hauptaktion") und JEDE seiteneigene Aktion bleibt neutral
   (.knopf bzw. .knopf--navy) - siehe kunde/new.html.twig, mitarbeiter/
   new.html.twig usw. im Portal. Eine einzelne Seite, die exakt dieselbe
   Handlung wie der Kopf noch einmal ausfuehrt (Sendung anlegen/bearbeiten
   selbst) oder bereits genug eigene Aktionen hat (Sendungs-Detailseite:
   Label drucken, Bearbeiten, Stornieren), leert den Kopf-Block bewusst
   (siehe sendung/new.html.twig, sendung/edit.html.twig, sendung/
   show.html.twig) und setzt ihr eigenes .knopf--haupt bzw. bleibt ganz ohne
   Rot, statt zwei rote Knoepfe zu zeigen.
   Hat ein Dienst KEINE solche uebergreifende Handlung, weil die sinnvolle
   Haupthandlung von Seite zu Seite wechselt (Linien-Management, Clearing:
   "Hub anlegen" auf der Hub-Liste, "Zusatzlinie ..." bzw. "Offene Sendungen
   verteilen" auf dem Linienplan, "Clearing-Lauf starten"/"Belege erzeugen"
   je Lauf-Seite), bleibt der Kopf ohne rote Aktion (kein "hauptaktion"-Block
   in services/linien und services/clearing), und STATTDESSEN traegt jede
   Uebersichts-/Lauf-Seite ihre eigene EINE Hauptaktion rot in ihrem eigenen
   Seitenkopf bzw. ihrer Aktionszeile - so wie es das Referenz-Mockup
   linienplan.html mit "+ Zusatzlinie buchen" zeigt.
   Reine Reporting-/Uebersichtsseiten ganz ohne eine einzelne Kernhandlung
   (Kontokorrent, Belege, Reklamationen-Liste in Clearing; Sendungs-
   Detailseite in beiden Portalen) duerfen bewusst ganz ohne Rot bleiben -
   Rot zu erzwingen waere hier reine Dekoration.
   In jedem Fall gilt: Loeschen/Stornieren/Sperren wird NIE die rote
   Hauptaktion (bleibt .knopf--gefahr), und eine je Datensatz/Tabellenzeile
   wiederholte Aktion (z. B. "Zusatzlinie ... anlegen" je ueberladener
   Linie) ist NIE rot (bleibt .knopf--navy) - sonst waere Rot kein Signal
   mehr, sondern Dekoration. */
button, .knopf, input[type="submit"] {
    display: inline-block;
    background: var(--atf-karte);
    color: var(--atf-text-kraeftig);
    border: 1px solid var(--atf-eingabe-rand);
    border-radius: var(--atf-radius);
    padding: 9px 16px;
    font-size: 14px;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    text-decoration: none;
    line-height: 1.3;
}
button:hover, .knopf:hover, input[type="submit"]:hover { border-color: var(--atf-navy); color: var(--atf-navy); }

.knopf--haupt, button.haupt, input[type="submit"].haupt {
    background: var(--atf-rot);
    border-color: var(--atf-rot);
    color: #ffffff;
}
.knopf--haupt:hover, button.haupt:hover, input[type="submit"].haupt:hover {
    background: var(--atf-rot-dunkel);
    border-color: var(--atf-rot-dunkel);
    color: #ffffff;
}

/* Gefuellter Navy-Knopf fuer Aktionen, die sichtbar/wichtig sind, aber NICHT
   die eine rote Hauptaktion der Seite sein duerfen - z. B. "Zusatzlinie ...
   buchen" je ueberladener Linie im Linienplan: die Seite kann mehrere davon
   zeigen, Rot bleibt aber der einen Hauptaktion vorbehalten. */
.knopf--navy {
    background: var(--atf-navy);
    border-color: var(--atf-navy);
    color: #ffffff;
}
.knopf--navy:hover {
    background: var(--atf-navy-dunkel);
    border-color: var(--atf-navy-dunkel);
    color: #ffffff;
}

/* Zurueckhaltendere Zweit-Aktion, z. B. "Bearbeiten" neben Hauptaktionen -
   faellt bewusst weniger auf als der Standard-Knopf. */
.knopf--leise { color: var(--atf-gedaempft); }
.knopf--leise:hover { color: var(--atf-navy); border-color: var(--atf-navy); }

/* Rahmen-Knopf fuer eine vorsichtige, aber nicht die HAUPT-Aktion, z. B.
   "Stornieren" neben "Bearbeiten"/"Label drucken" (sendung-detail.html). */
.knopf--gefahr { border-color: var(--atf-gefahr-rand); color: var(--atf-status-fehler); }
.knopf--gefahr:hover { background: var(--atf-fehler-flaeche); border-color: var(--atf-status-fehler); color: var(--atf-status-fehler); }

/* Reiner Text-Knopf ohne Rahmen, z. B. "Abbrechen" neben einem Formular. */
.knopf--text { background: none; border-color: transparent; color: var(--atf-nebentext); }
.knopf--text:hover { color: var(--atf-navy); border-color: transparent; text-decoration: underline; }

/* Ladezustand: Bewegung, die etwas aussagt - der Text verschwindet zugunsten
   eines drehenden Rings, der Knopf reagiert nicht mehr auf Klicks. */
@keyframes atf-drehen { to { transform: rotate(360deg); } }
.knopf--laedt {
    position: relative;
    color: transparent !important;
    pointer-events: none;
}
.knopf--laedt::after {
    content: '';
    position: absolute;
    inset: 0;
    margin: auto;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    border: 2px solid rgba(var(--atf-navy-rgb), 0.25);
    border-top-color: var(--atf-navy);
    animation: atf-drehen 0.6s linear infinite;
}
.knopf--haupt.knopf--laedt::after {
    border-color: rgba(255, 255, 255, 0.4);
    border-top-color: #ffffff;
}

/* Ein Knopf, der allein in einem Formular in einer Tabellenzelle steht
   (Entfernen, Loeschen) - kompakter und ohne Aussenabstand. */
td form { display: inline; }
td button { padding: 5px 11px; font-size: 13px; font-weight: 500; }

/* Aktionsleiste unter einer Ueberschrift: Links mit Abstand statt Pipes. */
.atf-aktionen { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-bottom: 18px; }
/* Kompakt: ohne Aussenabstand, z. B. als letztes Element einer Karte oder
   in einer Tabellenzelle. */
.atf-aktionen--kompakt { margin-bottom: 0; }

/* Aktions-Zeile: Hauptaktion/Sekundaeraktion + erklaerender Satz oder kleine
   Eingabe(n) nebeneinander - das Muster hinter den Formularen von Laeufen und
   Einzelaktionen (Abrechnungslauf, Clearing-Lauf, Mahnlauf, Zahlung
   automatisch/von Hand zuordnen, Zuschlag duplizieren, Beleg/Reklamation
   stornieren bzw. zuruecknehmen/ablehnen) UND fuer eine schmale Tabellenzelle
   mit mehreren Aktions-Links (z. B. "Ansehen"/"Bearbeiten" bei einem
   Kundenzuschlag). */
.atf-aktions-zeile { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.atf-aktions-zeile--unten { align-items: flex-end; }
.atf-aktions-zeile--kompakt { gap: 8px; }
/* Innerhalb einer Tabellenzelle darf die Aktions-Zeile nicht umbrechen - sie
   bleibt einzeilig, auch in einer schmalen letzten Spalte. */
td .atf-aktions-zeile { flex-wrap: nowrap; }

ul, ol { margin: 0 0 14px; padding-left: 20px; }
li { margin-bottom: 5px; }

/* Die alte Trennung "Link | Link" aus den Vorlagen bleibt lesbar, wirkt aber
   ruhiger. */
nav a { text-decoration: none; }

/* ---------- 5. Kleine Bildschirme ---------------------------------------- */

@media (max-width: 900px) {
    .atf-kopf-innen { padding: 10px 16px; gap: 14px; }
    .atf-kopf-rechts { margin-left: 0; width: 100%; }
    .atf-benutzer { padding-left: 0; border-left: 0; }
    .atf-inhalt { padding: 16px; }
    .atf-fuss { padding: 10px 16px 20px; }
    .atf-menue a { min-height: 34px; padding: 6px 10px; }
    /* Breite Tabellen duerfen seitlich rollen statt die Seite zu sprengen. */
    table { display: block; overflow-x: auto; white-space: nowrap; }
    tbody tr > th:first-child, table > tr > th:first-child { width: auto; }

    /* Formular-Layout: Zusammenfassung/Details wandern unter das Formular
       und werden volle Breite statt fester 330px-Spalte. */
    .atf-formular-layout { flex-direction: column; }
    .atf-formular-seite { width: 100%; }
    .atf-feld-raster { grid-template-columns: 1fr; }
    .atf-zeilen-kopf { display: none; }
    .atf-zeilen-raster { grid-template-columns: 1fr; gap: 6px; padding: 10px 16px; border-bottom: 1px solid var(--atf-rand-leicht); }

    /* Filterzeile und Blaetterleiste duerfen umbrechen und nehmen dann die
       volle Breite ein, statt sich zu quetschen. */
    .atf-abschnitt-kopf { padding: 13px 16px; }
    .atf-filterzeile { width: 100%; }
    input[type="search"].atf-suchfeld { width: 100%; }
    .atf-tabellen-fuss { padding: 11px 16px; flex-direction: column; align-items: flex-start; }

    /* Routenlauf: die beiden Endpunkte stehen nebeneinander in fester
       Mindestbreite, die Strecke faellt in eine eigene Zeile darunter. */
    .atf-routenlauf { flex-wrap: wrap; }
    .atf-routenlauf-endpunkt { width: auto; flex: 1 1 45%; }
    .atf-routenlauf-strecke { order: 3; width: 100%; margin-top: 12px; }

    .atf-auslastung { flex-wrap: wrap; gap: 10px; padding: 14px 16px; }
    .atf-auslastung-prozent { width: auto; text-align: left; }

    /* Schritt-Anzeige: kleinere Kreise/Schrift und knapperer Linienabstand,
       damit auch drei Schritte auf schmalen Bildschirmen nebeneinander
       Platz finden. */
    .atf-schritte { margin-bottom: 16px; }
    .atf-schritt-marke { width: 22px; height: 22px; font-size: 11px; }
    .atf-schritt-label { margin-left: 6px; font-size: 11px; }
    .atf-schritt:not(:last-child)::after { margin: 0 6px; }
}

@media print {
    .atf-kopf, .atf-bereiche, .atf-fuss, .atf-aktionen, .atf-sprunglink, .atf-filterzeile, .atf-tabellen-fuss, button, .knopf { display: none; }
    body { background: #ffffff; }
    .atf-inhalt { padding: 0; }
}
