/* ==========================================================================
   Anfragen und WhatsApp
   --------------------------------------------------------------------------
   Liste, Detail und Board der Anfragen. Am Ende die WhatsApp-Bausteine, die
   auch das Lead-Detail und das Personenpanel brauchen – das Maß des
   Verlaufs auf der eigenen Seite steht in whatsapp.css.

   TEIL 5 VON 9 von assets/css/style.css.

   ACHTUNG, REIHENFOLGE: CSS ist kaskadierend. Diese Dateien werden in
   includes/header.php in genau dieser Nummerierung eingebunden, und die
   Nummer im Dateinamen IST die Reihenfolge. Wer eine Datei dazwischen
   schiebt oder die Einbindung umsortiert, ändert stillschweigend, welche
   Regel bei gleicher Spezifität gewinnt.
   ========================================================================== */

/* ==========================================================================
   Leads (leads.php) – Anfragen aus den öffentlichen Landingpages.
   Der Zweispalter kommt aus dem Postfach (.ml-split), hier stehen nur die
   Teile, die es dort nicht gibt: Kennzahlen, Listenzeile, Detailspalte.

   Umgekehrt benutzt das Postfach inzwischen die Kennzahlenkacheln, die
   Kontaktkacheln und die Abschnitte von hier – die Regeln tragen deshalb
   beide Präfixe (.ld- und .ml-). Wer hier etwas ändert, ändert es dort mit.
   ========================================================================== */
/* Kennzahlenkacheln – eine Familie für die ganze Anwendung. Sie hießen
   einmal .ld-kpi (Leads), .ml-kpi (Postfach), .dp-kpi (Übertragen) und
   .stat-tile (Startseite, Kundenseiten); die letzte Fassung stellte die
   Beschriftung sogar unter die Zahl statt darüber. Jetzt ist es überall
   dasselbe: Mikrolabel, Zahl, leise Fußnote.

   Aufbau:  <div class="kpi-grid">
              <div class="kpi"><span class="section-label">…</span>
                <b>42</b><span class="kpi-note">…</span></div> */
.kpi-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--sp-4);
    margin-bottom: var(--sp-6);
}
.kpi-grid.is-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.kpi-grid.is-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* Fünf – im Adressbuch, seit es vier Kundenarten gibt (kontakte.php). */
.kpi-grid.is-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.kpi {
    padding: var(--sp-4) var(--sp-5);
    border: 1px solid var(--brand-border);
    border-radius: var(--r-card);
    background: var(--brand-surface);
    /* Dieselbe Erhebung wie die Karte – die Kachelreihe steht auf jeder Seite
       direkt über Karten und gehörte sonst sichtbar zu einer anderen Ebene. */
    box-shadow: var(--sh-1);
}
.kpi > .section-label { display: block; }
/* Das Zeichen der Beschriftung trägt das Leuchtblau des Hauses – überall, wo
   Kennzahlen stehen, nicht nur auf der Startseite. Es ist die Marke, an der
   man die Kachelreihe als eine Familie erkennt; die Beschriftung daneben
   bleibt im Grau der Mikrolabel, die Zahl behält ihren Zustandston. */
.kpi > .section-label svg { color: var(--btn-leucht); }
.kpi b {
    display: block;
    margin: 0.1rem 0 0;
    font-size: var(--fs-11);
    font-weight: 700;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
    line-height: 1.15;
    /* Die Zahl im tiefen Blaugrau statt im Tintenton: Eine Kennzahl ist eine
       Ansage und keine Fließtextzeile, und Schwarz auf Weiß ist auf einer
       kühlen Fläche die einzige Stelle, die warm wirkt. */
    color: var(--brand-titel);
}
.kpi-note {
    display: block;
    font-size: var(--fs-4);
    color: var(--brand-faint);
}
/* Abgeleitete Zahl neben der Kennzahl (z.B. die Provision zur Beitragssumme) */
.kpi-zweit {
    font-size: var(--fs-7);
    font-weight: 600;
    color: var(--btn-green);
    white-space: nowrap;
}
/* Erläuterung in der Kartenüberschrift, rechts und leise */
.ld-card-note {
    float: right;
    font-size: var(--fs-3);
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--brand-faint);
}
/* Eine Kachel darf ein Link sein („Dokumente" in der Kontaktakte springt zu
   ihrem Kasten) – sie sieht dann aus wie ihre Nachbarn und verrät sich erst
   unter dem Zeiger. */
a.kpi { text-decoration: none; color: inherit; display: block; }

/* ==========================================================================
   EINE KACHEL, DIE MAN ANFASSEN KANN, HEBT SICH (22.08.2026)

   Ein Pixel und die zweite Schattenstufe. Bis dahin sahen anklickbare Kacheln
   genauso aus wie die, die nur dastehen – die Auskunft „hier geht etwas" kam
   erst, wenn der Zeiger zur Hand wurde.

   Ein Pixel, nicht zwei: Bei zwei Pixeln sieht man die Kachel springen; bei
   einem sieht man nur, dass sie näher steht.
   ========================================================================== */
@media (hover: hover) and (pointer: fine) {
    a.kpi:hover {
        transform: translateY(-1px);
        border-color: var(--blau-rand);
        box-shadow: var(--sh-2);
    }
}
@media (prefers-reduced-motion: reduce) {
    a.kpi:hover { transform: none; }
}

/* Offene Anfragen (bzw. ungelesene Mails) sind das Einzige, was hier rot sein darf */
.kpi.is-alert {
    border-color: var(--btn-red-border-light);
    background: var(--btn-red-bg-light);
}
.kpi.is-alert b { color: var(--brand-accent); }

