/* Track A ergaenzt hier. Tokens aus app.css verwenden, keine rohen Farbwerte. */

/* ---------- Mailspur: Versandkopien ---------- */
/* Der gespeicherte Mailtext wird als Text ausgegeben, nie als Auszeichnung.
   Lange Links und Kopfzeilen muessen umbrechen, sonst schiebt eine einzige
   Zeile die ganze Seite in die Breite. */
.mailspur-text {
    margin: var(--luft-2) 0 0;
    padding: var(--luft-3);
    max-height: 30rem;
    overflow: auto;
    background: var(--flaeche-tief);
    border: 1px solid var(--linie);
    border-radius: var(--ecke-flaeche);
    color: var(--text);
    font-family: var(--schrift-zahl);
    font-size: 12px;
    line-height: 1.6;
    white-space: pre-wrap;
    word-break: break-word;
}

/* ---------- A6: oeffentliche Angebotsseite ---------- */
/* Eigene Klassen statt Aenderungen an app.css. Nur Tokens, keine rohen Farbwerte.
   Die Seite muss eine fuenfspaltige Positionstabelle tragen und laeuft deshalb
   breiter als die schmale Karte aus layout-public.php. */
.angebot-seite {
    max-width: 56rem;
    margin: 0 auto;
    padding: var(--luft-5) var(--luft-4) var(--luft-7);
}

.angebot-marke {
    font-family: var(--schrift-titel);
    font-size: 15px;
    color: var(--marke);
    margin-bottom: var(--luft-4);
}

.angebot-schmal { max-width: 34rem; }

.angebot-titel {
    font-family: var(--schrift-titel);
    font-size: 20px;
    margin: 0 0 var(--luft-1);
    color: var(--text);
}

/* Kopfzeile: Angebotsdaten links, Absenderanschrift rechts. Auf schmalen
   Fenstern untereinander, damit nichts abgeschnitten wird. */
.angebot-kopf {
    display: flex;
    flex-wrap: wrap;
    gap: var(--luft-3);
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: var(--luft-3);
}

.angebot-absender { text-align: right; }

/* Der Text kommt bereits mit nl2br() aus der Ansicht, deshalb KEIN pre-line:
   sonst waere jeder Umbruch doppelt. */
.angebot-text { margin: var(--luft-3) 0; }

/* Summenblock unter der Positionstabelle, rechtsbuendig ausgerichtet. */
.angebot-summe {
    margin-top: var(--luft-3);
    margin-left: auto;
    max-width: 24rem;
}

@media (max-width: 40rem) {
    .angebot-absender { text-align: left; }
    .angebot-summe { max-width: none; }
}

/* =========================================================================
   Hilfeseite
   Eigener Abschnitt, weil die Anleitung Bausteine braucht, die es sonst
   nirgends gibt: eine Ablaufkette, Aufzaehlungen mit Luft und kleine
   Erklaerkaesten. Sie gehoeren nicht ins Fundament, sie kommen nur hier vor.
   ========================================================================= */

.hilfe-kette {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--luft-2);
    margin-top: var(--luft-4);
}
.hilfe-schritt {
    background: var(--marke-schleier);
    color: var(--marke);
    border-radius: var(--ecke-element);
    padding: 6px 12px;
    font-size: 13px;
    font-weight: 600;
    white-space: nowrap;
}
.hilfe-pfeil { color: var(--text-leise); }

/* Aufzaehlungen in der Anleitung stehen luftiger als im uebrigen Programm:
   hier wird gelesen und nicht ueberflogen. */
.hilfe-liste { padding-left: var(--luft-4); margin: var(--luft-2) 0 0; max-width: 58ch; }
.hilfe-liste li { margin-bottom: var(--luft-2); }

.hilfe-block {
    background: var(--flaeche-tief);
    border-radius: var(--ecke-element);
    padding: var(--luft-3);
}
.hilfe-block p:last-child { margin-bottom: 0; }

/* Zwischenueberschriften innerhalb einer Karte. h2 traegt schon den Kartentitel. */
.karte h3 {
    font-family: var(--schrift-text);
    font-size: 14px;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--text-kopf);
    margin-top: var(--luft-4);
    margin-bottom: var(--luft-2);
}

/* Feldnamen und Platzhalter im Fliesstext. */
.karte code {
    font-family: var(--schrift-zahl);
    font-size: .92em;
    background: var(--flaeche-tief);
    border-radius: 3px;
    padding: 1px 5px;
}

@media (max-width: 900px) {
    /* Auf dem Telefon untereinander statt in einer Reihe: sonst steht die Kette
       zweizeilig gebrochen da und die Pfeile zeigen ins Leere. */
    .hilfe-kette { flex-direction: column; align-items: flex-start; gap: var(--luft-1); }
    .hilfe-pfeil { transform: rotate(90deg); margin-left: var(--luft-3); }
    .hilfe-schritt, .mailspur-text { font-size: 16px; }
    a.hilfe-sprung { min-height: 44px; }
}

/* Frage und Antwort untereinander, statt zwei schmale Tabellenspalten. */
.hilfe-fragen { margin: var(--luft-2) 0 0; max-width: 58ch; }
.hilfe-fragen dt {
    font-weight: 600;
    margin-top: var(--luft-3);
}
.hilfe-fragen dd {
    margin: var(--luft-1) 0 0;
    color: var(--text-leise);
}

/* =========================================================================
   Datenausgabe
   Liste statt Tabelle: eine Tabelle mit einer Schaltflaeche je Zeile ist auf
   einem Telefon breiter als der Bildschirm, und dann scrollt die ganze Seite
   seitlich. Diese Zeilen brechen um.
   ========================================================================= */

.ausgabe-liste { list-style: none; margin: var(--luft-3) 0 0; padding: 0; }
.ausgabe-zeile {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--luft-2);
    padding: var(--luft-3) 0;
    border-bottom: 1px solid var(--linie-zart);
}
.ausgabe-zeile:last-child { border-bottom: 0; }
.ausgabe-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }

/*
 * Sprunglink am Ende einer Antwort.
 *
 * Auf einer Hilfeseite ist ein Link mitten im Satz zweimal schlecht: er ist auf
 * einem Tastfeld nur 21px hoch, und man liest darueber hinweg. WCAG 2.5.8 nimmt
 * Links im Fliesstext zwar von der Mindestgroesse aus, aber die Ausnahme braucht
 * man hier gar nicht, wenn der Verweis ohnehin ans Ende gehoert.
 */
.hilfe-sprung {
    display: inline-flex;
    align-items: center;
    min-height: 24px;
    margin-top: var(--luft-1);
    font-weight: 600;
}
.hilfe-sprung::before { content: "→ "; margin-right: 4px; }

/* =========================================================================
   A5: Kundenrechnung, Gutschrift und Stornorechnung
   ========================================================================= */

/*
 * Nur fuer Hilfstechnik sichtbar. Die Spalte mit den Entfernen-Schaltflaechen
 * braucht eine Ueberschrift, damit die Tabelle vollstaendig bleibt; auf dem
 * Bildschirm waere sie ein leeres Wort ueber einer schmalen Spalte.
 */
