/* ==========================================================================
   Die gemeinsamen Bausteine
   --------------------------------------------------------------------------
   Seitenkopf (.cal-masthead), Kennzahlen (.kpi-grid), Leerzustand (.leer),
   Segmentschalter (.cal-seg). Wer eine neue Seite baut, benutzt diese vier
   und erfindet nichts daneben.

   TEIL 2 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.
   ========================================================================== */

/* Kalender-Monatsraster */
/* ==========================================================================
   Kalender – Look B „Arbeitsfläche": flach, dicht, kühl-neutral.
   Signatur: Rot = HEUTE (das eine laute Element), sonst ruhig & präzise.

   Die --cal-* Marken standen früher auf .cal-page. Das war ein Fehler:
   Seitenkopf (.cal-masthead) und Segmentschalter (.cal-seg) stehen auf
   fast jeder Seite, aber .cal-page gibt es nur im Kalender – überall sonst
   waren die Variablen also nicht definiert, und die Regeln fielen still
   aus (kein Trennstrich unter dem Kopf, dunkles Mikrolabel, keine Fuge
   zwischen den Segmenten). Sie gehören deshalb ins :root, siehe ganz oben.
   ========================================================================== */

/* ==========================================================================
   Seitenkopf – auf jeder angemeldeten Seite derselbe (siehe seitenkopf()
   in includes/functions.php): Mikrolabel, Titel mit leisem Zusatz, optional
   eine Unterzeile; rechts die Aktionen der Seite.
   ========================================================================== */
.cal-masthead {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-4);
    flex-wrap: wrap;
    /* Enger als früher (06.09.2026, vorher sp-4/sp-6): Mit dem Menü links
       sagt schon die Leiste, wo man ist – der Kopf darf sich deshalb näher an
       den Inhalt legen, statt ihn ein Stück weiter nach unten zu schieben. */
    padding-bottom: var(--sp-3);
    border-bottom: 1px solid var(--cal-line);
    margin-bottom: var(--sp-5);
    /* Für den kurzen Strich darunter (siehe ::after). */
    position: relative;
}
/* Der Anstrich unter dem Titel: die ersten 44 Pixel der Trennlinie im
   Leuchtblau des Hauses. Er ist die einzige Stelle, an der auf jeder Seite
   dieselbe Farbe an derselben Stelle steht – zusammen mit dem Mikrolabel
   darüber gibt er sechzig sonst sehr verschiedenen Seiten denselben Anfang.
   Zwei Pixel, nicht mehr: Er soll den Blick anlegen, nicht ihn halten. */
.cal-masthead::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: -1px;
    width: 44px;
    height: 2px;
    border-radius: var(--r-pill);
    background: var(--btn-leucht);
}
.cal-masthead-titel {
    min-width: 0;
    display: flex;
    align-items: center;
    gap: var(--sp-4);
}
.cal-masthead-wort { min-width: 0; }
.cal-masthead-medien { flex: none; }
/* Kurze Merkmale unter dem Titel (Rechtsform, Branche, Alter, Beruf …) */
.cal-masthead-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    margin-top: 0.3rem;
}
/* Die Aktionen der Seite. Sie stehen rechts – auch dann noch, wenn sie in
   eine eigene Zeile rutschen.

   WARUM `flex: 1 1 auto` (25.08.2026): .cal-masthead ist eine umbrechende
   Flexspur mit space-between. Wird die Knopfreihe zu breit, bricht sie um –
   und ein Flexelement ist auf der neuen Zeile nur so breit wie sein Inhalt.
   Das `justify-content: flex-end` darin hatte damit nichts mehr zu verteilen,
   und die Knöpfe standen plötzlich LINKS unter dem Titel. Aufgefallen ist das
   auf der Startseite, als im Anpassen-Modus ein siebter Knopf dazukam
   („Wetterort"). Mit dem Wachsen füllt die Reihe die Zeile und bleibt
   rechtsbündig; in der ersten Zeile ändert sich dadurch nichts, weil die
   Knöpfe ohnehin am rechten Rand sitzen. */
.cal-masthead-aktionen {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    flex-wrap: wrap;
    justify-content: flex-end;
    flex: 1 1 auto;
    min-width: 0;
}
.cal-masthead-aktionen:empty { display: none; }
/* Das Mikrolabel über dem Titel („ÜBERSICHT", „ADRESSBUCH", „KALENDERWOCHE
   34"). Es trägt seit dem 21.08.2026 das tiefe Blaugrau statt des
   Sekundärgraus: Es ist der Bereich, in dem man steht, und stand als graue
   Zeile über einem grauen Titel wie eine Fußnote da. */
.cal-eyebrow {
    font-size: var(--fs-3);
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--brand-titel);
    opacity: 0.72;
    margin-bottom: 0.15rem;
}
/* Der Titel im dunklen Blaugrau (--brand-titel), nicht im Tintenton des
   Fließtextes: So hebt sich das Wort der Seite – „Dashboard", „Kontakte",
   „Telefon" – vom Text darunter ab, ohne zu leuchten. Der Zusatz daneben
   (.cal-year) bleibt blass, das Mikrolabel darüber grau. */
.cal-title {
    font-family: 'Plus Jakarta Sans', sans-serif;
    font-weight: 700;
    font-size: var(--fs-10);
    line-height: 1.15;
    letter-spacing: -0.015em;
    color: var(--brand-titel);
    font-variant-numeric: tabular-nums;
    margin: 0;
}
.cal-title .cal-year { color: var(--brand-faint); font-weight: 500; }

/* ==========================================================================
   DAS KARTENZEICHEN DER KUNDENKARTE (11.09.2026, kundenkarteZeichen())

   Hochgestellt wie ein Exponent: Unterkante auf etwa halber x-Höhe, Oberkante
   knapp über der Versalhöhe. So liest es sich als Anhang des Namens und nicht
   als eigenes Wort daneben. Gemessen im Seitenkopf bei 20,8 px: das Zeichen
   4 px über der Versalhöhe, 8 px über der Grundlinie.

   Es BERICHTET und trägt deshalb das Metall statt Leuchtblau. In der Akte ist
   es trotzdem ein Sprung zum Kasten – dass man es anfassen kann, sagt die
   Fläche unter dem Zeiger, nicht die Farbe (wie überall seit dem 09.09.2026).

   16 × 11 Pixel: ein Metallverlauf, der Chip, eine schräge Lichtkante. Ohne
   die Lichtkante sähe Silber aus wie Grau.
   ========================================================================== */