/* --------------------------------------------------------------------------
   ES GIBT GENAU EIN KACHELFORMAT – und das steht oben
   --------------------------------------------------------------------------
   Hier stand am 22.08.2026 einen halben Tag lang eine zweite, flache Fassung
   (.kpi-grid.is-schlank, rund 52px statt 112) für die drei Seiten der
   Arbeitsfläche. Die Rechnung dahinter stimmte – auf einer Seite, die nicht
   rollt, ist jeder Pixel der Kopfzone dauerhaft weg – aber sie war die
   falsche Frage. Wer zwischen Postfach und Kontakten umschaltet, sieht
   dieselbe Kachelreihe an derselben Stelle in zwei Höhen: Das Auge sucht bei
   jedem Wechsel neu, wo die Seite anfängt.

   MERKSATZ: Eine Kennzahlenkachel ist auf jeder der 28 Seiten gleich hoch.
   Wer auf einer Seite Platz braucht, nimmt ihn woanders her (weniger
   Kacheln, kürzere Unterzeile) – nicht am gemeinsamen Maß.
   -------------------------------------------------------------------------- */

/* Listenzeile */
.ld-row-name {
    font-size: var(--fs-6);
    font-weight: 600;
}
.ld-row-zeit {
    flex: none;
    font-size: var(--fs-3);
    color: var(--brand-faint);
    font-variant-numeric: tabular-nums;
}
.ld-row-meta {
    font-size: var(--fs-4);
    color: var(--brand-quiet);
}
/* Unbearbeitet: schmaler roter Streifen am Zeilenanfang */
.ml-row.ist-neu { box-shadow: inset 3px 0 0 0 var(--brand-accent); }
.ml-row.ist-neu.is-active { box-shadow: inset 3px 0 0 0 var(--btn-leucht-dark); }

/* Liegedauer in der Bewerbungsliste – dieselbe Sprache wie überall sonst
   (.is-warnung/.is-dringend): blaugrau heißt „wird alt",
   rot heißt „wartet zu lange". Die Regeln stehen NACH .ist-neu, weil beide
   dieselbe Spezifität haben und dieselbe Eigenschaft setzen; eine neue
   Bewerbung, die schon liegt, soll die Liegedauer zeigen und nicht nur, dass
   sie neu ist. Die Farbe ist in diesem Fall ohnehin dieselbe. */
.ml-row.is-warnung { box-shadow: inset 3px 0 0 0 var(--btn-blue); }
.ml-row.is-dringend { box-shadow: inset 3px 0 0 0 var(--brand-accent); }
.ml-row.is-warnung.is-active,
.ml-row.is-dringend.is-active { box-shadow: inset 3px 0 0 0 var(--btn-leucht-dark); }

/* Detailspalte. Rand, Rundung und Polster kommen aus `.ml-read-pane > *`
   (04-arbeitsflaechen.css) – Kopf und Rumpf sind zwei eigene Flächen mit
   einer Fuge dazwischen. Der graue Grund und die Trennlinie sind deshalb
   weg: beides sagte, was die Fuge jetzt zeigt. */
.ld-detail-head {
    padding-bottom: var(--sp-4);
}
.ld-detail-name {
    margin: 0;
    font-size: var(--fs-8);
}
/* Der Bearbeitungsstand sitzt hochgestellt am Namen – wie ein Exponent,
   nicht als eigene Zeile und nicht in der Ecke des Bereichs. */
.ld-stand-hoch {
    margin-left: 0.4rem;
    vertical-align: super;
    font-size: var(--fs-1);
    padding: 0.15em 0.5em;
    line-height: 1.4;
    position: relative;
    top: -0.15em;
}
.ld-detail-sub {
    font-size: var(--fs-4);
    color: var(--brand-quiet);
}
/* Polster aus `.ml-read-pane > *`. */

.ld-kontakt,
.ml-kontakt {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--sp-3);
    margin-bottom: 0.9rem;
}
.ld-kontakt-item,
.ml-kontakt-item {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    min-width: 0;
    padding: var(--sp-3) 0.7rem;
    border: 1px solid var(--brand-border);
    border-radius: var(--r-ctl);
    background: var(--brand-row);
    color: var(--brand-text);
    font-size: var(--fs-6);
    text-decoration: none;
    word-break: break-word;
    transition: border-color var(--t-fast) var(--ease-out), background-color var(--t-fast) var(--ease-out);
}
/* Eine Kachel, die etwas AUSLÖST, ist ein Knopf und kein Verweis – der
   Rückruf im Telefonmodul lässt die Telefonanlage wählen (telefon.php). Der
   Browser bringt für <button> eigene Schrift, eigene Ausrichtung und einen
   eigenen Hintergrund mit; die drei Zeilen nehmen sie ihm wieder ab, damit
   die Kachel neben den anderen nicht auffällt. Das Formular darum herum
   verschwindet mit `display: contents` aus dem Raster – sonst säße es als
   Zelle dazwischen und die Kachel darin hätte keine Breite. */
.ml-kontakt-form { display: contents; }
button.ml-kontakt-item {
    width: 100%;
    text-align: left;
    font: inherit;
    cursor: pointer;
}
.ld-kontakt-item:hover,
a.ml-kontakt-item:hover,
button.ml-kontakt-item:hover,
button.ml-kontakt-item:focus-visible {
    border-color: var(--btn-blue-border-light);
    background: var(--btn-blue-bg-light);
    color: var(--brand-text);
}
/* Der Rückruf-Knopf, solange die Anlage noch nicht wählen kann (kein Token,
   keine Nebenstelle hinterlegt): Er bleibt anfassbar – ein Druck darauf sagt,
   was fehlt –, sieht aber zurückhaltender aus als einer, der sofort ein
   Gespräch aufbaut. Gestrichelt wie die Kacheln ohne Inhalt (`is-off`), aber
   mit Zeigefinger: Hier ist etwas zu holen, nur noch nicht das Gespräch. */