.sr-only {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/*
 * Positionszeilen mit Eingabefeldern. Die Felder fuellen ihre Zelle, sonst
 * springt die Spaltenbreite mit dem laengsten Wert, und die Zeilen stehen
 * dichter als in einer Lesetabelle: hier wird getippt, nicht gelesen.
 */
.positionen td { padding-top: 4px; padding-bottom: 4px; vertical-align: middle; }
.positionen td input { width: 100%; margin: 0; }
.positionen .zeilennummer { text-align: right; }

/*
 * Positionszeilen auf dem Telefon.
 *
 * Die Tabelle braucht mit ihren festen Spaltenbreiten 675px. In einem 390px
 * breiten Fenster bleiben davon 308px sichtbar: gemessen sah man Nummer und
 * Bezeichnung, waehrend Menge, Einheit, Einzelpreis und Nachlass hinter dem
 * rechten Rand lagen und nur durch seitliches Schieben IN der Tabelle erreichbar
 * waren. Beim Schieben verschwindet die Bezeichnung, man traegt also einen Preis
 * ein, ohne noch zu sehen wozu. Die Seite selbst scrollte nie, der Fehler waere
 * einem reinen Ueberlauftest deshalb entgangen.
 *
 * Statt zu schieben wird jede Position zu einem Block: Bezeichnung ueber die
 * volle Breite, darunter die vier Zahlenfelder in zwei Spalten. Die Beschriftung
 * kommt aus data-feld, weil der Tabellenkopf hier nicht mehr ueber der Spalte
 * steht. Der Kopf wird ausgeblendet und nicht entfernt: auf dem Bildschirm
 * bleibt die Tabelle eine Tabelle.
 *
 * 900px ist die Schwelle der uebrigen Oberflaeche (app.css), damit die Maske
 * nicht bei einer eigenen Breite umspringt.
 */
@media (max-width: 900px) {
    .positionen thead { display: none; }
    .positionen, .positionen tbody, .positionen tr, .positionen td { display: block; }
    .positionen { width: 100%; }
    .positionen tr {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--luft-2);
        padding: var(--luft-3) 0;
        border-bottom: 1px solid var(--linie-zart);
    }
    .positionen tr:last-child { border-bottom: 0; }
    .positionen td { padding: 0; border: 0; }
    /* Zeilennummer, Bezeichnung und die Schaltflaeche ueber beide Spalten. */
    .positionen .zeilennummer,
    .positionen .pos-bezeichnung,
    .positionen .pos-weg { grid-column: 1 / -1; }
    .positionen .zeilennummer { text-align: left; font-size: 16px; }
    .positionen .zeilennummer::before { content: 'Position '; }
    .positionen td[data-feld]::before {
        content: attr(data-feld);
        display: block;
        margin-bottom: 4px;
        /* 16px: Kanon fuer Fliesstext auf dem Telefon. Die Abstufung zur
           Bezeichnung kommt ueber die Farbe, nicht ueber die Groesse. */
        font-size: 16px;
        color: var(--text-leise);
    }
    .positionen .pos-weg { justify-self: start; }
}

/*
 * Belegarten in der Uebersicht. Eine Kundenrechnung darf nicht wie eine
 * Provisionsrechnung aussehen, sonst mahnt jemand den falschen Empfaenger. Die
 * Zeile bekommt deshalb zusaetzlich zur Plakette eine Kante in der Farbe der
 * Art; Farbe allein traegt keine Aussage, die Plakette daneben nennt sie im
 * Wortlaut (WCAG 1.4.1).
 */
.buch tr.beleg-kunde td:first-child { box-shadow: inset 3px 0 0 var(--marke); }
.buch tr.beleg-gutschrift td:first-child,
.buch tr.beleg-storno td:first-child { box-shadow: inset 3px 0 0 var(--schlecht); }

/* Ein Korrekturbeleg traegt negative Betraege. Sie stehen gedaempft, damit die
   Zeile nicht wie eine Warnung wirkt: die Gutschrift ist ein normaler Vorgang. */
.buch tr.beleg-gutschrift .betrag,
.buch tr.beleg-storno .betrag { color: var(--text-leise); }

/* =========================================================================
   Belegvorlagen: Briefpapier einstellen und ansehen (/belegvorlagen)
   =========================================================================

   Die Seite stellt ein Formular neben eine PDF-Vorschau. Nebeneinander geht
   erst, wenn beide Spalten breit genug bleiben: eine A4-Seite in einer 300px
   schmalen Spalte ist keine Vorschau mehr, sondern ein Briefmarkenbild. Die
   Umschaltschwelle liegt deshalb bei 1100px und nicht bei den 900px des
   uebrigen Rasters. Unterhalb davon steht alles untereinander, und die
   Vorschau wird gar nicht erst eingebettet (das Skript in der Ansicht setzt
   sie ein) - mobile Browser zeigen ein PDF im Rahmen ohnehin nicht an.

   minmax(0, 1fr) und nicht 1fr: "1fr" heisst "minmax(auto, 1fr)", und "auto"
   ist mindestens so breit wie der breiteste unteilbare Inhalt. Eine Tabelle in
   der Spalte schoebe die Seite damit waagerecht ueber den Rand. */
.beleg-raster {
    display: grid;
    gap: var(--luft-3);
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
}

@media (min-width: 1100px) {
    .beleg-raster { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
    /* Beim Scrollen durch das Formular soll der Beleg im Bild bleiben; sonst
       stellt man etwas ein und sieht die Wirkung nicht. */
    .beleg-vorschau-spalte { position: sticky; top: var(--luft-3); }
}

/* Seitenverhaeltnis von A4 (1:1.414), damit der Rahmen die Seite nicht
   beschneidet und nicht mit halbem Weiss endet. */
.beleg-rahmen {
    margin-top: var(--luft-3);
    aspect-ratio: 210 / 297;
    border: 1px solid var(--linie);
    border-radius: var(--ecke-flaeche);
    background: var(--flaeche-tief);
    overflow: hidden;
}
.beleg-rahmen iframe { display: block; width: 100%; height: 100%; border: 0; }

/* Der Farbwaehler ist ein Bedienelement wie jedes andere und faellt sonst auf
   die Groesse, die der Browser fuer richtig haelt (gemessen 46x25px in Chrome,
   also unter den 44px des Kanons in der Hoehe). */
.beleg-farbwert { max-width: 12ch; font-family: var(--schrift-zahl); }
.beleg-farbwahl-name {
    display: inline-flex;
    align-items: center;
    gap: var(--luft-2);
    min-height: 44px;
    font-size: 13px;
    color: var(--text-leise);
    cursor: pointer;
}
.beleg-farbwahl {
    width: 44px;
    height: 44px;
    min-height: 44px;
    padding: 2px;
    border: 1px solid var(--linie);
    border-radius: var(--ecke-flaeche);
    background: var(--flaeche);
    cursor: pointer;
}

@media (max-width: 900px) {
    /* Der Kanon verlangt 16px Fliesstext auf dem Telefon. Die Beschriftung des
       Farbwaehlers steht in einem <label> und wurde von der Regel in app.css
       nicht erfasst, weil sie kein .feld > label ist. */
    .beleg-farbwahl-name { font-size: 16px; }
}

/* Schalter mit Kontrollkaestchen. Die 44px stehen hier und nicht als
   style-Attribut in der Ansicht: ein style-Attribut schlaegt jedes Stylesheet
   und ist damit die Stelle, an der eine spaetere Korrektur nicht mehr greift.
   Gemessen wurde die Trefferflaeche vorher mit 24x24px, also auf der harten
   Untergrenze von WCAG 2.2 AA statt auf der Tivaos-Vorgabe. */
.beleg-schalter {
    display: flex;
    align-items: center;
    gap: var(--luft-2);
    min-height: 44px;
    font-weight: 400;
}

/* Die Verweise auf die Mailvorlagen. Der Kompromiss aus docs/SEITENCHECK.md
   ("Links in Tabellenzeilen bleiben bei 24px") gilt fuer Listen mit hunderten
   Zeilen, in denen 44px die Haelfte des Bildschirms kosten. Diese Tabelle hat
   sieben feste Zeilen; hier kostet die Vorgabe nichts.

   Der Waehler wiederholt "table.buch tbody td a" aus app.css samt eigener
   Klasse. Ohne die Wiederholung verliert die Regel auf Spezifitaet und die
   Hoehe bleibt bei 24px - dieselbe Falle wie bei ".knopf.klein" und
   "input[type=text]". Gemessen wurden vorher 121x24px. */
table.buch.beleg-mailtabelle tbody td a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
}