.kdk-marke {
    display: inline-block;
    position: relative;
    line-height: 0;
    padding: 3px;
    margin-left: 1px;
    border-radius: var(--r-sm);
    vertical-align: 0.24em;
    letter-spacing: 0;
    text-decoration: none;
    color: inherit;
}
a.kdk-marke {
    cursor: pointer;
    transition: background-color var(--t-fast) var(--ease-out), box-shadow var(--t-fast) var(--ease-out);
}
a.kdk-marke:hover,
a.kdk-marke:focus-visible {
    background: var(--brand-surface);
    box-shadow: var(--sh-1);
    outline: none;
}
a.kdk-marke:focus-visible { box-shadow: var(--sh-1), 0 0 0 3px rgba(0, 162, 239, 0.25); }
.kdk-plakette {
    display: block;
    position: relative;
    font-size: 10px;
    width: 1.6em;
    height: 1.1em;
    border-radius: .26em;
    background: linear-gradient(135deg, var(--kdk-a) 0%, var(--kdk-b) 100%);
    box-shadow: inset 0 0 0 max(1px, .1em) var(--kdk-rand);
}
.kdk-plakette::before {
    content: "";
    position: absolute;
    left: .28em;
    top: .36em;
    width: .42em;
    height: .32em;
    border-radius: .08em;
    background: var(--kdk-rand);
    opacity: .5;
}
.kdk-plakette::after {
    content: "";
    position: absolute;
    inset: max(1px, .1em);
    border-radius: .18em;
    background: linear-gradient(115deg, transparent 42%, rgba(255, 255, 255, .7) 54%, transparent 66%);
}
[data-kdk="bronze"] { --kdk-a: var(--kdk-bronze-a); --kdk-b: var(--kdk-bronze-b); --kdk-rand: var(--kdk-bronze-rand); --kdk-text: var(--kdk-bronze-text); }
[data-kdk="silber"] { --kdk-a: var(--kdk-silber-a); --kdk-b: var(--kdk-silber-b); --kdk-rand: var(--kdk-silber-rand); --kdk-text: var(--kdk-silber-text); }
[data-kdk="gold"]   { --kdk-a: var(--kdk-gold-a);   --kdk-b: var(--kdk-gold-b);   --kdk-rand: var(--kdk-gold-rand);   --kdk-text: var(--kdk-gold-text); }

/* Der Hinweis unter dem Zeichen – nur am Verweis in der Akte. In Listen
   steht das Zeichen in einer Zeile, die selbst ein Verweis ist, und sagt
   sein Wort über `title`. */
.kdk-marke[data-tip]::after {
    content: attr(data-tip);
    position: absolute;
    left: 50%;
    top: calc(100% + 6px);
    z-index: 30;
    transform: translate(-50%, -2px);
    white-space: nowrap;
    padding: 6px 9px;
    border-radius: var(--r-sm);
    background: var(--tip-bg);
    color: var(--tip-ink);
    font: 500 var(--fs-4)/1.3 'Plus Jakarta Sans', sans-serif;
    box-shadow: var(--sh-2);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--t-fast) var(--ease-out), transform var(--t-fast) var(--ease-out);
}
.kdk-marke[data-tip]:hover::after,
.kdk-marke[data-tip]:focus-visible::after {
    opacity: 1;
    transform: translate(-50%, 0);
}
/* In Listenzeilen und Kacheln sitzt es dichter am Namen. */
.ml-row-partner .kdk-marke,
.kt-card-wort .kdk-marke { padding: 2px; }
@media (prefers-reduced-motion: reduce) {
    a.kdk-marke,
    .kdk-marke[data-tip]::after { transition: none; }
}
/* Ruhige Unterzeile unter dem Titel (Stand, Zählung, kurze Erklärung) */
.cal-sub {
    margin: 0.15rem 0 0;
    font-size: var(--fs-5);
    color: var(--brand-quiet);
}

/* ==========================================================================
   DER GRUSS AUF DER STARTSEITE (22.08.2026)

   Die eine Zeile, die ein Kunde beim ersten Aufschlagen liest. Sie ist KEIN
   neuer Block über dem Seitenkopf – dann sagte die Seite zweimal
   hintereinander, wo man ist. Sie IST der Titel: Das Mikrolabel „Übersicht"
   bleibt darüber, das Wort „Dashboard" fällt weg (auf der Startseite weiß
   das ohnehin jeder), und die Lage wird die Unterzeile, die seitenkopf()
   längst kann.

   Nur hier größer, nicht überall: --fs-12 ist die Bühnenzeile der
   öffentlichen Seiten. Auf sechzig Arbeitsseiten wäre sie zu laut; auf der
   einen, die morgens als erste aufgeht, ist sie richtig.
   ========================================================================== */
.cal-masthead.ist-gruss .cal-title { font-size: var(--fs-12); }
.cal-masthead.ist-gruss .cal-title .cal-year { font-weight: 400; }
/* Das Datum unter dem Gruß – die Einordnung, mehr nicht. Was offen ist,
   steht als Zusatz im Titel und ausführlich in den Kacheln darunter; hier
   stand es eine Zeit lang ein drittes Mal (erst als Satz, dann als Knöpfe)
   und ist am 24.08.2026 wieder herausgenommen worden. */
.gruss-lage {
    margin: var(--sp-2) 0 0;
    font-size: var(--fs-6);
    color: var(--brand-quiet);
}

/* Bedienelemente im Seitenkopf sind überall gleich hoch (--h-ctl), egal ob
   die Seite btn oder btn-sm geschrieben hat. Eine Regel statt einer
   Verabredung, an die sich die nächste Seite doch nicht hält.
   -------------------------------------------------------------------------
   SEIT DEM 22.08.2026 GILT DASSELBE FÜR DIE LEISTE DARUNTER (.ml-bar im
   Postfach, bei den Nachrichten, am Telefon, bei Objekten, Bewerbungen,
   Formularen und Leads; .cal-toolbar im Kalender und auf dem Board). Dort
   standen Segmentschalter (34px, weil .cal-seg seine Höhe selbst setzt) und
   Knöpfe nebeneinander, die die Seite als `btn-sm` geschrieben hatte – rund
   31px. Drei Pixel Unterschied liest man nicht als Absicht, sondern als
   schiefe Zeile: Die Oberkanten trafen sich nicht, und beim Umschalten von
   einer Seite zur nächsten sprang die Leiste.

   MERKSATZ: Alles, was in der Kopfzone einer Seite steht – Seitenkopf und
   die Leiste darunter –, ist --h-ctl hoch und trägt --fs-5. Was eine Seite
   im Markup schreibt, entscheidet nur über Farbe und Wort, nicht über das
   Maß. */