button.ml-kontakt-item.is-wartet {
    border-style: dashed;
    color: var(--brand-quiet);
}
button.ml-kontakt-item.is-wartet svg { color: var(--brand-faint); }
/* Der Satz dazu – über die ganze Breite unter den Kacheln, im selben Rahmen. */
.ml-kontakt-hinweis {
    grid-column: 1 / -1;
    font-size: var(--fs-5);
    color: var(--brand-quiet);
}

.ld-kontakt-item svg,
.ml-kontakt-item svg { flex: none; color: var(--btn-blue-dark); }
/* WhatsApp trägt seine eigene Farbe – aber nur, wenn der Kunde zugestimmt hat */
.ld-kontakt-item.is-whatsapp svg { color: var(--btn-green); }
.ld-kontakt-item.is-whatsapp:hover {
    border-color: var(--btn-green-border-light);
    background: var(--btn-green-bg-light);
}
/* Derselbe grüne Hover wie beim WhatsApp-Knopf – für Wege, die aus dem
   Dashboard hinausführen (z.B. „Landingpage ansehen"). */
.ld-gruen-hover:hover,
.ld-gruen-hover:focus-visible {
    border-color: var(--btn-green-border-light);
    background: var(--btn-green-bg-light);
    color: var(--btn-green);
}
.ld-gruen-hover:hover svg,
.ld-gruen-hover:focus-visible svg { color: var(--btn-green); }

/* Nicht gewünscht: sichtbar, aber ohne Aufforderung */
.ld-kontakt-item.is-off,
.ml-kontakt-item.is-off {
    color: var(--brand-faint);
    background: var(--brand-surface);
    border-style: dashed;
    cursor: default;
}
.ld-kontakt-item.is-off svg,
.ml-kontakt-item.is-off svg { color: var(--brand-faint); }
/* Reine Angabe (z.B. der Zeitpunkt): steht da, führt aber nirgendwohin */
.ml-kontakt-item.is-still { background: var(--brand-surface); cursor: default; }
.ld-row-wa svg { color: var(--btn-green); vertical-align: -2px; }

.ld-facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
    gap: var(--sp-3);
    margin: 0 0 0.9rem;
    padding: 0.6rem 0.7rem;
    border: 1px solid var(--brand-border);
    border-radius: var(--r-ctl);
}
.ld-facts dd {
    margin: 0.1rem 0 0;
    font-size: var(--fs-6);
    font-weight: 600;
}

.ld-block + .ld-block,
.ml-block + .ml-block { margin-top: 0.9rem; }
.ld-nachricht {
    margin: 0.3rem 0 0;
    padding: 0.6rem var(--sp-4);
    border-left: 2px solid var(--brand-line-strong);
    background: var(--brand-row);
    border-radius: 0 var(--r-sm) var(--r-sm) 0;
    font-size: var(--fs-6);
    line-height: 1.6;
}

.ld-bearbeiter {
    font-size: var(--fs-5);
    color: var(--brand-quiet);
    margin-left: 0.4rem;
}
.ld-bearbeiter strong { color: var(--brand-text); }

/* Die Stände tragen ihre eigene Farbe – dieselbe wie die Blasen in der Liste,
   damit „Neu" hier und dort dasselbe Rot ist. Ruhend nur als Kontur, beim
   Überfahren füllt sich der Ton. */
.ld-status {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    margin-top: 0.35rem;
}
.ld-status-btn {
    display: inline-flex;
    align-items: center;
    height: var(--h-ctl-sm);
    padding: 0 var(--sp-4);
    border: 1px solid var(--btn-gray-border);
    border-radius: var(--r-pill);
    background: var(--brand-surface);
    color: var(--brand-quiet);
    font-size: var(--fs-5);
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    transition: background-color var(--t-fast) var(--ease-out), border-color var(--t-fast) var(--ease-out), color var(--t-fast) var(--ease-out);
}
/* Je Stand ein Ton: Neu rot, In Arbeit orange, Kontaktiert blaugrau,
   Abgeschlossen grün, Kein Interesse bleibt grau. */
.ld-status-btn.is-neu           { border-color: var(--btn-red-border-light); color: var(--btn-red-text); }
.ld-status-btn.is-in_arbeit     { border-color: var(--btn-orange-border-light); color: var(--btn-orange-text); }
.ld-status-btn.is-kontaktiert   { border-color: var(--btn-blue-border-light); color: var(--btn-blue-dark); }
.ld-status-btn.is-abgeschlossen { border-color: var(--btn-green-border-light); color: var(--btn-green); }

.ld-status-btn.is-neu:hover           { background: var(--btn-red-bg-light); color: var(--btn-red-text); }
.ld-status-btn.is-in_arbeit:hover     { background: var(--btn-orange-bg-light); color: var(--btn-orange-text); }
.ld-status-btn.is-kontaktiert:hover   { background: var(--btn-blue-bg-light); color: var(--btn-blue-dark); }
.ld-status-btn.is-abgeschlossen:hover { background: var(--btn-green-bg-light); color: var(--btn-green); }
.ld-status-btn.is-kein_interesse:hover { background: var(--btn-gray-bg-hover); color: var(--brand-text); }

/* Der aktuelle Stand ist gefüllt und nicht anklickbar */
.ld-status-btn.is-active { color: var(--auf-marke); cursor: default; }
.ld-status-btn.is-neu.is-active           { background: var(--brand-accent); border-color: var(--brand-accent); }
.ld-status-btn.is-in_arbeit.is-active     { background: var(--btn-orange-text); border-color: var(--btn-orange-text); }
.ld-status-btn.is-kontaktiert.is-active   { background: var(--btn-blue-dark); border-color: var(--btn-blue-dark); }
.ld-status-btn.is-abgeschlossen.is-active { background: var(--btn-green); border-color: var(--btn-green); }
.ld-status-btn.is-kein_interesse.is-active { background: var(--brand-quiet); border-color: var(--brand-quiet); }