/* =========================================================================
   Reiter innerhalb einer Seite (Stufe 1: Oberflaeche entschlacken)
   =========================================================================

   WARUM UEBERHAUPT
   Fuenf Ansichten trugen bis zu 22 optisch getrennte Bloecke untereinander.
   Wer eine Rechnung mahnen will, scrollt an Positionen, Zahlungen, Mailspur
   und Verlauf vorbei. Die Bloecke bleiben alle erhalten, sie liegen nur nicht
   mehr gleichzeitig da.

   OHNE JAVASCRIPT MUSS ALLES SICHTBAR SEIN
   Deshalb ist die Grundstellung: Leiste AUSGEBLENDET, jedes Blatt sichtbar.
   Erst das Skript setzt .bereit auf den Behaelter, blendet die Leiste ein und
   versteckt die nicht gewaehlten Blaetter. Wer kein Skript hat, bekommt genau
   die Seite von vorher - lang, aber vollstaendig. Der umgekehrte Weg (Leiste
   sichtbar, Blaetter per CSS versteckt) haette ohne Skript eine Seite ergeben,
   auf der man nichts mehr erreicht.

   Die Kante des aktiven Reiters traegt Farbe UND aria-selected; Farbe allein
   traegt keine Aussage (WCAG 1.4.1). */
.sc-reiter-leiste {
    display: none;
    flex-wrap: wrap;
    gap: var(--luft-1);
    margin-bottom: var(--luft-3);
    border-bottom: 1px solid var(--linie);
}
.sc-reiter.bereit > .sc-reiter-leiste { display: flex; }

.sc-reiter-knopf {
    /* Ein <button> erbt die Browserschrift, nicht die der Seite. */
    font-family: var(--schrift-text);
    font-size: 14px;
    padding: var(--luft-2) var(--luft-3);
    color: var(--text-leise);
    background: transparent;
    border: 0;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    cursor: pointer;
}
.sc-reiter-knopf:hover { color: var(--marke); background: var(--marke-schleier); }
.sc-reiter-knopf:focus-visible { outline: 2px solid var(--signal); outline-offset: -2px; }
.sc-reiter-knopf[aria-selected="true"] {
    color: var(--marke);
    border-bottom-color: var(--marke);
    font-weight: 600;
}

/* Ohne Skript trennt die Ueberschrift die Blaetter; mit Skript stuende sie
   doppelt da, weil der Reiter denselben Namen traegt. Sie wird deshalb nur
   optisch entfernt und bleibt fuer die Sprachausgabe stehen - sie ist die
   Ueberschrift des Bereichs, auf den aria-labelledby zeigt. */