.cal-masthead .btn,
.cal-masthead .form-select,
.cal-masthead .form-control,
.ml-bar .btn,
.ml-bar .form-select,
.ml-bar .form-control,
.cal-toolbar .btn,
.cal-toolbar .form-select,
.cal-toolbar .form-control {
    height: var(--h-ctl);
    display: inline-flex;
    align-items: center;
    font-size: var(--fs-5);
    border-radius: var(--r-ctl);
    padding-top: 0;
    padding-bottom: 0;
}
.cal-masthead .btn,
.ml-bar .btn,
.cal-toolbar .btn { padding-left: 0.8rem; padding-right: 0.8rem; }
.cal-masthead form,
.ml-bar form,
.cal-toolbar form { margin: 0; }

/* Zweispaltiges Layout mit einklappbarer Seitenleiste */
.cal-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 288px;
    gap: var(--sp-5);
    align-items: start;
    transition: grid-template-columns var(--t-slow) var(--ease-in-out);
}
.cal-page.side-collapsed .cal-layout {
    grid-template-columns: minmax(0, 1fr) 0px;
    gap: 0;
}
.cal-main { min-width: 0; }
.cal-side {
    min-width: 0;
    position: sticky;
    top: 1rem;
    max-height: calc(100vh - 2rem);
    overflow-y: auto;
    overscroll-behavior: contain;
    opacity: 1;
    transition: opacity var(--t-fast) var(--ease-out);
}
.cal-page.side-collapsed .cal-side {
    opacity: 0;
    pointer-events: none;
    visibility: hidden;
}
.cal-side::-webkit-scrollbar { width: 8px; }
.cal-side::-webkit-scrollbar-thumb { background: var(--cal-line); border-radius: 4px; }

/* Toolbar über dem Raster */
.cal-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    flex-wrap: wrap;
    margin-bottom: var(--sp-5);
}
.cal-toolbar-end { display: flex; align-items: center; gap: 0.6rem; }

/* Panel-Umschalter */
.cal-side-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    height: var(--h-ctl);
    padding: 0 var(--sp-4);
    border: 1px solid var(--brand-line-strong);
    border-radius: var(--r-ctl);
    background: var(--cal-paper);
    color: var(--cal-quiet);
    font-size: var(--fs-5);
    font-weight: 600;
    cursor: pointer;
    transition: color var(--t-fast) var(--ease-out), background-color var(--t-fast) var(--ease-out);
}
.cal-side-toggle:hover { color: var(--btn-leucht-tief); background: var(--blau-hell); }
.cal-side-toggle svg { transition: transform var(--t-slow) var(--ease-in-out); }
.cal-page.side-collapsed .cal-side-toggle svg { transform: rotate(180deg); }

/* Seitenleisten-Panels (Planer-Sprache statt Bootstrap-Karten) */
.cal-panel {
    background: var(--cal-paper);
    border: 1px solid var(--cal-line);
    border-radius: var(--r-card);
    box-shadow: var(--sh-1);
    overflow: hidden;
}
.cal-panel + .cal-panel { margin-top: var(--sp-4); }
.cal-panel-head {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: var(--sp-3) var(--sp-4);
    border-bottom: 1px solid var(--cal-line);
    font-size: var(--fs-3);
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--cal-quiet);
    /* Der Kopf ist zugleich der Griff zum Umsortieren (wie im Aufgaben-Board) */
    cursor: grab;
    user-select: none;
}
.cal-panel-head:active { cursor: grabbing; }
.cal-panel-head::before {
    content: '⠿';
    margin-right: -0.1rem;
    font-size: var(--fs-6);
    line-height: 1;
    letter-spacing: 0;
    color: var(--brand-faint);
    opacity: 0.5;
}
.cal-panel.is-dragging {
    opacity: 0.45;
    box-shadow: var(--sh-2);
}
.cal-panel-head svg { color: var(--cal-quiet); }
/* Ein-/Ausklappen je Panel */
.cal-panel-toggle {
    margin-left: auto;
    flex: 0 0 auto;
    width: 22px;
    height: 22px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--brand-border);
    border-radius: var(--r-sm);
    background: var(--brand-surface);
    color: var(--cal-quiet);
    font-size: var(--fs-7);
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
    padding: 0;
    transition: background-color var(--t-fast) var(--ease-out), color var(--t-fast) var(--ease-out), border-color var(--t-fast) var(--ease-out);
}
.cal-panel-toggle:hover {
    background: var(--blau-hell);
    border-color: var(--blau-rand);
    color: var(--btn-leucht-tief);
}
.cal-panel-toggle:focus-visible { outline: 2px solid var(--focus-col); outline-offset: 2px; }
.cal-panel.is-collapsed .cal-panel-body { display: none; }
.cal-panel.is-collapsed .cal-panel-head { border-bottom: 0; }
.cal-panel-body { padding: var(--sp-4); }
.cal-panel-note { font-size: var(--fs-4); color: var(--cal-quiet); line-height: 1.5; }

/* Steuerelemente: 34px hoch, 8px Radius – gleiche Sprache wie die Buttons */
.cal-nav {
    display: inline-flex;
    align-items: center;
    border: 1px solid var(--brand-line-strong);
    border-radius: var(--r-ctl);
    overflow: hidden;
    background: var(--cal-paper);
}
.cal-nav a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 34px;
    height: var(--h-ctl);
    padding: 0 0.7rem;
    color: var(--cal-quiet);
    text-decoration: none;
    font-size: var(--fs-5);
    font-weight: 600;
    transition: background-color var(--t-fast) var(--ease-out), color var(--t-fast) var(--ease-out);
}
/* Dieselbe Tönung wie am Segmentschalter darunter – beide stehen in
   derselben Leiste und dürfen nicht zwei verschiedene Blau anzeigen. */
.cal-nav a:hover { background: var(--blau-hell); color: var(--btn-leucht-tief); }
.cal-nav a + a { border-left: 1px solid var(--cal-line); }
.cal-nav .cal-today-btn { color: var(--cal-today); }
.cal-nav .cal-today-btn:hover { background: var(--brand-chip-bg); color: var(--cal-today); }