/* Der Stand, für den das Formular gerade offen steht */
.ld-status-btn.is-gewaehlt {
    box-shadow: var(--focus-ring);
}

/* --- Formular zum Dokumentieren eines Statuswechsels --- */
.ld-stand-form {
    margin-top: 0.7rem;
    padding: 0.8rem 0.9rem 0.9rem;
    border: 1px solid var(--brand-border);
    border-left: 3px solid var(--brand-line-strong);
    border-radius: var(--r-ctl);
    background: var(--brand-row);
}
/* Die Kante links greift den Ton des Ziel-Stands auf */
.ld-stand-form.is-in_arbeit     { border-left-color: var(--btn-orange-text); }
.ld-stand-form.is-kontaktiert   { border-left-color: var(--btn-blue-dark); }
.ld-stand-form.is-abgeschlossen { border-left-color: var(--btn-green); }
.ld-stand-form.is-kein_interesse { border-left-color: var(--brand-quiet); }
.ld-stand-form.is-neu           { border-left-color: var(--brand-accent); }

.ld-stand-kopf {
    display: flex;
    align-items: baseline;
    gap: var(--sp-3);
    flex-wrap: wrap;
    margin-bottom: 0.7rem;
}
.ld-stand-hinweis {
    font-size: var(--fs-5);
    color: var(--brand-quiet);
}
.ld-stand-felder {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.6rem;
}
.ld-feld { display: block; min-width: 0; }
.ld-feld-breit { grid-column: 1 / -1; }
.ld-feld .section-label {
    display: block;
    margin-bottom: 0.2rem;
}
.ld-optional {
    font-weight: 500;
    letter-spacing: 0;
    text-transform: none;
    color: var(--brand-faint);
}
.ld-stand-fuss {
    display: flex;
    gap: 0.4rem;
    margin-top: 0.8rem;
}

/* --- Verlauf --- */
.ld-verlauf {
    margin: 0.4rem 0 0;
    padding: 0;
    list-style: none;
}
.ld-v-zeile {
    position: relative;
    display: flex;
    gap: 0.7rem;
    padding-bottom: 0.8rem;
}
/* Die Linie verbindet die Punkte, endet aber am letzten */
.ld-v-zeile:not(:last-child)::before {
    content: "";
    position: absolute;
    left: 4px;
    top: 14px;
    bottom: 0;
    width: 1px;
    background: var(--brand-border);
}
.ld-v-punkt {
    position: relative;
    z-index: 1;
    flex: none;
    width: 9px; height: 9px;
    margin-top: 5px;
    border-radius: 50%;
    background: var(--brand-line-strong);
}
.ld-v-punkt.is-neu           { background: var(--brand-accent); }
.ld-v-punkt.is-in_arbeit     { background: var(--btn-orange-text); }
.ld-v-punkt.is-kontaktiert   { background: var(--btn-blue-dark); }
.ld-v-punkt.is-abgeschlossen { background: var(--btn-green); }
/* Vorwarnung vor der Anonymisierung: rote Fahne in der Liste, Kasten im Detail. */
.ld-fahne {
    display: inline-flex;
    vertical-align: -2px;
    color: var(--btn-orange-text);
}
.ld-fahne svg { width: 13px; height: 13px; }
.ld-fahne.ist-faellig { color: var(--brand-accent); }

.ld-warnung {
    display: flex;
    align-items: flex-start;
    gap: 0.7rem;
    margin-bottom: 0.9rem;
    padding: 0.7rem 0.9rem;
    border: 1px solid var(--btn-orange-bg-light);
    background: var(--btn-orange-bg-light);
    border-radius: var(--r-ctl);
    font-size: var(--fs-5);
}
.ld-warnung strong { display: block; color: var(--btn-orange-text); }
.ld-warnung-text { color: var(--brand-quiet); line-height: 1.5; }
.ld-warnung-fahne { color: var(--btn-orange-text); display: inline-flex; margin-top: 1px; }
.ld-warnung-fahne svg { width: 16px; height: 16px; }

/* Notizen sind kein Schritt im Ablauf – hohler Punkt statt gefülltem. */
.ld-v-punkt.is-notiz {
    background: var(--brand-surface);
    box-shadow: inset 0 0 0 2px var(--brand-line-strong);
}
.ld-v-inhalt { flex: 1; min-width: 0; }
.ld-v-kopf {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
    flex-wrap: wrap;
}
.ld-v-zeit {
    font-size: var(--fs-4);
    color: var(--brand-text);
    font-variant-numeric: tabular-nums;
}
.ld-v-wer {
    font-size: var(--fs-4);
    color: var(--brand-faint);
}
.ld-v-angabe {
    margin-top: 0.15rem;
    font-size: var(--fs-5);
    color: var(--brand-quiet);
}
.ld-v-notiz {
    margin: 0.35rem 0 0;
    padding: 0.4rem 0.6rem;
    border-radius: var(--r-sm);
    background: var(--brand-row);
    font-size: var(--fs-5);
    line-height: 1.55;
    color: var(--brand-text);
}

/* --- Auswertung --- */
.kpi.is-gut {
    border-color: var(--btn-green-border-light);
    background: var(--btn-green-bg-light);
}
.kpi.is-gut b { color: var(--btn-green); }

.ld-aus-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.7rem;
}
.ld-aus-fuss {
    margin: 0.9rem 0 0;
    font-size: var(--fs-5);
    line-height: 1.6;
    color: var(--brand-faint);
}