.sc-blatt-titel {
    font-family: var(--schrift-titel);
    font-size: 17px;
    margin: var(--luft-5) 0 var(--luft-3);
}
.sc-reiter.bereit .sc-blatt-titel {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* Reiter, die auf eine EIGENE Seite fuehren (Akte gegen Bearbeitung, Mail-
   gegen Belegvorlagen, CSV-Import gegen Eingangsquellen). Sie brauchen kein
   Skript und sehen deshalb genauso aus wie die Reiter innerhalb einer Seite. */
.sc-seitenreiter {
    display: flex;
    flex-wrap: wrap;
    gap: var(--luft-1);
    margin-bottom: var(--luft-3);
    border-bottom: 1px solid var(--linie);
}
.sc-seitenreiter a {
    font-size: 14px;
    padding: var(--luft-2) var(--luft-3);
    color: var(--text-leise);
    text-decoration: none;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
}
.sc-seitenreiter a:hover { color: var(--marke); background: var(--marke-schleier); }
.sc-seitenreiter a[aria-current="page"] {
    color: var(--marke);
    border-bottom-color: var(--marke);
    font-weight: 600;
}

/* =========================================================================
   Breite Tabellen auf dem Telefon: stapeln statt schieben
   =========================================================================

   Dasselbe Muster wie bei .positionen weiter oben, nur als allgemeine Klasse
   fuer die Listen: Leaduebersicht (13 Spalten), Importhistorie (12),
   Produkte (10 bis 11), Kampagnen (10), Partner-Auswertung (10),
   Importvorschau (9 bis 10).

   Waagerechtes Schieben allein reicht dort nicht: gemessen an der Leadliste
   blieben bei 390px von 13 Spalten drei sichtbar, und beim Schieben nach
   rechts verschwindet die Kennung, zu der die Werte gehoeren. Gestapelt traegt
   jede Zelle ihre Beschriftung aus data-feld selbst.

   900px ist die Schwelle der uebrigen Oberflaeche (app.css), damit nichts bei
   einer eigenen Breite umspringt. */
@media (max-width: 900px) {
    table.buch.stapelt thead { display: none; }
    table.buch.stapelt,
    table.buch.stapelt tbody,
    table.buch.stapelt tr,
    table.buch.stapelt td { display: block; }
    table.buch.stapelt { width: 100%; }
    table.buch.stapelt tr {
        padding: var(--luft-3) var(--luft-2);
        border-bottom: 1px solid var(--linie);
    }
    table.buch.stapelt tr:last-child { border-bottom: 0; }
    table.buch.stapelt td {
        padding: 3px 0;
        border: 0;
        /* Beschriftung links, Wert daneben: zwei Zeilen je Zelle waeren bei
           zehn Feldern eine Seite ohne Ende. minmax(0, ...) statt einer festen
           Breite, sonst schiebt ein langer Wert die Zeile ueber den Rand.

           7rem statt 10rem. Gemessen auf 360px: nach Seiten- und Kartenrand
           bleiben 278px Zeilenbreite. Davon nahm die Beschriftung 160px und
           liess dem Wert 88px - die Firma brach in acht Zeilen um, eine
           einzige Zeile wurde 1294px hoch, und die Telefonnummer (.kennung,
           bricht bewusst nicht um) ragte auf 131px ueber den Rand hinaus, was
           die ganze Liste waagerecht schiebbar machte. Mit 7rem bleiben dem
           Wert 158px, also fast doppelt so viel. */
        display: grid;
        grid-template-columns: minmax(0, 7rem) minmax(0, 1fr);
        gap: var(--luft-2);
        /* Kanon: 16px Fliesstext auf dem Telefon. Schlaegt .klein (13px) ueber
           die hoehere Spezifitaet, ohne dass in der Ansicht etwas steht. */
        font-size: 16px;
        text-align: left;
        overflow-wrap: anywhere;
    }
    /* Auch eine Kennung bricht hier um.
       Die Grundregel haelt Kennungen bewusst zusammen (eine zerrissene
       Leadnummer ist keine Leadnummer mehr). Auf dem Telefon gewinnt die
       Breite: eine Telefonnummer, die 43px ueber den Rand ragt, macht die
       GANZE Liste waagerecht schiebbar, und dann sucht man die Firma, zu der
       ein Wert gehoert. */
    table.buch.stapelt td .kennung,
    table.buch.stapelt td a.kennung {
        overflow-wrap: anywhere;
        white-space: normal;
        max-width: 100%;
    }
    /* Eine Plakette haelt ihren Text sonst bewusst in einer Zeile: umgebrochen
       sieht sie aus wie zwei. In der gestapelten Zeile bleiben ihr aber 112px,
       und "kein anwendbarer Verkaufssatz" braucht 189px - dann schiebt sie die
       ganze Liste ueber den Rand. Hier gewinnt die Breite. */
    table.buch.stapelt td .plakette {
        white-space: normal;
        max-width: 100%;
    }

    /* PREISE IN DER GESTAPELTEN ZEILE.
       .kennzahl-wert steht mit 26px in Kacheln der Uebersicht; in einer
       gestapelten Zeile bleiben dem Wert 151px, und "1.380,00 EUR" braucht
       dort 183px. Gemessen auf 375px lief die Produktliste damit ueber den
       Rand, obwohl das Stapeln selbst griff.

       .betrag haelt einen Betrag bewusst zusammen: eine Zahl, die mitten drin
       umbricht, ist keine Zahl mehr. Eine Preisspanne ist aber kein Betrag,
       sondern zwei davon mit einem Wort dazwischen ("3.600,00 EUR bis
       8.400,00 EUR", gemessen 442px). Sie darf an diesem Wort brechen, und
       genau das erlaubt white-space: normal, ohne die Zahlen anzutasten -
       innerhalb von "3.600,00" gibt es keinen Trennpunkt. Zusammen mit der
       kleineren Schrift passt der einzelne Betrag wieder in eine Zeile. */
    table.buch.stapelt td .kennzahl-wert {
        font-size: 20px;
    }
    table.buch.stapelt td .kennzahl-wert.betrag {
        white-space: normal;
        overflow-wrap: normal;
    }

    /* Nebensachen: Herkunft, Zustaendig, Erfasst, naechste Erinnerung.
       Sie gehoeren in die Liste, aber nicht in dieselbe Schriftgroesse wie
       Firma und Telefon. Zusammen sparen sie rund ein Drittel der Zeilenhoehe,
       und der Blick bleibt an dem haengen, wonach man sucht. */
    table.buch.stapelt td.stapel-nebensache {
        font-size: 14px;
        color: var(--text-leise);
        grid-template-columns: minmax(0, 7rem) minmax(0, 1fr);
        padding: 1px 0;
    }
    table.buch.stapelt td.stapel-nebensache[data-feld]::before { font-size: 14px; }
    /* Die zwei Zellen, wegen derer man in die Liste schaut: Firma und
       Kontaktdaten. Sie bekommen die VOLLE Breite, Beschriftung darueber.

       Gerechnet auf 360px: in zwei Spalten blieben dem Wert 158px, ein
       Firmenname von 88 Zeichen brach dort in 14 Zeilen (gemessen 353px hoch).
       Ueber die ganze Breite sind es 278px und drei Zeilen. Die Nebensachen
       bleiben bei zwei Spalten - dort ist die Beschriftung laenger als der
       Wert, und eine eigene Zeile dafuer waere verschwendet. */
    table.buch.stapelt td.stapel-breit {
        grid-template-columns: minmax(0, 1fr);
        gap: 2px;
        padding-top: var(--luft-2);
    }
    table.buch.stapelt td.stapel-breit[data-feld]::before {
        font-size: 13px;
        text-transform: uppercase;
        letter-spacing: .04em;
    }
    /* NUR AM RECHNER.
       Eine Zeile der Leadliste war auf 360px rund 610px hoch: ein Lead je
       Bildschirm, und dazwischen stand, was beim Durchsehen niemand liest.
       Mailadresse, Website und Branche gehoeren in die Akte; wer sie braucht,
       tippt den Lead an. Sie bleiben im Markup und erscheinen ab 900px wieder,
       damit am Rechner nichts fehlt. */
    table.buch.stapelt td .nur-breit { display: none; }
    /* Ganze Zellen, die auf dem Telefon nicht in die Liste gehoeren.
       Herkunft (Kampagne, Produkt) und das Erfassungsdatum entscheiden beim
       Durchsehen nichts: der Caller sucht Firma, Nummer, Stand und die
       naechste Erinnerung. Auf dem Rechner stehen sie unveraendert da. */
    table.buch.stapelt td.stapel-nur-breit { display: none; }
    /* Die verbleibenden Nebensachen ruecken enger zusammen: bei vier Zeilen
       zu je 24px war ein Drittel der Kartenhoehe Luft zwischen Daten. */
    table.buch.stapelt td.stapel-nebensache { line-height: 1.35; }
    table.buch.stapelt td[data-feld]::before {
        content: attr(data-feld);
        font-size: 16px;
        color: var(--text-leise);
    }
    /* Die Kennungszelle traegt die Zeile an und steht ueber die volle Breite. */
    table.buch.stapelt td.stapel-kopf {
        grid-template-columns: minmax(0, 1fr);
        font-size: 17px;
        padding-bottom: var(--luft-2);
    }
    /* Eine Zelle, die nur eine Schaltflaeche traegt ("Zur Vorschau", "Ansehen").
       Sie bekommt bewusst KEIN data-feld: die Beschriftung stuende auf dem Knopf
       und daneben noch einmal. Die eigene Klasse ist zugleich die Erlaubnis
       dafuer - selftest-oberflaeche.php verlangt sonst an jeder Zelle eine
       Beschriftung, und eine Ausnahme ohne Namen waere ein Loch in der Zusage. */
    table.buch.stapelt td.stapel-aktion {
        grid-template-columns: minmax(0, 1fr);
        padding-top: var(--luft-2);
    }
    table.buch.stapelt td.rechts { text-align: left; }
    /* Die Kennungszelle traegt in der Leadliste .spur (92px Belegspur). Als
       gestapelter Block wuerde sie sonst 92px breit bleiben; im Arbeitsvorrat
       stehen dort Firmenname, Nummer und "Anruf starten", die auf 92px
       zeichenweise brechen (gemessen: Firmenname 57x124, Knopf 57x61). */
    table.buch.stapelt td.spur { width: auto; }
}

/*
 * Kerndaten-Tabellen (Beschriftung links, Wert rechts) auf dem Telefon.
 *
 * Tabellen ohne <thead>, deren Zeilen aus th/td-Paaren bestehen (Arbeitsmaske,
 * Leadakte, Produkt-, Provisions-, Mailspur-Detail, Anruf-Panel): auf 390px
 * standen in der Arbeitsmaske vier Zellen nebeneinander (zwei Beschriftungen zu
 * je 9rem), die Tabelle war 480px breit, Kampagne/Produkt/Ort/Letzter Kontakt
 * lagen ausserhalb des Bildschirms und die Zeile "Naechster Schritt" wurde
 * 268px hoch. Jede Beschriftung und ihr Wert bilden mobil stattdessen ein
 * Zweispaltenpaar; das vierspaltige Raster faltet sich damit von selbst auf
 * zwei Spalten. Dieselbe Regel stand bisher nur unter .sc-panel.
 *
 * Erkannt wird das Muster am Aufbau (tbody direkt am Tabellenanfang, th in
 * den Zeilen), nicht an einer Klasse: die Arbeitsmaske gehoert einem anderen
 * Arbeitspaket und bekommt hier keine neue Klasse. Datentabellen ohne Kopf und
 * ohne th (Verlauf, Benachrichtigungen) bleiben unberuehrt.
 */
@media (max-width: 700px) {
    table.buch:not(.stapelt):has(> tbody:first-child > tr > th) {
        display: block;
        width: 100%;
        min-width: 0;
    }
    table.buch:not(.stapelt):has(> tbody:first-child > tr > th) > tbody {
        display: block;
        width: 100%;
        min-width: 0;
    }
    table.buch:not(.stapelt):has(> tbody:first-child > tr > th) > tbody > tr {
        display: grid;
        /* 9.5rem Mindestbreite bei 10px Polster: "ANSPRECHPARTNER" in
           Kapitaelchen misst rund 130px und soll nicht mitten im Wort brechen
           (gemessen im Panel: bei 8.5rem und 15px Polster brach es). */
        grid-template-columns: minmax(9.5rem, .8fr) minmax(0, 1.2fr);
        width: 100%;
        min-width: 0;
    }
    table.buch:not(.stapelt):has(> tbody:first-child > tr > th) > tbody > tr > th,
    table.buch:not(.stapelt):has(> tbody:first-child > tr > th) > tbody > tr > td {
        position: static;
        width: auto !important;   /* schlaegt style="width:9rem" der Arbeitsmaske */
        min-width: 0;
        max-width: 100%;
        padding: var(--luft-2);
        white-space: normal;
    }
    /* Beschriftungen brechen nur im Notfall im Wort, Werte (Adressen ohne
       Trennstelle) an jeder Stelle. word-break: normal hebt das break-word der
       aelteren Panelregel auf, das wie anywhere wirkt. */
    table.buch:not(.stapelt):has(> tbody:first-child > tr > th) > tbody > tr > th { overflow-wrap: break-word; word-break: normal; }
    table.buch:not(.stapelt):has(> tbody:first-child > tr > th) > tbody > tr > td { overflow-wrap: anywhere; }
    table.buch:not(.stapelt):has(> tbody:first-child > tr > th) > tbody > tr > td[colspan] {
        grid-column: 2 / -1;
    }
    /* Knoepfe in einer Wertzelle bleiben ganze Woerter. */
    table.buch:not(.stapelt):has(> tbody:first-child > tr > th) > tbody > tr > td .knopf {
        overflow-wrap: normal;
    }
    /* Verlaufstabellen ohne Kopf und ohne Beschriftungen (Arbeitsmaske,
       Benachrichtigungen, Engpaesse): drei Spalten mit festen Breiten
       (style="width:130px") liessen der Textspalte auf 390px rund 50px, jedes
       Wort stand einzeln (gemessen: Zelle 117x194). Mobil stehen Zeitpunkt,
       Art und Text je Eintrag untereinander. */
    table.buch:not(.stapelt):not(:has(th)),
    table.buch:not(.stapelt):not(:has(th)) > tbody,
    table.buch:not(.stapelt):not(:has(th)) > tbody > tr,
    table.buch:not(.stapelt):not(:has(th)) > tbody > tr > td { display: block; width: auto !important; }
    table.buch:not(.stapelt):not(:has(th)) > tbody > tr {
        padding: var(--luft-2) 0;
        border-bottom: 1px solid var(--linie-zart);
    }
    table.buch:not(.stapelt):not(:has(th)) > tbody > tr:last-child { border-bottom: 0; }
    table.buch:not(.stapelt):not(:has(th)) > tbody > tr > td {
        padding: 2px 0;
        border: 0;
        overflow-wrap: anywhere;
    }
}

/* =========================================================================
   Weitere Filter der Leaduebersicht
   =========================================================================
   Zehn Filter nebeneinander sind kein Filter mehr, sondern ein Formular.
   Sichtbar bleiben Suche, Anrufstatus und Qualifizierung; der Rest steht
   hinter einem Aufklapper, der von selbst offen steht, sobald einer der
   verborgenen Filter gesetzt ist - sonst filtert die Liste sichtbar anders,
   als die sichtbaren Felder sagen. */
.sc-lead-hauptfilter {
    grid-template-columns: repeat(3, minmax(0, 1fr)) max-content;
}
.sc-lead-hauptfilter > .knopfreihe { flex-wrap: nowrap; }
.sc-lead-filter-hinweis { margin-top: var(--luft-2); }
.sc-mehr-filter { margin-top: var(--luft-3); }
.sc-mehr-filter > summary {
    cursor: pointer;
    list-style: none;
    display: inline-flex;
    align-items: center;
    gap: var(--luft-2);
    min-height: 44px;
    font-size: 14px;
    color: var(--marke);
}
.sc-mehr-filter > summary::-webkit-details-marker { display: none; }
.sc-mehr-filter > summary::marker { content: ''; }
.sc-mehr-filter > summary::after { content: '\25B8'; transition: transform .15s ease; }
.sc-mehr-filter[open] > summary::after { transform: rotate(90deg); }
.sc-mehr-filter[open] { padding-bottom: var(--luft-2); }
.sc-filter-zahl { font-size: 12px; color: var(--text-leise); }

@media (max-width: 1100px) and (min-width: 901px) {
    .sc-lead-hauptfilter { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .sc-lead-hauptfilter > .knopfreihe { grid-column: 1 / -1; }
}

@media (max-width: 900px) {
    .sc-lead-hauptfilter { grid-template-columns: minmax(0, 1fr); }
    .sc-lead-hauptfilter > .knopfreihe {
        grid-column: auto;
        flex-wrap: wrap;
    }
}

/* =========================================================================
   Partnerportal: ein Partner ist kein Caller
   =========================================================================

   Der Unterschied lag bisher allein darin, dass die Seitenleiste fehlt - das
   sieht man erst, wenn man beide Ansichten nebeneinander haelt. Ein Partner,
   der glaubt, im internen Bereich zu sein, sucht dort Zahlen, die ihn nichts
   angehen; ein Mitarbeiter, der die Portalansicht fuer die interne haelt,
   sucht Funktionen, die es dort nie gab.

   Kein zweites Erscheinungsbild: dieselbe Marke, dieselbe Schrift, dieselben
   Bausteine. Unterschieden wird ueber die FLAECHE (gedecktes Papier statt
   heller Arbeitsflaeche), ueber ein durchgehendes Band am oberen Rand in der
   Markenfarbe und ueber die Plakette "Partnerbereich", die den Unterschied
   ausspricht statt ihn nur zu faerben (WCAG 1.4.1). */
body.portal-koerper { background: var(--flaeche-tief); }
.public-seite {
    min-height: 100vh;
    min-height: 100dvh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--luft-4);
}
.public-karte {
    width: 100%;
    max-width: 46rem;
    padding: var(--luft-6) var(--luft-5);
    text-align: center;
}
.portal-band { height: 4px; background: var(--marke); }
/* Bei Platznot (lange Firmennamen, viele Reiter) bricht der Kopf um statt
   die linke Spalte zu quetschen: deren Chips liefen sonst unter die
   Navigation. flex-shrink 0 haelt Marke und Kennzeichen zusammen. */
.portal-kopf { background: var(--flaeche); flex-wrap: wrap; row-gap: var(--luft-2); }
.portal-kopf .kopfzeile-start { flex: 0 0 auto; max-width: 100%; }
.portal-navi { margin-left: auto; }
.portal-marke {
    display: inline-block;
    max-width: 100%;
    font-family: var(--schrift-titel);
    font-size: 17px;
    color: var(--marke);
    text-decoration: none;
    overflow-wrap: anywhere;
}
.portal-kennzeichen {
    display: flex;
    align-items: center;
    gap: var(--luft-2);
    margin-top: 2px;
}
.portal-navi {
    display: flex;
    gap: var(--luft-2);
    align-items: center;
    flex-wrap: wrap;
    min-width: 0;
}
.portal-navi .knopf[aria-current="page"] {
    background: var(--marke-schleier);
    color: var(--marke-tief);
}
.portal-nutzer {
    min-width: 0;
    margin-left: var(--luft-2);
    overflow-wrap: anywhere;
}
.portal-sprung {
    position: fixed;
    z-index: 1000;
    top: -5rem;
    left: var(--luft-3);
    padding: var(--luft-2) var(--luft-3);
    border-radius: var(--ecke-element);
    background: var(--marke);
    color: var(--auf-marke);
}
.portal-sprung:focus { top: var(--luft-3); }

/* Das 4px-Markenband des Portal-Gastgeruests stapelt sich ueber .anmeldung
   mit voller Bildschirmhoehe: zusammen ein Dauer-Scrollbalken von 4px. */
.portal-koerper .anmeldung {
    min-height: calc(100vh - 4px);
    min-height: calc(100dvh - 4px);
}
.portal-einstieg {
    margin-bottom: var(--luft-5);
    scroll-margin-top: var(--luft-4);
}
.portal-kurzanleitung {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--luft-2) var(--luft-5);
    margin: 0 0 var(--luft-4);
    padding-left: 1.4rem;
}
.portal-kurzanleitung li { padding-left: var(--luft-1); }
.portal-freie-zeiten {
    columns: 2;
    margin: 0;
    padding-left: 1.1rem;
}