.cal-seg {
    display: inline-flex;
    align-items: center;
    background: var(--cal-paper);
    border: 1px solid var(--brand-line-strong);
    border-radius: var(--r-ctl);
    overflow: hidden;
    height: var(--h-ctl);
}
.cal-seg a {
    display: inline-flex;
    align-items: center;
    height: 100%;
    padding: 0 0.8rem;
    /* EIN REITER IST EINE ZEILE (22.08.2026). Der Schalter ist --h-ctl hoch
       und schneidet ab (overflow: hidden) – ein umbrechendes Wort ist hier
       also nie eine zweite Zeile, sondern ein halb abgeschnittenes Wort. Am
       Telefon stand „Ohne Zuordnung" genau so da, sobald der Schalter aufs
       Kachelraster einrastete und der Platz für das lange Wort knapp wurde. */
    white-space: nowrap;
    font-size: var(--fs-5);
    font-weight: 600;
    text-decoration: none;
    color: var(--cal-quiet);
    transition: background-color var(--t-fast) var(--ease-out), color var(--t-fast) var(--ease-out);
}
.cal-seg a + a { border-left: 1px solid var(--cal-line); }
/* ZUR FARBE (22.08.2026): Der Schalter stand im Blaugrau des Hauses – der
   gewählte Reiter auf --btn-blue-dark, der Zeiger auf --btn-blue-bg-light.
   Seit der gefüllte Knopf (.btn-primary in 01-basis.css) das helle Blau der
   Werbeseite trägt, war das der zweite blaue Ton auf demselben Bildschirm:
   In der Leiste über dem Postfach stand „Alle | Ungelesen | Ohne Zuordnung"
   blaugrau neben einem leuchtblauen Knopf, und keiner der beiden Töne
   bedeutete etwas anderes als der andere. Der Schalter trägt jetzt dieselbe
   Fassung wie der Knopf: die Tönung (--blau-hell) unter dem Zeiger, das
   tiefe Leuchtblau (--btn-leucht-dark, Weiß darauf 4,1 : 1) am gewählten
   Reiter. Flach, nicht im Verlauf: Der Verlauf gehört dem einen Knopf, um
   den es auf einer Seite geht – ein Schalter aus vier Feldern wäre damit
   vier gefüllte Knöpfe nebeneinander. */