/* Trichter und Ranglisten teilen sich die Balkenbahn */
.ld-t-stufe + .ld-t-stufe { margin-top: 0.85rem; }
.ld-t-kopf,
.ld-rang-kopf {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.6rem;
    margin-bottom: var(--sp-1);
    font-size: var(--fs-6);
}
.ld-t-titel { font-weight: 600; }
.ld-t-zahl,
.ld-rang-zahl {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.ld-t-zahl small,
.ld-rang-zahl small {
    margin-left: 0.35rem;
    font-weight: 500;
    color: var(--brand-faint);
}
.ld-t-bahn {
    height: 9px;
    border-radius: var(--r-pill);
    background: var(--btn-gray-bg);
    overflow: hidden;
}
.ld-t-balken {
    display: block;
    height: 100%;
    border-radius: var(--r-pill);
    background: var(--btn-blue);
}
.ld-t-balken.is-eingegangen   { background: var(--brand-line-strong); }
.ld-t-balken.is-in_arbeit     { background: var(--btn-orange); }
.ld-t-balken.is-kontaktiert   { background: var(--btn-blue); }
.ld-t-balken.is-abgeschlossen { background: var(--btn-green); }
.ld-t-balken.is-absage        { background: var(--brand-faint); }
.ld-t-verlust {
    margin-top: 0.2rem;
    font-size: var(--fs-4);
    color: var(--brand-faint);
}
.ld-rang + .ld-rang { margin-top: 0.7rem; }

/* Säulen je Monat */
.ld-monate {
    display: flex;
    align-items: flex-end;
    gap: var(--sp-3);
    height: 150px;
}
.ld-m-spalte {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    height: 100%;
    min-width: 0;
}
.ld-m-saeulen {
    flex: 1;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    gap: 3px;
    width: 100%;
}
.ld-m-saeule {
    width: 38%;
    max-width: 22px;
    min-height: 2px;
    border-radius: 3px 3px 0 0;
    background: var(--brand-line-strong);
}
.ld-m-saeule.is-ein { background: var(--btn-blue); }
.ld-m-saeule.is-ab { background: var(--btn-green); }
.ld-m-label {
    margin-top: 0.35rem;
    font-size: var(--fs-3);
    color: var(--brand-faint);
    font-variant-numeric: tabular-nums;
}
.ld-legende {
    display: flex;
    gap: var(--sp-5);
    margin-top: 0.7rem;
    font-size: var(--fs-4);
    color: var(--brand-quiet);
}
.ld-legende span { display: inline-flex; align-items: center; gap: 0.35rem; }
.ld-key { width: 8px; height: 8px; border-radius: 2px; }
.ld-key.is-ein { background: var(--btn-blue); }
.ld-key.is-ab { background: var(--btn-green); }

/* --- Aufbau beim Laden ----------------------------------------------------
   Die Auswertung entwickelt sich von null zum Endstand, statt fertig
   dazustehen. Der Trichter füllt sich Stufe um Stufe von „Eingegangen" bis
   „Abgeschlossen" – so läuft der Weg jeder Anfrage einmal sichtbar bis zum
   Abschluss durch –, die Monatssäulen wachsen von unten, die Ranglisten von
   links. `--i` zählt Stufe bzw. Zeile und kommt als Inline-Stil aus leads.php;
   dieselbe Staffelung wie beim Auftritt der Kalenderzellen (03-kalender.css).

   Die Keyframes nennen nur den Anfang: das Ende ist der Wert, der ohnehin am
   Element steht (die Breite und Höhe aus dem Inline-Stil). Die Zahlen dazu
   zählt assets/js/anfragen-auswertung.js hoch.

   Wer weniger Bewegung eingestellt hat, bekommt sofort den Endstand: Die
   Dauern kürzt die globale Regel in 01-basis.css auf 1ms, die Verzögerungen
   – die sie nicht anfasst – nimmt die Medienabfrage am Ende des Blocks raus. */
.ld-aus-kpi .kpi,
.ld-aus-grid > .card { animation: ldAuftritt 360ms var(--ease-out) backwards; }
.ld-aus-kpi .kpi:nth-child(2),
.ld-aus-grid > .card:nth-child(2) { animation-delay: 70ms; }
.ld-aus-kpi .kpi:nth-child(3),
.ld-aus-grid > .card:nth-child(3) { animation-delay: 140ms; }
.ld-aus-kpi .kpi:nth-child(4),
.ld-aus-grid > .card:nth-child(4) { animation-delay: 210ms; }

.ld-trichter .ld-t-balken {
    animation: ldBreiteAuf 520ms var(--ease-out) backwards;
    animation-delay: calc(var(--i, 0) * 240ms);
}
/* Prozent und Verlustzeile erst, wenn ihre Stufe gefüllt ist – vorher
   erklärten sie einen Balken, den es noch nicht gibt. */
.ld-trichter .ld-t-zahl small,
.ld-trichter .ld-t-verlust {
    animation: ldEinblenden 240ms var(--ease-out) backwards;
    animation-delay: calc(var(--i, 0) * 240ms + 340ms);
}
.ld-rang .ld-t-balken {
    animation: ldBreiteAuf 480ms var(--ease-out) backwards;
    animation-delay: calc(var(--i, 0) * 90ms + 180ms);
}
/* Ohne Ortsbindung: dieselben Säulen zeichnen auch den Jahresvergleich und
   die Bestandsentwicklung auf der Umsatzseite – dort ohne `--i`, also alle
   zugleich. Die Abschluss-Säule kommt nach der Eingangs-Säule: erst die
   Anfrage, dann ihr Abschluss. */
.ld-m-saeule {
    animation: ldHoeheAuf 480ms var(--ease-out) backwards;
    animation-delay: calc(var(--i, 0) * 70ms + 160ms);
}
.ld-m-saeule.is-ab { animation-delay: calc(var(--i, 0) * 70ms + 280ms); }

@keyframes ldAuftritt { from { opacity: 0; transform: translateY(6px); } }
@keyframes ldEinblenden { from { opacity: 0; } }
@keyframes ldBreiteAuf { from { width: 0; } }
@keyframes ldHoeheAuf { from { height: 0; } }

@media (prefers-reduced-motion: reduce) {
    /* !important wegen der nth-child- und .is-ab-Staffelungen oben – eine
       Medienabfrage erhöht die Spezifität nicht. */
    .ld-aus-kpi .kpi,
    .ld-aus-grid > .card,
    .ld-trichter .ld-t-balken,
    .ld-trichter .ld-t-zahl small,
    .ld-trichter .ld-t-verlust,
    .ld-rang .ld-t-balken,
    .ld-m-saeule { animation-delay: 0s !important; }
}

.ld-detail-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    margin-top: 1.1rem;
    padding-top: 0.7rem;
    border-top: 1px solid var(--brand-border);
}