/* input[type=time] gehörte im Fundament noch nicht zu den Formularfeldern.
   Das Portal nutzt es im Wochenplan an jeder Zeile. */
.portal-koerper input[type="time"] {
    width: 100%;
    min-height: 38px;
    padding: 8px 11px;
    border: 1px solid var(--linie);
    border-radius: var(--ecke-element);
    background: var(--flaeche);
    color: var(--text);
    font: inherit;
}
.portal-koerper input[type="time"]:focus {
    outline: 2px solid var(--signal);
    outline-offset: 1px;
    border-color: var(--marke-hell);
}

/* =========================================================================
   Partnerübergabe: vier Schritte und eine klare Hauptaktion
   ========================================================================= */

.partner-fortschritt { margin-bottom: var(--luft-3); }
.partner-schritte {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--luft-2);
    margin: 0;
    padding: 0;
    list-style: none;
}
.partner-schritt {
    display: flex;
    gap: var(--luft-2);
    align-items: flex-start;
    min-width: 0;
    padding: var(--luft-2);
    border: 1px solid var(--linie);
    border-radius: var(--ecke-element);
    background: var(--flaeche-tief);
    color: var(--text-leise);
}
.partner-schritt > span:last-child { min-width: 0; }
.partner-schritt strong,
.partner-schritt small { display: block; overflow-wrap: anywhere; }
.partner-schritt strong { color: var(--text); font-size: 14px; }
.partner-schritt small { margin-top: 2px; font-size: 12px; line-height: 1.35; }
.partner-schritt-nummer {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 26px;
    width: 26px;
    height: 26px;
    border: 1px solid var(--linie);
    border-radius: var(--ecke-plakette);
    background: var(--flaeche);
    color: var(--text-leise);
    font-family: var(--schrift-zahl);
    font-size: 12px;
    font-weight: 700;
}
.partner-schritt.erledigt { background: var(--gut-flaeche); border-color: var(--gut); }
.partner-schritt.erledigt .partner-schritt-nummer { border-color: var(--gut); color: var(--gut); }
.partner-schritt.aktuell {
    border: 2px solid var(--marke);
    padding: calc(var(--luft-2) - 1px);
    background: var(--marke-schleier);
}
.partner-schritt.aktuell .partner-schritt-nummer { background: var(--marke); border-color: var(--marke); color: var(--auf-marke); }
.partner-schritt.entfaellt { opacity: .72; }