.cal-seg a:hover { background: var(--blau-hell); color: var(--btn-leucht-tief); }
.cal-seg a.active,
.cal-seg a.active:hover { background: var(--btn-leucht-dark); color: #fff; }

/* ==========================================================================
   DER GEWÄHLTE BEREICH ALS PILLE (22.08.2026)

   Er stand als scharfkantiges Rechteck von Rand zu Rand in der Leiste – ein
   Feld unter anderen, nur farbig. Als Pille mit einem Hauch Erhebung sieht
   man auf einen Blick, dass er OBEN liegt und die anderen darunter.

   Der Innenabstand von drei Pixeln macht den Platz dafür; die Trennlinien
   zwischen den Feldern fallen damit weg, weil eine Pille sich selbst
   abgrenzt und zwei Begrenzungen nebeneinander wie ein Fehler aussehen.
   ========================================================================== */
.cal-seg { padding: 3px; gap: 2px; }
.cal-seg a { border-radius: var(--r-sm); }
.cal-seg a + a { border-left: 0; }
/* Die Erhebung aus der gemeinsamen Leiter und nicht als eigener Wert: Ein
   fester `rgba(24, 44, 66, …)` wäre auf dunklem Grund ein Schleier statt
   eines Schattens – --sh-1 kennt beide Fassungen (includes/farbschema.php). */
.cal-seg a.active,
.cal-seg a.active:hover { box-shadow: var(--sh-1); }
/* Zahl hinter der Beschriftung (Reiter Firmen-/Privatkunden auf der Startseite) */
.cal-seg .seg-zahl {
    margin-left: 0.45rem;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
    opacity: 0.65;
}
.cal-seg a.active .seg-zahl { opacity: 0.85; }

/* ==========================================================================
   WhatsApp-Marke – das kleine Zeichen hinter einer Mobilnummer
   --------------------------------------------------------------------------
   Steht auf der Kontaktseite (privat_detail.php). Erzeugt wird sie in einer Hand von
   whatsappErreichbarZeichen() (includes/whatsapp_erreichbar.php).

   DREI ZUSTAENDE, DREI ANSICHTEN – und das ist der ganze Sinn der Sache. Ein
   einziges Zeichen für „könnte sein" und „ist bewiesen" wäre bequemer und
   sagte weniger als nichts: Man verlässt sich darauf und schreibt ins Leere.

     ist-bestätigt  grün. Der Nachrichtenverlauf beweist es.
     ist-vermerkt    blaugrau. Jemand hat das Häkchen gesetzt, mehr nicht.
     ist-aus         blass und durchgestrichen. Eine Nachricht kam nicht an.

   GRUEN IST HIER ERLAUBT, obwohl Look B von Blaugrau getragen wird: Es ist
   keine Zierde, sondern ein Zustand – dieselbe Ausnahme wie beim Zustellhaken
   im Verlauf, und es ist genau die Farbe, die jeder von WhatsApp kennt
   (.text-whatsapp in 01-basis.css tragt denselben Wert).
   ========================================================================== */
.wa-marke {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    margin-left: 0.3rem;
    border-radius: var(--r-sm);
    vertical-align: -4px;
    cursor: help;
}
.wa-marke.ist-bestaetigt {
    color: #25d366;
    background: rgba(37, 211, 102, 0.12);
}
.wa-marke.ist-vermerkt {
    color: var(--brand-quiet);
    background: var(--btn-gray-bg);
}
/* Widerlegt: still, aber nicht unsichtbar. Der Strich liegt über dem Zeichen
   statt daneben – ein Wort dafür wäre in einer Zeile mit vier Nummern eine
   Zeile zu viel; was er bedeutet, sagt der Kurzhinweis. */
.wa-marke.ist-aus {
    color: var(--brand-faint);
    background: transparent;
    position: relative;
}
.wa-marke.ist-aus::after {
    content: "";
    position: absolute;
    left: 2px;
    right: 2px;
    top: 50%;
    height: 1px;
    background: currentColor;
    transform: rotate(-20deg);
}

/* ==========================================================================
   WhatsApp im Bestand (whatsapp_erreichbarkeit.php)
   --------------------------------------------------------------------------
   Die Liste unter dem Zeichen: je Zeile eine Mobilnummer, dahinter dieselbe
   .wa-marke wie auf der Kontaktseite und daneben der Satz, woher die Auskunft
   kommt.

   DER SATZ STEHT ALS EIGENE SPALTE UND NICHT NUR IM KURZHINWEIS. Auf der
   Kontaktseite reicht der title= am Zeichen – dort geht es um zwei Nummern,
   und wer genau hinsehen will, zeigt darauf. Hier stehen vierhundert Zeilen
   untereinander, und die Frage der Seite ist gerade die nach dem Woher. Ein
   Blatt, auf dem man vierhundertmal mit der Maus verharren muss, beantwortet
   sie nicht.

   ZWEITRANGIGES STEHT KLEINER UND STILLER, nicht in einer eigenen Spalte:
   Firma unter dem Namen, „Mobil geschäftlich" hinter der Nummer. Vier Spalten
   trägt die Tabelle auf einem Notebook, sieben nicht mehr.
   ========================================================================== */
.wa-bestand-firma {
    display: block;
    font-size: var(--fs-4);
    color: var(--brand-quiet);
}
.wa-bestand-nummer {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.wa-bestand-feld {
    margin-left: 0.4rem;
    font-size: var(--fs-4);
    color: var(--brand-quiet);
}
/* --fs-4 („Nebentext in Listen") und nicht --fs-3: Das ist ein ganzer Satz,
   keine Beschriftung. Elf Wörter in Chipgröße liest niemand. */
.wa-bestand-satz {
    font-size: var(--fs-4);
    color: var(--brand-quiet);
}
/* „nichts bekannt" ist der Regelfall, solange der Verlauf jung ist – und der
   Regelfall soll die Zeilen nicht zupflastern, in denen wirklich etwas steht. */
.wa-bestand-still { color: var(--brand-faint); }

/* ==========================================================================
   Querabgleich (includes/querabgleich.php)
   --------------------------------------------------------------------------
   Der Kasten, der beim Anlegen einer Firma oder einer Person dazwischengeht:
   „Diese Rufnummer steht schon bei jemandem." Er sitzt IM Formular, dessen
   Absenden er aufgehalten hat, und seine Knöpfe schicken dasselbe Formular
   noch einmal – deshalb ist er ein Baustein und keine eigene Seite.

   ZWEI STUFEN, und der Unterschied ist Absicht: Ein gleicher Name ist ein
   Hinweis (blass), eine doppelt vergebene Rufnummer ist ein Fehler mit Folgen
   (`.is-schwer`, warmer Ton wie die bekannte Zeile im Import). Wäre beides
   gleich laut, würde die laute Fassung nach der dritten Namensgleichheit
   weggeklickt.
   ========================================================================== */
.qa-kasten {
    margin: 0 0 var(--sp-6);
    padding: .85rem var(--sp-5);
    border: 1px solid var(--btn-gray-border);
    border-left: 3px solid var(--brand-line-strong);
    border-radius: var(--r-card);
    background: var(--brand-row);
}
.qa-kasten.is-schwer {
    border-color: var(--btn-orange-border-light);
    border-left-color: var(--btn-orange-text);
    background: var(--btn-orange-bg-light);
}
.qa-kopf {
    display: flex;
    align-items: center;
    font-size: var(--fs-7);
}
.qa-kasten.is-schwer .qa-kopf { color: var(--btn-orange-text); }
.qa-text {
    margin: .35rem 0 .75rem;
    font-size: var(--fs-6);
    color: var(--brand-quiet);
}
.qa-liste {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: .55rem;
}
.qa-zeile {
    padding: .55rem .7rem;
    border: 1px solid var(--btn-gray-border);
    border-radius: var(--r-sm);
    background: var(--brand-surface);
}
.qa-wer {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: .4rem;
    font-size: var(--fs-7);
}
.qa-art  { font-size: var(--fs-5); color: var(--brand-quiet); }
.qa-feld { font-size: var(--fs-5); color: var(--brand-faint); }
/* Die Angaben des Treffers stehen in einer Zeile, durch Mittelpunkte getrennt.
   Untereinander wäre der Kasten bei vier Nummern höher als das Formular. */
.qa-daten {
    margin-top: .2rem;
    font-size: var(--fs-5);
    color: var(--brand-quiet);
    overflow-wrap: anywhere;
}
.qa-tat,
.qa-fuss {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .5rem;
}
.qa-tat  { margin-top: .5rem; }
.qa-fuss { margin-top: .9rem; }

/* ==========================================================================
   Geburtstagskacheln (.gb-*)
   --------------------------------------------------------------------------
   Gesicht, Name, Tag, kommendes Alter – eine Kachel je Mensch. Gebaut wird
   sie in geburtstagsKachel() (includes/functions/oberflaeche.php), gezeigt an
   zwei Stellen: als Leiste über dem Adressbuch (.kt-anlass in
   08-kontakte.css) und in der Geburtstagskarte der Startseite. Deshalb steht
   sie hier bei den Bausteinen und nicht in einer der beiden Seitendateien.

   VORHER WAREN ES ZWEI DARSTELLUNGEN: im Adressbuch eine Zeile Fließtext mit
   vier Namen, auf der Startseite eine Liste aus Textzeilen (.birthday-row).
   Zweimal dieselbe Auskunft in zwei Formen – wer von der einen Seite auf die
   andere ging, musste neu hinsehen. .birthday-row war die zweite Form; sie ist
   am 10.08.2026 mit dem Firmenbereich weggefallen.
   ========================================================================== */

/* Die Reihe: gleich breite Felder, die sich auf schmalen Schirmen umbrechen.
   RASTER, NICHT FLEX: Mit flex-wrap zieht sich die Kachel, die als einzige in
   die zweite Zeile rutscht, über deren ganze Breite – ein Name in einem
   Banner, während die drei darüber handtellergroß sind. Im Raster behält
   jede Kachel ihre Spalte, egal in welcher Zeile sie steht; bleibt eine
   Spalte leer, bleibt sie eben leer. */
.gb-reihe {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: 0.4rem;
}

.gb-karte {
    min-width: 0;
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    padding: 0.4rem 0.55rem;
    border: 1px solid var(--brand-border);
    border-radius: var(--r-ctl);
    background: var(--brand-row);
    color: inherit;
    text-decoration: none;
    transition: background-color var(--t-fast) var(--ease-out), border-color var(--t-fast) var(--ease-out);
}
/* Der Hover zieht den Rand nur halb zum Blau: Ein voller Signalrand um eine
   Kachel, über der man beim Lesen ohnehin hängt, war mehr Betrieb als
   Auskunft. */
.gb-karte:hover,
.gb-karte:focus-visible {
    color: inherit;
    background: var(--brand-surface);
    border-color: color-mix(in srgb, var(--btn-blue) 50%, var(--brand-border));
}
.gb-karte:focus-visible {
    outline: 2px solid var(--focus-col);
    outline-offset: 2px;
}
/* Das Bild ist das gemeinsame .avatar-sm (36px) aus 01-basis.css, hier eine
   Nummer kleiner: Die Kachel ist eine Randnotiz, kein Kontaktbogen. */
.gb-karte .avatar-sm {
    height: 32px;
    width: 32px;
}
.gb-karte .avatar-placeholder svg { width: 17px; height: 17px; }
/* Grün hinterlegt heißt: Bei diesem Menschen steht eine Handynummer, der
   Glückwunsch kann hinausgehen (gesetzt in dashboardGeburtstageAnreichern(),
   nur auf der Startseite). Es ist der gedeckte Hausgrün-Ton, nicht das
   Signalgrün: Die Kachel meldet nichts, sie sagt nur, was möglich ist. Ohne
   Nummer bleibt es beim gewohnten Blaugrau. */
/* NICHT MEHR AN `.gb-karte` GEBUNDEN (09.09.2026).
   -------------------------------------------------------------------------
   Die Regel hing am KACHELNAMEN statt am Zustand, und damit verlor jede neue
   Darstellungsform die Auskunft stillschweigend: erst das Band der
   Startseite, dann die Listenzeile, dann die Achse – jedes Mal war die
   Silhouette wieder blaugrau, und im hellen Schema fiel es kaum auf. Wer
   `is-mobil` setzt, meint den Zustand; also steht er hier allein. */
.avatar-placeholder.is-mobil {
    background-color: var(--btn-green-bg-light);
    color: var(--btn-green-dark);
}

.gb-wort {
    min-width: 0;
    display: flex;
    flex-direction: column;
    line-height: 1.25;
}
/* Alle drei Zeilen werden beschnitten, nicht umgebrochen: Die Kachel führt
   zum Menschen, und alles steht noch einmal im Zeiger (title). Eine zweite
   Zeile für einen langen Namen machte die ganze Reihe höher. */
.gb-name {
    font-size: var(--fs-5);
    font-weight: 600;
}
.gb-wann {
    font-size: var(--fs-3);
    color: var(--brand-quiet);
    font-variant-numeric: tabular-nums;
}
.gb-herkunft {
    font-size: var(--fs-3);
    color: var(--brand-faint);
}
.gb-name,
.gb-wann,
.gb-herkunft {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Heute und morgen – die beiden Tage, an denen der Anruf noch etwas wert ist.
   DAS SIGNAL LIEGT IN DER FLAECHE UND IM WORT, NICHT MEHR IM RAND: Bis zum
   10.08.2026 trug die heutige Kachel einen roten Rahmen und links eine 3px
   breite rote Kante (als Innenschatten). Drei rote Linien um eine handteller-
   große Kachel, daneben ruhige Nachbarn – das las sich wie eine Warnung,
   dabei ist ein Geburtstag eine freundliche Nachricht. Geblieben ist der
   blasse Grund, noch einmal mit Weiß gebrochen, und das gefärbte Wort
   („heute" / „morgen") in der zweiten Zeile. Der Rand ist überall derselbe
   neutrale wie an jeder anderen Kachel.

   SEIT DEM 21.08.2026 BLAU STATT ROT UND ORANGE: Die Tönung blieb bis dahin
   die der Warnfarben – blass zwar, aber aus derselben Familie wie „Vertrag
   gekündigt" und „Frist läuft ab". Heute trägt die nächste Kachel das
   helle Blau der Werbeseite (--btn-leucht, dieselbe 9-%-Tönung wie die
   offene Kachel der Handy-App), morgen das Blaugrau des Hausgrundtons
   (--btn-blue-bg-light). Damit steht auf der Startseite kein Alarm mehr, wo
   eine freundliche Nachricht steht, und die beiden Tage bleiben trotzdem
   auseinanderzuhalten: Der eine Ton leuchtet, der andere ist still.
   (Dieselben zwei Töne standen bis zum 05.08.2026 an .birthday-row in
   01-basis.css – der Zeilenform, aus der diese Kachel hervorging.) */
.gb-karte.is-heute {
    background: color-mix(in srgb, var(--btn-leucht) 9%, var(--brand-surface));
}
.gb-karte.is-morgen {
    background: var(--btn-blue-bg-light);
}
/* Das Wort trägt jetzt allein, was vorher drei Ränder sagten – deshalb
   bleibt es voll gefärbt, aber ohne Fettung: Es steht als einziges Farbige
   in der Kachel und fällt auch so auf.
   NICHT --btn-leucht SELBST: Auf der hellen Tönung läge der reine Ton bei
   2,4 : 1, die dritte Stufe --btn-leucht-tief bei 5,3 : 1 – und 0,72rem
   Schrift braucht 4,5 : 1. „Morgen" nimmt das dunkle Blaugrau der
   Ueberschriften (6,7 : 1 auf seinem Grund). */
.gb-karte.is-heute .gb-wann {
    color: var(--btn-leucht-tief);
}
.gb-karte.is-morgen .gb-wann {
    color: var(--brand-titel);
}
/* Der Hover darf die Tönung nicht wegwischen: Sonst verlöre die eine
   Kachel, auf die es ankommt, ihr Signal genau in dem Moment, in dem man sie
   anfasst. Er vertieft sie stattdessen eine Spur. */
.gb-karte.is-heute:hover,
.gb-karte.is-heute:focus-visible {
    background: color-mix(in srgb, var(--btn-leucht) 18%, var(--brand-surface));
}
.gb-karte.is-morgen:hover,
.gb-karte.is-morgen:focus-visible {
    background: color-mix(in srgb, var(--btn-blue) 18%, var(--brand-surface));
}

/* Das Kanalzeichen am rechten Rand (nur auf der Startseite, nur heute): Es
   sagt, dass dieser Klick nicht zur Akte führt, sondern zu WhatsApp. Blass
   und klein – die Kachel bleibt der Name, nicht der Knopf. Beim Hover zieht es
   auf die volle Farbe an, wie jeder andere Kanal auch. */
.gb-kanal {
    margin-left: auto;
    display: flex;
    color: var(--brand-faint);
}
.gb-kanal svg {
    width: 15px;
    height: 15px;
}
.gb-karte:hover .gb-kanal,
.gb-karte:focus-visible .gb-kanal {
    color: var(--btn-green-dark);
}

/* Die Restkachel („+3 weitere", nur im Adressbuch) ist kein Link und sieht
   auch nicht aus wie einer: gestrichelt und blass, wie ein Kanal ohne
   Nummer. */
.gb-karte.is-rest {
    justify-content: center;
    background: transparent;
    border-style: dashed;
    color: var(--brand-faint);
    font-size: var(--fs-4);
    font-weight: 600;
    white-space: nowrap;
    cursor: default;
}

/* Schmale Schirme: engeres Maß, damit zwei nebeneinander passen. Unter
   190px bleibt vom Namen zu wenig übrig, deshalb erst hier. */
@media (max-width: 575.98px) {
    .gb-reihe { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
}

/* ==========================================================================
   Suchauswahl (.suchauswahl*)
   --------------------------------------------------------------------------
   Ein Feld zum Tippen, darunter die Treffer – gebaut von
   assets/js/suchauswahl.js. Zwei Stellen benutzen es, und beide sollen gleich
   aussehen: der Dialog „Neue Konversation" in WhatsApp (dort wird eine
   Auswahlliste dazu umgebaut) und die Kontaktsuche im Versandkasten der
   Formulare (dort fragt das Feld beim Tippen den Server).

   Bis zum 11.08.2026 hieß die Familie `.wa-suchauswahl*` und stand in
   05-vertrieb.css – also im WhatsApp-Abschnitt, obwohl mit dem Versandkasten
   eine zweite Fläche dasselbe braucht. Sie liegt deshalb hier bei den
   Bausteinen; die Werte sind unverändert übernommen.
   ========================================================================== */
.suchauswahl { position: relative; }
.suchauswahl-liste {
    position: absolute;
    z-index: 30;
    left: 0;
    right: 0;
    top: calc(100% + 2px);
    max-height: 260px;
    overflow-y: auto;
    margin: 0;
    padding: 4px;
    list-style: none;
    background: var(--brand-surface);
    border: 1px solid var(--brand-border);
    border-radius: var(--r-ctl);
    box-shadow: var(--shadow-pop);
}
.suchauswahl-treffer {
    padding: 5px 8px;
    border-radius: var(--r-sm);
    font-size: var(--fs-5);
    line-height: 1.3;
    cursor: pointer;
}
.suchauswahl-treffer.is-aktiv,
.suchauswahl-treffer:hover { background: var(--blau-hell); }
.suchauswahl-detail {
    display: block;
    color: var(--brand-quiet);
    font-size: var(--fs-3);
}
.suchauswahl-hinweis {
    padding: 5px 8px;
    color: var(--brand-quiet);
    font-size: var(--fs-5);
}

/* Das Personenzeichen vor dem Namen (die Formulare setzen es; in WhatsApp
   steht dort nichts). Es sitzt IM .suchauswahl-name, damit die zweite Zeile
   darunter bündig bleibt. */
.suchauswahl-name {
    display: flex;
    align-items: center;
    gap: 0.45rem;
}
.suchauswahl-name > svg {
    width: 15px;
    height: 15px;
    flex: none;
    color: var(--brand-quiet);
}
/* Der Name als EIN Flexelement – siehe suchauswahl.js: Die Hervorhebung der
   Fundstelle zerlegt ihn sonst in mehrere, und der Abstand der Spur stünde
   mitten im Wort. `min-width: 0` lässt einen langen Namen schrumpfen, statt
   die Zeile über die Liste hinauszuschieben. */
.suchauswahl-text { min-width: 0; }
.suchauswahl-treffer.is-aktiv .suchauswahl-name > svg,
.suchauswahl-treffer:hover .suchauswahl-name > svg { color: var(--btn-leucht-dark); }

/* DIE ÜBERNAHME, DIE MAN SIEHT (29.08.2026)

   Steht das Suchfeld nicht neben der Stelle, die es füllt, sondern unter der
   ganzen Maske (Kasten „Darlehensnehmer suchen" unter finanzierung_form.php),
   passiert auf den Klick hin scheinbar nichts: Der Name landet dreißig
   Zentimeter weiter oben. Er leuchtet deshalb einmal kurz auf – eine Sekunde,
   dann ist es wieder eine gewöhnliche Zeile. Ohne Bewegung, nur Farbe: Die
   Zeile darf nicht springen, sie steht mitten im Formular. */
.ist-uebernommen {
    animation: wahl-uebernommen 1.1s ease-out 1;
    border-radius: var(--r-sm);
}
@keyframes wahl-uebernommen {
    from { background: var(--blau-hell); }
    to   { background: transparent; }
}
@media (prefers-reduced-motion: reduce) {
    /* Kein Verblassen, aber auch nicht nichts: Die Tönung bleibt einfach
       stehen, bis die Maske abgeschickt und die Seite neu ist. */
    .ist-uebernommen { animation: none; background: var(--blau-hell); }
}

/* ==========================================================================
   Farbwahl im Formular (.farbwahl)

   Die acht Haustöne als Reihe von Feldern, eins davon an. Steht dort, wo
   eine Sache in einem gewöhnlichen Formular ihre Farbe bekommt – zuerst
   bei den Terminarten (terminarten.php).

   DIE AUSWAHL MUSS SOFORT STEHEN. Der Ring hing bis zum 26.08.2026 an dem,
   was der Server gerendert hatte: Wer eine Farbe anklickte, sah nichts,
   klickte die nächste und hielt die Wahl für kaputt – sichtbar wurde sie
   erst nach dem Speichern. Den Ring macht jetzt `:has(input:checked)`,
   ohne Server und ohne JavaScript.

   DAS FELD IST DAS BEDIENELEMENT, kein Bild daneben. Der Knopf liegt
   deckungsgleich darüber (opacity: 0) statt auf `display: none`: Was nicht
   angezeigt wird, gibt es für Tastatur und Vorleseprogramm nicht, und mit
   den Pfeiltasten war die Reihe deshalb nicht zu bedienen.

   Dieselbe Fassung wie die Farbreihe beim Anlegen eines Kalenders
   (.cal-swatches-wahl in 03-kalender.css), nur in Formulargröße.
   ========================================================================== */
.farbwahl { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.farbwahl-feld {
    position: relative;
    display: inline-flex;
    width: 30px;
    height: 24px;
    border: 1px solid var(--brand-border);
    border-radius: var(--r-sm);
    cursor: pointer;
    transition: transform var(--t-fast) var(--ease-out);
}
.farbwahl-feld:hover { transform: scale(1.08); }
.farbwahl-feld input {
    position: absolute;
    inset: 0;
    margin: 0;
    opacity: 0;
    cursor: pointer;
}
.farbwahl-feld:has(input:checked) {
    outline: 2px solid var(--btn-leucht-dark);
    outline-offset: 1px;
}
/* Der Fokusring der Tastatur – zwei Pixel weiter außen, damit er neben dem
   Ring der Auswahl noch als eigener Zustand zu lesen ist. */
.farbwahl-feld:has(input:focus-visible) {
    outline: 2px solid var(--btn-leucht-dark);
    outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
    .farbwahl-feld { transition: none; }
    .farbwahl-feld:hover { transform: none; }
}

/* ==========================================================================
   DIE FUNDSTELLE IM TREFFER (29.08.2026)

   In der Trefferliste eines Suchfeldes standen bis hierher lauter gleich
   aussehende Namen. Wer „marc" tippt und vier Zeilen bekommt – zwei Marc
   Höfer, einen Marc Loibl und eine Adresse, in der „bismarcks" steckt –,
   muss jede Zeile lesen, um zu sehen, WARUM sie da ist.

   Hervorgehoben wird nicht mit Fläche, sondern mit Gewicht und Farbe. Eine
   Tönung hinter dem Wort wäre auf --blau-hell (Zeile unter dem Zeiger, Zeile
   mit der Tastaturmarke) nicht mehr zu sehen; das tiefe Blau steht dort bei
   5,3 : 1 und auf Weiß darüber.

   suchauswahl.js hebt nur hervor, was WÖRTLICH getroffen ist. Die Suche
   selbst faltet Umlaute („mueller" findet „Müller"); dort fällt die
   Hervorhebung weg statt an der falschen Stelle zu stehen.
   ========================================================================== */
.suchauswahl-fund {
    background: none;
    color: var(--btn-leucht-tief);
    font-weight: 700;
}

/* ==========================================================================
   SKELETT – die Form vor dem Inhalt (29.08.2026)

   Bis hierher stand während eines Abrufs entweder nichts da oder der Satz
   „Wird geladen …". Beides sagt „warte", keines sagt „was". Ein Skelett
   sagt beides: Es hat die Maße dessen, was gleich kommt, also springt
   nichts, wenn der Inhalt eintrifft.

   ES IST EINE ZUGABE, KEIN ZUSTAND. Gebaut wird es nur von JavaScript und
   nur für die Dauer eines Abrufs; ohne Skript gibt es weder Skelett noch
   den Abruf, für den es steht.

   DER SCHIMMER LÄUFT NUR, WENN ER DARF. Bei `prefers-reduced-motion` bleibt
   der Balken still stehen – die Aussage „hier kommt gleich etwas" trägt die
   Form, nicht die Bewegung.
   ========================================================================== */
.skelett-zeile {
    /* Als Block, nicht als Zeile: Ein <span> im Fließtext nähme weder Höhe
       noch Breite an. */
    display: block;
    height: 10px;
    border-radius: var(--r-pill);
    background: var(--brand-border);
    /* Der Schimmer ist ein heller Streifen, der einmal je 1,4 s durchläuft.
       Er sitzt im Verlauf, nicht in einem zweiten Element darüber: ein
       Pseudoelement bräuchte Überlauf-Beschneidung an jeder Stelle, an der
       ein Skelett steht. */
    background-image: linear-gradient(
        90deg,
        var(--brand-border) 0%,
        var(--blau-hauch) 40%,
        var(--brand-border) 80%
    );
    background-size: 300% 100%;
    animation: skelett-schimmer 1.4s var(--ease-out) infinite;
}
.skelett-zeile + .skelett-zeile { margin-top: 7px; }
/* Zwei Maße reichen: die volle Zeile und die kurze darunter. Mehr Stufen
   sähen aus wie echter Inhalt und wären beim nächsten Abruf falsch. */
.skelett-zeile.ist-kurz { width: 45%; }
.skelett-zeile.ist-halb { width: 70%; }

/* Die Platzhalterzeile in einer Trefferliste – dasselbe Polster wie ein
   echter Treffer, damit beim Eintreffen nichts springt. */
.suchauswahl-skelett {
    padding: 7px 8px;
    list-style: none;
}

@keyframes skelett-schimmer {
    from { background-position: 100% 0; }
    to   { background-position: -60% 0; }
}

@media (prefers-reduced-motion: reduce) {
    .skelett-zeile { animation: none; background-image: none; }
}

/* ==========================================================================
   Die Zeichentafel – Emojis in ein Textfeld setzen (hierher am 29.08.2026)
   --------------------------------------------------------------------------
   NICHT ZU VERWECHSELN MIT .emoji-wahl / .emoji-tafel in 01-basis.css: Das ist
   der Zeichenwähler des Terminformulars, der EIN Zeichen als Marke des Termins
   aussucht. Diese hier setzt Zeichen in einen laufenden Text ein – zwei
   Bausteine, zwei Namen; unter demselben hätten sie sich gegenseitig verstellt.

   Sie stand in 05-vertrieb.css, solange es sie nur im Antwortfeld der
   Nachrichten gab. Seit die Instagram-Beiträge sie an Bildunterschrift und
   erstem Kommentar tragen, ist sie ein Baustein: eine Tafel, ein Raster,
   ein Zeichen – und jede Seite sagt nur, wo sie aufklappt.

   VORGABE IST NACH UNTEN: Ein Formular hat unter dem Feld Platz, ein
   Gespräch nicht. Das Antwortfeld dreht sie deshalb selbst um
   (.wa-send-form .zeichentafel in 05-vertrieb.css).

   Gefüllt wird sie von assets/js/zeichentafel.js; ohne das Skript steht sie
   nicht da, und der Knopf davor auch nicht.
   ========================================================================== */
.zeichentafel-anker { position: relative; }

.zeichentafel {
    position: absolute;
    top: 100%;
    right: 0;
    z-index: 20;
    /* Breit genug für zehn Zeichen nebeneinander, aber nie breiter als das
       Fenster: Auf dem Handy stünde sie sonst halb außerhalb. */
    width: min(22rem, calc(100vw - 2rem));
    max-height: 260px;
    margin-top: 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);
}
.zeichentafel-gruppe + .zeichentafel-gruppe { margin-top: 0.55rem; }
.zeichentafel-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);
}
.zeichentafel-taste {
    width: 32px;
    height: 32px;
    padding: 0;
    border: 0;
    border-radius: var(--r-sm);
    background: none;
    /* Die Emoji-Schriften des Systems zuerst – ohne sie zeichnet manche
       Textschrift ein leeres Kästchen statt des Bildes. Dieselbe Reihe wie am
       Zeichen des Terminformulars (.emoji-knopf-zeichen, 01-basis.css). */
    font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif;
    font-size: var(--fs-9);
    line-height: 1;
    cursor: pointer;
}
.zeichentafel-taste:hover,
.zeichentafel-taste:focus-visible { background: var(--brand-row); }