@media (max-width: 899.98px) {
    /* Auch für das Postfach – die Grundregeln oben gelten für beide Präfixe,
       und eine Medienabfrage erhöht die Spezifität nicht. */
    .kpi-grid,
    .kpi-grid.is-3,
    .kpi-grid.is-5 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .ld-kontakt,
    .ml-kontakt,
    .ld-facts,
    .ld-stand-felder,
    .ld-aus-grid { grid-template-columns: minmax(0, 1fr); }
}

/* HIER STAND .lb-spur – eine 1560px breite Spur für Seiten, die angeblich
   mehr Platz brauchen als .container. Sie stammte aus dem früheren Lead-Board
   und blieb zuletzt allein für das Monatsraster der Umsatzseite stehen.

   Am 21.08.2026 herausgenommen: Sie war die einzige Seite der Anwendung, die
   nicht in derselben Bahn lief. Auf einem breiten Bildschirm stand ihr Inhalt
   240 Pixel weiter außen als überall sonst und klebte am Fensterrand – wer
   von einer anderen Seite herkam, sah das ganze Bild springen. Gebraucht hat
   das Raster die Breite ohnehin nie: Es rollt in seinem eigenen Kasten
   (.um-raster-scroll in 06-verwaltung.css) und hätte die Seite auch in einer
   noch schmaleren Spur nicht gesprengt.

   WER WIEDER EINE BREITE SEITE BAUEN WILL, baut nicht diese Spur nach,
   sondern lässt den breiten Teil in seinem Kasten rollen. Eine zweite Bahn
   neben .container heißt: zwei Seiten, die nebeneinander nicht fluchten. */

/* ==========================================================================
   WhatsApp – gemeinsame Bausteine
   Das Maß des Verlaufs auf der eigenen Seite steht in assets/css/whatsapp.css.
   Hier bleibt, was auch das Lead-Detail und das Personenpanel brauchen:
   Blasen, Datumstrenner, Antwortfenster und der Antwortbereich.
   ========================================================================== */

/* Das 24-Stunden-Fenster: offen ist eine Zusage, zu ist eine Einschränkung */
.wa-fenster {
    display: inline-flex;
    align-items: center;
    padding: 1px 7px;
    border-radius: var(--r-sm);
    font-size: var(--fs-3);
    font-weight: 600;
}
.wa-fenster.is-offen {
    background: var(--btn-green-bg-light);
    color: var(--btn-green);
}
.wa-fenster.is-zu {
    background: var(--btn-gray-bg);
    color: var(--brand-quiet);
}

/* DER DATUMSTRENNER IST EINE BLAUE MARKE (24.08.2026).
   -------------------------------------------------------------------------
   Bis dahin war er grau (--btn-gray-bg auf --brand-quiet) und ging im Verlauf
   unter – er sagt aber etwas, das man beim Blättern sucht. Blau ist in dieser
   Anwendung die eigene Seite, und der Trenner gehört zur Ansicht, nicht zur
   Nachricht.

   FESTE WERTE, KEINE TOKENS – derselbe Grund wie bei den Zählblasen der
   Kopfleiste (.nav-badge in 01-basis.css) und bei der eigenen Blase: Die
   blaue Familie hängt am Haus und wird im Dunkeln aus dem Akzent gemischt.
   Bei einem roten Haus stünde hier sonst eine braune Marke. Die Marke ist
   17 Pixel hoch und soll auf heller wie auf dunkler Fläche gleich aussehen.

   Kontrast: #0b63a8 auf #d3e7fa sind 4,9 : 1. */