.partner-statusformular fieldset {
    min-width: 0;
    margin: 0 0 var(--luft-3);
    padding: 0;
    border: 0;
}
.partner-statusformular legend {
    width: 100%;
    margin-bottom: var(--luft-2);
    font-weight: 700;
    color: var(--text);
}
.status-auswahl,
.abschlussart-auswahl {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--luft-2);
}
.status-steuerung,
.abschlussart-steuerung {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}
.status-option {
    display: block;
    min-width: 0;
    min-height: 58px;
    padding: var(--luft-2) var(--luft-3);
    border: 1px solid var(--linie);
    border-radius: var(--ecke-element);
    background: var(--flaeche);
    cursor: pointer;
}
.status-option strong,
.status-option span { display: block; overflow-wrap: anywhere; }
.status-option span { margin-top: 2px; color: var(--text-leise); font-size: 12px; }
.status-steuerung:checked + .status-option,
.abschlussart-steuerung:checked + .status-option {
    border: 2px solid var(--marke);
    padding: calc(var(--luft-2) - 1px) calc(var(--luft-3) - 1px);
    background: var(--marke-schleier);
}
.status-steuerung:focus-visible + .status-option,
.abschlussart-steuerung:focus-visible + .status-option {
    outline: 2px solid var(--signal);
    outline-offset: 2px;
}
.status-felder,
.abschlussart-felder {
    display: none;
    grid-column: 1 / -1;
    margin-top: var(--luft-2);
    padding: var(--luft-3);
    border-left: 3px solid var(--marke);
    background: var(--flaeche-tief);
}
.status-felder > :last-child,
.abschlussart-felder > :last-child { margin-bottom: 0; }
.status-steuerung[value="abschluss"]:checked ~ .status-felder-abschluss,
.status-steuerung[value="abgelehnt"]:checked ~ .status-felder-ablehnung,
.abschlussart-steuerung[value="einmalig"]:checked ~ .abschlussart-felder-einmalig,
.abschlussart-steuerung[value="abo"]:checked ~ .abschlussart-felder-abo { display: block; }

.partner-hauptaktion .knopf { min-width: min(100%, 18rem); }
.portal-zurueck-stand { margin-bottom: var(--luft-3); }
.portal-zurueck-stand a {
    display: inline-flex;
    align-items: center;
    min-height: 38px;
    font-weight: 600;
}
.buch tr:target { outline: 2px solid var(--signal); outline-offset: -2px; }
.partner-nebenaktion { margin-top: var(--luft-3); }
.partner-nebenaktion > summary {
    display: inline-flex;
    align-items: center;
    min-height: 38px;
    color: var(--marke);
    font-weight: 600;
    cursor: pointer;
}
.partner-nebenaktion[open] > summary { margin-bottom: var(--luft-3); }

@media (max-width: 700px) {
    .partner-schritte,
    .status-auswahl,
    .abschlussart-auswahl { grid-template-columns: minmax(0, 1fr); }
    .partner-schritt { align-items: center; }
    .partner-schritt strong,
    .status-option strong { font-size: 16px; }
    .partner-schritt small,
    .status-option span { font-size: 14px; }
    .partner-hauptaktion .knopf,
    .partner-statusformular .knopf,
    .partner-nebenaktion .knopf { width: 100%; }

    .public-seite {
        align-items: flex-start;
        padding: var(--luft-2);
    }
    .public-karte { padding: var(--luft-4) var(--luft-3); }
    .portal-kurzanleitung { grid-template-columns: minmax(0, 1fr); }
    .portal-einstieg .knopf { width: 100%; }
    .portal-freie-zeiten { columns: 1; }
    .portal-koerper input[type="time"] {
        min-height: 44px;
        font-size: 16px;
    }

    .portal-wochenplan thead { display: none; }
    .portal-wochenplan,
    .portal-wochenplan tbody,
    .portal-wochenplan tr,
    .portal-wochenplan th,
    .portal-wochenplan td {
        display: block;
        width: 100%;
    }
    .portal-wochenplan tr {
        padding: var(--luft-3) 0;
        border-bottom: 1px solid var(--linie);
    }
    .portal-wochenplan tr:last-child { border-bottom: 0; }
    .portal-wochenplan tbody th {
        padding: 0 0 var(--luft-2);
        border: 0;
        font-size: 17px;
        text-align: left;
    }
    .portal-wochenplan td {
        display: grid;
        grid-template-columns: minmax(0, 7rem) minmax(0, 1fr);
        gap: var(--luft-2);
        align-items: center;
        padding: 3px 0;
        border: 0;
    }
    .portal-wochenplan td::before {
        content: attr(data-feld);
        color: var(--text-leise);
    }
    table.buch.stapelt.portal-empfaenger-tabelle td:not(:first-child) {
        grid-template-columns: minmax(0, 1fr);
        gap: 2px;
        padding-top: var(--luft-2);
    }

    /* Die Portalnavigation bricht in ein festes Raster um. Damit liegt keine
       Aktion außerhalb des sichtbaren 390-Pixel-Bereichs. */
    .portal-kopf { position: static; flex-wrap: wrap; align-items: stretch; }
    .portal-kopf .kopfzeile-start { flex-basis: 100%; }
    .portal-navi {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        width: 100%;
    }
    .portal-navi .knopf,
    .portal-navi form,
    .portal-navi form .knopf { width: 100%; }
    .portal-navi > span { grid-column: 1 / -1; margin-left: 0; }
}

/* =========================================================== Anruf-Panel ===
   Ein Dialog ueber der Arbeitsmaske (app/Views/_partials/anruf-panel.php).

   Alle Farben und Abstaende kommen aus app.css. Es entsteht kein zweites
   Erscheinungsbild, nur eine zweite Ebene.

   Ohne JavaScript bleibt <dialog> ohne open-Attribut unsichtbar; hier steht
   deshalb bewusst KEINE Regel, die das Panel sichtbar machen wuerde. Die
   Arbeitsmaske darunter traegt dieselben Angaben. */
dialog.sc-panel {
    width: min(720px, 96vw);
    max-width: 96vw;
    max-height: 92vh;
    max-height: 92dvh;
    padding: 0;
    border: 1px solid var(--linie);
    border-radius: 10px;
    background: var(--flaeche);
    color: var(--text);
    box-shadow: var(--schatten-hoch);
    overflow: hidden;
}
dialog.sc-panel[open] {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
}
dialog.sc-panel::backdrop { background: rgba(28, 35, 33, .45); }

.sc-panel-kopf {
    position: relative;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--luft-2);
    padding: var(--luft-3);
    min-width: 0;
    max-width: 100%;
    box-sizing: border-box;
    overflow: hidden;
    background: var(--flaeche);
    border-bottom: 1px solid var(--linie);
}
/* Firmenname und Kennung sind Fremdwerte. Der Text darf deshalb schrumpfen und
   umbrechen, während der Schließen-Knopf immer vollständig erreichbar bleibt. */