.wa-tag {
    align-self: center;
    margin: var(--sp-3) 0 0.2rem;
    padding: 1px 8px;
    border-radius: var(--r-sm);
    background: #d3e7fa;
    color: #0b63a8;
    font-size: var(--fs-3);
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

/* Der Kasten um einen Tag – er trägt den Trenner und die Nachrichten dieses
   Tages (renderWhatsappThread()). Er ist da, damit der klebende Trenner am
   Ende seines Tages hinausgeschoben wird statt über dem nächsten liegen zu
   bleiben; siehe .wa-verlauf .wa-tag in whatsapp.css.

   `gap: inherit`, weil der Kasten die Reihe unterbricht: Ohne das stünden die
   Nachrichten innerhalb eines Tages dichter oder weiter als die Kästen
   zueinander, und der Verlauf bekäme alle paar Zeilen einen anderen Takt. */
.wa-tag-gruppe {
    display: flex;
    flex-direction: column;
    gap: inherit;
}

.wa-vorlage {
    margin-bottom: 0.2rem;
    color: var(--brand-faint);
    font-size: var(--fs-2);
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

/* Der nachgeschlagene Wortlaut einer alten Vorlage (siehe renderWhatsappThread):
   kursiv und gedämpft, damit er nicht wie der mitgeschriebene Text aussieht. */
.wa-body.ist-nachgeschlagen { color: var(--brand-quiet); font-style: italic; }
.wa-nachgeschlagen-hinweis {
    margin-top: 0.25rem;
    color: var(--brand-faint);
    font-size: var(--fs-3);
}

.wa-bubble.ist-fehler {
    background: var(--btn-red-bg-light);
    border-color: var(--btn-red-border-light);
}
.wa-fehler {
    clear: both;              /* muss unter die schwebende Zeitangabe */
    margin-top: var(--sp-1);
    padding-top: var(--sp-1);
    border-top: 1px solid var(--btn-red-border-light);
    color: var(--btn-red-text);
    font-size: var(--fs-3);
}

/* Antwortbereich: Freitext oben, Vorlage darunter */
.wa-antwort {
    margin-top: 0.7rem;
    padding-top: 0.7rem;
    border-top: 1px solid var(--brand-border);
}
/* Das Wort im Sendeknopf gehört der Handy-App (assets/css/mobil.css). Auf den
   großen Seiten bleibt der Knopf ein Zeichen in einer Zeile – dort ist es aus. */
.wa-send-wort { display: none; }

/* --------------------------------------------------------------------------
   Die Farbe der beiden Wege hinaus (21.08.2026, heraus am 22.08.2026)
   --------------------------------------------------------------------------
   Freitext und Vorlage senden an dieselbe Nummer – also tragen beide Knöpfe
   dieselbe Fassung: das helle Blau der Werbeseite. Beide sind .btn-primary,
   und der trägt dieses Blau seit dem 22.08.2026 von sich aus (01-basis.css).
   Die Sonderregel, die es hier für den Antwortkasten von Hand nachtrug, ist
   damit überflüssig und heraus – samt der Zeilen, die Bootstraps !important
   am Zeiger zurückholen mussten. whatsapp.css regelt weiterhin nur, wie groß
   die Knöpfe im Postfach sind und dass aus dem Zeichen das Wort „senden"
   wird. */

/* --------------------------------------------------------------------------
   Emojis (21.08.2026)
   --------------------------------------------------------------------------
   Die Tafel schwebt ÜBER dem Antwortfeld, nicht darunter: Unten ist bei einem
   Gespräch das Ende der Seite – eine Tafel dort schöbe beim Aufklappen das
   Feld aus dem Bild, in das man gerade schreibt. Nach oben legt sie sich über
   die letzten Blasen, und die stehen ohnehin still. */
.wa-send-form { position: relative; }

.wa-emoji-tafel {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 100%;
    z-index: 20;
    max-height: 260px;
    margin-bottom: 0.4rem;
    padding: 0.6rem 0.7rem;
    overflow-y: auto;
    overscroll-behavior: contain;
    border: 1px solid var(--brand-border);
    border-radius: var(--r-ctl);
    background: var(--brand-surface);
    box-shadow: 0 8px 24px rgba(26, 36, 48, 0.14);
}
.wa-emoji-gruppe + .wa-emoji-gruppe { margin-top: 0.55rem; }
.wa-emoji-raster {
    display: grid;
    /* Feste Spaltenbreite statt auto-fit über die ganze Zeile: Die Zeichen
       sollen in einem RASTER stehen, nicht auf Abstand gezogen werden – sonst
       sieht dieselbe Gruppe in jeder Fensterbreite anders aus. */
    grid-template-columns: repeat(auto-fill, 32px);
    gap: 2px;
    margin-top: var(--sp-1);
}
.wa-emoji {
    width: 32px;
    height: 32px;
    padding: 0;
    border: 0;
    border-radius: var(--r-sm);
    background: none;
    font-size: var(--fs-9);
    line-height: 1;
    cursor: pointer;
}
.wa-emoji:hover,
.wa-emoji:focus-visible { background: var(--brand-row); }

/* --------------------------------------------------------------------------
   Anhänge (21.08.2026)
   --------------------------------------------------------------------------
   Drei Teile: die Büroklammer neben dem Textfeld, die Liste der gewählten
   Dateien darüber und die Fläche, die beim Ziehen über dem Gespräch erscheint.

   ZURÜCKHALTEND WIE ALLES ANDERE (Look B): keine große gestrichelte Kiste
   unter dem Antwortfeld, die dauerhaft Platz nimmt und Aufmerksamkeit fordert.
   Zu sehen ist sie erst, wenn wirklich etwas über dem Gespräch schwebt. */

/* Das Dateifeld steckt hinter der Büroklammer. Nicht display:none: Sonst wäre
   es ohne Skript nicht erreichbar – dieselbe Überlegung wie bei der Ablage in
   den Serviceformularen (assets/css/formular.css). */
.wa-klammer {
    position: relative;
    overflow: hidden;
    flex: none;
    cursor: pointer;
}
.wa-klammer input[type="file"] {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
}

.wa-dateien {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin: 0 0 0.45rem;
    padding: 0;
    list-style: none;
}
.wa-dateien:empty { display: none; }
.wa-dateien li {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    padding: 0.3rem var(--sp-3);
    border: 1px solid var(--brand-border);
    border-radius: var(--r-ctl);
    background: var(--brand-row);
    font-size: var(--fs-5);
}
.wa-dateien b {
    flex: 1 1 auto;
    min-width: 0;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.wa-dateien span { flex: none; color: var(--brand-quiet); font-size: var(--fs-3); }
.wa-datei-weg {
    flex: none;
    padding: 0 0.2rem;
    border: 0;
    background: none;
    color: var(--brand-faint);
    line-height: 1;
    cursor: pointer;
}
.wa-datei-weg:hover { color: var(--brand-accent); }

.wa-ablage-hinweis {
    margin: 0.35rem 0 0;
    color: var(--brand-faint);
    font-size: var(--fs-3);
}

/* Die Fläche selbst. assets/js/wa-antwort.js hängt sie in das Gespräch und
   nimmt ihr das `hidden`, sobald etwas darüber schwebt – ohne Skript bleibt
   sie im Formular liegen und ist nie zu sehen. */
.wa-ablage-zone { position: relative; }
.wa-ablage {
    position: absolute;
    inset: 0;
    z-index: 5;
    display: none;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    border: 2px dashed var(--brand-accent);
    border-radius: var(--r-ctl);
    /* Durchscheinend, damit das Gespräch darunter erkennbar bleibt: Man legt
       eine Datei IN ein Gespräch, nicht auf eine leere Fläche. */
    background: color-mix(in srgb, var(--brand-chip-bg) 78%, transparent);
    color: var(--brand-accent);
    font-size: var(--fs-6);
    font-weight: 600;
    text-align: center;
    pointer-events: none;      /* sonst schluckt sie ihre eigenen Ereignisse */
}
.wa-ablage-zone.ist-ueber .wa-ablage { display: flex; }
.wa-ablage-schild {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: var(--sp-3) 0.9rem;
    border-radius: var(--r-pill, 999px);
    background: var(--brand-surface);
    box-shadow: 0 1px 3px rgba(26, 36, 48, 0.12);
}

.wa-hinweis {
    margin: 0;
    padding: var(--sp-3) 0.65rem;
    border: 1px dashed var(--brand-line-strong);
    border-radius: var(--r-ctl);
    color: var(--brand-quiet);
    font-size: var(--fs-5);
}
.wa-vorlage-form {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    flex-wrap: wrap;
    margin-top: 0.6rem;
}
/* Die Vorschau steht immer in einer eigenen Zeile unter Auswahl und Knopf.
   Ohne diese Regel ist sie ein gewöhnliches Flex-Element: kurze Vorlagentexte
   passen neben den Knopf, längere rutschen darunter – dieselbe Stelle sähe
   also je nach Vorlage anders aus. */
.wa-vorlage-form > .wa-vorschau {
    flex: 0 0 100%;
    width: 100%;
}

/* Empfänger suchen statt blättern: Das Feld mit der Trefferliste ist seit dem
   11.08.2026 ein gemeinsamer Baustein (.suchauswahl in 02-bausteine.css) – es
   steht auch im Versandkasten der Formulare. Hier gab es dafür einmal eine
   eigene Familie .wa-suchauswahl*; sie ist restlos dorthin gewandert. */

/* Vorschau im Dialog „Neue Konversation" */
/* Das Bild aus dem Kopf der Vorlage steht über dem Text – wie in WhatsApp.
   Die Höhe ist gedeckelt: Ein Aufsteller im Hochformat schöbe den Text sonst
   aus dem Blick. */
.wa-vorschau-bild {
    display: block;
    max-width: 260px;
    max-height: 180px;
    width: auto;
    margin: 0.2rem 0 0;
    border-radius: var(--r-ctl);
    border: 1px solid var(--brand-border);
    object-fit: cover;
}
.wa-vorschau-text {
    margin: 0.2rem 0 0;
    padding: var(--sp-3) 0.65rem;
    border-radius: var(--r-ctl);
    background: var(--btn-green-bg-light);
    border: 1px solid var(--btn-green-border-light);
    font-size: var(--fs-5);
    white-space: pre-line;
}

/* Chat im Lead-Detail: schmaler als auf der eigenen Seite */
.ld-chat .wa-thread {
    max-height: 260px;
    background: var(--brand-row);
    border: 1px solid var(--brand-border);
    border-radius: var(--r-ctl);
}
.ld-chat-leer {
    margin: 0 0 0.6rem;
    color: var(--brand-quiet);
    font-size: var(--fs-5);
}

/* ==========================================================================
   Beiträge (beitraege.php, beitrag_form.php) – Präfix .bt-

   NUR VIER REGELN, UND DAS IST ABSICHT. Die Seite ist ein gewöhnlicher
   Seitenkopf, eine Kennzahlenreihe, eine Segmentleiste und eine Tabelle –
   alles Bausteine, die es gibt. Neu ist einzig, dass hier BILDER in der
   Liste stehen, und für die gibt es kein Maß im Haus: Eine Instagram-Karte
   ist 4:5, jede andere Miniatur in dieser Anwendung ist quadratisch (Foto)
   oder frei (Logo).

   Die Karten des Karussells liegen in einer Reihe und nicht in einem Raster:
   Ihre Reihenfolge IST die Wischrichtung, und ein Raster mit Umbruch macht
   aus einer Reihenfolge ein Feld, in dem „nach vorn" nichts mehr heißt.
   ========================================================================== */

/* Die Miniatur in der Liste – 4:5 wie die Karte selbst. */
.bt-mini {
    display: block;
    width: 48px;
    height: 60px;
    object-fit: cover;
    border-radius: var(--r-ctl);
    border: 1px solid var(--brand-border);
    background: var(--brand-row);
}
.bt-mini-leer {
    display: grid;
    place-items: center;
    color: var(--brand-quiet);
}

/* Die Karten des Beitrags: eine Reihe, die rollt statt umzubrechen. */
.bt-karten {
    display: flex;
    gap: var(--sp-4);
    overflow-x: auto;
    padding-bottom: var(--sp-3);
}
.bt-karte {
    flex: 0 0 168px;
}
.bt-karte-bild {
    position: relative;
    aspect-ratio: 4 / 5;
    border-radius: var(--r-ctl);
    border: 1px solid var(--brand-border);
    background: var(--brand-row);
    overflow: hidden;
    display: grid;
    place-items: center;
}
.bt-karte-bild img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Die Nummer sitzt IM Bild, nicht darunter: Sie ist die Antwort auf
   „welche Karte ist das?" und muss dort stehen, wo hingesehen wird. */
.bt-karte-nr {
    position: absolute;
    top: var(--sp-2);
    left: var(--sp-2);
    min-width: 20px;
    padding: 0 0.3rem;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
    font-size: var(--fs-6);
    font-weight: 700;
    text-align: center;
}
.bt-karte-fuss {
    display: flex;
    flex-direction: column;
    gap: var(--sp-2);
    margin-top: var(--sp-2);
}
.bt-karte-knoepfe {
    display: flex;
    gap: var(--sp-2);
}