.sc-panel-kopf > strong {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    overflow-wrap: anywhere;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.sc-panel-kopf > button { flex: 0 0 auto; }

.sc-panel-koerper {
    display: flex;
    flex-direction: column;
    gap: var(--luft-3);
    padding: var(--luft-3);
    min-width: 0;
    max-width: 100%;
    box-sizing: border-box;
    min-height: 0;
    overflow-x: hidden;
    overflow-y: auto;
    overscroll-behavior: contain;
}

/*
 * Die Kerndaten (Ansprechpartner, Telefon, E-Mail, Website) im Panel.
 *
 * .tabelle-rahmen ist ein Scrollcontainer (overflow-x: auto) und als solcher
 * das einzige Flex-Kind des Panelkoerpers, dessen automatische Mindesthoehe 0
 * ist. Sobald der Panelinhalt hoeher ist als der Koerper - und das ist er
 * immer, das Ergebnisformular allein misst rund 760px - verteilt Flexbox das
 * Schrumpfen ausschliesslich auf dieses Kind und drueckt es auf 0px; die
 * Tabelle mit dem tel:-Verweis, dem wichtigsten Knopf des Panels, war damit
 * unsichtbar. Gemessen bei 390x844 und 1280x800: rahmenH 0, elementFromPoint
 * am Verweis traf den Panelkoerper. Der Rahmen darf deshalb nicht schrumpfen;
 * der Koerper selbst scrollt (overflow-y: auto), das reicht.
 */
.sc-panel-koerper > .tabelle-rahmen {
    flex: 0 0 auto;
    min-height: max-content;
}

.sc-panel-daten th { width: 8rem; }

/* Der Anrufverweis. Er ist der WICHTIGSTE Knopf des Panels - alles andere hier
   ist Nacharbeit, das hier ist der Anruf - und war bei 390px genau 24px hoch,
   also so hoch wie seine Schrift. Gemessen, nicht geschaetzt. Er bekommt
   deshalb dieselbe Trefferflaeche wie jeder Knopf: 44px, mit sichtbarem Rand,
   damit er auch als Knopf erkennbar ist und nicht als unterstrichener Text.

   Die Pruefung dazu steht in scripts/selftest-kichat.php, Kriterium 76 - sie sah
   bis dahin nur button, summary, select, textarea und datetime-local an und ging
   an genau diesem Verweis vorbei.

   a.anrufweg IST DERSELBE VERWEIS AUSSERHALB DES PANELS. Er stand in der
   Arbeitsmaske darunter, im Leaddetail und am Termin weiterhin auf 24px -
   gemessen im Browser bei 390px, angemeldet als Vertriebler: "Karte h=24.0 |
   Panel h=44.0". Die Trefferflaeche hing an der Maske statt an der Handlung,
   und die Maske, die der Caller ohne Panel benutzt, war die kleinere. Gesetzt
   wird die Klasse in LeadController::telefonHtml($alsAnrufweg); in der
   Leadliste bleibt sie aus, dort ist die Nummer eine Angabe und keine
   Handlung.

   DIE DREI SELEKTOREN SIND KEIN VERSEHEN. "a.anrufweg" allein wog zu wenig:
   in app.css steht "table.buch tbody td a { min-height: 24px }" und
   "p > strong:first-child + a.kennung { min-height: 24px }", und beide wiegen
   mehr. Gemessen wurde genau das - die Klasse griff, der Rand war da, die Hoehe
   blieb bei 24px. Jeder Selektor nennt deshalb die Umgebung, gegen die er
   antritt: Tabellenzelle (Arbeitsmaske, Leaddetail) und Absatz (Termin). */
.sc-panel a[href^="tel:"],
a.anrufweg,
table.buch tbody td a.anrufweg,
p > strong:first-child + a.anrufweg {
    display: inline-flex;
    align-items: center;
    gap: var(--luft-1);
    min-height: 44px;
    padding: 0 var(--luft-2);
    /* Der Rand ist die einzige Knopf-Affordanz dieses Verweises (die
       Unterstreichung ist entfernt). var(--linie) lag bei 1,4:1 auf Weiss,
       der Kanon verlangt 3:1 - Electric Blue ist die Aktionsfarbe der Marke
       und liegt bei 5,4:1 auf Weiss. */
    border: 1px solid var(--marke-hell);
    border-radius: 6px;
    /* Die Nummer ist der wichtigste Knopf der Anrufmaske und erbte 12px aus
       .kennung im 14px-Tabellenkontext. */
    font-size: 15px;
    font-weight: 600;
    text-decoration: none;
}
@media (max-width: 900px) {
    .sc-panel a[href^="tel:"],
    a.anrufweg { font-size: 16px; }
}
.sc-panel a[href^="tel:"]:hover,
.sc-panel a[href^="tel:"]:focus-visible,
a.anrufweg:hover,
a.anrufweg:focus-visible,
table.buch tbody td a.anrufweg:hover,
table.buch tbody td a.anrufweg:focus-visible { background: var(--flaeche-tief); }

/* Abschnitte, die von selbst offen stehen. Die Trefferflaeche der Zusammen-
   fassung ist 44px hoch, nicht nur so hoch wie ihre Schrift. */
.sc-abschnitt {
    border: 1px solid var(--linie-zart);
    border-radius: 8px;
    background: var(--flaeche);
}
.sc-abschnitt > summary {
    display: flex;
    align-items: center;
    min-height: 44px;
    padding: var(--luft-2) var(--luft-3);
    font-weight: 600;
    cursor: pointer;
}
.sc-abschnitt > .sc-abschnitt-koerper { padding: 0 var(--luft-3) var(--luft-3); }
[data-panel-produktinhalt]:not([hidden]) {
    display: flex;
    flex-direction: column;
    gap: var(--luft-3);
}

/* ------------------------------------------------------------- KI-Chat --- */
.ki-chat { display: flex; flex-direction: column; gap: var(--luft-2); }

/* DAS GESPRAECHSFENSTER.
   240px waren zweieinhalb Antworten: wer nachfragte, scrollte in einem Feld
   von der Hoehe einer Zeile Fliesstext und verlor die vorherige Antwort aus
   dem Blick. Es waechst jetzt mit dem Gespraech und deckelt erst bei der
   halben Bildschirmhoehe - dort, wo Scrollen wirklich noetig wird. */
.ki-log {
    min-height: 160px;
    max-height: 52vh;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: var(--luft-2);
    border: 1px solid var(--linie-zart);
    border-radius: 6px;
    background: var(--flaeche-tief);
}

/* Die Wartezeile: sichtbar, aber ohne Aufmerksamkeit zu fordern. Sie steht nur
   die paar Sekunden bis zur Antwort da. */
.ki-zeile.ki-wartet .ki-text {
    color: var(--text-leise);
    font-style: italic;
}

.ki-zeile {
    display: flex;
    gap: var(--luft-2);
    margin-bottom: var(--luft-2);
    font-size: 14px;
    line-height: 1.5;
}
.ki-zeile:last-child { margin-bottom: 0; }
.ki-rolle { flex: 0 0 2.2rem; font-weight: 600; color: var(--text-kopf); }
/* Eine Antwort kann eine lange Zeichenkette ohne Leerzeichen enthalten. Ohne
   diesen Umbruch schoebe sie das Panel auf, und die Seite scrollte waagerecht. */
.ki-text { flex: 1; min-width: 0; overflow-wrap: anywhere; }

.ki-schnellfragen {
    border: 1px solid var(--linie-zart);
    border-radius: 6px;
    background: var(--flaeche);
}
/* Die eigene Flex-Regel der Fragenliste darf den geschlossenen Zustand des
   nativen Details-Elements nicht überstimmen. */
.ki-schnellfragen:not([open]) > :not(summary) { display: none; }
.ki-schnellfragen > summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--luft-2);
    min-height: 44px;
    padding: var(--luft-2) var(--luft-3);
    font-weight: 600;
}
.ki-schnellfragen > summary::after {
    content: '+';
    flex: 0 0 auto;
    color: var(--text-leise);
    font-size: 1.2rem;
}
.ki-schnellfragen[open] > summary::after { content: '\2212'; }
.ki-schnellfragen > p { margin: 0; padding: 0 var(--luft-3) var(--luft-2); }
.ki-vorschlaege {
    display: flex;
    flex-wrap: wrap;
    gap: var(--luft-1);
    padding: 0 var(--luft-3) var(--luft-3);
}
.ki-vorschlaege .knopf {
    height: auto;
    white-space: normal;
    text-align: left;
}
.ki-wiederholen-hinweis { margin: var(--luft-2) 0 0; }
.ki-hinweis { color: var(--text-leise); }
.ki-protokoll > summary,
.ki-protokoll .stapel > details > summary {
    min-height: 44px;
    box-sizing: border-box;
    padding-block: var(--luft-2);
    cursor: pointer;
    overflow-wrap: anywhere;
}
.ki-protokoll .ki-log { margin-top: var(--luft-1); }

@media (max-width: 700px) {
    .ki-zeile {
        display: grid;
        grid-template-columns: minmax(4rem, auto) minmax(0, 1fr);
    }
    .ki-vorschlaege { flex-direction: column; }
    .ki-vorschlaege .knopf {
        width: 100%;
        min-height: 44px;
        justify-content: flex-start;
    }
    .ki-chat form .knopfreihe { align-items: stretch; }
    .ki-chat form .knopfreihe .knopf { width: 100%; }

    dialog.sc-panel {
        width: 100%;
        max-width: 100%;
        height: 100vh;
        height: 100dvh;
        max-height: 100vh;
        max-height: 100dvh;
        margin: 0;
        border: 0;
        border-radius: 0;
    }
    .sc-panel-kopf {
        padding: max(var(--luft-3), env(safe-area-inset-top)) var(--luft-3) var(--luft-3);
    }
    .sc-panel-koerper {
        padding: var(--luft-3);
        padding-bottom: max(var(--luft-3), env(safe-area-inset-bottom));
    }
    /* Vier Tabellenzellen nebeneinander erzeugten auf 390px eine breite,
       waagerecht verschobene Fläche. Jede Beschriftung und ihr Wert bilden
       mobil stattdessen ein echtes Zweispaltenpaar. */
    .sc-panel .tabelle-rahmen { max-width: 100%; overflow-x: hidden; }
    .sc-panel .buch,
    .sc-panel .buch tbody { display: block; width: 100%; min-width: 0; }
    .sc-panel .buch tr {
        display: grid;
        grid-template-columns: minmax(6.75rem, .8fr) minmax(0, 1.2fr);
        width: 100%;
        min-width: 0;
    }
    .sc-panel .buch th,
    .sc-panel .buch td {
        position: static;
        width: auto;
        min-width: 0;
        max-width: 100%;
        white-space: normal;
        overflow-wrap: anywhere;
        word-break: break-word;
    }
    .sc-panel .buch td[colspan] { grid-column: 2 / -1; }
    .sc-panel .buch a { min-width: 0; max-width: 100%; overflow-wrap: anywhere; }
    /* Auf dem Telefon 16px im Fliesstext (Design-Kanon). */
    .ki-zeile { font-size: 16px; }
    .sc-panel-daten th { width: auto; }
}
